

<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.amigaos.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Simon+Archer</id>
	<title>AmigaOS Documentation Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.amigaos.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Simon+Archer"/>
	<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/wiki/Special:Contributions/Simon_Archer"/>
	<updated>2026-04-04T08:17:46Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=AmiWest_2013_Lesson_4&amp;diff=7522</id>
		<title>AmiWest 2013 Lesson 4</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=AmiWest_2013_Lesson_4&amp;diff=7522"/>
		<updated>2014-04-13T21:53:33Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Simple IP Clients &amp;amp; Servers =&lt;br /&gt;
&lt;br /&gt;
Simple network access is easy!&lt;br /&gt;
&lt;br /&gt;
Developing applications that use TCP/IP &amp;quot;sockets&amp;quot; for network communications&lt;br /&gt;
have a reputation of being a challenging task.  But AmigaOS and its Roadshow &lt;br /&gt;
TCP/IP stack provides a couple of built-in shorthand mechanisms for easily&lt;br /&gt;
creating simple network clients and servers: the TCP: handler and Roadshow&#039;s&lt;br /&gt;
Superserver.&lt;br /&gt;
&lt;br /&gt;
Using these Roadshow shortcuts, creating simple network client and server&lt;br /&gt;
applications for single user or light-duty uses is no more complicated than&lt;br /&gt;
reading or writing a file.  The real challenge is understanding the protocol&lt;br /&gt;
to be used (f.e. HTTP communications with web browsers) and being careful not&lt;br /&gt;
to create a security risk on your or another user&#039;s Amiga.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==An Internet Client==&lt;br /&gt;
&lt;br /&gt;
First, we will look at creating a small client to retrieve some simple&lt;br /&gt;
information from an Internet website.  Similar applications could be made&lt;br /&gt;
to retrieve basic information like stock quotes, email contents, &lt;br /&gt;
server conditions or other basic interactions.  Aminet has a number&lt;br /&gt;
examples of such clients written in ARexx that use the TCP: device&lt;br /&gt;
that can be examined.&lt;br /&gt;
&lt;br /&gt;
The Roadshow shortcut we will use is its built-in TCP: handler.  This is&lt;br /&gt;
mechanism that creates a virtual filesystem device  (&amp;quot;TCP:&amp;quot;) whenever&lt;br /&gt;
Roadhsow gets online.  To interact with a remote server, one just opens a&lt;br /&gt;
file with the name being the URL of the server and port to be accessed.&lt;br /&gt;
&lt;br /&gt;
===Connect to the Server===&lt;br /&gt;
&lt;br /&gt;
To begin with, one opens a connection to the internet server as if one&lt;br /&gt;
were opening a file.  As described above, when Roadshow gets online, it&lt;br /&gt;
creates a virtual TCP: device.  To open a connection, one opens a file&lt;br /&gt;
to the URL and port in question using this format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
TCP:&amp;lt;server URL&amp;gt;/&amp;lt;port number&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, to connect to the website &amp;quot;www.wunderground.com&amp;quot; one would&lt;br /&gt;
use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
	fileh = fopen(&amp;quot;TCP:www.wunderground.com/80&amp;quot;,&amp;quot;r+&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file name starts with TCP:, then the website URL and finally the&lt;br /&gt;
port number - here &amp;quot;80&amp;quot; is site&#039;s HTTP port (used by almost all websites).&lt;br /&gt;
&lt;br /&gt;
Typically, the port number reflects the type of port or protocol that&lt;br /&gt;
is to be used.  Such protocols could be FTP (file transfer), POP/SMTP&lt;br /&gt;
(email) or many others.  Port 80 is usually used for HTTP communications&lt;br /&gt;
with websites.&lt;br /&gt;
&lt;br /&gt;
If the file open request is successful, your Amiga is then connected to&lt;br /&gt;
that server and any further interaction with the &amp;quot;fileh&amp;quot; file handle&lt;br /&gt;
communicates directly with that port on that server.  In this case,&lt;br /&gt;
we would have connected to a websserver.&lt;br /&gt;
&lt;br /&gt;
===Talk to the Server===&lt;br /&gt;
&lt;br /&gt;
Once one has connected to a server, knowledge of the communications&lt;br /&gt;
protoccol for that type of connection is required.   &lt;br /&gt;
&lt;br /&gt;
For each of those, a server expects a certain format of interaction to&lt;br /&gt;
proceed and respond.  Fortunately, common protocols are publicly&lt;br /&gt;
documented.&lt;br /&gt;
&lt;br /&gt;
	http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers&lt;br /&gt;
&lt;br /&gt;
For each protocol there is usually an &amp;quot;RFC&amp;quot; document that describes how one&lt;br /&gt;
uses the protocol, interacts with the port and accomplishes that protocol&#039;s&lt;br /&gt;
goals.&lt;br /&gt;
&lt;br /&gt;
In the case of &amp;quot;HTTP&amp;quot; (or a &amp;quot;Hypertext Transfer Protocol&amp;quot;) connection to&lt;br /&gt;
a webserver, we are usually expected to submit a &amp;quot;GET&amp;quot; request.  Here are&lt;br /&gt;
a couple more complete references on the HTTP protocol:&lt;br /&gt;
&lt;br /&gt;
	http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol&lt;br /&gt;
&lt;br /&gt;
	http://tools.ietf.org/html/rfc2616&lt;br /&gt;
&lt;br /&gt;
To keep things simple, lets just look at submitting a &amp;quot;GET&amp;quot; request, such&lt;br /&gt;
as a web browser, like IBrowse, would do.  A simple HTTP version 1.1 GET &lt;br /&gt;
request would include the following lines:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
	GET /&amp;lt;path&amp;gt; HTTP/1.1&lt;br /&gt;
	host: &amp;lt;domain&amp;gt;&lt;br /&gt;
	user-agent: IBrowse/2.4 (AmigaOS 4.1; PPC; 68K build)&lt;br /&gt;
	Pragma: no-cache&lt;br /&gt;
	Accept-Language: en, *&lt;br /&gt;
	Accept: text/html;level=3&lt;br /&gt;
	Accept: text/html;version=3.0&lt;br /&gt;
	Accept: */*&lt;br /&gt;
	&amp;lt;blank line&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;path&amp;gt; would be the rest of the URL (if any) on that system and&lt;br /&gt;
&amp;lt;domain&amp;gt; is the name of the server.  &lt;br /&gt;
&lt;br /&gt;
Using the &amp;quot;WeatherUnderground&amp;quot; website URL from above and their pathname for&lt;br /&gt;
searching for airport conditions, we can find the current conditions at&lt;br /&gt;
Washington&#039;s Dulles International Airport with these domain &amp;amp; path values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   URL = www.wunderground.com&lt;br /&gt;
   PATH = cgi-bin/findweather/getForecast?query=IAD&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The GET request syntax can be transcribed into C code which builds the entire&lt;br /&gt;
request in a string and then sends it to the server with a simple &amp;quot;fprintf&amp;quot; to our &lt;br /&gt;
open file handle, as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
	// build web req text&lt;br /&gt;
	strcpy(line,&amp;quot;GET /&amp;quot;);&lt;br /&gt;
	strcat(line,path);&lt;br /&gt;
	strcat(line,&amp;quot; HTTP/1.1\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;host: &amp;quot;);&lt;br /&gt;
	strcat(line,domain);&lt;br /&gt;
	strcat(line,&amp;quot;\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;user-agent: IBrowse/2.4 (AmigaOS 4.1; PPC; 68K build)\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Pragma: no-cache\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept-Language: en, *\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept: text/html;level=3\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept: text/html;version=3.0\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept: */*\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;\r\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	// send web req line to server&lt;br /&gt;
	fprintf(fileh,&amp;quot;%s&amp;quot;,line);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, the variables &amp;quot;path&amp;quot; and &amp;quot;domain&amp;quot; are used to fill in some&lt;br /&gt;
blanks in the request.  The blank line at the end completes the GET request, &lt;br /&gt;
after which the server will reply using the same file handle.&lt;br /&gt;
&lt;br /&gt;
===Listen to the Server===&lt;br /&gt;
&lt;br /&gt;
Once the GET request has been sent to the webserver, the server will start&lt;br /&gt;
sending back either the requested webpage (or other content) or an error page.&lt;br /&gt;
To see what sort of content is returned by the server, you can combine the&lt;br /&gt;
domain and path values above and enter them in your web browser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   www.wunderground.com/cgi-bin/findweather/getForecast?query=IAD&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the page is loaded, viewing the page source (f.e., IBrowse menu item&lt;br /&gt;
&amp;quot;Page/Display Source...&amp;quot;) will show you the same text that your program&lt;br /&gt;
will receive after sending the get request.&lt;br /&gt;
&lt;br /&gt;
As such, your program needs to start reading from the same file handle&lt;br /&gt;
the request was sent with.  This loop will print out the first hundred&lt;br /&gt;
lines returned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
	// read in the response&lt;br /&gt;
	count = 0;&lt;br /&gt;
	while( (fgets(inStr,MAX_STR,fileh) != NULL) &amp;amp;&amp;amp; (count&amp;lt;100) )&lt;br /&gt;
	{&lt;br /&gt;
		++ count;&lt;br /&gt;
		printf(&amp;quot;line %ld = %s\n&amp;quot;,count,inStr);&lt;br /&gt;
		&lt;br /&gt;
		// process lines received here !&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this loop your applcation can parse the received lines for whatever&lt;br /&gt;
data your application is tryng to obtain.  In the case of our example program below,&lt;br /&gt;
the program searches for a string precedes the weather information we want.&lt;br /&gt;
&lt;br /&gt;
After the returned content has been read, output or otherwise processed,&lt;br /&gt;
simply closing the file handle will close the connection to the server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
	fclose(fileh);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===EXAMPLE ONE: IPClient.c===&lt;br /&gt;
&lt;br /&gt;
All of these elements are combined in the following example program&lt;br /&gt;
&amp;quot;IPClient.c&amp;quot; that asks you for a IATA airport code (f.e., IAD = Washington&lt;br /&gt;
Dulles, FRA=Frankfurt, SYD=Sydney), then parses &amp;amp; prints out the weather&lt;br /&gt;
conditions from the returned page.  &lt;br /&gt;
&lt;br /&gt;
Please Note: this example program worked with the wunderground.com&lt;br /&gt;
website in 2013-2014, as the served webpages change over time, it is &lt;br /&gt;
likely the parsing in this example is likely to fail and the program&lt;br /&gt;
no longer return useful information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
************************************************************&lt;br /&gt;
**&lt;br /&gt;
** Created by: CodeBench 0.41 (12.10.2013)&lt;br /&gt;
** Project: IPclient&lt;br /&gt;
** Date: 12-10-2013 18:51:10&lt;br /&gt;
**&lt;br /&gt;
************************************************************&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;proto/exec.h&amp;gt;&lt;br /&gt;
#include &amp;lt;proto/dos.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*****************************************************************************&lt;br /&gt;
 *		GLOBAL VARIABLES&lt;br /&gt;
 *****************************************************************************/&lt;br /&gt;
&lt;br /&gt;
STATIC CONST_STRPTR version USED = &amp;quot;$VER: IPclient v.02 (12.10.2013)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
char URL[200] = &amp;quot;www.wunderground.com/cgi-bin/findweather/getForecast?query=&amp;quot;;&lt;br /&gt;
char domain[200];&lt;br /&gt;
char path[200];&lt;br /&gt;
char fname[256] = &amp;quot;&amp;quot;;&lt;br /&gt;
#define MAX_STR 2056&lt;br /&gt;
char line[MAX_STR] = &amp;quot;&amp;quot;;&lt;br /&gt;
char inStr[MAX_STR];&lt;br /&gt;
uint16 uLen;&lt;br /&gt;
uint16 dLen;&lt;br /&gt;
uint16 count = 0;&lt;br /&gt;
char *found;&lt;br /&gt;
FILE *fileh;&lt;br /&gt;
&lt;br /&gt;
/*****************************************************************************&lt;br /&gt;
 *		PROGRAM START&lt;br /&gt;
 *****************************************************************************/&lt;br /&gt;
&lt;br /&gt;
int main(int argc,char **argv)&lt;br /&gt;
{&lt;br /&gt;
	// get URL from user&lt;br /&gt;
	printf(&amp;quot;IPclient example\n&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;======================\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;   enter airport code &amp;gt;&amp;quot;);&lt;br /&gt;
	fgets(line,sizeof(line),stdin);&lt;br /&gt;
	line[strlen(line)-1] = &#039;\0&#039;;		// strip \n off end of string&lt;br /&gt;
	printf(&amp;quot;======================\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// append airport code on URLprefix&lt;br /&gt;
	strcat(URL,line);&lt;br /&gt;
	&lt;br /&gt;
	// parse domain from path&lt;br /&gt;
	uLen = strlen(URL) - 2;&lt;br /&gt;
	strcpy(domain,strtok(URL,&amp;quot;/\n&amp;quot;));&lt;br /&gt;
	dLen = strlen(domain);&lt;br /&gt;
	if (uLen&amp;gt;dLen)&lt;br /&gt;
		strcpy(path,strtok(NULL,&amp;quot;\n&amp;quot;));&lt;br /&gt;
	else&lt;br /&gt;
		printf(&amp;quot;   No chars remain for path\n&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;   URL domain &amp;gt;%s&amp;lt;\n&amp;quot;,domain);&lt;br /&gt;
	printf(&amp;quot;   URL path &amp;gt;%s&amp;lt;\n&amp;quot;,path);&lt;br /&gt;
	&lt;br /&gt;
	// build URL filename from domain name&lt;br /&gt;
	strcpy(fname,&amp;quot;TCP:&amp;quot;);&lt;br /&gt;
	strcat(fname,domain);&lt;br /&gt;
	strcat(fname,&amp;quot;/80&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// open file access to URL&lt;br /&gt;
	printf(&amp;quot;      Opening URL &amp;gt;%s&amp;lt;\n&amp;quot;,fname);&lt;br /&gt;
	fileh = fopen(fname,&amp;quot;r+&amp;quot;);&lt;br /&gt;
	if (fileh == NULL)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Couldn&#039;t open connection domain server via \&amp;quot;%s\&amp;quot;\n&amp;quot;,fname);&lt;br /&gt;
		return RETURN_ERROR;&lt;br /&gt;
	};&lt;br /&gt;
	printf(&amp;quot;      TCP: file opened\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// build web req text&lt;br /&gt;
	strcpy(line,&amp;quot;GET /&amp;quot;);&lt;br /&gt;
	strcat(line,path);&lt;br /&gt;
	strcat(line,&amp;quot; HTTP/1.1\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;host: &amp;quot;);&lt;br /&gt;
	strcat(line,domain);&lt;br /&gt;
	strcat(line,&amp;quot;\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;user-agent: IBrowse/2.4 (AmigaOS 4.1; PPC; 68K build)\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Pragma: no-cache\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept-Language: en, *\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept: text/html;level=3\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept: text/html;version=3.0\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;Accept: */*\r\n&amp;quot;);&lt;br /&gt;
	strcat(line,&amp;quot;\r\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// send web req line to server&lt;br /&gt;
	fprintf(fileh,&amp;quot;%s&amp;quot;,line);&lt;br /&gt;
	strcpy(line,&amp;quot;&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;      Web req sent\n&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;======================\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// read in the response&lt;br /&gt;
	while( (fgets(inStr,MAX_STR,fileh) != NULL) &amp;amp;&amp;amp; (count&amp;lt;100) )&lt;br /&gt;
	{&lt;br /&gt;
		++ count;&lt;br /&gt;
		//printf(&amp;quot;line %d = %s\n&amp;quot;,count,inStr);&lt;br /&gt;
		&lt;br /&gt;
		// look for name of airport&lt;br /&gt;
		found = strstr(inStr,&amp;quot;og:title&amp;quot;);&lt;br /&gt;
		if (found != NULL)&lt;br /&gt;
		{&lt;br /&gt;
			found = strtok(inStr,&amp;quot;=&amp;quot;);&lt;br /&gt;
			found = strtok(NULL,&amp;quot;=&amp;quot;);&lt;br /&gt;
			printf(&amp;quot;WeatherUnderground.com reports:\n&amp;quot;);&lt;br /&gt;
			printf(&amp;quot;   Airport   = %s\n&amp;quot;,strtok(NULL,&amp;quot;|&amp;quot;)+1);&lt;br /&gt;
			printf(&amp;quot;   Temp      =%s F\n&amp;quot;,strtok(NULL,&amp;quot;&amp;amp;&amp;quot;));&lt;br /&gt;
			found = strtok(NULL,&amp;quot;|&amp;quot;);&lt;br /&gt;
			printf(&amp;quot;   Condition =%s\n&amp;quot;,strtok(NULL,&amp;quot;\&amp;quot;&amp;quot;));			&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;======================\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	// close file&lt;br /&gt;
	fclose(fileh);&lt;br /&gt;
	&lt;br /&gt;
	return RETURN_OK;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Designing Your Network Client===&lt;br /&gt;
&lt;br /&gt;
As you see, the above code and the example program, the mechanics&lt;br /&gt;
of connecting to a internet server and obtaining data are relatively&lt;br /&gt;
trivial.  The real challenge for the developer lies in understanding&lt;br /&gt;
the protocol used and in processing the data sent and received.&lt;br /&gt;
&lt;br /&gt;
Public webservers make for fairly rich and easy targets to interact&lt;br /&gt;
with.  You can explore simple interaction with any webbrowser and mimic&lt;br /&gt;
that interaction with your code.  In many cases, you can control the&lt;br /&gt;
feedback just by crafting the web request as we did above and then&lt;br /&gt;
parse the results.&lt;br /&gt;
&lt;br /&gt;
Naturally, the more complicated the interactions, like logging into&lt;br /&gt;
a website, would require much more knowledge of the protocols used&lt;br /&gt;
more complicated code that is beyond the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
But there are a number of basic topics you should consider when&lt;br /&gt;
designing a web client!&lt;br /&gt;
&lt;br /&gt;
====Server Suitability:====&lt;br /&gt;
&lt;br /&gt;
Unless you are connecting to your own server or it invites such&lt;br /&gt;
connections (some publish API&#039;s for you to make such connections),&lt;br /&gt;
your application&#039;s &amp;quot;visit&amp;quot; may not be welcome or even legal.&lt;br /&gt;
&lt;br /&gt;
At the very least, your program should &amp;quot;tread lightly&amp;quot; - do not abuse&lt;br /&gt;
the server with unnecesary or intrusive requests.  Furthermore, if &lt;br /&gt;
your client uses the resources of someone else&#039;s server, you should&lt;br /&gt;
credit the server within your application and documentation.&lt;br /&gt;
&lt;br /&gt;
====Server Changes:====&lt;br /&gt;
&lt;br /&gt;
As with any programming that interacts with external inputs, your&lt;br /&gt;
code should provide for the possibility the connection may not&lt;br /&gt;
succeed or that the returned results may not be what was expected.&lt;br /&gt;
&lt;br /&gt;
As servers and websites change over time, the processing and&lt;br /&gt;
parsing of your program may often have to change accordingly.  &lt;br /&gt;
To maintain your program and deal with such changes, you may want&lt;br /&gt;
to consider how to make changing those things easy (by the user?).&lt;br /&gt;
The parsing strings could be kept in program tooltypes or config&lt;br /&gt;
text file, you could provide a GUI for managing the parsing, employ&lt;br /&gt;
an external, editable ARexx macro.&lt;br /&gt;
&lt;br /&gt;
====Protocol Details &amp;amp; Vagaries:====&lt;br /&gt;
&lt;br /&gt;
Our example code presented a very simple interaction with a web&lt;br /&gt;
server using the a widely supported version of the HTTP protocol.&lt;br /&gt;
As one develops an application and uses a protocol, one should get&lt;br /&gt;
familiar with the details of that protocol.  Typically a &amp;quot;RFC&amp;quot;&lt;br /&gt;
document (as linked above) will describe the details of how things&lt;br /&gt;
are to work and how they might fail.  Your application should be&lt;br /&gt;
careful to comply with the details of the protocol (&amp;quot;Are we sending&lt;br /&gt;
a CR-LF or LF-CR?!&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
===Ideas===&lt;br /&gt;
&lt;br /&gt;
The above example was just a quick, simple exercise in demosntrating&lt;br /&gt;
the use of the AmigaOS Roadshow TCP: handler to access a web server.&lt;br /&gt;
There are many ways applications could be created to have simple&lt;br /&gt;
interactions with all sorts internet services, such as:&lt;br /&gt;
&lt;br /&gt;
 · Check stock quotes from a financial site.&lt;br /&gt;
 · Get package tracking information from a shipping site.&lt;br /&gt;
 · Check for new emails on a POP email server.&lt;br /&gt;
 · Convert currencies with a financial or travel web site.&lt;br /&gt;
 · Check for files on an FTP server.&lt;br /&gt;
 · Send messages with a SMTP email server.&lt;br /&gt;
 · Look up words on a dictionary website.&lt;br /&gt;
&lt;br /&gt;
You could also write your own server for another Amiga and interact&lt;br /&gt;
with your own client.   A remote controlled media player?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==An Internet Server==&lt;br /&gt;
&lt;br /&gt;
Next we will look at creating a simple internet server program that relies on AmigaOS Roadshow&#039;s &amp;quot;SuperServer&amp;quot; to receive the incoming&lt;br /&gt;
internet connection and share it with our application.&lt;br /&gt;
&lt;br /&gt;
Simply speaking, once Roadshow is configured to recognize the incoming&lt;br /&gt;
request and that your application is there to handle it; our program&lt;br /&gt;
just has to deal with another case of simple file-like interaction.&lt;br /&gt;
&lt;br /&gt;
For this example, we will create a simple server that accepts an HTTP&lt;br /&gt;
protocol request (like from IBrowse) and then respponds to it with a&lt;br /&gt;
simple webpage.  Of course, you could write a server to serve an&lt;br /&gt;
interactive webpage, some machine information, media files, etc.&lt;br /&gt;
Just be careful.&lt;br /&gt;
&lt;br /&gt;
===Receive the Request===&lt;br /&gt;
&lt;br /&gt;
When Roadshow receives an internet request on the designated port that&lt;br /&gt;
corresponds to our server, it starts our server program and routes the&lt;br /&gt;
network connection to our program using the &amp;quot;standard&amp;quot; input stream&lt;br /&gt;
(otherwise known as &amp;quot;stdin&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Our application then reads the stream almost like reading from any&lt;br /&gt;
other file or user input, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
	// read in the response&lt;br /&gt;
	while( (fgets(inStr,MAX_STR,(FILE *)stdin) != NULL) &amp;amp;&amp;amp; (count&amp;lt;100) )&lt;br /&gt;
	{&lt;br /&gt;
		if (strlen(inStr)&amp;lt;3)&lt;br /&gt;
		{&lt;br /&gt;
			IExec-&amp;gt;DebugPrintF(&amp;quot;   received nearly empty line, ending read loop.\n&amp;quot;,NULL,NULL);&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
		++ count;&lt;br /&gt;
		IExec-&amp;gt;DebugPrintF(&amp;quot;   %s\n&amp;quot;,inStr,NULL,NULL,NULL);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
As you can see, we loop reading incoming lines until we encounter a&lt;br /&gt;
line with two or fewer characters (essentially an empty line with&lt;br /&gt;
what should be a CR-LF).  There is also a counter that kicks us out&lt;br /&gt;
if the loop if we read 100 lines - that&#039;s a sign something else is &lt;br /&gt;
wrong, we should never see that with the HTTP protocol.&lt;br /&gt;
&lt;br /&gt;
With the HTTP protocol, the first line is where we would see what is&lt;br /&gt;
being requested.  Were our server to use other protocols, we may have to&lt;br /&gt;
add our server&#039;s &amp;quot;intelligence&amp;quot; elsewhere.&lt;br /&gt;
&lt;br /&gt;
We also do all our diagnostics output using the &amp;quot;DebugPrintf&amp;quot;. Which&lt;br /&gt;
means we either need to run Sashimi or watch output on the serial port&lt;br /&gt;
(with your second Amiga, naturally).  In the case of this example, we&lt;br /&gt;
will see the entire incoming request printed out on the serial port.&lt;br /&gt;
Of course, there&#039;s a reason why we have to use the serial for our debug output...&lt;br /&gt;
&lt;br /&gt;
===Respond to the Visitor===&lt;br /&gt;
&lt;br /&gt;
Once we&#039;ve read the (almost) empty line at the end of the incoming&lt;br /&gt;
web request, we will use another &amp;quot;standard&amp;quot; stream (know as &amp;quot;stdout&amp;quot;) to respond to our&lt;br /&gt;
internet visitor.&lt;br /&gt;
&lt;br /&gt;
Anything we output to &amp;quot;stdout&amp;quot; will be sent by Roadshow back to our&lt;br /&gt;
internet visitor.  This is the reason why we used the serial port for&lt;br /&gt;
diagnostic print outs, since a simple &amp;quot;printf&amp;quot; would have gone to&lt;br /&gt;
our web visitor.&lt;br /&gt;
&lt;br /&gt;
In this example, we create a basic loop that feeds a predefined series of lines&lt;br /&gt;
of a very simple webpage to Roadshow and our web visitor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
	//loop thru text writing to stdout&lt;br /&gt;
	do&lt;br /&gt;
	{&lt;br /&gt;
		if (strlen(lines[l]) &amp;gt; 0)&lt;br /&gt;
		{&lt;br /&gt;
			IExec-&amp;gt;DebugPrintF(&amp;quot;   printing line = %s\n&amp;quot;,lines[l],NULL,NULL);			&lt;br /&gt;
			if (fprintf(stdout,&amp;quot;%s\n&amp;quot;,lines[l]) &amp;lt; 0)&lt;br /&gt;
			{&lt;br /&gt;
				IExec-&amp;gt;DebugPrintF(&amp;quot;ERROR printing line\n&amp;quot;,NULL,NULL);&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			fflush(stdout);&lt;br /&gt;
		}&lt;br /&gt;
		else&lt;br /&gt;
		{&lt;br /&gt;
			IExec-&amp;gt;DebugPrintF(&amp;quot;   empty line, loop end\n&amp;quot;,NULL,NULL);&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
		++l;&lt;br /&gt;
	} while (l &amp;lt; 25);		// emergency loop escape to stop endlessness&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, our loop ends when we hit an empty line in our webpage&lt;br /&gt;
definition or a maximum of 25 lines (a failsafe).  Then we &amp;quot;flush&amp;quot; the output&lt;br /&gt;
stream and quit our program.&lt;br /&gt;
&lt;br /&gt;
The request was received, our little webpage sent, we quit and Roadshow takes&lt;br /&gt;
care of all the housekeeping.&lt;br /&gt;
&lt;br /&gt;
===EXMAPLE TWO:  IPserver.c===&lt;br /&gt;
&lt;br /&gt;
We can see all these pieces and the definition of our simple webpage in&lt;br /&gt;
the full program here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
************************************************************&lt;br /&gt;
**&lt;br /&gt;
** Created by: CodeBench 0.41 (12.10.2013)&lt;br /&gt;
** Project: IPserver&lt;br /&gt;
** Date: 13-10-2013 23:41:17&lt;br /&gt;
**&lt;br /&gt;
************************************************************&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;proto/exec.h&amp;gt;&lt;br /&gt;
#include &amp;lt;proto/dos.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*****************************************************************************&lt;br /&gt;
 *		GLOBAL VARIABLES&lt;br /&gt;
 *****************************************************************************/&lt;br /&gt;
&lt;br /&gt;
STATIC CONST_STRPTR version USED = &amp;quot;$VER: IPserver 0.14 (13.10.2013)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// define maximum web request lines &amp;amp; length&lt;br /&gt;
#define MAX_STR 2048&lt;br /&gt;
&lt;br /&gt;
// ARS path &amp;amp; file name&lt;br /&gt;
uint16 count = 0;&lt;br /&gt;
char inStr[MAX_STR];&lt;br /&gt;
&lt;br /&gt;
CONST_STRPTR lines[] =&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;HTTP/1.0\015&amp;quot;,&lt;br /&gt;
	&amp;quot;Content-Type: text/html\015&amp;quot;,&lt;br /&gt;
	&amp;quot;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;lt;HTML&amp;gt;&amp;lt;HEAD&amp;gt;&amp;lt;TITLE&amp;gt;IPserver&amp;lt;/TITLE&amp;gt;&amp;lt;/HEAD&amp;gt;&amp;lt;BODY BGCOLOR=\&amp;quot;cccccc\&amp;quot;&amp;gt;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;lt;TABLE WIDTH=100%&amp;gt;&amp;lt;TD ALIGN=\&amp;quot;center\&amp;quot; BGCOLOR=\&amp;quot;cccccc\&amp;quot;&amp;gt;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;lt;BR&amp;gt;&amp;lt;TABLE WIDTH=90%&amp;gt;&amp;lt;TR&amp;gt;&amp;lt;TD&amp;gt;&amp;lt;B&amp;gt;&amp;lt;H1&amp;gt;WELCOME&amp;lt;/H1&amp;gt;&amp;lt;/B&amp;gt;&amp;lt;BR&amp;gt;&amp;lt;/TD&amp;gt;&amp;lt;/TR&amp;gt;&amp;lt;/TABLE&amp;gt;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;lt;TR&amp;gt;&amp;lt;TD BGCOLOR=\&amp;quot;6688ee\&amp;quot;&amp;gt;&amp;lt;H3&amp;gt;&amp;lt;P&amp;gt;&amp;lt;P&amp;gt;&amp;lt;FONT COLOR=\&amp;quot;white\&amp;quot;&amp;gt;&amp;lt;B&amp;gt;AmigaOS IPserver example&amp;lt;/B&amp;gt;&amp;lt;/FONT&amp;gt;&amp;lt;/TD&amp;gt;&amp;lt;/TR&amp;gt;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;lt;TR&amp;gt;&amp;lt;TD ALIGN=\&amp;quot;center\&amp;quot; BGCOLOR=\&amp;quot;cccccc\&amp;quot;&amp;gt;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;lt;BR&amp;gt;&amp;lt;TABLE CELLSPACING=0 WIDTH=90%&amp;gt;&amp;lt;TR BGCOLOR=\&amp;quot;ffffff\&amp;quot;&amp;gt;&amp;lt;TD WIDTH=100&amp;gt;&amp;lt;H4&amp;gt;&amp;lt;B&amp;gt;And so it begins...&amp;lt;/B&amp;gt;&amp;lt;/TD&amp;gt;&amp;lt;TD&amp;gt; Your Amiga internet server! &amp;lt;/TD&amp;gt;&amp;lt;/TR&amp;gt;&amp;lt;/TABLE&amp;gt;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;lt;/TR&amp;gt;&amp;lt;/TD&amp;gt;&amp;lt;/TABLE&amp;gt;&amp;lt;/BODY&amp;gt;&amp;lt;/HTML&amp;gt;\015&amp;quot;,&lt;br /&gt;
	&amp;quot;&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
uint16 l = 0;&lt;br /&gt;
&lt;br /&gt;
/*****************************************************************************&lt;br /&gt;
 *		PROGRAM START&lt;br /&gt;
 *****************************************************************************/&lt;br /&gt;
&lt;br /&gt;
// Starting program&lt;br /&gt;
int main(int argc,char **argv)&lt;br /&gt;
{&lt;br /&gt;
	&lt;br /&gt;
	IExec-&amp;gt;DebugPrintF(&amp;quot;======================================\n&amp;quot;);&lt;br /&gt;
	IExec-&amp;gt;DebugPrintF(&amp;quot;IPserver starting\n&amp;quot;);&lt;br /&gt;
	IExec-&amp;gt;DebugPrintF(&amp;quot;======================================\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	//		Was program started from shell or WB ?&lt;br /&gt;
	if (argc &amp;gt; 0)&lt;br /&gt;
	{&lt;br /&gt;
		&lt;br /&gt;
		// read in the response&lt;br /&gt;
		while( (fgets(inStr,MAX_STR,(FILE *)stdin) != NULL) &amp;amp;&amp;amp; (count&amp;lt;100) )&lt;br /&gt;
		{&lt;br /&gt;
			//  ####   Test for CR-LR only line&lt;br /&gt;
			if (strlen(inStr)&amp;lt;3)&lt;br /&gt;
			{&lt;br /&gt;
				IExec-&amp;gt;DebugPrintF(&amp;quot;   received nearly empty line, ending read loop.\n&amp;quot;,NULL,NULL);&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			++ count;&lt;br /&gt;
			IExec-&amp;gt;DebugPrintF(&amp;quot;   %s\n&amp;quot;,inStr,NULL,NULL,NULL);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		IExec-&amp;gt;DebugPrintF(&amp;quot;======================================\n&amp;quot;);&lt;br /&gt;
		IExec-&amp;gt;DebugPrintF(&amp;quot;FINISHED READING WEB REQUEST\n&amp;quot;);&lt;br /&gt;
		IExec-&amp;gt;DebugPrintF(&amp;quot;SERVING WEB PAGE...\n&amp;quot;);&lt;br /&gt;
		IExec-&amp;gt;DebugPrintF(&amp;quot;======================================\n&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		//loop thru text writing to stdout&lt;br /&gt;
		do&lt;br /&gt;
		{&lt;br /&gt;
			if (strlen(lines[l]) &amp;gt; 0)&lt;br /&gt;
			{&lt;br /&gt;
				IExec-&amp;gt;DebugPrintF(&amp;quot;   printing line = %s\n&amp;quot;,lines[l],NULL,NULL);&lt;br /&gt;
				&lt;br /&gt;
				if (fprintf(stdout,&amp;quot;%s\n&amp;quot;,lines[l]) &amp;lt; 0)&lt;br /&gt;
				{&lt;br /&gt;
					IExec-&amp;gt;DebugPrintF(&amp;quot;ERROR printing line\n&amp;quot;,NULL,NULL);&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				fflush(stdout);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				IExec-&amp;gt;DebugPrintF(&amp;quot;   empty line, loop end\n&amp;quot;,NULL,NULL);&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			++l;&lt;br /&gt;
		} while (l &amp;lt; 25);		// emergency loop escape to stop endlessness&lt;br /&gt;
		&lt;br /&gt;
		IExec-&amp;gt;DebugPrintF(&amp;quot;======================================\n&amp;quot;);&lt;br /&gt;
		IExec-&amp;gt;DebugPrintF(&amp;quot;Web service finished... \n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
		printf(&amp;quot;IPserver started from Workbench - Don&#039;t do it again, this is a Roadshow app!\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	IExec-&amp;gt;DebugPrintF(&amp;quot;IPserver Quitting!\n&amp;quot;);&lt;br /&gt;
	IExec-&amp;gt;DebugPrintF(&amp;quot;======================================\n&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	return RETURN_OK;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see there&#039;s also a bit of housekeeping code at the beginning&lt;br /&gt;
to check if the program was run from the Workbench and to tell the user not to.&lt;br /&gt;
As it stands, this is program is only meant to be used by Roadshow for&lt;br /&gt;
serving your Amiga&#039;s internet visitors.&lt;br /&gt;
&lt;br /&gt;
But how do we test this all out?  First we have to let Roadshow know that&lt;br /&gt;
we&#039;ve created this server and where visitors will find it.&lt;br /&gt;
&lt;br /&gt;
===Roadshow Configuration===&lt;br /&gt;
&lt;br /&gt;
There are two areas where Roadshow needs to be told about your server&lt;br /&gt;
and the service it is going to provide.  Both of these can be configured&lt;br /&gt;
using Internet Prefs.  You can also make this configuration by editing&lt;br /&gt;
the &amp;quot;servers&amp;quot; and &amp;quot;services&amp;quot; files in the &amp;quot;DEVS:internet/&amp;quot; directory.&lt;br /&gt;
Configuration of these files is described in the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   SYS:Documentation?Roadshow/README&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you would like to spare your user from having to do either of those&lt;br /&gt;
chores, your application can even modify those files.  As soon as&lt;br /&gt;
Roadshow sees those files have been modified, it will reconfigure itself&lt;br /&gt;
accordingly.&lt;br /&gt;
&lt;br /&gt;
====Services====&lt;br /&gt;
&lt;br /&gt;
First, we need to tell Roadshow about the &amp;quot;service&amp;quot; we are providing.&lt;br /&gt;
If one opens Internet Prefs and clicks on the &amp;quot;Services&amp;quot; page, one will&lt;br /&gt;
see a list of standard internet services with their TCPIP port numbers,&lt;br /&gt;
types and aliases.&lt;br /&gt;
&lt;br /&gt;
Click the &amp;quot;New...&amp;quot; button to define a new Service.  An &amp;quot;Add service&amp;quot;&lt;br /&gt;
window will open where we can define how our server will be accessed.&lt;br /&gt;
Criticially, we need to pick a port number that is not already in use.&lt;br /&gt;
Such settings could be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   Name = IPserver&lt;br /&gt;
   Port = 7600&lt;br /&gt;
   Type = tcp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we click &amp;quot;Use&amp;quot; to accept our new values.  As soon as one clicks&lt;br /&gt;
&amp;quot;Save&amp;quot; in Internet Prefs, this service will be recognized by Roadshow.&lt;br /&gt;
&lt;br /&gt;
The same configuration could be added to Roadshow by adding this line&lt;br /&gt;
(in port number location) into the file &amp;quot;DEVS:Internet/Services&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   IPServer         7600/tcp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as one saves the file, Roadshow will be notified and adjust&lt;br /&gt;
itself for the service.&lt;br /&gt;
&lt;br /&gt;
====Servers====&lt;br /&gt;
&lt;br /&gt;
Before we can use the service above, we also need to tell Roadshow&lt;br /&gt;
about our server app and where to find it.  Again, this can be done&lt;br /&gt;
while in Internet Prefs.  Click on the &amp;quot;Servers&amp;quot; page and one will see&lt;br /&gt;
any servers configured with the services they provide (as set above),&lt;br /&gt;
their type, wait method and program path.&lt;br /&gt;
&lt;br /&gt;
Click on the &amp;quot;New...&amp;quot; button to define a new Server.  In the &amp;quot;Add server&amp;quot;&lt;br /&gt;
window we can define what sort of service our server is for, the&lt;br /&gt;
characteristics of how it will be called and where it is located on&lt;br /&gt;
our Amiga system.  Such settings could be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   Service = IPserver&lt;br /&gt;
   Type = Stream&lt;br /&gt;
   Stack = 65536&lt;br /&gt;
   Program = data:Projects/C/OS4ex-IPserver/IPserver.debug&lt;br /&gt;
   Arguments = &amp;lt;empty&amp;gt;&lt;br /&gt;
   Active = &amp;lt;checked&amp;gt;&lt;br /&gt;
   Wait for completion = &amp;lt;not checked&amp;gt;&lt;br /&gt;
   Use socket I/O streams = &amp;lt;checked&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Naturally, you should enter the server program path &amp;amp; name for your own system.&lt;br /&gt;
Again we click &amp;quot;Use&amp;quot; to accept our new Server entry and saving Internet&lt;br /&gt;
Prefs will adjust Roadshow.&lt;br /&gt;
&lt;br /&gt;
We can also make this adjustment to Roadshow&#039;s server list by adding the&lt;br /&gt;
following line to the &amp;quot;DEVS:Internet/servers&amp;quot; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   IPServer        stream     dos stack=65536 data:Projects/C/OS4ex-IPserver/IPserver.debug&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again, saving the file is automatically noticed by Roadhsow.&lt;br /&gt;
&lt;br /&gt;
Once both the service and server are correctly configured, Roadshow is ready&lt;br /&gt;
to use our new server.&lt;br /&gt;
&lt;br /&gt;
===Let&#039;s See Our Server!===&lt;br /&gt;
&lt;br /&gt;
To test our new server example, you can access it by connecting to your&lt;br /&gt;
Amiga and the designated IP port number.  On the same machine, you can&lt;br /&gt;
enter this in your browser URL line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   http://localhost:7600/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From another machine, you will need to have the IP address or defined host&lt;br /&gt;
name for your Amiga running the test server program.  The URL should&lt;br /&gt;
look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   http://192.168.1.07:7600/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In any case, the browser will connect to your Amiga at the port number&lt;br /&gt;
following the colon (&amp;quot;:&amp;quot;) and Roadshow will call up your server program&lt;br /&gt;
and let it talk to your browser and send it the preset webpage.&lt;br /&gt;
&lt;br /&gt;
===Where to go?   More Webpages?===&lt;br /&gt;
&lt;br /&gt;
Clearly the above example does little more than say &amp;quot;Hello World&amp;quot; to a&lt;br /&gt;
visiting web browser user.  It offers no interactivity, performs no task&lt;br /&gt;
and serves no media.  &lt;br /&gt;
&lt;br /&gt;
When this web server receives the incoming web request, the first line&lt;br /&gt;
(starting with &amp;quot;GET&amp;quot;) tells the server what the browser is looking for.&lt;br /&gt;
For example, if you watch the serial output and connect with a newer browser than&lt;br /&gt;
IBrowse, you can see most browsers actually make two connections to the&lt;br /&gt;
server, with one of them saying:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   GET /favicon.ico HTTP/1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In that case, the browser is requesting your server send an icon&lt;br /&gt;
that it can display on the browser tab.  Just like that, anything in the URL&lt;br /&gt;
after the machine&#039;s network name (or IP address) and the port number&lt;br /&gt;
is taken as a requested path and your server will receive it after &amp;quot;GET&amp;quot; in&lt;br /&gt;
the first line of the request.&lt;br /&gt;
&lt;br /&gt;
This just scratches the surface of requests your server may receive and&lt;br /&gt;
how it can respond to web visitors.  To dig deeper you can search the&lt;br /&gt;
many sources online or in your local bookstore on HTTP communications and&lt;br /&gt;
the formatting of HTML webpages.  Of course, you should make sure your&lt;br /&gt;
server continues outputting the request contents so you know what your server&lt;br /&gt;
is getting and should respond to.&lt;br /&gt;
&lt;br /&gt;
===Just Webpages?===&lt;br /&gt;
&lt;br /&gt;
There&#039;s also ne reason why your server needs to be limited to dealing&lt;br /&gt;
with browsers and sending webpages.  The internet is full of other&lt;br /&gt;
protocols and services that your could write a server for.  Or you could&lt;br /&gt;
create your own online client and server pair of applications that just&lt;br /&gt;
talked with each other.&lt;br /&gt;
&lt;br /&gt;
Just as we discussed with creating an Internet client, there are many&lt;br /&gt;
topics you should consider when designing an internet server program.&lt;br /&gt;
It&#039;s not just about the coding!&lt;br /&gt;
&lt;br /&gt;
====Security====&lt;br /&gt;
&lt;br /&gt;
Obviously, opening your Amiga with an internet server represents more of a&lt;br /&gt;
risk than if you had done nothing.  So it is criticially important one&lt;br /&gt;
considers security when creating a server.  While it&#039;s beyond the scope&lt;br /&gt;
of this article to inclusively discuss all the issues involved, here are some&lt;br /&gt;
basics to consider.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t blindly serve sensitive information to visitors.  How can you be&lt;br /&gt;
sure who&#039;s at the other end of the connection and who might be watching&lt;br /&gt;
along the way?  Even if randomized pathnames and request are used by&lt;br /&gt;
your server, there&#039;s no guarantee the connection is 100% secure.&lt;br /&gt;
&lt;br /&gt;
Limit commands and functions served to visitors.  Obviously, creating a&lt;br /&gt;
means of offering anything like command line access or unfettered file &lt;br /&gt;
editing/deleting powers to a web visitor would represent dangerous hole&lt;br /&gt;
in any system&#039;s security.  But one also has to make sure no whatsoever holes&lt;br /&gt;
or bugs exist in the server design that would let such access slip&lt;br /&gt;
through.&lt;br /&gt;
&lt;br /&gt;
====Server Instances &amp;amp; Load====&lt;br /&gt;
&lt;br /&gt;
One has to keep in mind the &amp;quot;SuperServer&amp;quot; method where Roadshow runs&lt;br /&gt;
your server also means your server will be executed with each and every&lt;br /&gt;
request Roadshow receives for that port.  In each case, your server&lt;br /&gt;
will do its duty and then be expected to quit.  That should be fine for&lt;br /&gt;
light duty, personal server tasks.&lt;br /&gt;
&lt;br /&gt;
But one should focus server development on keeping things as&lt;br /&gt;
&amp;quot;lightweight&amp;quot; and simple as possible.  If the server needs to&lt;br /&gt;
read data files or perform other complicated initialization, this may&lt;br /&gt;
slow reaction time for each incoming request to an unacceptable level.&lt;br /&gt;
&lt;br /&gt;
To avoid time consuming chores, one might considering using interprocess&lt;br /&gt;
communciations (such as ARexx messages) to interact with a separate&lt;br /&gt;
master program that handles all the housekeeping and remains continuously running&lt;br /&gt;
while each of internet server instance handles an incoming request, gets the information it&lt;br /&gt;
needs from the master program and quits.  &lt;br /&gt;
&lt;br /&gt;
Naturally, at some point usage requirements may require one bypasses the&lt;br /&gt;
Roadshow  SuperServer method of running servers and goes to using &lt;br /&gt;
longhand socket programming that is better suited to heavy duty use&lt;br /&gt;
- like running a serious public server.  That&#039;s beyond the scope of this article.&lt;br /&gt;
&lt;br /&gt;
Furthermore, there are whole areas of study and technology involved with the&lt;br /&gt;
handling of network user load that should be explored in implementing a serious&lt;br /&gt;
server system.&lt;br /&gt;
&lt;br /&gt;
====Protocols and Compatibility====&lt;br /&gt;
&lt;br /&gt;
As one develops a more a complex or interactive server meant to handle&lt;br /&gt;
a wider group of users (even those on lesser platforms!), one needs&lt;br /&gt;
to pay much closer attention to the protocols involved.  With each new client&lt;br /&gt;
and platform encountered, the more important implrementation details of a&lt;br /&gt;
protocol are likely to be.&lt;br /&gt;
&lt;br /&gt;
As mentioned in elsewhere in this text, there RFC&#039;s that describe the&lt;br /&gt;
formal protocols and there are likely countless webpages that address&lt;br /&gt;
idiosynacracies of implementing the protocols.&lt;br /&gt;
&lt;br /&gt;
Beyond all those, a developer will need to do serious testing with as&lt;br /&gt;
wide a pool of possible clients to refine a server&#039;s operation.  &amp;quot;You&lt;br /&gt;
aren&#039;t in Kansas anymore!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Issues==&lt;br /&gt;
&lt;br /&gt;
Whether creating a server or a client program, there are many general&lt;br /&gt;
issues that one should consider in developing such programs.&lt;br /&gt;
&lt;br /&gt;
====Complexity and Speed====&lt;br /&gt;
&lt;br /&gt;
These days it seems like few developers on lesser platforms care terribly&lt;br /&gt;
much about optimization and speed.  Those platforms typically just throw&lt;br /&gt;
more horsepower &amp;amp; memory at their chores and try to go about their business.&lt;br /&gt;
&lt;br /&gt;
In the Amiga world, without the glut of idle horsepower, development of&lt;br /&gt;
any applications and internet clients &amp;amp; servers in particular should be&lt;br /&gt;
mindful of overhead.  For every client or server transaction, there is&lt;br /&gt;
likely some user that clicked a button and is waiting for an answer.&lt;br /&gt;
Keep things simple and optimize!&lt;br /&gt;
&lt;br /&gt;
====Incomplete transactions====&lt;br /&gt;
&lt;br /&gt;
Since all these programs are dependent on communications over many links,&lt;br /&gt;
these programs need to have a robustness for failed links.  Transfers can&lt;br /&gt;
be interupted mid-stream.  Received data can be incomplete or corrupted.&lt;br /&gt;
These applications need to have the error trapping to deal with such real&lt;br /&gt;
possibilities.&lt;br /&gt;
&lt;br /&gt;
====Statelessness====&lt;br /&gt;
&lt;br /&gt;
Given the nature of internet communications and web browsing in particular,&lt;br /&gt;
servers and clients need to be &amp;quot;stateless&amp;quot; as possible.  While a visitor&lt;br /&gt;
may have just &amp;quot;logged in&amp;quot; to your server, it&#039;s not guaranteed &lt;br /&gt;
the next transaction your server receives is that logged-in user, that&lt;br /&gt;
the user hasn&#039;t left or hit the back or reload button on their browser&lt;br /&gt;
(reloading the log-in page again).  So a server should avoid making&lt;br /&gt;
assumptions about the state of the connection and status of a&lt;br /&gt;
visitor whenever possible or provide explicit means for addressing such&lt;br /&gt;
things, if possible.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7042</id>
		<title>AmigaOS Manual: Workbench Basic Operations</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7042"/>
		<updated>2014-02-01T10:39:39Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: /* Mouse Pointer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before using your Amiga, you should familiarize yourself with the basic Amiga system concepts and techniques provided in this chapter. These include:&lt;br /&gt;
&lt;br /&gt;
* Booting your system&lt;br /&gt;
* Using the pointers&lt;br /&gt;
* Using the mouse&lt;br /&gt;
* Handling disks and using disk drives&lt;br /&gt;
* Creating and accessing files and directories &lt;br /&gt;
&lt;br /&gt;
= Booting/Rebooting Your System =&lt;br /&gt;
&lt;br /&gt;
Booting powers on your computer and loads the operating system information from a disk to the computer&#039;s memory. Each time the Amiga is booted, the system must find the Amiga system software on a bootable hard disk or floppy disk inserted into a disk drive. If there are no bootable disks when the system is powered on, an animated screen requests that you insert a bootable disk into a floppy drive.&lt;br /&gt;
&lt;br /&gt;
Rebooting resets you computer without turning off the power. This process terminates any active programs and erases any data stored in the Amiga&#039;s memory.&lt;br /&gt;
&lt;br /&gt;
For information about booting and rebooting floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
Each time the Amiga is booted or rebooted, the following events occur:&lt;br /&gt;
&lt;br /&gt;
1. The Amiga executes a script file called the Startup-sequence. The Startup-sequence file contains AmigaDOS commands that load the Amiga software and handle various hardware and software setup tasks.&lt;br /&gt;
&lt;br /&gt;
2. The Startup-sequence executes a script file called User-startup, if you have created it. In general, User-startup files contain your own customized configurations, resident commands, and directory assignments. It also executes a script file called Network-startup. This script is designed to have any programs added to it that may require the networking to be functional before running programs that require it. The script is called in a special way so as not to delay the boot process while the network is initializing, but it will defer programs that rely on the network while it does.&lt;br /&gt;
Appendix B offer some instructions and suggestions of items that you can place in the User-startup and Network-startup files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. The Amiga Workbench screen appears, as illustrated in Figure 2-1. &lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-1.png|center|frame|Workbench Screen]]&lt;br /&gt;
&lt;br /&gt;
4. Workbench runs any programs that are set up in the WBStartup preferences. By adding programs to the WBStartup preferences, you can also customize your system startup. &lt;br /&gt;
&lt;br /&gt;
Do not alter the Startup-sequence file, doing so can prevent the Amiga from booting properly.&lt;br /&gt;
&lt;br /&gt;
To reboot your system:&lt;br /&gt;
&lt;br /&gt;
# Be sure that all disk activity has stopped and that all floppy disk drive and hard disk drive lights are unlit.&lt;br /&gt;
# If you are rebooting from a floppy disk drive, insert a copy of the Workbench disk into a floppy disk drive.&lt;br /&gt;
# Simultaneously hold down the Ctrl (Control), left Amiga, and right Amiga keys and then release them.&lt;br /&gt;
&lt;br /&gt;
== Special Boot Options ==&lt;br /&gt;
&lt;br /&gt;
Extra memory used for maintaining devices can prevent floppy-based games from running. See Appendix D for information about how to avoid this problem.&lt;br /&gt;
&lt;br /&gt;
= Using the Workbench Pointers =&lt;br /&gt;
&lt;br /&gt;
The Workbench has two pointers: the mouse pointer and the busy pointer.&lt;br /&gt;
&lt;br /&gt;
== Mouse Pointer ==&lt;br /&gt;
&lt;br /&gt;
The mouse pointer is a small movable picture that is used to indicate to the system the location at which you wish to do some operation. By default the mouse pointer is an image of an arrow. The mouse pointer is moved and positioned with the mouse. The tip of the pointer has a hot spot, which is one pixel (a dot of light that makes up the monitor screen display) that the system is programmed to recognize a the pointer&#039;s locator. The pointer indicates to the system the position of an item that you wish to work with. Through the mouse, you communicate the action that the system should take on this item. You can change the shape and color of the mouse pointer using the Pointer Preferences editor, described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
== Busy Pointer ==&lt;br /&gt;
&lt;br /&gt;
The busy pointer, also referred to as the wait pointer, is displayed in place of the mouse pointer to indicate that the system is attempting to execute an instruction. By default the busy pointer is an image of a stopwatch. Most Workbench operations are unavailable while the busy pointer is displayed. However, you can still move, size, and depth-arrange windows with the busy pointer. The appearance of this pointer can also be changed using the Pointer Preferences editor described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
= Using the Mouse =&lt;br /&gt;
&lt;br /&gt;
The Amiga comes equipped with a mouse, illustrated in Figure 2-2, used to communicate with the system through the pointer. The mouse pointer is positioned by moving the mouse. Manipulating the mouse so that the pointer is located over various objects and pictures on the screen and pressing the mouse buttons tells the Amiga what to do.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-2.png|center|frame|Amiga Mouse]]&lt;br /&gt;
&lt;br /&gt;
== Holding the Mouse ==&lt;br /&gt;
&lt;br /&gt;
Hold the mouse on a flat surface with the cable extending away from you so that the mouse box rests under the palm of your hand with the buttons under your fingertips. In this position, the left mouse button is the selection button and the right mouse button is the menu button.&lt;br /&gt;
&lt;br /&gt;
== Mouse Operations ==&lt;br /&gt;
&lt;br /&gt;
When using the mouse,&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Pointing || means moving the mouse so that the tip of the pointer is positioned over an object on the screen. The pointer moves in the same direction you move the mouse. The mouse can be lifted and repositioned at any time. Lifting the mouse does not move the pointer.&lt;br /&gt;
|-&lt;br /&gt;
| Clicking || means pressing and releasing the selection button.&lt;br /&gt;
|-&lt;br /&gt;
| Double-Clicking || means clicking the selection button twice in rapid succession. Double-clicking on an icon causes a window to appear or a program to start.&lt;br /&gt;
|-&lt;br /&gt;
| Holding Down || means pressing the mouse button until your action is completed.&lt;br /&gt;
|-&lt;br /&gt;
| Dragging || means moving screens, windows, and icons by holding down the selection button and moving the mouse. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Using the Selection Button ==&lt;br /&gt;
&lt;br /&gt;
The left mouse button is the selection button, used for selecting items on the monitor display for processing. This button is also used to move, or drag, items on the screen. For information about these operations, see Chapter 3.&lt;br /&gt;
&lt;br /&gt;
== Using the Menu Button ==&lt;br /&gt;
&lt;br /&gt;
The right mouse button is the menu button, which is used to display the menu bar and menus and to choose items from them. Menu bars contain the headings of each menu available for a selected window, program, or icon. Menus contain lists of options for the operations that you can do with the selected item.&lt;br /&gt;
&lt;br /&gt;
=== Using Menus ===&lt;br /&gt;
&lt;br /&gt;
Menu bars appear across the top of the screen, containing any menu headings available.&lt;br /&gt;
&lt;br /&gt;
Hold down the menu button to display the menu bar as illustrated in Figure 2-3. Hol down the menu button while pointing to the different menu headings to show the available items listed beneath each. To choose a particular item, move the pointer down and release the menu button when the pointer touches it.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-3.png|center|frame|Sample Menu Bar and Menu]]&lt;br /&gt;
&lt;br /&gt;
Some menu items have submenus, which are additional related options that appear to the right of the menu item when it is selected. The symbol » after the item name indicates a submenu. If a menu has submenus, select one of the submenu options. Choosing a main menu item without choosing one of its submenus has no effect. In addition to the » symbol, other symbols may appear on the menu:&lt;br /&gt;
&lt;br /&gt;
* An ellipsis (...) follows the name of menu items that open a requester.&lt;br /&gt;
* A checkmark in the area to the left of a menu item indicates that the items is an option that is currently selected. When this area is empty, the option is deselected. &lt;br /&gt;
&lt;br /&gt;
To execute several menu options at once, hold down the menu button and, using the selection button, click on the menu options of your choice.&lt;br /&gt;
&lt;br /&gt;
The menu button can also be used to cancel operations being performed by the selection button, such as drag selection.&lt;br /&gt;
&lt;br /&gt;
=== Ghosted Menu Items ===&lt;br /&gt;
&lt;br /&gt;
If a menu item is not available for a particular operation, it is ghosted or displayed less distinctly than the others, as illustrated in Figure 2-4.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-4.png|center|frame|Ghosted versus Available Menu Items]]&lt;br /&gt;
&lt;br /&gt;
== Canceling an Operation ==&lt;br /&gt;
&lt;br /&gt;
Cancel the operation being performed with the selection button by clicking the menu button while still holding down the selection button. The following operations can be cancelled:&lt;br /&gt;
&lt;br /&gt;
* Selecting&lt;br /&gt;
* Dragging&lt;br /&gt;
* Drag selection&lt;br /&gt;
* Changing the size of a window &lt;br /&gt;
&lt;br /&gt;
== Using the Amiga Without a Mouse ==&lt;br /&gt;
&lt;br /&gt;
All mouse actions can also be done using the keyboard. Certain key combinations allow use of the keyboard to move the pointer, select icons, and choose menu items. Keyboard shortcuts appear in the menu boxes to the right of some options. Holding down the right Amiga key and simultaneously pressing the letter displayed attains the same results as activating that menu option. Using the keyboard shortcuts instead of the menus speeds your work. For a full description of key functions, see the hardware manual for your Amiga model.&lt;br /&gt;
&lt;br /&gt;
= Using Disk Drives =&lt;br /&gt;
&lt;br /&gt;
Disk drives are devices from which information is retrieved or to which information is written or stored. An Amiga can have one or more hard disk drives, as well as floppy disk drives, depending on the model. All Amiga floppy disk drives can use low density floppy disks. However, if you have a high density floppy disk drive on your Amiga, you can also use high density floppy disks. Refer to the hardware manual that came with your system if you are not sure about the type of floppy disk drive you have.&lt;br /&gt;
&lt;br /&gt;
Each disk drive has a device name, such as DF0: for the internal floppy drive. (Additional floppy drives are designated DF1:, DF2:, and DF3:). A disk icon is displayed on the Workbench screen for each disk inserted in a drive and for each hard disk partition.&lt;br /&gt;
&lt;br /&gt;
The device name and the volume name are two ways of identifying a given disk. For most purposes use either name to refer to the disk when entering a path or within a file requester. The device name refers to the disk that is in the specified disk drive. The volume name refers specifically to a particular disk. For example, if you have a floppy disk in device DF0: with a volume name of Mydisk, you can reference it as either DF0: or Mydisk:. Referencing the disk as Mydisk: lets you insert Mydisk into any drive, not only DF0:.&lt;br /&gt;
&lt;br /&gt;
Each drive has an activity light that is lit when the device is in use, either reading or writing data.&lt;br /&gt;
&lt;br /&gt;
{{Note|title=Caution|text=Never reboot or turn off you Amiga and never remove a floppy disk from a floppy disk drive when any of the drive activity lights are lit or you risk damaging the drive and/or the files on the disk.}}&lt;br /&gt;
&lt;br /&gt;
== Inserting Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
The standard 3.5-inch floppy disk can be inserted only one way. Insert the disk into the disk drive with the label side facing up and the metal end with the indicator arrow entering first.&lt;br /&gt;
&lt;br /&gt;
== Using Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
Floppy disks must be write-enabled and formatted before information can be written on them. To write-enable a floppy disk, turn the disk to its back side and push the plastic tab in the upper left corner down to cover the hole. Conversely, to write-protect a floppy disk, push the plastic tab up, uncovering the hole Figure 2-5 illustrates the write-enable/protect tab on a floppy disk. Formatting floppy disks is described in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-5.png|center|frame|Write Protecting/Enabling Floppy Disks]]&lt;br /&gt;
&lt;br /&gt;
The disk from which information is copied is referred to as the source disk (FROM disk). The disk to which the information is copied is referred to as the destination disk (TO disk). The source disk should always be write-protected to avoid accidental erasure. The destination disk can be a blank disk or a previously used disk whose contents are no longer needed. This disk must be write-enabled to accept the information from the source disk.&lt;br /&gt;
&lt;br /&gt;
== Using the Ram Disk ==&lt;br /&gt;
&lt;br /&gt;
The Ram Disk icon represents RAM:, an area of the Amiga&#039;s internal memory that is set up as a file storage device like a disk. Files, directories, and entire floppy disk (available memory permitting) can be copied to RAM: for temporary storage. The Ram Disk serves as a work area that the system can quickly access.&lt;br /&gt;
&lt;br /&gt;
The size of RAM: is dynamic. It is never any larger than necessary to hold its contents. Therefore, it is always 100% full. Its maximum size is limited by the amount of free memory.&lt;br /&gt;
&lt;br /&gt;
The primary advantage of RAM: is speed. Since it is electronic rather than mechanical, storage and retrieval are almost instantaneous. The disadvantage of RAM: is that data stored in RAM: does not survive when the computer is powered down or rebooted. You must save to floppy disk or to hard disk anything in the Ram Disk that you want to use again.&lt;br /&gt;
&lt;br /&gt;
Applications commonly use RAM: to store temporary files created when the program runs or for backup files created when the program is exited. RAM: can also be used as storage for experimental script files, as a destination for testing command output, and when the creation of a file on an actual disk is too slow, risky, or inconvenient.&lt;br /&gt;
&lt;br /&gt;
Be careful when using RAM: for storing important files. If the Amiga loses power, has a software failure, or you reboot, everything stored in RAM: is lost. Be sure when working with RAM: to regularly back up any important files onto disk.&lt;br /&gt;
&lt;br /&gt;
{{Note|You cannot copy a disk to RAM: by dragging the source disk icon over the Ram Disk icon. To copy a disk to RAM:, open the Ram Disk icon and drag the floppy disk icon into the Ram Disk window. This creates a drawer with the name and contents of the floppy disk.}}&lt;br /&gt;
&lt;br /&gt;
== Backup Disks ==&lt;br /&gt;
&lt;br /&gt;
Backup disks ensure against a loss of data in the event of damage, corruption, or accidental erasure of the original disk. We recommend that you make backup copies of important disks and files, following the licensing agreements provided with your applications software. Making and distributing unlicensed copies of disks is a copyright violation known as software piracy. Store your original disks in a safe place and use your backup disks for everyday purposes. For information on making backup copies of your system disks on floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
= Managing Your Files =&lt;br /&gt;
&lt;br /&gt;
The basic units of data management on your Amiga are files, directories, and drawers. Files are organized collections of data that are given a name and are stored on the system or on removable media. Files are contained in directories or drawers. Directories and drawers are the same thing - a subdivision in your Amiga&#039;s filing system that is used to organize files and other directories/drawers (subdirectories).&lt;br /&gt;
&lt;br /&gt;
== Organizing Information on Disks ==&lt;br /&gt;
&lt;br /&gt;
Information should be stored on disk in a logical manner to allow easy access to your files. The Amiga Workbench organizes information into a hierarchical system of drawers.&lt;br /&gt;
&lt;br /&gt;
A drawer - a directory in AmigaDOS - is a container for items that are related. These items can be files and even other drawers.&lt;br /&gt;
&lt;br /&gt;
On any disk you can create multiple drawers containing multiple files, as available disk space allows. Workbench also allows the creation of drawers within drawers, subdrawers or subdirectories, for further file management. Create as many drawers and subdrawers on your disk as needed.&lt;br /&gt;
&lt;br /&gt;
A drawer icon is displayed in the disk window for each drawer created on a particular disk. Each drawer window contains the icons of the files and subdrawers that exist in it.&lt;br /&gt;
&lt;br /&gt;
== Paths ==&lt;br /&gt;
&lt;br /&gt;
A path is a complete description of the location of a particular file on a disk. When a program requests the name of a file for retrieval, specify the file&#039;s path, including the volume or device name and all the drawers that lead to that file.&lt;br /&gt;
&lt;br /&gt;
The method for specifying paths varies from program to program. Most programs use a file requester with a scrolling list, in which the disk name, any drawer names, and the file name are displayed. Click on the appropriate names to specify the path. However, for some programs you may have to type in the complete path name.&lt;br /&gt;
&lt;br /&gt;
To enter a complete path:&lt;br /&gt;
&lt;br /&gt;
* Type the name of the disk followed by a colon. This name is the volume name of the disk, such as Mydisk:. You can substitute the disk&#039;s device name, such as DF0:, in place of the disk name. However, if you enter the device name rather than the volume name, be sure the correct disk is in that device.&amp;lt;br/&amp;gt;Diskname:&lt;br /&gt;
&lt;br /&gt;
* For a file that is not in a drawer, specify the file name after the colon following the disk name to complete the path.&amp;lt;br/&amp;gt;Diskname:filename&lt;br /&gt;
&lt;br /&gt;
* For a file in a drawer, after the colon following the disk name specify the drawer name followed by a slash (/) followed by the file name.&amp;lt;br/&amp;gt;Diskname:drawername/filename&lt;br /&gt;
&lt;br /&gt;
* If there are more drawers in the path, each drawer must be specified followed by a slash.&amp;lt;br/&amp;gt;Diskname:drawername/subdrawername/filename&lt;br /&gt;
&lt;br /&gt;
{{Note|File and drawer names containing spaces can cause recognition problems. We recommend that you avoid using spaces in file or drawer names. If you have trouble referencing a name that contains a space, enclose the entire path in double quotation marks.}}&lt;br /&gt;
&lt;br /&gt;
== File and Drawer Names ==&lt;br /&gt;
&lt;br /&gt;
The following rules apply for naming files and drawers:&lt;br /&gt;
&lt;br /&gt;
* Names can be up to 30 characters long. Names can contain upper case letters and any punctuation marks that are not reserved.&lt;br /&gt;
* Colons (:) and slashes (/) are not allowed within a name. These characters are reserved for path statements. However, other non-alphabetic characters can be used.&lt;br /&gt;
* The use of spaces before or after names should be avoided due to the possibility of omission.&lt;br /&gt;
* Upper and lower case differences (capitalization) are preserved and displayed by the Amiga. However, the system is not case-sensitive: upper and lower case are considered the same.&lt;br /&gt;
* Duplicate file names are not allowed within the same drawer. If you save a file with the same name as an existing file in a drawer, it overwrites the original file in that drawer.&lt;br /&gt;
* Two files with the same name can exist in separate drawers or within different paths.&lt;br /&gt;
&lt;br /&gt;
== Trashcan ==&lt;br /&gt;
&lt;br /&gt;
The Trashcan is a special drawer that can be placed on a disk for storing files that you no longer needed and may wish to delete. Discard icons or pseudo-icons for the files to be deleted by dragging them into the Trashcan. If the icon to be discarded is a drawer, is associated files are also moved to the Trashcan.&lt;br /&gt;
&lt;br /&gt;
Choosing Empty Trash from the Icons menu deletes the icons and all of their associated files from the Trashcan. Before choosing Empty Trash, you can still recover any of the Trashcan&#039;s contents by opening its window and dragging the icons back out.&lt;br /&gt;
&lt;br /&gt;
For more information about putting a Trashcan on a disk, see the Format Disk description in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
= Using Application Software =&lt;br /&gt;
&lt;br /&gt;
Applications are software programs, such as databases, video and sound programs, word processing programs, recreational programs, and educational programs that are available for use on your Amiga. Most Amiga programs use windows, menus, and gadgets in ways very similar to the Workbench programs on your system disks. However, you should always read the documentation that comes with your applications for directions on using unfamiliar menu items and gadgets.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7041</id>
		<title>AmigaOS Manual: Workbench Basic Operations</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7041"/>
		<updated>2014-02-01T10:34:46Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: /* Booting/Rebooting Your System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before using your Amiga, you should familiarize yourself with the basic Amiga system concepts and techniques provided in this chapter. These include:&lt;br /&gt;
&lt;br /&gt;
* Booting your system&lt;br /&gt;
* Using the pointers&lt;br /&gt;
* Using the mouse&lt;br /&gt;
* Handling disks and using disk drives&lt;br /&gt;
* Creating and accessing files and directories &lt;br /&gt;
&lt;br /&gt;
= Booting/Rebooting Your System =&lt;br /&gt;
&lt;br /&gt;
Booting powers on your computer and loads the operating system information from a disk to the computer&#039;s memory. Each time the Amiga is booted, the system must find the Amiga system software on a bootable hard disk or floppy disk inserted into a disk drive. If there are no bootable disks when the system is powered on, an animated screen requests that you insert a bootable disk into a floppy drive.&lt;br /&gt;
&lt;br /&gt;
Rebooting resets you computer without turning off the power. This process terminates any active programs and erases any data stored in the Amiga&#039;s memory.&lt;br /&gt;
&lt;br /&gt;
For information about booting and rebooting floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
Each time the Amiga is booted or rebooted, the following events occur:&lt;br /&gt;
&lt;br /&gt;
1. The Amiga executes a script file called the Startup-sequence. The Startup-sequence file contains AmigaDOS commands that load the Amiga software and handle various hardware and software setup tasks.&lt;br /&gt;
&lt;br /&gt;
2. The Startup-sequence executes a script file called User-startup, if you have created it. In general, User-startup files contain your own customized configurations, resident commands, and directory assignments. It also executes a script file called Network-startup. This script is designed to have any programs added to it that may require the networking to be functional before running programs that require it. The script is called in a special way so as not to delay the boot process while the network is initializing, but it will defer programs that rely on the network while it does.&lt;br /&gt;
Appendix B offer some instructions and suggestions of items that you can place in the User-startup and Network-startup files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. The Amiga Workbench screen appears, as illustrated in Figure 2-1. &lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-1.png|center|frame|Workbench Screen]]&lt;br /&gt;
&lt;br /&gt;
4. Workbench runs any programs that are set up in the WBStartup preferences. By adding programs to the WBStartup preferences, you can also customize your system startup. &lt;br /&gt;
&lt;br /&gt;
Do not alter the Startup-sequence file, doing so can prevent the Amiga from booting properly.&lt;br /&gt;
&lt;br /&gt;
To reboot your system:&lt;br /&gt;
&lt;br /&gt;
# Be sure that all disk activity has stopped and that all floppy disk drive and hard disk drive lights are unlit.&lt;br /&gt;
# If you are rebooting from a floppy disk drive, insert a copy of the Workbench disk into a floppy disk drive.&lt;br /&gt;
# Simultaneously hold down the Ctrl (Control), left Amiga, and right Amiga keys and then release them.&lt;br /&gt;
&lt;br /&gt;
== Special Boot Options ==&lt;br /&gt;
&lt;br /&gt;
Extra memory used for maintaining devices can prevent floppy-based games from running. See Appendix D for information about how to avoid this problem.&lt;br /&gt;
&lt;br /&gt;
= Using the Workbench Pointers =&lt;br /&gt;
&lt;br /&gt;
The Workbench has two pointers: the mouse pointer and the busy pointer.&lt;br /&gt;
&lt;br /&gt;
== Mouse Pointer ==&lt;br /&gt;
&lt;br /&gt;
The mouse pointer is a small movable picture that is used to indicate to te system the location at which you wish to do some operation. By default the mouse pointer is an image of an arrow. The mouse pointer is moved and positioned with the mouse. The tip of the pointer has a hot spot, which is one pixel (a dot of light that makes up the monitor screen display) that the system is programmed to recognize a the pointer&#039;s locator. The pointer indicates to the system the position of an item that you wish to work with. Through the mouse, you communicate the action that the system should take on this item. You can change the shape and color of the mouse pointer using the Pointer Preferences editor, described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
== Busy Pointer ==&lt;br /&gt;
&lt;br /&gt;
The busy pointer, also referred to as the wait pointer, is displayed in place of the mouse pointer to indicate that the system is attempting to execute an instruction. By default the busy pointer is an image of a stopwatch. Most Workbench operations are unavailable while the busy pointer is displayed. However, you can still move, size, and depth-arrange windows with the busy pointer. The appearance of this pointer can also be changed using the Pointer Preferences editor described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
= Using the Mouse =&lt;br /&gt;
&lt;br /&gt;
The Amiga comes equipped with a mouse, illustrated in Figure 2-2, used to communicate with the system through the pointer. The mouse pointer is positioned by moving the mouse. Manipulating the mouse so that the pointer is located over various objects and pictures on the screen and pressing the mouse buttons tells the Amiga what to do.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-2.png|center|frame|Amiga Mouse]]&lt;br /&gt;
&lt;br /&gt;
== Holding the Mouse ==&lt;br /&gt;
&lt;br /&gt;
Hold the mouse on a flat surface with the cable extending away from you so that the mouse box rests under the palm of your hand with the buttons under your fingertips. In this position, the left mouse button is the selection button and the right mouse button is the menu button.&lt;br /&gt;
&lt;br /&gt;
== Mouse Operations ==&lt;br /&gt;
&lt;br /&gt;
When using the mouse,&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Pointing || means moving the mouse so that the tip of the pointer is positioned over an object on the screen. The pointer moves in the same direction you move the mouse. The mouse can be lifted and repositioned at any time. Lifting the mouse does not move the pointer.&lt;br /&gt;
|-&lt;br /&gt;
| Clicking || means pressing and releasing the selection button.&lt;br /&gt;
|-&lt;br /&gt;
| Double-Clicking || means clicking the selection button twice in rapid succession. Double-clicking on an icon causes a window to appear or a program to start.&lt;br /&gt;
|-&lt;br /&gt;
| Holding Down || means pressing the mouse button until your action is completed.&lt;br /&gt;
|-&lt;br /&gt;
| Dragging || means moving screens, windows, and icons by holding down the selection button and moving the mouse. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Using the Selection Button ==&lt;br /&gt;
&lt;br /&gt;
The left mouse button is the selection button, used for selecting items on the monitor display for processing. This button is also used to move, or drag, items on the screen. For information about these operations, see Chapter 3.&lt;br /&gt;
&lt;br /&gt;
== Using the Menu Button ==&lt;br /&gt;
&lt;br /&gt;
The right mouse button is the menu button, which is used to display the menu bar and menus and to choose items from them. Menu bars contain the headings of each menu available for a selected window, program, or icon. Menus contain lists of options for the operations that you can do with the selected item.&lt;br /&gt;
&lt;br /&gt;
=== Using Menus ===&lt;br /&gt;
&lt;br /&gt;
Menu bars appear across the top of the screen, containing any menu headings available.&lt;br /&gt;
&lt;br /&gt;
Hold down the menu button to display the menu bar as illustrated in Figure 2-3. Hol down the menu button while pointing to the different menu headings to show the available items listed beneath each. To choose a particular item, move the pointer down and release the menu button when the pointer touches it.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-3.png|center|frame|Sample Menu Bar and Menu]]&lt;br /&gt;
&lt;br /&gt;
Some menu items have submenus, which are additional related options that appear to the right of the menu item when it is selected. The symbol » after the item name indicates a submenu. If a menu has submenus, select one of the submenu options. Choosing a main menu item without choosing one of its submenus has no effect. In addition to the » symbol, other symbols may appear on the menu:&lt;br /&gt;
&lt;br /&gt;
* An ellipsis (...) follows the name of menu items that open a requester.&lt;br /&gt;
* A checkmark in the area to the left of a menu item indicates that the items is an option that is currently selected. When this area is empty, the option is deselected. &lt;br /&gt;
&lt;br /&gt;
To execute several menu options at once, hold down the menu button and, using the selection button, click on the menu options of your choice.&lt;br /&gt;
&lt;br /&gt;
The menu button can also be used to cancel operations being performed by the selection button, such as drag selection.&lt;br /&gt;
&lt;br /&gt;
=== Ghosted Menu Items ===&lt;br /&gt;
&lt;br /&gt;
If a menu item is not available for a particular operation, it is ghosted or displayed less distinctly than the others, as illustrated in Figure 2-4.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-4.png|center|frame|Ghosted versus Available Menu Items]]&lt;br /&gt;
&lt;br /&gt;
== Canceling an Operation ==&lt;br /&gt;
&lt;br /&gt;
Cancel the operation being performed with the selection button by clicking the menu button while still holding down the selection button. The following operations can be cancelled:&lt;br /&gt;
&lt;br /&gt;
* Selecting&lt;br /&gt;
* Dragging&lt;br /&gt;
* Drag selection&lt;br /&gt;
* Changing the size of a window &lt;br /&gt;
&lt;br /&gt;
== Using the Amiga Without a Mouse ==&lt;br /&gt;
&lt;br /&gt;
All mouse actions can also be done using the keyboard. Certain key combinations allow use of the keyboard to move the pointer, select icons, and choose menu items. Keyboard shortcuts appear in the menu boxes to the right of some options. Holding down the right Amiga key and simultaneously pressing the letter displayed attains the same results as activating that menu option. Using the keyboard shortcuts instead of the menus speeds your work. For a full description of key functions, see the hardware manual for your Amiga model.&lt;br /&gt;
&lt;br /&gt;
= Using Disk Drives =&lt;br /&gt;
&lt;br /&gt;
Disk drives are devices from which information is retrieved or to which information is written or stored. An Amiga can have one or more hard disk drives, as well as floppy disk drives, depending on the model. All Amiga floppy disk drives can use low density floppy disks. However, if you have a high density floppy disk drive on your Amiga, you can also use high density floppy disks. Refer to the hardware manual that came with your system if you are not sure about the type of floppy disk drive you have.&lt;br /&gt;
&lt;br /&gt;
Each disk drive has a device name, such as DF0: for the internal floppy drive. (Additional floppy drives are designated DF1:, DF2:, and DF3:). A disk icon is displayed on the Workbench screen for each disk inserted in a drive and for each hard disk partition.&lt;br /&gt;
&lt;br /&gt;
The device name and the volume name are two ways of identifying a given disk. For most purposes use either name to refer to the disk when entering a path or within a file requester. The device name refers to the disk that is in the specified disk drive. The volume name refers specifically to a particular disk. For example, if you have a floppy disk in device DF0: with a volume name of Mydisk, you can reference it as either DF0: or Mydisk:. Referencing the disk as Mydisk: lets you insert Mydisk into any drive, not only DF0:.&lt;br /&gt;
&lt;br /&gt;
Each drive has an activity light that is lit when the device is in use, either reading or writing data.&lt;br /&gt;
&lt;br /&gt;
{{Note|title=Caution|text=Never reboot or turn off you Amiga and never remove a floppy disk from a floppy disk drive when any of the drive activity lights are lit or you risk damaging the drive and/or the files on the disk.}}&lt;br /&gt;
&lt;br /&gt;
== Inserting Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
The standard 3.5-inch floppy disk can be inserted only one way. Insert the disk into the disk drive with the label side facing up and the metal end with the indicator arrow entering first.&lt;br /&gt;
&lt;br /&gt;
== Using Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
Floppy disks must be write-enabled and formatted before information can be written on them. To write-enable a floppy disk, turn the disk to its back side and push the plastic tab in the upper left corner down to cover the hole. Conversely, to write-protect a floppy disk, push the plastic tab up, uncovering the hole Figure 2-5 illustrates the write-enable/protect tab on a floppy disk. Formatting floppy disks is described in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-5.png|center|frame|Write Protecting/Enabling Floppy Disks]]&lt;br /&gt;
&lt;br /&gt;
The disk from which information is copied is referred to as the source disk (FROM disk). The disk to which the information is copied is referred to as the destination disk (TO disk). The source disk should always be write-protected to avoid accidental erasure. The destination disk can be a blank disk or a previously used disk whose contents are no longer needed. This disk must be write-enabled to accept the information from the source disk.&lt;br /&gt;
&lt;br /&gt;
== Using the Ram Disk ==&lt;br /&gt;
&lt;br /&gt;
The Ram Disk icon represents RAM:, an area of the Amiga&#039;s internal memory that is set up as a file storage device like a disk. Files, directories, and entire floppy disk (available memory permitting) can be copied to RAM: for temporary storage. The Ram Disk serves as a work area that the system can quickly access.&lt;br /&gt;
&lt;br /&gt;
The size of RAM: is dynamic. It is never any larger than necessary to hold its contents. Therefore, it is always 100% full. Its maximum size is limited by the amount of free memory.&lt;br /&gt;
&lt;br /&gt;
The primary advantage of RAM: is speed. Since it is electronic rather than mechanical, storage and retrieval are almost instantaneous. The disadvantage of RAM: is that data stored in RAM: does not survive when the computer is powered down or rebooted. You must save to floppy disk or to hard disk anything in the Ram Disk that you want to use again.&lt;br /&gt;
&lt;br /&gt;
Applications commonly use RAM: to store temporary files created when the program runs or for backup files created when the program is exited. RAM: can also be used as storage for experimental script files, as a destination for testing command output, and when the creation of a file on an actual disk is too slow, risky, or inconvenient.&lt;br /&gt;
&lt;br /&gt;
Be careful when using RAM: for storing important files. If the Amiga loses power, has a software failure, or you reboot, everything stored in RAM: is lost. Be sure when working with RAM: to regularly back up any important files onto disk.&lt;br /&gt;
&lt;br /&gt;
{{Note|You cannot copy a disk to RAM: by dragging the source disk icon over the Ram Disk icon. To copy a disk to RAM:, open the Ram Disk icon and drag the floppy disk icon into the Ram Disk window. This creates a drawer with the name and contents of the floppy disk.}}&lt;br /&gt;
&lt;br /&gt;
== Backup Disks ==&lt;br /&gt;
&lt;br /&gt;
Backup disks ensure against a loss of data in the event of damage, corruption, or accidental erasure of the original disk. We recommend that you make backup copies of important disks and files, following the licensing agreements provided with your applications software. Making and distributing unlicensed copies of disks is a copyright violation known as software piracy. Store your original disks in a safe place and use your backup disks for everyday purposes. For information on making backup copies of your system disks on floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
= Managing Your Files =&lt;br /&gt;
&lt;br /&gt;
The basic units of data management on your Amiga are files, directories, and drawers. Files are organized collections of data that are given a name and are stored on the system or on removable media. Files are contained in directories or drawers. Directories and drawers are the same thing - a subdivision in your Amiga&#039;s filing system that is used to organize files and other directories/drawers (subdirectories).&lt;br /&gt;
&lt;br /&gt;
== Organizing Information on Disks ==&lt;br /&gt;
&lt;br /&gt;
Information should be stored on disk in a logical manner to allow easy access to your files. The Amiga Workbench organizes information into a hierarchical system of drawers.&lt;br /&gt;
&lt;br /&gt;
A drawer - a directory in AmigaDOS - is a container for items that are related. These items can be files and even other drawers.&lt;br /&gt;
&lt;br /&gt;
On any disk you can create multiple drawers containing multiple files, as available disk space allows. Workbench also allows the creation of drawers within drawers, subdrawers or subdirectories, for further file management. Create as many drawers and subdrawers on your disk as needed.&lt;br /&gt;
&lt;br /&gt;
A drawer icon is displayed in the disk window for each drawer created on a particular disk. Each drawer window contains the icons of the files and subdrawers that exist in it.&lt;br /&gt;
&lt;br /&gt;
== Paths ==&lt;br /&gt;
&lt;br /&gt;
A path is a complete description of the location of a particular file on a disk. When a program requests the name of a file for retrieval, specify the file&#039;s path, including the volume or device name and all the drawers that lead to that file.&lt;br /&gt;
&lt;br /&gt;
The method for specifying paths varies from program to program. Most programs use a file requester with a scrolling list, in which the disk name, any drawer names, and the file name are displayed. Click on the appropriate names to specify the path. However, for some programs you may have to type in the complete path name.&lt;br /&gt;
&lt;br /&gt;
To enter a complete path:&lt;br /&gt;
&lt;br /&gt;
* Type the name of the disk followed by a colon. This name is the volume name of the disk, such as Mydisk:. You can substitute the disk&#039;s device name, such as DF0:, in place of the disk name. However, if you enter the device name rather than the volume name, be sure the correct disk is in that device.&amp;lt;br/&amp;gt;Diskname:&lt;br /&gt;
&lt;br /&gt;
* For a file that is not in a drawer, specify the file name after the colon following the disk name to complete the path.&amp;lt;br/&amp;gt;Diskname:filename&lt;br /&gt;
&lt;br /&gt;
* For a file in a drawer, after the colon following the disk name specify the drawer name followed by a slash (/) followed by the file name.&amp;lt;br/&amp;gt;Diskname:drawername/filename&lt;br /&gt;
&lt;br /&gt;
* If there are more drawers in the path, each drawer must be specified followed by a slash.&amp;lt;br/&amp;gt;Diskname:drawername/subdrawername/filename&lt;br /&gt;
&lt;br /&gt;
{{Note|File and drawer names containing spaces can cause recognition problems. We recommend that you avoid using spaces in file or drawer names. If you have trouble referencing a name that contains a space, enclose the entire path in double quotation marks.}}&lt;br /&gt;
&lt;br /&gt;
== File and Drawer Names ==&lt;br /&gt;
&lt;br /&gt;
The following rules apply for naming files and drawers:&lt;br /&gt;
&lt;br /&gt;
* Names can be up to 30 characters long. Names can contain upper case letters and any punctuation marks that are not reserved.&lt;br /&gt;
* Colons (:) and slashes (/) are not allowed within a name. These characters are reserved for path statements. However, other non-alphabetic characters can be used.&lt;br /&gt;
* The use of spaces before or after names should be avoided due to the possibility of omission.&lt;br /&gt;
* Upper and lower case differences (capitalization) are preserved and displayed by the Amiga. However, the system is not case-sensitive: upper and lower case are considered the same.&lt;br /&gt;
* Duplicate file names are not allowed within the same drawer. If you save a file with the same name as an existing file in a drawer, it overwrites the original file in that drawer.&lt;br /&gt;
* Two files with the same name can exist in separate drawers or within different paths.&lt;br /&gt;
&lt;br /&gt;
== Trashcan ==&lt;br /&gt;
&lt;br /&gt;
The Trashcan is a special drawer that can be placed on a disk for storing files that you no longer needed and may wish to delete. Discard icons or pseudo-icons for the files to be deleted by dragging them into the Trashcan. If the icon to be discarded is a drawer, is associated files are also moved to the Trashcan.&lt;br /&gt;
&lt;br /&gt;
Choosing Empty Trash from the Icons menu deletes the icons and all of their associated files from the Trashcan. Before choosing Empty Trash, you can still recover any of the Trashcan&#039;s contents by opening its window and dragging the icons back out.&lt;br /&gt;
&lt;br /&gt;
For more information about putting a Trashcan on a disk, see the Format Disk description in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
= Using Application Software =&lt;br /&gt;
&lt;br /&gt;
Applications are software programs, such as databases, video and sound programs, word processing programs, recreational programs, and educational programs that are available for use on your Amiga. Most Amiga programs use windows, menus, and gadgets in ways very similar to the Workbench programs on your system disks. However, you should always read the documentation that comes with your applications for directions on using unfamiliar menu items and gadgets.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7040</id>
		<title>AmigaOS Manual: Workbench Basic Operations</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7040"/>
		<updated>2014-02-01T10:33:39Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: /* Booting/Rebooting Your System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before using your Amiga, you should familiarize yourself with the basic Amiga system concepts and techniques provided in this chapter. These include:&lt;br /&gt;
&lt;br /&gt;
* Booting your system&lt;br /&gt;
* Using the pointers&lt;br /&gt;
* Using the mouse&lt;br /&gt;
* Handling disks and using disk drives&lt;br /&gt;
* Creating and accessing files and directories &lt;br /&gt;
&lt;br /&gt;
= Booting/Rebooting Your System =&lt;br /&gt;
&lt;br /&gt;
Booting powers on your computer and loads the operating system information from a disk to the computer&#039;s memory. Each time the Amiga is booted, the system must find the Amiga system software on a bootable hard disk or floppy disk inserted into a disk drive. If there are no bootable disks when the system is powered on, an animated screen requests that you insert a bootable disk into a floppy drive.&lt;br /&gt;
&lt;br /&gt;
Rebooting resets you computer without turning off the power. This process terminates any active programs and erases any data stored in the Amiga&#039;s memory.&lt;br /&gt;
&lt;br /&gt;
For information about booting and rebooting floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
Each time the Amiga is booted or rebooted, the following events occur:&lt;br /&gt;
&lt;br /&gt;
1. The Amiga executes a script file called the Startup-sequence. The Startup-sequence file contains AmigaDOS commands that load the Amiga software and handle various hardware and software setup tasks.&lt;br /&gt;
&lt;br /&gt;
2. The Startup-sequence executes a script file called User-startup, if you have created it. In general, User-startup files contain your own customized configurations, resident commands, and directory assignments. It also executes a script file called Network-startup. This script is designed to have any programs added to it that may require the networking to be functional before running programs that require it. The script is called in a special way so as not to hold up the boot process while the network is &amp;quot;coming up&amp;quot;, but it will hold off programs that rely on the network while it does.&lt;br /&gt;
Appendix B offer some instructions and suggestions of items that you can place in the User-startup and Network-startup files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. The Amiga Workbench screen appears, as illustrated in Figure 2-1. &lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-1.png|center|frame|Workbench Screen]]&lt;br /&gt;
&lt;br /&gt;
4. Workbench runs any programs that are set up in the WBStartup preferences. By adding programs to the WBStartup preferences, you can also customize your system startup. &lt;br /&gt;
&lt;br /&gt;
Do not alter the Startup-sequence file, doing so can prevent the Amiga from booting properly.&lt;br /&gt;
&lt;br /&gt;
To reboot your system:&lt;br /&gt;
&lt;br /&gt;
# Be sure that all disk activity has stopped and that all floppy disk drive and hard disk drive lights are unlit.&lt;br /&gt;
# If you are rebooting from a floppy disk drive, insert a copy of the Workbench disk into a floppy disk drive.&lt;br /&gt;
# Simultaneously hold down the Ctrl (Control), left Amiga, and right Amiga keys and then release them.&lt;br /&gt;
&lt;br /&gt;
== Special Boot Options ==&lt;br /&gt;
&lt;br /&gt;
Extra memory used for maintaining devices can prevent floppy-based games from running. See Appendix D for information about how to avoid this problem.&lt;br /&gt;
&lt;br /&gt;
= Using the Workbench Pointers =&lt;br /&gt;
&lt;br /&gt;
The Workbench has two pointers: the mouse pointer and the busy pointer.&lt;br /&gt;
&lt;br /&gt;
== Mouse Pointer ==&lt;br /&gt;
&lt;br /&gt;
The mouse pointer is a small movable picture that is used to indicate to te system the location at which you wish to do some operation. By default the mouse pointer is an image of an arrow. The mouse pointer is moved and positioned with the mouse. The tip of the pointer has a hot spot, which is one pixel (a dot of light that makes up the monitor screen display) that the system is programmed to recognize a the pointer&#039;s locator. The pointer indicates to the system the position of an item that you wish to work with. Through the mouse, you communicate the action that the system should take on this item. You can change the shape and color of the mouse pointer using the Pointer Preferences editor, described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
== Busy Pointer ==&lt;br /&gt;
&lt;br /&gt;
The busy pointer, also referred to as the wait pointer, is displayed in place of the mouse pointer to indicate that the system is attempting to execute an instruction. By default the busy pointer is an image of a stopwatch. Most Workbench operations are unavailable while the busy pointer is displayed. However, you can still move, size, and depth-arrange windows with the busy pointer. The appearance of this pointer can also be changed using the Pointer Preferences editor described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
= Using the Mouse =&lt;br /&gt;
&lt;br /&gt;
The Amiga comes equipped with a mouse, illustrated in Figure 2-2, used to communicate with the system through the pointer. The mouse pointer is positioned by moving the mouse. Manipulating the mouse so that the pointer is located over various objects and pictures on the screen and pressing the mouse buttons tells the Amiga what to do.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-2.png|center|frame|Amiga Mouse]]&lt;br /&gt;
&lt;br /&gt;
== Holding the Mouse ==&lt;br /&gt;
&lt;br /&gt;
Hold the mouse on a flat surface with the cable extending away from you so that the mouse box rests under the palm of your hand with the buttons under your fingertips. In this position, the left mouse button is the selection button and the right mouse button is the menu button.&lt;br /&gt;
&lt;br /&gt;
== Mouse Operations ==&lt;br /&gt;
&lt;br /&gt;
When using the mouse,&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Pointing || means moving the mouse so that the tip of the pointer is positioned over an object on the screen. The pointer moves in the same direction you move the mouse. The mouse can be lifted and repositioned at any time. Lifting the mouse does not move the pointer.&lt;br /&gt;
|-&lt;br /&gt;
| Clicking || means pressing and releasing the selection button.&lt;br /&gt;
|-&lt;br /&gt;
| Double-Clicking || means clicking the selection button twice in rapid succession. Double-clicking on an icon causes a window to appear or a program to start.&lt;br /&gt;
|-&lt;br /&gt;
| Holding Down || means pressing the mouse button until your action is completed.&lt;br /&gt;
|-&lt;br /&gt;
| Dragging || means moving screens, windows, and icons by holding down the selection button and moving the mouse. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Using the Selection Button ==&lt;br /&gt;
&lt;br /&gt;
The left mouse button is the selection button, used for selecting items on the monitor display for processing. This button is also used to move, or drag, items on the screen. For information about these operations, see Chapter 3.&lt;br /&gt;
&lt;br /&gt;
== Using the Menu Button ==&lt;br /&gt;
&lt;br /&gt;
The right mouse button is the menu button, which is used to display the menu bar and menus and to choose items from them. Menu bars contain the headings of each menu available for a selected window, program, or icon. Menus contain lists of options for the operations that you can do with the selected item.&lt;br /&gt;
&lt;br /&gt;
=== Using Menus ===&lt;br /&gt;
&lt;br /&gt;
Menu bars appear across the top of the screen, containing any menu headings available.&lt;br /&gt;
&lt;br /&gt;
Hold down the menu button to display the menu bar as illustrated in Figure 2-3. Hol down the menu button while pointing to the different menu headings to show the available items listed beneath each. To choose a particular item, move the pointer down and release the menu button when the pointer touches it.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-3.png|center|frame|Sample Menu Bar and Menu]]&lt;br /&gt;
&lt;br /&gt;
Some menu items have submenus, which are additional related options that appear to the right of the menu item when it is selected. The symbol » after the item name indicates a submenu. If a menu has submenus, select one of the submenu options. Choosing a main menu item without choosing one of its submenus has no effect. In addition to the » symbol, other symbols may appear on the menu:&lt;br /&gt;
&lt;br /&gt;
* An ellipsis (...) follows the name of menu items that open a requester.&lt;br /&gt;
* A checkmark in the area to the left of a menu item indicates that the items is an option that is currently selected. When this area is empty, the option is deselected. &lt;br /&gt;
&lt;br /&gt;
To execute several menu options at once, hold down the menu button and, using the selection button, click on the menu options of your choice.&lt;br /&gt;
&lt;br /&gt;
The menu button can also be used to cancel operations being performed by the selection button, such as drag selection.&lt;br /&gt;
&lt;br /&gt;
=== Ghosted Menu Items ===&lt;br /&gt;
&lt;br /&gt;
If a menu item is not available for a particular operation, it is ghosted or displayed less distinctly than the others, as illustrated in Figure 2-4.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-4.png|center|frame|Ghosted versus Available Menu Items]]&lt;br /&gt;
&lt;br /&gt;
== Canceling an Operation ==&lt;br /&gt;
&lt;br /&gt;
Cancel the operation being performed with the selection button by clicking the menu button while still holding down the selection button. The following operations can be cancelled:&lt;br /&gt;
&lt;br /&gt;
* Selecting&lt;br /&gt;
* Dragging&lt;br /&gt;
* Drag selection&lt;br /&gt;
* Changing the size of a window &lt;br /&gt;
&lt;br /&gt;
== Using the Amiga Without a Mouse ==&lt;br /&gt;
&lt;br /&gt;
All mouse actions can also be done using the keyboard. Certain key combinations allow use of the keyboard to move the pointer, select icons, and choose menu items. Keyboard shortcuts appear in the menu boxes to the right of some options. Holding down the right Amiga key and simultaneously pressing the letter displayed attains the same results as activating that menu option. Using the keyboard shortcuts instead of the menus speeds your work. For a full description of key functions, see the hardware manual for your Amiga model.&lt;br /&gt;
&lt;br /&gt;
= Using Disk Drives =&lt;br /&gt;
&lt;br /&gt;
Disk drives are devices from which information is retrieved or to which information is written or stored. An Amiga can have one or more hard disk drives, as well as floppy disk drives, depending on the model. All Amiga floppy disk drives can use low density floppy disks. However, if you have a high density floppy disk drive on your Amiga, you can also use high density floppy disks. Refer to the hardware manual that came with your system if you are not sure about the type of floppy disk drive you have.&lt;br /&gt;
&lt;br /&gt;
Each disk drive has a device name, such as DF0: for the internal floppy drive. (Additional floppy drives are designated DF1:, DF2:, and DF3:). A disk icon is displayed on the Workbench screen for each disk inserted in a drive and for each hard disk partition.&lt;br /&gt;
&lt;br /&gt;
The device name and the volume name are two ways of identifying a given disk. For most purposes use either name to refer to the disk when entering a path or within a file requester. The device name refers to the disk that is in the specified disk drive. The volume name refers specifically to a particular disk. For example, if you have a floppy disk in device DF0: with a volume name of Mydisk, you can reference it as either DF0: or Mydisk:. Referencing the disk as Mydisk: lets you insert Mydisk into any drive, not only DF0:.&lt;br /&gt;
&lt;br /&gt;
Each drive has an activity light that is lit when the device is in use, either reading or writing data.&lt;br /&gt;
&lt;br /&gt;
{{Note|title=Caution|text=Never reboot or turn off you Amiga and never remove a floppy disk from a floppy disk drive when any of the drive activity lights are lit or you risk damaging the drive and/or the files on the disk.}}&lt;br /&gt;
&lt;br /&gt;
== Inserting Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
The standard 3.5-inch floppy disk can be inserted only one way. Insert the disk into the disk drive with the label side facing up and the metal end with the indicator arrow entering first.&lt;br /&gt;
&lt;br /&gt;
== Using Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
Floppy disks must be write-enabled and formatted before information can be written on them. To write-enable a floppy disk, turn the disk to its back side and push the plastic tab in the upper left corner down to cover the hole. Conversely, to write-protect a floppy disk, push the plastic tab up, uncovering the hole Figure 2-5 illustrates the write-enable/protect tab on a floppy disk. Formatting floppy disks is described in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-5.png|center|frame|Write Protecting/Enabling Floppy Disks]]&lt;br /&gt;
&lt;br /&gt;
The disk from which information is copied is referred to as the source disk (FROM disk). The disk to which the information is copied is referred to as the destination disk (TO disk). The source disk should always be write-protected to avoid accidental erasure. The destination disk can be a blank disk or a previously used disk whose contents are no longer needed. This disk must be write-enabled to accept the information from the source disk.&lt;br /&gt;
&lt;br /&gt;
== Using the Ram Disk ==&lt;br /&gt;
&lt;br /&gt;
The Ram Disk icon represents RAM:, an area of the Amiga&#039;s internal memory that is set up as a file storage device like a disk. Files, directories, and entire floppy disk (available memory permitting) can be copied to RAM: for temporary storage. The Ram Disk serves as a work area that the system can quickly access.&lt;br /&gt;
&lt;br /&gt;
The size of RAM: is dynamic. It is never any larger than necessary to hold its contents. Therefore, it is always 100% full. Its maximum size is limited by the amount of free memory.&lt;br /&gt;
&lt;br /&gt;
The primary advantage of RAM: is speed. Since it is electronic rather than mechanical, storage and retrieval are almost instantaneous. The disadvantage of RAM: is that data stored in RAM: does not survive when the computer is powered down or rebooted. You must save to floppy disk or to hard disk anything in the Ram Disk that you want to use again.&lt;br /&gt;
&lt;br /&gt;
Applications commonly use RAM: to store temporary files created when the program runs or for backup files created when the program is exited. RAM: can also be used as storage for experimental script files, as a destination for testing command output, and when the creation of a file on an actual disk is too slow, risky, or inconvenient.&lt;br /&gt;
&lt;br /&gt;
Be careful when using RAM: for storing important files. If the Amiga loses power, has a software failure, or you reboot, everything stored in RAM: is lost. Be sure when working with RAM: to regularly back up any important files onto disk.&lt;br /&gt;
&lt;br /&gt;
{{Note|You cannot copy a disk to RAM: by dragging the source disk icon over the Ram Disk icon. To copy a disk to RAM:, open the Ram Disk icon and drag the floppy disk icon into the Ram Disk window. This creates a drawer with the name and contents of the floppy disk.}}&lt;br /&gt;
&lt;br /&gt;
== Backup Disks ==&lt;br /&gt;
&lt;br /&gt;
Backup disks ensure against a loss of data in the event of damage, corruption, or accidental erasure of the original disk. We recommend that you make backup copies of important disks and files, following the licensing agreements provided with your applications software. Making and distributing unlicensed copies of disks is a copyright violation known as software piracy. Store your original disks in a safe place and use your backup disks for everyday purposes. For information on making backup copies of your system disks on floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
= Managing Your Files =&lt;br /&gt;
&lt;br /&gt;
The basic units of data management on your Amiga are files, directories, and drawers. Files are organized collections of data that are given a name and are stored on the system or on removable media. Files are contained in directories or drawers. Directories and drawers are the same thing - a subdivision in your Amiga&#039;s filing system that is used to organize files and other directories/drawers (subdirectories).&lt;br /&gt;
&lt;br /&gt;
== Organizing Information on Disks ==&lt;br /&gt;
&lt;br /&gt;
Information should be stored on disk in a logical manner to allow easy access to your files. The Amiga Workbench organizes information into a hierarchical system of drawers.&lt;br /&gt;
&lt;br /&gt;
A drawer - a directory in AmigaDOS - is a container for items that are related. These items can be files and even other drawers.&lt;br /&gt;
&lt;br /&gt;
On any disk you can create multiple drawers containing multiple files, as available disk space allows. Workbench also allows the creation of drawers within drawers, subdrawers or subdirectories, for further file management. Create as many drawers and subdrawers on your disk as needed.&lt;br /&gt;
&lt;br /&gt;
A drawer icon is displayed in the disk window for each drawer created on a particular disk. Each drawer window contains the icons of the files and subdrawers that exist in it.&lt;br /&gt;
&lt;br /&gt;
== Paths ==&lt;br /&gt;
&lt;br /&gt;
A path is a complete description of the location of a particular file on a disk. When a program requests the name of a file for retrieval, specify the file&#039;s path, including the volume or device name and all the drawers that lead to that file.&lt;br /&gt;
&lt;br /&gt;
The method for specifying paths varies from program to program. Most programs use a file requester with a scrolling list, in which the disk name, any drawer names, and the file name are displayed. Click on the appropriate names to specify the path. However, for some programs you may have to type in the complete path name.&lt;br /&gt;
&lt;br /&gt;
To enter a complete path:&lt;br /&gt;
&lt;br /&gt;
* Type the name of the disk followed by a colon. This name is the volume name of the disk, such as Mydisk:. You can substitute the disk&#039;s device name, such as DF0:, in place of the disk name. However, if you enter the device name rather than the volume name, be sure the correct disk is in that device.&amp;lt;br/&amp;gt;Diskname:&lt;br /&gt;
&lt;br /&gt;
* For a file that is not in a drawer, specify the file name after the colon following the disk name to complete the path.&amp;lt;br/&amp;gt;Diskname:filename&lt;br /&gt;
&lt;br /&gt;
* For a file in a drawer, after the colon following the disk name specify the drawer name followed by a slash (/) followed by the file name.&amp;lt;br/&amp;gt;Diskname:drawername/filename&lt;br /&gt;
&lt;br /&gt;
* If there are more drawers in the path, each drawer must be specified followed by a slash.&amp;lt;br/&amp;gt;Diskname:drawername/subdrawername/filename&lt;br /&gt;
&lt;br /&gt;
{{Note|File and drawer names containing spaces can cause recognition problems. We recommend that you avoid using spaces in file or drawer names. If you have trouble referencing a name that contains a space, enclose the entire path in double quotation marks.}}&lt;br /&gt;
&lt;br /&gt;
== File and Drawer Names ==&lt;br /&gt;
&lt;br /&gt;
The following rules apply for naming files and drawers:&lt;br /&gt;
&lt;br /&gt;
* Names can be up to 30 characters long. Names can contain upper case letters and any punctuation marks that are not reserved.&lt;br /&gt;
* Colons (:) and slashes (/) are not allowed within a name. These characters are reserved for path statements. However, other non-alphabetic characters can be used.&lt;br /&gt;
* The use of spaces before or after names should be avoided due to the possibility of omission.&lt;br /&gt;
* Upper and lower case differences (capitalization) are preserved and displayed by the Amiga. However, the system is not case-sensitive: upper and lower case are considered the same.&lt;br /&gt;
* Duplicate file names are not allowed within the same drawer. If you save a file with the same name as an existing file in a drawer, it overwrites the original file in that drawer.&lt;br /&gt;
* Two files with the same name can exist in separate drawers or within different paths.&lt;br /&gt;
&lt;br /&gt;
== Trashcan ==&lt;br /&gt;
&lt;br /&gt;
The Trashcan is a special drawer that can be placed on a disk for storing files that you no longer needed and may wish to delete. Discard icons or pseudo-icons for the files to be deleted by dragging them into the Trashcan. If the icon to be discarded is a drawer, is associated files are also moved to the Trashcan.&lt;br /&gt;
&lt;br /&gt;
Choosing Empty Trash from the Icons menu deletes the icons and all of their associated files from the Trashcan. Before choosing Empty Trash, you can still recover any of the Trashcan&#039;s contents by opening its window and dragging the icons back out.&lt;br /&gt;
&lt;br /&gt;
For more information about putting a Trashcan on a disk, see the Format Disk description in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
= Using Application Software =&lt;br /&gt;
&lt;br /&gt;
Applications are software programs, such as databases, video and sound programs, word processing programs, recreational programs, and educational programs that are available for use on your Amiga. Most Amiga programs use windows, menus, and gadgets in ways very similar to the Workbench programs on your system disks. However, you should always read the documentation that comes with your applications for directions on using unfamiliar menu items and gadgets.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7039</id>
		<title>AmigaOS Manual: Workbench Basic Operations</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=AmigaOS_Manual:_Workbench_Basic_Operations&amp;diff=7039"/>
		<updated>2014-02-01T10:32:38Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before using your Amiga, you should familiarize yourself with the basic Amiga system concepts and techniques provided in this chapter. These include:&lt;br /&gt;
&lt;br /&gt;
* Booting your system&lt;br /&gt;
* Using the pointers&lt;br /&gt;
* Using the mouse&lt;br /&gt;
* Handling disks and using disk drives&lt;br /&gt;
* Creating and accessing files and directories &lt;br /&gt;
&lt;br /&gt;
= Booting/Rebooting Your System =&lt;br /&gt;
&lt;br /&gt;
Booting powers on your computer and loads the operating system information from a disk to the computer&#039;s memory. Each time the Amiga is booted, the system must find the Amiga system software on a bootable hard disk or floppy disk inserted into a disk drive. If there are no bootable disks when the system is powered on, an animated screen requests that you insert a bootable disk into a floppy drive.&lt;br /&gt;
&lt;br /&gt;
Rebooting resets you computer without turning off the power. This process terminates any active programs and erases any data stored in the Amiga&#039;s memory.&lt;br /&gt;
&lt;br /&gt;
For information about booting and rebooting floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
Each time the Amiga is booted or rebooted, the following events occur:&lt;br /&gt;
&lt;br /&gt;
1. The Amiga executes a script file called the Startup-sequence. The Startup-sequence file contains AmigaDOS commands that load the Amiga software and handle various hardware and software setup tasks.&lt;br /&gt;
&lt;br /&gt;
2. The Startup-sequence executes a script file called User-startup, if you have created it. In general, User-startup files contain your own customized configurations, resident commands, and directory assignments. It also executes a script file called Network-startup. This script is designed to have any programs added to it that may require the networking functional before running programs that require it. The script is called in a special way so as not to hold up the boot process while the network is &amp;quot;coming up&amp;quot;, but it will hold off programs that rely on the network while it does.&lt;br /&gt;
Appendix B offer some instructions and suggestions of items that you can place in the User-startup and Network-startup files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. The Amiga Workbench screen appears, as illustrated in Figure 2-1. &lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-1.png|center|frame|Workbench Screen]]&lt;br /&gt;
&lt;br /&gt;
4. Workbench runs any programs that are set up in the WBStartup preferences. By adding programs to the WBStartup preferences, you can also customize your system startup. &lt;br /&gt;
&lt;br /&gt;
Do not alter the Startup-sequence file, doing so can prevent the Amiga from booting properly.&lt;br /&gt;
&lt;br /&gt;
To reboot your system:&lt;br /&gt;
&lt;br /&gt;
# Be sure that all disk activity has stopped and that all floppy disk drive and hard disk drive lights are unlit.&lt;br /&gt;
# If you are rebooting from a floppy disk drive, insert a copy of the Workbench disk into a floppy disk drive.&lt;br /&gt;
# Simultaneously hold down the Ctrl (Control), left Amiga, and right Amiga keys and then release them.&lt;br /&gt;
&lt;br /&gt;
== Special Boot Options ==&lt;br /&gt;
&lt;br /&gt;
Extra memory used for maintaining devices can prevent floppy-based games from running. See Appendix D for information about how to avoid this problem.&lt;br /&gt;
&lt;br /&gt;
= Using the Workbench Pointers =&lt;br /&gt;
&lt;br /&gt;
The Workbench has two pointers: the mouse pointer and the busy pointer.&lt;br /&gt;
&lt;br /&gt;
== Mouse Pointer ==&lt;br /&gt;
&lt;br /&gt;
The mouse pointer is a small movable picture that is used to indicate to te system the location at which you wish to do some operation. By default the mouse pointer is an image of an arrow. The mouse pointer is moved and positioned with the mouse. The tip of the pointer has a hot spot, which is one pixel (a dot of light that makes up the monitor screen display) that the system is programmed to recognize a the pointer&#039;s locator. The pointer indicates to the system the position of an item that you wish to work with. Through the mouse, you communicate the action that the system should take on this item. You can change the shape and color of the mouse pointer using the Pointer Preferences editor, described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
== Busy Pointer ==&lt;br /&gt;
&lt;br /&gt;
The busy pointer, also referred to as the wait pointer, is displayed in place of the mouse pointer to indicate that the system is attempting to execute an instruction. By default the busy pointer is an image of a stopwatch. Most Workbench operations are unavailable while the busy pointer is displayed. However, you can still move, size, and depth-arrange windows with the busy pointer. The appearance of this pointer can also be changed using the Pointer Preferences editor described in Chapter 5.&lt;br /&gt;
&lt;br /&gt;
= Using the Mouse =&lt;br /&gt;
&lt;br /&gt;
The Amiga comes equipped with a mouse, illustrated in Figure 2-2, used to communicate with the system through the pointer. The mouse pointer is positioned by moving the mouse. Manipulating the mouse so that the pointer is located over various objects and pictures on the screen and pressing the mouse buttons tells the Amiga what to do.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-2.png|center|frame|Amiga Mouse]]&lt;br /&gt;
&lt;br /&gt;
== Holding the Mouse ==&lt;br /&gt;
&lt;br /&gt;
Hold the mouse on a flat surface with the cable extending away from you so that the mouse box rests under the palm of your hand with the buttons under your fingertips. In this position, the left mouse button is the selection button and the right mouse button is the menu button.&lt;br /&gt;
&lt;br /&gt;
== Mouse Operations ==&lt;br /&gt;
&lt;br /&gt;
When using the mouse,&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Pointing || means moving the mouse so that the tip of the pointer is positioned over an object on the screen. The pointer moves in the same direction you move the mouse. The mouse can be lifted and repositioned at any time. Lifting the mouse does not move the pointer.&lt;br /&gt;
|-&lt;br /&gt;
| Clicking || means pressing and releasing the selection button.&lt;br /&gt;
|-&lt;br /&gt;
| Double-Clicking || means clicking the selection button twice in rapid succession. Double-clicking on an icon causes a window to appear or a program to start.&lt;br /&gt;
|-&lt;br /&gt;
| Holding Down || means pressing the mouse button until your action is completed.&lt;br /&gt;
|-&lt;br /&gt;
| Dragging || means moving screens, windows, and icons by holding down the selection button and moving the mouse. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Using the Selection Button ==&lt;br /&gt;
&lt;br /&gt;
The left mouse button is the selection button, used for selecting items on the monitor display for processing. This button is also used to move, or drag, items on the screen. For information about these operations, see Chapter 3.&lt;br /&gt;
&lt;br /&gt;
== Using the Menu Button ==&lt;br /&gt;
&lt;br /&gt;
The right mouse button is the menu button, which is used to display the menu bar and menus and to choose items from them. Menu bars contain the headings of each menu available for a selected window, program, or icon. Menus contain lists of options for the operations that you can do with the selected item.&lt;br /&gt;
&lt;br /&gt;
=== Using Menus ===&lt;br /&gt;
&lt;br /&gt;
Menu bars appear across the top of the screen, containing any menu headings available.&lt;br /&gt;
&lt;br /&gt;
Hold down the menu button to display the menu bar as illustrated in Figure 2-3. Hol down the menu button while pointing to the different menu headings to show the available items listed beneath each. To choose a particular item, move the pointer down and release the menu button when the pointer touches it.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-3.png|center|frame|Sample Menu Bar and Menu]]&lt;br /&gt;
&lt;br /&gt;
Some menu items have submenus, which are additional related options that appear to the right of the menu item when it is selected. The symbol » after the item name indicates a submenu. If a menu has submenus, select one of the submenu options. Choosing a main menu item without choosing one of its submenus has no effect. In addition to the » symbol, other symbols may appear on the menu:&lt;br /&gt;
&lt;br /&gt;
* An ellipsis (...) follows the name of menu items that open a requester.&lt;br /&gt;
* A checkmark in the area to the left of a menu item indicates that the items is an option that is currently selected. When this area is empty, the option is deselected. &lt;br /&gt;
&lt;br /&gt;
To execute several menu options at once, hold down the menu button and, using the selection button, click on the menu options of your choice.&lt;br /&gt;
&lt;br /&gt;
The menu button can also be used to cancel operations being performed by the selection button, such as drag selection.&lt;br /&gt;
&lt;br /&gt;
=== Ghosted Menu Items ===&lt;br /&gt;
&lt;br /&gt;
If a menu item is not available for a particular operation, it is ghosted or displayed less distinctly than the others, as illustrated in Figure 2-4.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-4.png|center|frame|Ghosted versus Available Menu Items]]&lt;br /&gt;
&lt;br /&gt;
== Canceling an Operation ==&lt;br /&gt;
&lt;br /&gt;
Cancel the operation being performed with the selection button by clicking the menu button while still holding down the selection button. The following operations can be cancelled:&lt;br /&gt;
&lt;br /&gt;
* Selecting&lt;br /&gt;
* Dragging&lt;br /&gt;
* Drag selection&lt;br /&gt;
* Changing the size of a window &lt;br /&gt;
&lt;br /&gt;
== Using the Amiga Without a Mouse ==&lt;br /&gt;
&lt;br /&gt;
All mouse actions can also be done using the keyboard. Certain key combinations allow use of the keyboard to move the pointer, select icons, and choose menu items. Keyboard shortcuts appear in the menu boxes to the right of some options. Holding down the right Amiga key and simultaneously pressing the letter displayed attains the same results as activating that menu option. Using the keyboard shortcuts instead of the menus speeds your work. For a full description of key functions, see the hardware manual for your Amiga model.&lt;br /&gt;
&lt;br /&gt;
= Using Disk Drives =&lt;br /&gt;
&lt;br /&gt;
Disk drives are devices from which information is retrieved or to which information is written or stored. An Amiga can have one or more hard disk drives, as well as floppy disk drives, depending on the model. All Amiga floppy disk drives can use low density floppy disks. However, if you have a high density floppy disk drive on your Amiga, you can also use high density floppy disks. Refer to the hardware manual that came with your system if you are not sure about the type of floppy disk drive you have.&lt;br /&gt;
&lt;br /&gt;
Each disk drive has a device name, such as DF0: for the internal floppy drive. (Additional floppy drives are designated DF1:, DF2:, and DF3:). A disk icon is displayed on the Workbench screen for each disk inserted in a drive and for each hard disk partition.&lt;br /&gt;
&lt;br /&gt;
The device name and the volume name are two ways of identifying a given disk. For most purposes use either name to refer to the disk when entering a path or within a file requester. The device name refers to the disk that is in the specified disk drive. The volume name refers specifically to a particular disk. For example, if you have a floppy disk in device DF0: with a volume name of Mydisk, you can reference it as either DF0: or Mydisk:. Referencing the disk as Mydisk: lets you insert Mydisk into any drive, not only DF0:.&lt;br /&gt;
&lt;br /&gt;
Each drive has an activity light that is lit when the device is in use, either reading or writing data.&lt;br /&gt;
&lt;br /&gt;
{{Note|title=Caution|text=Never reboot or turn off you Amiga and never remove a floppy disk from a floppy disk drive when any of the drive activity lights are lit or you risk damaging the drive and/or the files on the disk.}}&lt;br /&gt;
&lt;br /&gt;
== Inserting Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
The standard 3.5-inch floppy disk can be inserted only one way. Insert the disk into the disk drive with the label side facing up and the metal end with the indicator arrow entering first.&lt;br /&gt;
&lt;br /&gt;
== Using Floppy Disks ==&lt;br /&gt;
&lt;br /&gt;
Floppy disks must be write-enabled and formatted before information can be written on them. To write-enable a floppy disk, turn the disk to its back side and push the plastic tab in the upper left corner down to cover the hole. Conversely, to write-protect a floppy disk, push the plastic tab up, uncovering the hole Figure 2-5 illustrates the write-enable/protect tab on a floppy disk. Formatting floppy disks is described in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
[[File:WorkbenchFig2-5.png|center|frame|Write Protecting/Enabling Floppy Disks]]&lt;br /&gt;
&lt;br /&gt;
The disk from which information is copied is referred to as the source disk (FROM disk). The disk to which the information is copied is referred to as the destination disk (TO disk). The source disk should always be write-protected to avoid accidental erasure. The destination disk can be a blank disk or a previously used disk whose contents are no longer needed. This disk must be write-enabled to accept the information from the source disk.&lt;br /&gt;
&lt;br /&gt;
== Using the Ram Disk ==&lt;br /&gt;
&lt;br /&gt;
The Ram Disk icon represents RAM:, an area of the Amiga&#039;s internal memory that is set up as a file storage device like a disk. Files, directories, and entire floppy disk (available memory permitting) can be copied to RAM: for temporary storage. The Ram Disk serves as a work area that the system can quickly access.&lt;br /&gt;
&lt;br /&gt;
The size of RAM: is dynamic. It is never any larger than necessary to hold its contents. Therefore, it is always 100% full. Its maximum size is limited by the amount of free memory.&lt;br /&gt;
&lt;br /&gt;
The primary advantage of RAM: is speed. Since it is electronic rather than mechanical, storage and retrieval are almost instantaneous. The disadvantage of RAM: is that data stored in RAM: does not survive when the computer is powered down or rebooted. You must save to floppy disk or to hard disk anything in the Ram Disk that you want to use again.&lt;br /&gt;
&lt;br /&gt;
Applications commonly use RAM: to store temporary files created when the program runs or for backup files created when the program is exited. RAM: can also be used as storage for experimental script files, as a destination for testing command output, and when the creation of a file on an actual disk is too slow, risky, or inconvenient.&lt;br /&gt;
&lt;br /&gt;
Be careful when using RAM: for storing important files. If the Amiga loses power, has a software failure, or you reboot, everything stored in RAM: is lost. Be sure when working with RAM: to regularly back up any important files onto disk.&lt;br /&gt;
&lt;br /&gt;
{{Note|You cannot copy a disk to RAM: by dragging the source disk icon over the Ram Disk icon. To copy a disk to RAM:, open the Ram Disk icon and drag the floppy disk icon into the Ram Disk window. This creates a drawer with the name and contents of the floppy disk.}}&lt;br /&gt;
&lt;br /&gt;
== Backup Disks ==&lt;br /&gt;
&lt;br /&gt;
Backup disks ensure against a loss of data in the event of damage, corruption, or accidental erasure of the original disk. We recommend that you make backup copies of important disks and files, following the licensing agreements provided with your applications software. Making and distributing unlicensed copies of disks is a copyright violation known as software piracy. Store your original disks in a safe place and use your backup disks for everyday purposes. For information on making backup copies of your system disks on floppy-only systems, see Appendix B.&lt;br /&gt;
&lt;br /&gt;
= Managing Your Files =&lt;br /&gt;
&lt;br /&gt;
The basic units of data management on your Amiga are files, directories, and drawers. Files are organized collections of data that are given a name and are stored on the system or on removable media. Files are contained in directories or drawers. Directories and drawers are the same thing - a subdivision in your Amiga&#039;s filing system that is used to organize files and other directories/drawers (subdirectories).&lt;br /&gt;
&lt;br /&gt;
== Organizing Information on Disks ==&lt;br /&gt;
&lt;br /&gt;
Information should be stored on disk in a logical manner to allow easy access to your files. The Amiga Workbench organizes information into a hierarchical system of drawers.&lt;br /&gt;
&lt;br /&gt;
A drawer - a directory in AmigaDOS - is a container for items that are related. These items can be files and even other drawers.&lt;br /&gt;
&lt;br /&gt;
On any disk you can create multiple drawers containing multiple files, as available disk space allows. Workbench also allows the creation of drawers within drawers, subdrawers or subdirectories, for further file management. Create as many drawers and subdrawers on your disk as needed.&lt;br /&gt;
&lt;br /&gt;
A drawer icon is displayed in the disk window for each drawer created on a particular disk. Each drawer window contains the icons of the files and subdrawers that exist in it.&lt;br /&gt;
&lt;br /&gt;
== Paths ==&lt;br /&gt;
&lt;br /&gt;
A path is a complete description of the location of a particular file on a disk. When a program requests the name of a file for retrieval, specify the file&#039;s path, including the volume or device name and all the drawers that lead to that file.&lt;br /&gt;
&lt;br /&gt;
The method for specifying paths varies from program to program. Most programs use a file requester with a scrolling list, in which the disk name, any drawer names, and the file name are displayed. Click on the appropriate names to specify the path. However, for some programs you may have to type in the complete path name.&lt;br /&gt;
&lt;br /&gt;
To enter a complete path:&lt;br /&gt;
&lt;br /&gt;
* Type the name of the disk followed by a colon. This name is the volume name of the disk, such as Mydisk:. You can substitute the disk&#039;s device name, such as DF0:, in place of the disk name. However, if you enter the device name rather than the volume name, be sure the correct disk is in that device.&amp;lt;br/&amp;gt;Diskname:&lt;br /&gt;
&lt;br /&gt;
* For a file that is not in a drawer, specify the file name after the colon following the disk name to complete the path.&amp;lt;br/&amp;gt;Diskname:filename&lt;br /&gt;
&lt;br /&gt;
* For a file in a drawer, after the colon following the disk name specify the drawer name followed by a slash (/) followed by the file name.&amp;lt;br/&amp;gt;Diskname:drawername/filename&lt;br /&gt;
&lt;br /&gt;
* If there are more drawers in the path, each drawer must be specified followed by a slash.&amp;lt;br/&amp;gt;Diskname:drawername/subdrawername/filename&lt;br /&gt;
&lt;br /&gt;
{{Note|File and drawer names containing spaces can cause recognition problems. We recommend that you avoid using spaces in file or drawer names. If you have trouble referencing a name that contains a space, enclose the entire path in double quotation marks.}}&lt;br /&gt;
&lt;br /&gt;
== File and Drawer Names ==&lt;br /&gt;
&lt;br /&gt;
The following rules apply for naming files and drawers:&lt;br /&gt;
&lt;br /&gt;
* Names can be up to 30 characters long. Names can contain upper case letters and any punctuation marks that are not reserved.&lt;br /&gt;
* Colons (:) and slashes (/) are not allowed within a name. These characters are reserved for path statements. However, other non-alphabetic characters can be used.&lt;br /&gt;
* The use of spaces before or after names should be avoided due to the possibility of omission.&lt;br /&gt;
* Upper and lower case differences (capitalization) are preserved and displayed by the Amiga. However, the system is not case-sensitive: upper and lower case are considered the same.&lt;br /&gt;
* Duplicate file names are not allowed within the same drawer. If you save a file with the same name as an existing file in a drawer, it overwrites the original file in that drawer.&lt;br /&gt;
* Two files with the same name can exist in separate drawers or within different paths.&lt;br /&gt;
&lt;br /&gt;
== Trashcan ==&lt;br /&gt;
&lt;br /&gt;
The Trashcan is a special drawer that can be placed on a disk for storing files that you no longer needed and may wish to delete. Discard icons or pseudo-icons for the files to be deleted by dragging them into the Trashcan. If the icon to be discarded is a drawer, is associated files are also moved to the Trashcan.&lt;br /&gt;
&lt;br /&gt;
Choosing Empty Trash from the Icons menu deletes the icons and all of their associated files from the Trashcan. Before choosing Empty Trash, you can still recover any of the Trashcan&#039;s contents by opening its window and dragging the icons back out.&lt;br /&gt;
&lt;br /&gt;
For more information about putting a Trashcan on a disk, see the Format Disk description in Chapter 3.&lt;br /&gt;
&lt;br /&gt;
= Using Application Software =&lt;br /&gt;
&lt;br /&gt;
Applications are software programs, such as databases, video and sound programs, word processing programs, recreational programs, and educational programs that are available for use on your Amiga. Most Amiga programs use windows, menus, and gadgets in ways very similar to the Workbench programs on your system disks. However, you should always read the documentation that comes with your applications for directions on using unfamiliar menu items and gadgets.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6633</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6633"/>
		<updated>2013-10-13T14:29:41Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag when the window object is created (OM_NEW).&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;br /&gt;
[[File:calculator_menus.png|left]]&lt;br /&gt;
As an example of this, we shall use the Calculator utility. Calculator has two modes, and each of these has a separate UniqueID, this means that we can actually save the position and size for each mode.&lt;br /&gt;
Here you can see we have some extra menu items, namely:&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Snapshot&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This will save the window objects size and position to a file stored in ENV(ARC):sys/WindowData. A drawer will be created there with the same name as your application, and the data for this object will be saved inside it with the UniqueID you gave the window object.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Unsnapshot&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Just as the data was saved above, this option will remove the size and position data, effectively making the window object use the defaults again.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Restore&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This option reloads the saved snapshot data and places the window back to that position. This is useful if you have moved or resized the window, and want to put it back to the last saved position/size.&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
That concludes our look into the window.class popup menu, we hope you found it useful.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6632</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6632"/>
		<updated>2013-10-13T14:27:13Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag.&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;br /&gt;
[[File:calculator_menus.png|left]]&lt;br /&gt;
As an example of this, we shall use the Calculator utility. Calculator has two modes, and each of these has a separate UniqueID, this means that we can actually save the position and size for each mode.&lt;br /&gt;
Here you can see we have some extra menu items, namely:&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Snapshot&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This will save the window objects size and position to a file stored in ENV(ARC):sys/WindowData. A drawer will be created there with the same name as your application, and the data for this object will be saved inside it with the UniqueID you gave the window object.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Unsnapshot&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Just as the data was saved above, this option will remove the size and position data, effectively making the window object use the defaults again.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Restore&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
This option reloads the saved snapshot data and places the window back to that position. This is useful if you have moved or resized the window, and want to put it back to the last saved position/size.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6631</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6631"/>
		<updated>2013-10-13T14:25:44Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag.&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;br /&gt;
[[File:calculator_menus.png|left]]&lt;br /&gt;
As an example of this, we shall use the Calculator utility. Calculator has two modes, and each of these has a separate UniqueID, this means that we can actually save the position and size for each mode.&lt;br /&gt;
Here you can see we have some extra menu items, namely:&lt;br /&gt;
&#039;&#039;&#039;Snapshot&#039;&#039;&#039;&lt;br /&gt;
This will save the window objects size and position to a file stored in ENV(ARC):sys/WindowData. A drawer will be created there with the same name as your application, and the data for this object will be saved inside it with the UniqueID you gave the window object.&lt;br /&gt;
&#039;&#039;&#039;Unsnapshot&#039;&#039;&#039;&lt;br /&gt;
Just as the data was saved above, this option will remove the size and position data, effectively making the window object use the defaults again.&lt;br /&gt;
&#039;&#039;&#039;Restore&#039;&#039;&#039;&lt;br /&gt;
This option reloads the saved snapshot data and places the window back to that position. This is useful if you have moved or resized the window, and want to put it back to the last saved position/size.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6630</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6630"/>
		<updated>2013-10-13T14:18:49Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag.&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;br /&gt;
[[File:calculator_menus.png|left]]&lt;br /&gt;
As an example of this, we shall use the Calculator utility. Calculator has two modes, and each of these has a separate UniqueID, this means that we can actually save the position and size for each mode.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6629</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6629"/>
		<updated>2013-10-13T14:18:28Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag.&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;br /&gt;
[[File:calculator_menus.png|top]]&lt;br /&gt;
As an example of this, we shall use the Calculator utility. Calculator has two modes, and each of these has a separate UniqueID, this means that we can actually save the position and size for each mode.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6628</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6628"/>
		<updated>2013-10-13T14:15:25Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag.&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;br /&gt;
[[File:calculator_menus.png]]&lt;br /&gt;
As an example of this, we shall use the Calculator utility. Calculator has two modes, and each of these has a separate UniqueID, this means that we can actually save the position and size for each mode.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=File:Calculator_menus.png&amp;diff=6627</id>
		<title>File:Calculator menus.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=File:Calculator_menus.png&amp;diff=6627"/>
		<updated>2013-10-13T14:14:38Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: Showing snapshot feature for Calculator&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Showing snapshot feature for Calculator&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6626</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6626"/>
		<updated>2013-10-13T14:11:36Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag.&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;br /&gt;
As an example of this, we shall use the Calculator utility. Calculator has two modes, and each of these has a separate UniqueID, this means that we can actually save the position and size for each mode.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6625</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6625"/>
		<updated>2013-10-13T14:08:18Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In parts one and two, we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what extra items could be added and how to deal with them. Since then, some extra features have been added which allows Snapshotting and Unsnapshotting of window.class objects. This will require at least version 53.54, and will be subject to a future update. For now, we shall discover how this feature is used in readiness for that update.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
As we saw in part one, there are a number of &amp;quot;default&amp;quot; items we can show in the menu, and we can add items for our own use. We can also enable an automatic way to save window size and position. In order to do this, we need to specify the WINDOW_UniqueID tag.&lt;br /&gt;
While this tag is not directly connected with the windows popup menu, it does affect the menu and the amount of default items.&lt;br /&gt;
WINDOW_UniqueID tells window.class that this object has a name, specified by the tag data. This should be a unique name within your application. It is highly possible that your application may open more than one window, and each may have their size and position saved separately by ensuring the string you supply is unique. For example, specifying &amp;quot;MAIN_Window&amp;quot; as the UniqueID for the main window, and &amp;quot;LIST_Window&amp;quot; for another will allow your users to specify different positions and sizes for each window object.&lt;br /&gt;
&lt;br /&gt;
= A Closer Look =&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6624</id>
		<title>BOOPSI Popup Menus - Part 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6624"/>
		<updated>2013-10-13T13:41:23Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In part one we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what the default options are and how to use them. In part two, we shall discuss how the application programmer can add items to the popup menu, and be notified when the user has selected one of these custom options.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
The popup menu available from the window objects title bar is not designed to be a replacement for the applications menus, it is purely to offer the user some options which are applicable to the window object the menu is attached to. Such options could be offering a &amp;quot;Snapshot&amp;quot; facility where the application could save the current window size and position so that it will always open in the same place and be the same size (&#039;&#039;more on that in part 3&#039;&#039;). Whatever the options, they should be relevant to the window and its operation. Remember, users are easily confused, so make your custom options simple and plainly obvious!&lt;br /&gt;
&lt;br /&gt;
= Adding items =&lt;br /&gt;
&lt;br /&gt;
The adding of custom options is done via the &amp;quot;Hook&amp;quot; method, and the hook function should use the standard popupmenu.class way of adding items. The hook function is called like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;hook&amp;quot; parameter is a pointer to the Hook structure used to declare this function, and the &amp;quot;o&amp;quot; parameter is the popupmenu object which you can add items to with PMA_AddItem. You may also use the standard h_Data pointer of the &amp;quot;hook&amp;quot; structure for your own use, such as passing a data pointer so that the hook function may better determine what options to offer.&lt;br /&gt;
&lt;br /&gt;
As with all hook functions, the pointers supplied are guaranteed to be valid when the function is called, but not afterwards. Do NOT cache any of these pointers, as they WILL change with each invocation of the popup menu.&lt;br /&gt;
&lt;br /&gt;
When adding custom items to the popup menu, it is advisable to supply a separator as the first item. This gives the user a visual distinction between the standard items, and the custom ones. For each item you add, you should supply a meaningful PMIA_ID value, as this is returned to you in the window event loop, and it is how your application determines which custom item has been selected by the user. There are no real restrictions on what IDs you can use here, but it is recommended to start the IDs at 1 rather than ZERO.&lt;br /&gt;
Also, always add your custom items to the bottom of the item list. The name of the game here is &amp;quot;Consistency&amp;quot;, and keeping an overall unform nature to these menus will help the users become accustomed to this new functionality.&lt;br /&gt;
&lt;br /&gt;
The hook function should return the amount of items successfully added to the menu. This is used to verify that an empty menu will not be shown.&lt;br /&gt;
&lt;br /&gt;
So, let&#039;s have a look at an example hook function that will add a separator and one custom item to the popup menu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
{&lt;br /&gt;
  LONG added = 0;&lt;br /&gt;
  Object *item;&lt;br /&gt;
     &lt;br /&gt;
  /* add a separator to separate custom items from default ones */&lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_WideTitleBar, TRUE,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* we failed to add the item, dispose of it */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
     &lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_Title, (ULONG) &amp;quot;Snapshot&amp;quot;,&lt;br /&gt;
    PMIA_ID, (ULONG)ID_SNAPSHOT,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* again, adding the item to the menu failed, so dispose of it here */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
  return added;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the items were added successfully, the popup menu will now contain a separator after the last default option, and a new custom &amp;quot;Snapshot&amp;quot; item which the user can select. All the rules of popupmenu.class apply here, which means we can add as many items as are required. This also includes adding sub-items etc. Please refer to the autodoc for popupmenu.class for further information on what can be done.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s look at how we get the notification of this event, and how to deal with it.&lt;br /&gt;
&lt;br /&gt;
= Specifying your hook =&lt;br /&gt;
&lt;br /&gt;
Once you have your hook function created and adding the items that you require, window.class needs to know about it. We do this by initialising a struct Hook, and adding our hook function to it. The code for that can be like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
struct Hook *popuphook;&lt;br /&gt;
popuphook = IExec-&amp;gt;AllocSysObjectTags( ASOT_HOOK,&lt;br /&gt;
  ASOHOOK_Entry, mypopupfunction,&lt;br /&gt;
  ASOHOOK_Subentry, NULL,&lt;br /&gt;
  ASOHOOK_Data, mydatapointer,&lt;br /&gt;
  TAG_END );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This hook now gets passed to the window.class by passing WINDOW_PopupHook, mypopuphook in the tags when the window object is created.&lt;br /&gt;
&lt;br /&gt;
Obviously, do not forget to &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
IExec-&amp;gt;FreeSysObject( ASOT_HOOK, mypopuphook );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Getting custom menu item events =&lt;br /&gt;
&lt;br /&gt;
In part one, we showed how to expand the window event loop to receive the new screen jumping event. In a similar vein, we also need to add a new event type so that we may be notified that the user selected one of our custom menu items. We do this by testing for the WMHI_POPUPMENU event. The enhanced event loop will now look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  while( !done )&lt;br /&gt;
  {&lt;br /&gt;
    IExec-&amp;gt;Wait( winsig );&lt;br /&gt;
     &lt;br /&gt;
    while(( result = IIntuition-&amp;gt;IDoMethod( winobj, WM_HANDLEINPUT, code )) != WMHI_LASTMSG )&lt;br /&gt;
    {&lt;br /&gt;
      switch( result &amp;amp; WMHI_CLASSMASK )&lt;br /&gt;
      {&lt;br /&gt;
        case WMHI_CLOSEWINDOW:&lt;br /&gt;
        done = TRUE;&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_ICONIFY:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_GADGETUP:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_JUMPSCREEN:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_POPUPMENU:&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Earlier we mentioned about supplying meaningful menu item IDs, and this is where they play their part. Once your event loop detects the WMHI_POPUPMENU event, we can get the ID of the menu item selected by using the WMHI_GADGETMASK just like we would for gadgets. Taking our example hook function above into account, the event loop code would be something like this to detect the menu item selected:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  case WMHI_POPUPMENU:&lt;br /&gt;
  {&lt;br /&gt;
    switch( result &amp;amp; WMHI_GADGETMASK )&lt;br /&gt;
    {&lt;br /&gt;
      case ID_SNAPSHOT:&lt;br /&gt;
      /* the code to snapshot the window goes here */&lt;br /&gt;
      break;&lt;br /&gt;
     &lt;br /&gt;
      /* we can add the IDs of extra menu items here */&lt;br /&gt;
    }&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Summary =&lt;br /&gt;
&lt;br /&gt;
We hope you have found this look at the popupmenu feature of window.class useful. Obviously the example code above is not complete, it is merely to show how the application programmer can go about using this new feature, and the steps required.&lt;br /&gt;
A fully working example with source code can be downloaded from [http://codebench.co.uk/os4coding/WindowPopup.lha here], which should give you a good indication of how to adapt your code. You will not be able to compile this code just yet, as a newer SDK will be required than that which is available at the time of writing.&lt;br /&gt;
&lt;br /&gt;
In part 3, we will take a look at some extra functionality that has been added to window.class, and allows saving of window positions. For now, this is purely for reference only, as it will require a newer version of window.class than is currently publicly available.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6623</id>
		<title>BOOPSI Popup Menus - Part 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6623"/>
		<updated>2013-10-13T13:38:21Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In part one we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what the default options are and how to use them. In part two, we shall discuss how the application programmer can add items to the popup menu, and be notified when the user has selected one of these custom options.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
The popup menu available from the window objects title bar is not designed to be a replacement for the applications menus, it is purely to offer the user some options which are applicable to the window object the menu is attached to. Such options could be offering a &amp;quot;Snapshot&amp;quot; facility where the application could save the current window size and position so that it will always open in the same place and be the same size (&#039;&#039;more on that in part 3&#039;&#039;). Whatever the options, they should be relevant to the window and its operation. Remember, users are easily confused, so make your custom options simple and plainly obvious!&lt;br /&gt;
&lt;br /&gt;
= Adding items =&lt;br /&gt;
&lt;br /&gt;
The adding of custom options is done via the &amp;quot;Hook&amp;quot; method, and the hook function should use the standard popupmenu.class way of adding items. The hook function is called like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;hook&amp;quot; parameter is a pointer to the Hook structure used to declare this function, and the &amp;quot;o&amp;quot; parameter is the popupmenu object which you can add items to with PMA_AddItem. You may also use the standard h_Data pointer of the &amp;quot;hook&amp;quot; structure for your own use, such as passing a data pointer so that the hook function may better determine what options to offer.&lt;br /&gt;
&lt;br /&gt;
As with all hook functions, the pointers supplied are guaranteed to be valid when the function is called, but not afterwards. Do NOT cache any of these pointers, as they WILL change with each invocation of the popup menu.&lt;br /&gt;
&lt;br /&gt;
When adding custom items to the popup menu, it is advisable to supply a separator as the first item. This gives the user a visual distinction between the standard items, and the custom ones. For each item you add, you should supply a meaningful PMIA_ID value, as this is returned to you in the window event loop, and it is how your application determines which custom item has been selected by the user. There are no real restrictions on what IDs you can use here, but it is recommended to start the IDs at 1 rather than ZERO.&lt;br /&gt;
Also, always add your custom items to the bottom of the item list. The name of the game here is &amp;quot;Consistency&amp;quot;, and keeping an overall unform nature to these menus will help the users become accustomed to this new functionality.&lt;br /&gt;
&lt;br /&gt;
The hook function should return the amount of items successfully added to the menu. This is used to verify that an empty menu will not be shown.&lt;br /&gt;
&lt;br /&gt;
So, let&#039;s have a look at an example hook function that will add a separator and one custom item to the popup menu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
{&lt;br /&gt;
  LONG added = 0;&lt;br /&gt;
  Object *item;&lt;br /&gt;
     &lt;br /&gt;
  /* add a separator to separate custom items from default ones */&lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_WideTitleBar, TRUE,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* we failed to add the item, dispose of it */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
     &lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_Title, (ULONG) &amp;quot;Snapshot&amp;quot;,&lt;br /&gt;
    PMIA_ID, (ULONG)ID_SNAPSHOT,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* again, adding the item to the menu failed, so dispose of it here */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
  return added;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the items were added successfully, the popup menu will now contain a separator after the last default option, and a new custom &amp;quot;Snapshot&amp;quot; item which the user can select. All the rules of popupmenu.class apply here, which means we can add as many items as are required. This also includes adding sub-items etc. Please refer to the autodoc for popupmenu.class for further information on what can be done.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s look at how we get the notification of this event, and how to deal with it.&lt;br /&gt;
&lt;br /&gt;
= Specifying your hook =&lt;br /&gt;
&lt;br /&gt;
Once you have your hook function created and adding the items that you require, window.class needs to know about it. We do this by initialising a struct Hook, and adding our hook function to it. The code for that can be like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
struct Hook *popuphook;&lt;br /&gt;
popuphook = IExec-&amp;gt;AllocSysObjectTags( ASOT_HOOK,&lt;br /&gt;
  ASOHOOK_Entry, mypopupfunction,&lt;br /&gt;
  ASOHOOK_Subentry, NULL,&lt;br /&gt;
  ASOHOOK_Data, mydatapointer,&lt;br /&gt;
  TAG_END );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This hook now gets passed to the window.class by passing WINDOW_PopupHook, mypopuphook in the tags when the window object is created.&lt;br /&gt;
&lt;br /&gt;
Obviously, do not forget to &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
IExec-&amp;gt;FreeSysObject( ASOT_HOOK, mypopuphook );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Getting custom menu item events =&lt;br /&gt;
&lt;br /&gt;
In part one, we showed how to expand the window event loop to receive the new screen jumping event. In a similar vein, we also need to add a new event type so that we may be notified that the user selected one of our custom menu items. We do this by testing for the WMHI_POPUPMENU event. The enhanced event loop will now look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  while( !done )&lt;br /&gt;
  {&lt;br /&gt;
    IExec-&amp;gt;Wait( winsig );&lt;br /&gt;
     &lt;br /&gt;
    while(( result = IIntuition-&amp;gt;IDoMethod( winobj, WM_HANDLEINPUT, code )) != WMHI_LASTMSG )&lt;br /&gt;
    {&lt;br /&gt;
      switch( result &amp;amp; WMHI_CLASSMASK )&lt;br /&gt;
      {&lt;br /&gt;
        case WMHI_CLOSEWINDOW:&lt;br /&gt;
        done = TRUE;&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_ICONIFY:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_GADGETUP:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_JUMPSCREEN:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_POPUPMENU:&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Earlier we mentioned about supplying meaningful menu item IDs, and this is where they play their part. Once your event loop detects the WMHI_POPUPMENU event, we can get the ID of the menu item selected by using the WMHI_GADGETMASK just like we would for gadgets. Taking our example hook function above into account, the event loop code would be something like this to detect the menu item selected:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  case WMHI_POPUPMENU:&lt;br /&gt;
  {&lt;br /&gt;
    switch( result &amp;amp; WMHI_GADGETMASK )&lt;br /&gt;
    {&lt;br /&gt;
      case ID_SNAPSHOT:&lt;br /&gt;
      /* the code to snapshot the window goes here */&lt;br /&gt;
      break;&lt;br /&gt;
     &lt;br /&gt;
      /* we can add the IDs of extra menu items here */&lt;br /&gt;
    }&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Summary =&lt;br /&gt;
&lt;br /&gt;
We hope you have found this look at the popupmenu feature of window.class useful. Obviously the example code above is not complete, it is merely to show how the application programmer can go about using this new feature, and the steps required.&lt;br /&gt;
A fully working example with source code can be downloaded from [http://codebench.co.uk/os4coding/WindowPopup.lha here], which should give you a good indication of how to adapt your code. You will not be able to compile this code just yet, as a newer SDK will be required than that which is available at the time of writing.&lt;br /&gt;
&lt;br /&gt;
Thanks for looking.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6622</id>
		<title>BOOPSI Popup Menus - Part 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6622"/>
		<updated>2013-10-13T13:33:49Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In part one we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what the default options are and how to use them. In part two, we shall discuss how the application programmer can add items to the popup menu, and be notified when the user has selected one of these custom options.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
The popup menu available from the window objects title bar is not designed to be a replacement for the applications menus, it is purely to offer the user some options which are applicable to the window object the menu is attached to. Such options could be offering a &amp;quot;Snapshot&amp;quot; facility where the application could save the current window size and position so that it will always open in the same place and be the same size (&#039;&#039;more on that in part 3&#039;&#039;). Whatever the options, they should be relevant to the window and its operation. Remember, users are easily confused, so make your custom options simple and plainly obvious!&lt;br /&gt;
&lt;br /&gt;
= Adding items =&lt;br /&gt;
&lt;br /&gt;
The adding of custom options is done via the &amp;quot;Hook&amp;quot; method, and the hook function should use the standard popupmenu.class way of adding items. The hook function is called like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;hook&amp;quot; parameter is a pointer to the Hook structure used to declare this function, and the &amp;quot;o&amp;quot; parameter is the popupmenu object which you can add items to with PMA_AddItem. You may also use the standard h_Data pointer of the &amp;quot;hook&amp;quot; structure for your own use, such as passing a data pointer so that the hook function may better determine what options to offer.&lt;br /&gt;
&lt;br /&gt;
As with all hook functions, the pointers supplied are guaranteed to be valid when the function is called, but not afterwards. Do NOT cache any of these pointers, as they WILL change with each invocation of the popup menu.&lt;br /&gt;
&lt;br /&gt;
When adding custom items to the popup menu, it is advisable to supply a separator as the first item. This gives the user a visual distinction between the standard items, and the custom ones. For each item you add, you should supply a meaningful PMIA_ID value, as this is returned to you in the window event loop, and it is how your application determines which custom item has been selected by the user. There are no real restrictions on what IDs you can use here, but it is recommended to start the IDs at 1 rather than ZERO.&lt;br /&gt;
Also, always add your custom items to the bottom of the item list. The name of the game here is &amp;quot;Consistency&amp;quot;, and keeping an overall unform nature to these menus will help the users become accustomed to this new functionality.&lt;br /&gt;
&lt;br /&gt;
The hook function should return the amount of items successfully added to the menu. This is used to verify that an empty menu will not be shown.&lt;br /&gt;
&lt;br /&gt;
So, let&#039;s have a look at an example hook function that will add a separator and one custom item to the popup menu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
{&lt;br /&gt;
  LONG added = 0;&lt;br /&gt;
  Object *item;&lt;br /&gt;
     &lt;br /&gt;
  /* add a separator to separate custom items from default ones */&lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_WideTitleBar, TRUE,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* we failed to add the item, dispose of it */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
     &lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_Title, (ULONG) &amp;quot;Snapshot&amp;quot;,&lt;br /&gt;
    PMIA_ID, (ULONG)ID_SNAPSHOT,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* again, adding the item to the menu failed, so dispose of it here */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
  return added;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the items were added successfully, the popup menu will now contain a separator after the last default option, and a new custom &amp;quot;Snapshot&amp;quot; item which the user can select. All the rules of popupmenu.class apply here, which means we can add as many items as are required. This also includes adding sub-items etc. Please refer to the autodoc for popupmenu.class for further information on what can be done.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s look at how we get the notification of this event, and how to deal with it.&lt;br /&gt;
&lt;br /&gt;
= Specifying your hook =&lt;br /&gt;
&lt;br /&gt;
Once you have your hook function created and adding the items that you require, window.class needs to know about it. We do this by initialising a struct Hook, and adding our hook function to it. The code for that can be like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
struct Hook *popuphook;&lt;br /&gt;
popuphook = IExec-&amp;gt;AllocSysObjectTags( ASOT_HOOK,&lt;br /&gt;
  ASOHOOK_Entry, mypopupfunction,&lt;br /&gt;
  ASOHOOK_Subentry, NULL,&lt;br /&gt;
  ASOHOOK_Data, mydatapointer,&lt;br /&gt;
  TAG_END );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This hook now gets passed to the window.class by passing WINDOW_PopupHook, mypopuphook in the tags when the window object is created.&lt;br /&gt;
&lt;br /&gt;
Obviously, do not forget to &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
IExec-&amp;gt;FreeSysObject( ASOT_HOOK, mypopuphook );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Getting custom menu item events =&lt;br /&gt;
&lt;br /&gt;
In part one, we showed how to expand the window event loop to receive the new screen jumping event. In a similar vein, we also need to add a new event type so that we may be notified that the user selected one of our custom menu items. We do this by testing for the WMHI_POPUPMENU event. The enhanced event loop will now look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  while( !done )&lt;br /&gt;
  {&lt;br /&gt;
    IExec-&amp;gt;Wait( winsig );&lt;br /&gt;
     &lt;br /&gt;
    while(( result = IIntuition-&amp;gt;IDoMethod( winobj, WM_HANDLEINPUT, code )) != WMHI_LASTMSG )&lt;br /&gt;
    {&lt;br /&gt;
      switch( result &amp;amp; WMHI_CLASSMASK )&lt;br /&gt;
      {&lt;br /&gt;
        case WMHI_CLOSEWINDOW:&lt;br /&gt;
        done = TRUE;&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_ICONIFY:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_GADGETUP:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_JUMPSCREEN:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_POPUPMENU:&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Earlier we mentioned about supplying meaningful menu item IDs, and this is where they play their part. Once your event loop detects the WMHI_POPUPMENU event, we can get the ID of the menu item selected by using the WMHI_GADGETMASK just like we would for gadgets. Taking our example hook function above into account, the event loop code would be something like this to detect the menu item selected:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  case WMHI_POPUPMENU:&lt;br /&gt;
  {&lt;br /&gt;
    switch( result &amp;amp; WMHI_GADGETMASK )&lt;br /&gt;
    {&lt;br /&gt;
      case ID_SNAPSHOT:&lt;br /&gt;
      /* the code to snapshot the window goes here */&lt;br /&gt;
      break;&lt;br /&gt;
     &lt;br /&gt;
      /* we can add the IDs of extra menu items here */&lt;br /&gt;
    }&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Summary =&lt;br /&gt;
&lt;br /&gt;
We hope you have found this look at the popupmenu feature of window.class useful. Obviously the example code above is not complete, it is merely to show how the application programmer can go about using this new feature, and the steps required.&lt;br /&gt;
A fully working example with source code can be downloaded from here, which should give you a good indication of how to adapt your code. You will not be able to compile this code just yet, as a newer SDK will be required than that which is available at the time of writing.&lt;br /&gt;
&lt;br /&gt;
Thanks for looking.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6621</id>
		<title>BOOPSI Popup Menus - Part 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6621"/>
		<updated>2013-10-13T13:26:00Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In part one we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what the default options are and how to use them. In part two, we shall discuss how the application programmer can add items to the popup menu, and be notified when the user has selected one of these custom options.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
The popup menu available from the window objects title bar is not designed to be a replacement for the applications menus, it is purely to offer the user some options which are applicable to the window object the menu is attached to. Such options could be offering a &amp;quot;Snapshot&amp;quot; facility where the application could save the current window size and position so that it will always open in the same place and be the same size (&#039;&#039;more on that in part 3&#039;&#039;). Whatever the options, they should be relevant to the window and its operation. Remember, users are easily confused, so make your custom options simple and plainly obvious!&lt;br /&gt;
&lt;br /&gt;
= Adding items =&lt;br /&gt;
&lt;br /&gt;
The adding of custom options is done via the &amp;quot;Hook&amp;quot; method, and the hook function should use the standard popupmenu.class way of adding items. The hook function is called like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;hook&amp;quot; parameter is a pointer to the Hook structure used to declare this function, and the &amp;quot;o&amp;quot; parameter is the popupmenu object which you can add items to with PMA_AddItem. You may also use the standard h_Data pointer of the &amp;quot;hook&amp;quot; structure for your own use, such as passing a data pointer so that the hook function may better determine what options to offer.&lt;br /&gt;
&lt;br /&gt;
As with all hook functions, the pointers supplied are guaranteed to be valid when the function is called, but not afterwards. Do NOT cache any of these pointers, as they WILL change with each invocation of the popup menu.&lt;br /&gt;
&lt;br /&gt;
When adding custom items to the popup menu, it is advisable to supply a separator as the first item. This gives the user a visual distinction between the standard items, and the custom ones. For each item you add, you should supply a meaningful PMIA_ID value, as this is returned to you in the window event loop, and it is how your application determines which custom item has been selected by the user. There are no real restrictions on what IDs you can use here, but it is recommended to start the IDs at 1 rather than ZERO.&lt;br /&gt;
Also, always add your custom items to the bottom of the item list. The name of the game here is &amp;quot;Consistency&amp;quot;, and keeping an overall unform nature to these menus will help the users become accustomed to this new functionality.&lt;br /&gt;
&lt;br /&gt;
The hook function should return the amount of items successfully added to the menu. This is used to verify that an empty menu will not be shown.&lt;br /&gt;
&lt;br /&gt;
So, let&#039;s have a look at an example hook function that will add a separator and one custom item to the popup menu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
{&lt;br /&gt;
  LONG added = 0;&lt;br /&gt;
  Object *item;&lt;br /&gt;
     &lt;br /&gt;
  /* add a separator to separate custom items from default ones */&lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_WideTitleBar, TRUE,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* we failed to add the item, dispose of it */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
     &lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_Title, (ULONG) &amp;quot;Snapshot&amp;quot;,&lt;br /&gt;
    PMIA_ID, (ULONG)ID_SNAPSHOT,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* again, adding the item to the menu failed, so dispose of it here */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
  return added;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the items were added successfully, the popup menu will now contain a separator after the last default option, and a new custom &amp;quot;Snapshot&amp;quot; item which the user can select. All the rules of popupmenu.class apply here, which means we can add as many items as are required. This also includes adding sub-items etc. Please refer to the autodoc for popupmenu.class for further information on what can be done.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s look at how we get the notification of this event, and how to deal with it.&lt;br /&gt;
&lt;br /&gt;
= Specifying your hook =&lt;br /&gt;
&lt;br /&gt;
Once you have your hook function created and adding the items that you require, window.class needs to know about it. We do this by initialising a struct Hook, and adding our hook function to it. The code for that can be like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
struct Hook *popuphook;&lt;br /&gt;
popuphook = IExec-&amp;gt;AllocSysObjectTags( ASOT_HOOK,&lt;br /&gt;
  ASOHOOK_Entry, mypopupfunction,&lt;br /&gt;
  ASOHOOK_Subentry, NULL,&lt;br /&gt;
  ASOHOOK_Data, mydatapointer,&lt;br /&gt;
  TAG_END );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This hook now gets passed to the window.class a by passing WINDOW_PopupHook, mypopuphook in the tags when the window object is created.&lt;br /&gt;
&lt;br /&gt;
Obviously, do not forget to &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
IExec-&amp;gt;FreeSysObject( ASOT_HOOK, mypopuphook );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Getting custom menu item events =&lt;br /&gt;
&lt;br /&gt;
In part one, we showed how to expand the window event loop to receive the new screen jumping event. In a similar vein, we also need to add a new event type so that we may be notified that the user selected one of our custom menu items. We do this by testing for the WMHI_POPUPMENU event. The enhanced event loop will now look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  while( !done )&lt;br /&gt;
  {&lt;br /&gt;
    IExec-&amp;gt;Wait( winsig );&lt;br /&gt;
     &lt;br /&gt;
    while(( result = IIntuition-&amp;gt;IDoMethod( winobj, WM_HANDLEINPUT, code )) != WMHI_LASTMSG )&lt;br /&gt;
    {&lt;br /&gt;
      switch( result &amp;amp; WMHI_CLASSMASK )&lt;br /&gt;
      {&lt;br /&gt;
        case WMHI_CLOSEWINDOW:&lt;br /&gt;
        done = TRUE;&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_ICONIFY:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_GADGETUP:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_JUMPSCREEN:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_POPUPMENU:&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Earlier we mentioned about supplying meaningful menu item IDs, and this is where they play their part. Once your event loop detects the WMHI_POPUPMENU event, we can get the ID of the menu item selected by using the WMHI_GADGETMASK just like we would for gadgets. Taking our example hook function above into account, the event loop code would something like this to detect the menu item selected:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  case WMHI_POPUPMENU:&lt;br /&gt;
  {&lt;br /&gt;
    switch( result &amp;amp; WMHI_GADGETMASK )&lt;br /&gt;
    {&lt;br /&gt;
      case ID_SNAPSHOT:&lt;br /&gt;
      /* the code to snapshot the window goes here */&lt;br /&gt;
      break;&lt;br /&gt;
     &lt;br /&gt;
      /* we can add the IDs of extra menu items here */&lt;br /&gt;
    }&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Summary =&lt;br /&gt;
&lt;br /&gt;
We hope you have found this look at the popupmenu feature of window.class useful. Obviously the example code above is not complete, it is merely to show how the application programmer can go about using this new feature, and the steps required.&lt;br /&gt;
A fully working example with source code can be downloaded from here, which should give you a good indication of how to adapt your code. You will not be able to compile this code just yet, as a newer SDK will be required than that which is available at the time of writing.&lt;br /&gt;
&lt;br /&gt;
Thanks for looking.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6620</id>
		<title>BOOPSI Popup Menus - Part 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_2&amp;diff=6620"/>
		<updated>2013-10-13T13:25:34Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Author =&lt;br /&gt;
&lt;br /&gt;
Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Copyright (c) 2011 Simon Archer&amp;lt;br/&amp;gt;&lt;br /&gt;
Used by Permission&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
In part one we took a look at the new &amp;quot;popup&amp;quot; menu feature of window.class and what the default options are and how to use them. In part two, we shall discuss how the application programmer can add items to the popup menu, and be notified when the user has selected one of these custom options.&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
The popup menu available from the window objects title bar is not designed to be a replacement for the applications menus, it is purely to offer the user some options which are applicable to the window object the menu is attached to. Such options could be offering a &amp;quot;Snapshot&amp;quot; facility where the application could save the current window size and position so that it will always open in the same place and be the same size more on that in part 3). Whatever the options, they should be relevant to the window and its operation. Remember, users are easily confused, so make your custom options simple and plainly obvious!&lt;br /&gt;
&lt;br /&gt;
= Adding items =&lt;br /&gt;
&lt;br /&gt;
The adding of custom options is done via the &amp;quot;Hook&amp;quot; method, and the hook function should use the standard popupmenu.class way of adding items. The hook function is called like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;hook&amp;quot; parameter is a pointer to the Hook structure used to declare this function, and the &amp;quot;o&amp;quot; parameter is the popupmenu object which you can add items to with PMA_AddItem. You may also use the standard h_Data pointer of the &amp;quot;hook&amp;quot; structure for your own use, such as passing a data pointer so that the hook function may better determine what options to offer.&lt;br /&gt;
&lt;br /&gt;
As with all hook functions, the pointers supplied are guaranteed to be valid when the function is called, but not afterwards. Do NOT cache any of these pointers, as they WILL change with each invocation of the popup menu.&lt;br /&gt;
&lt;br /&gt;
When adding custom items to the popup menu, it is advisable to supply a separator as the first item. This gives the user a visual distinction between the standard items, and the custom ones. For each item you add, you should supply a meaningful PMIA_ID value, as this is returned to you in the window event loop, and it is how your application determines which custom item has been selected by the user. There are no real restrictions on what IDs you can use here, but it is recommended to start the IDs at 1 rather than ZERO.&lt;br /&gt;
Also, always add your custom items to the bottom of the item list. The name of the game here is &amp;quot;Consistency&amp;quot;, and keeping an overall unform nature to these menus will help the users become accustomed to this new functionality.&lt;br /&gt;
&lt;br /&gt;
The hook function should return the amount of items successfully added to the menu. This is used to verify that an empty menu will not be shown.&lt;br /&gt;
&lt;br /&gt;
So, let&#039;s have a look at an example hook function that will add a separator and one custom item to the popup menu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
LONG PopupHook( struct Hook *hook, APTR o, UNUSED APTR reserved )&lt;br /&gt;
{&lt;br /&gt;
  LONG added = 0;&lt;br /&gt;
  Object *item;&lt;br /&gt;
     &lt;br /&gt;
  /* add a separator to separate custom items from default ones */&lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_WideTitleBar, TRUE,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* we failed to add the item, dispose of it */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
     &lt;br /&gt;
  if(( item = IIntuition-&amp;gt;NewObject( IPopupMenu-&amp;gt;POPUPMENU_GetItemClass(), NULL,&lt;br /&gt;
    PMIA_Title, (ULONG) &amp;quot;Snapshot&amp;quot;,&lt;br /&gt;
    PMIA_ID, (ULONG)ID_SNAPSHOT,&lt;br /&gt;
    TAG_END )))&lt;br /&gt;
  {&lt;br /&gt;
    if(!( IIntuition-&amp;gt;IDoMethod( o, PM_INSERT, item, ~0 )))&lt;br /&gt;
    {&lt;br /&gt;
      /* again, adding the item to the menu failed, so dispose of it here */&lt;br /&gt;
      IIntuition-&amp;gt;DisposeObject( item );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
      added++;&lt;br /&gt;
  }&lt;br /&gt;
  return added;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the items were added successfully, the popup menu will now contain a separator after the last default option, and a new custom &amp;quot;Snapshot&amp;quot; item which the user can select. All the rules of popupmenu.class apply here, which means we can add as many items as are required. This also includes adding sub-items etc. Please refer to the autodoc for popupmenu.class for further information on what can be done.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s look at how we get the notification of this event, and how to deal with it.&lt;br /&gt;
&lt;br /&gt;
= Specifying your hook =&lt;br /&gt;
&lt;br /&gt;
Once you have your hook function created and adding the items that you require, window.class needs to know about it. We do this by initialising a struct Hook, and adding our hook function to it. The code for that can be like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
struct Hook *popuphook;&lt;br /&gt;
popuphook = IExec-&amp;gt;AllocSysObjectTags( ASOT_HOOK,&lt;br /&gt;
  ASOHOOK_Entry, mypopupfunction,&lt;br /&gt;
  ASOHOOK_Subentry, NULL,&lt;br /&gt;
  ASOHOOK_Data, mydatapointer,&lt;br /&gt;
  TAG_END );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This hook now gets passed to the window.class a by passing WINDOW_PopupHook, mypopuphook in the tags when the window object is created.&lt;br /&gt;
&lt;br /&gt;
Obviously, do not forget to &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
IExec-&amp;gt;FreeSysObject( ASOT_HOOK, mypopuphook );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Getting custom menu item events =&lt;br /&gt;
&lt;br /&gt;
In part one, we showed how to expand the window event loop to receive the new screen jumping event. In a similar vein, we also need to add a new event type so that we may be notified that the user selected one of our custom menu items. We do this by testing for the WMHI_POPUPMENU event. The enhanced event loop will now look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  while( !done )&lt;br /&gt;
  {&lt;br /&gt;
    IExec-&amp;gt;Wait( winsig );&lt;br /&gt;
     &lt;br /&gt;
    while(( result = IIntuition-&amp;gt;IDoMethod( winobj, WM_HANDLEINPUT, code )) != WMHI_LASTMSG )&lt;br /&gt;
    {&lt;br /&gt;
      switch( result &amp;amp; WMHI_CLASSMASK )&lt;br /&gt;
      {&lt;br /&gt;
        case WMHI_CLOSEWINDOW:&lt;br /&gt;
        done = TRUE;&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_ICONIFY:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_GADGETUP:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_JUMPSCREEN:&lt;br /&gt;
        break;&lt;br /&gt;
     &lt;br /&gt;
        case WMHI_POPUPMENU:&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Earlier we mentioned about supplying meaningful menu item IDs, and this is where they play their part. Once your event loop detects the WMHI_POPUPMENU event, we can get the ID of the menu item selected by using the WMHI_GADGETMASK just like we would for gadgets. Taking our example hook function above into account, the event loop code would something like this to detect the menu item selected:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  case WMHI_POPUPMENU:&lt;br /&gt;
  {&lt;br /&gt;
    switch( result &amp;amp; WMHI_GADGETMASK )&lt;br /&gt;
    {&lt;br /&gt;
      case ID_SNAPSHOT:&lt;br /&gt;
      /* the code to snapshot the window goes here */&lt;br /&gt;
      break;&lt;br /&gt;
     &lt;br /&gt;
      /* we can add the IDs of extra menu items here */&lt;br /&gt;
    }&lt;br /&gt;
    break;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Summary =&lt;br /&gt;
&lt;br /&gt;
We hope you have found this look at the popupmenu feature of window.class useful. Obviously the example code above is not complete, it is merely to show how the application programmer can go about using this new feature, and the steps required.&lt;br /&gt;
A fully working example with source code can be downloaded from here, which should give you a good indication of how to adapt your code. You will not be able to compile this code just yet, as a newer SDK will be required than that which is available at the time of writing.&lt;br /&gt;
&lt;br /&gt;
Thanks for looking.&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
	<entry>
		<id>https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6563</id>
		<title>BOOPSI Popup Menus - Part 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.amigaos.net/w/index.php?title=BOOPSI_Popup_Menus_-_Part_3&amp;diff=6563"/>
		<updated>2013-09-26T20:58:07Z</updated>

		<summary type="html">&lt;p&gt;Simon Archer: Created page with &amp;quot; == Currently under construction... ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Currently under construction... ==&lt;/div&gt;</summary>
		<author><name>Simon Archer</name></author>
	</entry>
</feed>