Amiga Intuition Reference Manual
Amiga Intuition Reference Manual
Addison-Wesley Publishing Company, Inc.. Reading, Massachusetts Menlo Park, California Don Mills, Ontario Wokingham, England Amsterdam Sydney Singapore Tokyo Madrid Bogota Santiago San Juan
2 Introduction
PREFACE
This book provides information about the Intuition user interface and is intended for people who want to use this interface to write application programs for the Amiga. Some familiarity with C language programming is assumed. The first two chapters of this book are introductory in nature. Each of the next nine chapters concentrates on some aspect of Intuition. First, each chapter presents a complete description of the component in general terms. The second part of each chapter contains complete specifications for the data structure of the component and a brief summary of the function calls that affect the component. The last chapter contains some important programming style guidelines. Here is a brief overview of the contents of each chapter: Chapter 1, Introduction. A brief overview of the implementation and goals of the user interface, how the user sees an Intuition application, and an approach to using Intuition. Chapter 2, Getting Started with Intuition. A summary of Intuition components and a sample program that shows the header files, how to access the Intuition library, and some fundamental Intuition structures. Chapter 3, Screens. Discussion of the fundamental display component of Intuition. How to use the standard screens and how to design and use screens of your own. Chapter 4, Windows. Description of the windows through which applications carry out their input and output. How to define and open windows according to the needs of your application. Chapter 5, Gadgets. The multipurpose input devices that you can design and attach to your windows and requesters. Chapter 6, Menus. Designing the menu items that Intuition forms into a complete menu system for your window. How the user's choices of commands and options are transmitted to the application.
- vii -
Chapter 7, Requesters and Alerts. Description and instructions for using the requesters, information exchange boxes that block input to the window until the user responds. How to use the alerts, which are emergency communication devices. Chapter 8, Input and Output Methods. When and how to use the message port for input and the console device for input and output. How to use the message port messages. Chapter 9, Images, Line Drawing, and Text. Using the Intuition graphics, border and text structures. Using the graphics, border and text functions. Introduction to using the general Amiga graphics facilities in Intuition applications. Chapter 10, Keyboard and Mouse. Using the input from the keyboard and mouse (or other controller). Chapter 11, Other Features. Information about the Preferences program, features that affect the entire display, and notes for assembly language programmers. Chapter 12, Style. Guidelines and cautions for making the interface consistent and easy to use. Appendix A, Intuition Function Calls, contains a complete description of each Intuition function. Appendix B, Intuition Include File, contains the Intuition include file. Appendix C, Internal Procedures, contains some internal Intuition procedures for advanced users. The glossary contains definitions of all the important terms used in the book. You will find related information in the following Amiga manuals: o AmigaDOS Reference Manual o AmigaDOS User's Manual o AmigaDOS Technical Reference Manual o Amiga ROM Kernel Manual
viii
Table of Contents
Chapter 1 INTRODUCTION .................................................................................. How the User Sees an Intuition Application ...................................................... The Right Approach to Using Intuition .............................................................. Chapter 2 GETTING STARTED ............................................................................ Intuition Components ......................................................................................... General Program Requirements and Information ............................................... SIMPLE PROGRAM: OPENING A WINDOW ........................................ SIMPLE PROGRAM: ADDING THE CLOSE GADGET ......................... SIMPLE PROGRAM: ADDING THE REMAINING SYSTEM GADGETS .................................................................................................. SIMPLE PROGRAM: OPENING A CUSTOM SCREEN ......................... SIMPLE PROGRAM: THE FINAL VERSION ......................................... Chapter 3 SCREENS ................................................................................................ About Screens ..................................................................................................... Standard Screens ................................................................................................. WORKBENCH ........................................................................................... Custom Screens ................................................................................................... INTUITION-MANAGED CUSTOM SCREENS ....................................... APPLICATION-MANAGED CUSTOM SCREENS ................................. Screen Characteristics ......................................................................................... DISPLAY MODES ..................................................................................... DEPTH AND COLOR ................................................................................ TYPE STYLES ........................................................................................... HEIGHT, WIDTH, AND STARTING LOCATION .................................. SCREEN TITLE ......................................................................................... CUSTOM GADGETS ................................................................................. Using Custom Screens ........................................................................................ NEWSCREEN STRUCTURE .................................................................... SCREEN STRUCTURE ............................................................................. SCREEN FUNCTIONS .............................................................................. Chapter 4 WINDOWS ............................................................................................... About Windows ................................................................................................... WINDOW INPUT/OUTPUT ....................................................................... OPENING, ACTIVATING AND CLOSING WINDOWS ......................... SPECIAL WINDOW TYPES ......................................................................
1 3 7 9 9 10 11 14 15 16 18 23 24 27 28 29 30 30 32 32 33 34 35 37 38 38 39 41 42 45 46 48 49 50
- ix -
WINDOW GADGETS ................................................................................ WINDOW BORDERS ............................................................................... PRESERVING THE WINDOW DISPLAY ............................................... REFRESHING THE WINDOW DISPLAY ............................................... WINDOW POINTER.................................................................................. WINDOW COLORS................................................................................... WINDOW DIMENSIONS.......................................................................... Using Windows................................................................................................... NEWWINDOW STRUCTURE .................................................................. WINDOW STRUCTURE ........................................................................... WINDOW FUNCTIONS ............................................................................ SETTING UP A SUPERBITMAP WINDOW ........................................... SETTING UP A CUSTOM POINTER....................................................... Chapter 5 GADGETS ............................................................................................... About Gadgets .................................................................................................... System Gadgets................................................................................................... SIZING GADGET....................................................................................... DEPTH-ARRANGEMENT GADGETS..................................................... DRAGGING GADGET .............................................................................. CLOSE GADGET ....................................................................................... Application Gadgets ........................................................................................... RENDERING GADGETS .......................................................................... USER SELECTION OF GADGETS .......................................................... GADGET SELECT BOX............................................................................ GADGET POINTER MOVEMENTS ........................................................ GADGETS IN WINDOW BORDERS ....................................................... MUTUAL EXCLUDE ................................................................................ GADGET HIGHLIGHTING....................................................................... GADGET ENABLING AND DISABLING ............................................... BOOLEAN GADGET TYPE...................................................................... PROPORTIONAL GADGET TYPE .......................................................... STRING GADGET TYPE .......................................................................... INTEGER GADGET TYPE........................................................................ COMBINING GADGET TYPES ............................................................... Using Application Gadgets ................................................................................. GADGET STRUCTURE ............................................................................ FLAGS ........................................................................................................ ACTIVATION FLAGS............................................................................... SPECIALINFO DATA STRUCTURES..................................................... GADGET FUNCTIONS .............................................................................
Chapter 6 MENUS................................................................................................... About Menus...................................................................................................... SUBMITTING AND REMOVING MENU STRIPS ................................ ABOUT MENU ITEM BOXES................................................................. ACTION/ATTRIBUTE ITEMS AND THE CHECKMARK.................... MUTUAL EXCLUSION ........................................................................... COMMAND-KEY SEQUENCES AND IMAGERY................................ ENABLING AND DISABLING MENUS AND MENU ITEMS ............. CHANGING MENU STRIPS.................................................................... MENU NUMBERS AND MENU SELECTION MESSAGES ................. HOW MENU NUMBERS REALLY WORK............................................ INTERCEPTING NORMAL MENU OPERATIONS .............................. REQUESTERS AS MENUS...................................................................... Using Menus ...................................................................................................... MENU STRUCTURES.............................................................................. MENU FUNCTIONS................................................................................. Chapter 7 REQUESTERS AND ALERTS ............................................................ About Requesters ............................................................................................... RENDERING REQUESTERS................................................................... REQUESTER DISPLAY POSITION........................................................ DOUBLE-MENU REQUESTERS ............................................................ GADGETS IN REQUESTERS.................................................................. IDCMP REQUESTER FEATURES .......................................................... A SIMPLE, AUTOMATIC REQUESTER................................................ Using Requesters ............................................................................................... REQUESTER STRUCTURE..................................................................... THE VERY EASY REQUESTER............................................................. REQUESTER FUNCTIONS...................................................................... Alerts.................................................................................................................. Chapter 8 INPUT AND OUTPUT METHODS .................................................... An Overview of Input and Output ..................................................................... About Input and Output ..................................................................................... Using the IDCMP .............................................................................................. INTUIMESSAGES .................................................................................... IDCMP FLAGS.......................................................................................... SETTING UP YOUR OWN IDCMP MONITOR TASK AND USER PORT.......................................................................................................... An Example of the IDCMP................................................................................ Using the Console Device.................................................................................. USING THE AMIGADOS CONSOLE ..................................................... USING THE CONSOLE DEVICE DIRECTLY ....................................... SETTING THE KEYMAP.........................................................................
117 118 120 120 122 123 124 125 126 126 128 129 130 131 132 137 139 140 143 143 144 144 145 145 147 147 151 152 154 157 157 159 164 165 167 171 172 173 174 174 176
- xi -
Chapter 9 IMAGES, LINE DRAWING, AND TEXT ......................................... Using Intuition Graphics.................................................................................... DISPLAYING BORDERS, INTUITEXT, AND IMAGES....................... CREATING BORDERS ............................................................................ CREATING TEXT..................................................................................... CREATING IMAGES................................................................................ INTUITION GRAPHICS FUNCTIONS ................................................... Using the Amiga Graphics Primitives ............................................................... Chapter 10 MOUSE AND KEYBOARD ............................................................... About the Mouse................................................................................................ Mouse Messages ................................................................................................ About the Keyboard........................................................................................... Using the Keyboard as an Alternate to the Mouse ............................................ Chapter 11 OTHER FEATURES........................................................................... Easy Memory Allocation and Deallocation....................................................... INTUITION HELPS YOU REMEMBER ................................................. HOW TO REMEMBER............................................................................. THE REMEMBER STRUCTURE............................................................. AN EXAMPLE OF REMEMBERING...................................................... Preferences......................................................................................................... PREFERENCES STRUCTURE ................................................................ PREFERENCES FUNCTIONS ................................................................. Remaking the ViewPorts ................................................................................... Current Time Values.......................................................................................... Flashing the Display .......................................................................................... Using Sprites in Intuition Windows and Screens .............................................. Assembly Language Conventions ..................................................................... Chapter 12 STYLE .................................................................................................. Menu Style ......................................................................................................... PROJECT MENUS .................................................................................... EDIT MENUS ............................................................................................ Gadget Style....................................................................................................... Requester Style .................................................................................................. Command Key Style .......................................................................................... Mouse Style ....................................................................................................... The Sides of Good and Bad ............................................................................... Miscellaneous Style Notes................................................................................. A Final Note on Style ........................................................................................ Appendix A Intuition Function Calls ....................................................................... Appendix B Intuition Include File ...........................................................................
179 180 181 181 185 189 199 200 203 204 206 206 208 211 211 212 213 213 214 214 217 220 220 221 221 222 222 223 224 224 225 226 227 227 229 230 230 231 A-1 B-1
xii
- xiii -
xiv
Figures
Figure 1-1 A Screen with Windows........................................................................... Figure 1-2 Menu Items and Subitems ....................................................................... Figure 1-3 A Requester ............................................................................................. Figure 1-4 An Alert ................................................................................................... Figure 2-1 A Simple Window .................................................................................. Figure 2-2 A Simple Window with Gadgets............................................................. Figure 2-3 Display Created by Intuition's" Hello World" Program ......................... Figure 3-1 A Screen and Windows ........................................................................... Figure 3-2 Screen and Windows with Menu List Displayed ................................... Figure 3-3 The Workbench Screen and the Workbench Application....................... Figure 3-4 Topaz Font in 60-column and 80-column Types ................................... Figure 3-5 Acceptable Placement of Screens .......................................................... Figure 3-6 Unacceptable Placement of Screens........................................................ Figure 4-1 A High-resolution Screen and Windows ................................................ Figure 4-2 System Gadgets for Windows ................................................................. Figure 4-3 Simple Refresh ........................................................................................ Figure 4-4 Smart Refresh.......................................................................................... Figure 4-5 SuperBitMap Refresh ............................................................................. Figure 4-6 The X-Shaped Custom Pointer................................................................ Figure 5-1 System Gadgets in a Low-resolution Window ....................................... Figure 5-2 Hand-drawn Gadget Unselected and Selected ................................ Figure 5-3 Line-drawn Gadget Unselected and Selected ................................. Figure 5-4 Example of Combining Gadget Types ................................................... Figure 6-1 Screen with Menu Bar Displayed .......................................................... Figure 6-2 Example Item Box................................................................................... Figure 6-3 Example Subitem Box ............................................................................ Figure 6-4 Menu Items with Command Key Shortcuts ............................................ Figure 7-l Requester Deluxe .................................................................................... Figure 7-2 A Simple Requester Made with AutoRequest()...................................... Figure 7-3 The "Out of Memory" Alert ................................................................... Figure 8-1 Watching the Stream .............................................................................. Figure 8-2 Input from the IDCMP, Output through the Graphics Primitives .......... Figure 8-3 Input and Output through the Console Device ....................................... Figure 8-4 Full-system Input and Output (a Busy Program) ................................... Figure 8-5 Output Only............................................................................................. 4 5 6 7 13 16 21 25 26 28 35 36 37 47 55 58 59 60 79 84 87 88 102 119 121 122 125 140 146 154 158 161 162 162 163
- xv -
Figure 9-1 Example of Border Relative Position .................................................... Figure 9-2 Intuition's High-resolution Sizing Gadget Image .................................. Figure 9-3 Example of PlanePick and PlaneOnOff ................................................ Figure 9-4 Example Image the Front Gadget ................................................... Figure 11-1 Intuition Remembering ....................................................................... Figure 11-2 Preferences Display ............................................................................. Figure 12-1 The Dreaded Erase-Disk Requester .....................................................
xvi
- xvii -
xviii
Chapter 1
INTRODUCTION
Welcome to Intuition, the Amiga user interface. What is a user interface? This sweeping phrase covers all aspects of getting input from and sending output to the user. It includes the innermost mechanisms of the computer and rises to the height of defining a philosophy to guide the interaction between man and machine. Intuition is, above all else, a philosophy turned into software. Intuition's user interface philosophy is simple to describe: the interaction between the user and the computer should be simple, enjoyable, and consistent; in a word, intuitive. Intuition supplies a bevy of tools and environments that can be used to meet this philosophy.
Introduction 1
Intuition was designed with two major goals in mind. The first is to give users a convenient, constant, colorful interface with the functions and features of both the Amiga operating system and the programs that run in it. The other goal is to give application designers all the tools they need to create this colorful interface and to free them of the responsibility of worrying about any other programs that may be running at the same time, competing for the same display and resources. The Intuition software manages a many-faceted windowing and display system for input and output. This system allows full and flexible use of the Amiga's powerful multitasking, multigraphic, and sound synthesis capabilities. Under the Amiga Executive operating system, many programs can reside in memory at the same time, sharing the system's resources with one another. Intuition allows these programs to display their information in overlapping windows without interfering with one another; in addition, it provides an orderly way for the user to decide which program to work with at any given instant, and how to work with that program. Intuition is implemented as a library of C-language functions. These functions are also available to other high-level language programmers and to assembly-language programmers via alternate interface libraries. Application programmers use these routines along with simple data structures to generate program displays and to interface with the user. A program can have full access to all the functions and features of the machine by opening its own virtual terminal. When a virtual terminal is opened, your program will seem to have the entire machine and display to itself. It may then display text and graphics to its terminal, and it may ask for input from any number of sources, ignoring the fact that any number of other programs may be performing these same operations. In fact, your program can open several of these virtual terminals and treat each one as if it were the only program running on the machine. The user sees each virtual terminal as a window. Many windows can appear on the same display. Each window can be the virtual terminal of, a different application program, or several windows can be created by the same program. The Amiga also gives you extremely powerful graphics and audio tools for your applications. There are many display modes and combinations of modes (for instance, four display resolutions, hold-and-modify mode, dual-playfield mode, different color palettes, doublebuffering, and more plus animation and speech and music synthesis. You can combine sound, graphics, and animation in your Intuition windows. As you browse through this book, you'll find many creative ways to turn Intuition and the other Amiga tools into your own personal kind of interface.
2 Introduction
Introduction 3
Figure 1-1: A Screen with Windows Applications can use a variety of custom gadgets. For example, the program might use a gadget to request that the user type in a string of characters. Another gadget might be used to adjust the sound volume or the color of the screen. At any time, only one window is active in the sense that only one window receives input from the user. Other windows, however, can work on some task that requires no input. For the active window, the screen's title bar can be used to display a list of menus (called the menu bar) at the user's command. By moving the mouse pointer along the menu bar, the user can view a list of menu items for each menu category on the menu bar. Each item in the list of menus can have its own subitem list (see figure 1-2).
4 Introduction
Figure 1-2: Menu Items and Subitems Menus present lists of options and commands. The user can make choices from menus by using the mouse pointer and buttons. Applications can also provide the user with keysequence shortcuts, as an alternative to the mouse. Intuition supplies certain key-sequence shortcuts automatically. Windows can present the user with special requester boxes, invoked by the system or by applications (see figure 1-3). Requesters provide extended communication between the user and the application. When a requester is displayed, interaction with that window is halted until the user takes some action. The user, however, can make some other window active and deal with the requester later. If you wish, you can let the user bring up a requester on demand.
Introduction 5
Figure 1-3: A Requester The alert (see figure 1-4) is another kind of special information exchange device invoked by the system or an application. The alert display is dramatic. It appears in red and black at the top of the display, with text and a blinking border. Alerts are meant to be used when a serious problem has occurred or when the user must take some action immediately. The application may also try to get the user's attention by flashing the screen or windows in a complementary color.
6 Introduction
Introduction 7
No matter how simple, complex, or fanciful your program design, it will fit within the basic Intuition framework of windows and screens, gadgets, menus, requesters, and alerts. The users of the Amiga will come to understand these basic Intuition elements and to trust that the building blocks remain constant. This consistency ensures that a well-designed program will be understandable to the naive user as well as to the sophisticate. This is the essence and the beauty of the Intuition philosophy.
8 Introduction
Chapter 2
Intuition Components
Intuition's major components are summarized in the following list. o Windows provide the means for obtaining input from the user; they are also the normal destination for the program's output.
o Screens provide the background for opening windows. o Numerous mechanisms exist for interaction between users and applications: o Menus present users with options and give them an easy way of entering commands. o Requesters provide a menu-like exchange of information. o Gadgets are the main method of communication. o Alerts are for emergency communications. o The mouse is the user's primary tool for making selections and entering commands. o The keyboard is used for entering text and as an alternate shortcut method of entering commands. o Other input devices, like graphics tablets or music keyboards, provide additional means of user input. o The methods of program input and output are as follows: o Input is received through the console device or Intuition Direct Communication Message Ports (known as the IDCMP). o Output is transmitted through the console device or directly to the graphics, text, and animation library functions.
10
o You open a window by initializing the data of a NewWindow structure and then calling OpenWindow() with a pointer to that structure. o You open a screen by initializing the data of a NewScreen structure and then calling OpenScreen() with a pointer to that structure. o Finally, the example program writes some simple text to a window, illustrating how simple it is to use the graphics library with your window.
11
/* Initialize the NewWindow structure for the call to OpenWindow() */ NewWindow.LeftEdge = 20; NewWindow.TopEdge = 20; NewWindow.Width = 300; NewWindow.Height = 100; NewWindow.DetailPen = 0; NewWindow.BlockPen = 1; NewWindow.Title = "A Simple Window"; NewWindow.Flags = SMART_REFRESH | ACTIVATE; NewWindow.IDCMPFIags = NULL; NewWindow.Type = WBENCHSCREEN; NewWindow.FirstGadget = NULL; NewWindow.CheckMark = NULL; NewWindow.Screen = NULL; NewWindow.BitMap = NULL; NewWindow.MinWidth = 0; NewWindow.MinHeight = 0; NewWindow.MaxWidth = 0; NewWindow.MaxHeight = 0; /* Try to open the window. Like the call to OpenLibrary(), if * the OpenWindow() call is successful, it returns a pointer to * the structure for your new window. * If the OpenWindow() call fails, it returns a zero. */ if ((Window = (struct Window *)OpenWindow(&NewWindow) ) = = NULL) exit(FALSE); /* Do nothing a million times. How long do you think it will take for * the Amiga to do nothing a million times? Try it and see! */ for (i = 0; i < MILLION; i++) /* Finally, close the Window, and then exit */ CloseWindow(Window); } See how easy it is to create a window under Intuition? This example is a complete program that can be compiled as is. If run, this program would open the window shown in figure 2-1.
12
Figure 2-1: A Simple Window The Type variable in NewWindow describes the screen type you want for this window. With the Type variable set to WBENCHSCREEN, you are specifying to Intuition that you wish this window to open in the Workbench screen. With the Flags variable initialized to SMART-REFRESH and ACTIVATE, you are specifying that you want this window to take advantage of Intuition's SMART_REFRESH mode of window display and you want this window to become the active window when it opens. The rest of the NewWindow variables are set to simple, safe default values. Consequently, you cannot do much with this window.
13
14
special event occurs. In this simple example, only one type of event will wake up the program; thus when the program is awakened, it can automatically assume that it was because someone pressed the WINDOWCLOSE gadget. When you start using the IDCMP for more elaborate functions, your programs will have to get a message from the message port and examine it to see what event has occurred to awaken the program.
15
16
/* This font declaration will be used for the new screen */ { struct TextAttr MyFont = { "topaz.font", /* Font Name */ TOPAZ SIXTY, /* Font Height */ FS_NORMAL, /* Style */ FPF_ROMFONT, /* Preferences */ }; /* This is the declaration of a pre-initialized NewScreen data block. * It often requires less work and uses less code space to * pre-initialize data structures in this fashion. */ struct NewScreen NewScreen = { 0, /* the LeftEdge should be equal to zero */ 0, /* TopEdge */ 320, /* Width (low-resolution) */ 200, /* Height (non-interlace) */ 2, /* Depth (4 colors will be available) */ 0, 1, /* the DetailPen and BlockPen specifications */ NULL, /* no special display modes */ CUSTOMSCREEN, /* the screen type */ &MyFont, /* use my own font */ "My Own Screen", /* this declaration is compiled as a text pointer */ NULL, /* no special screen gadgets */ NULL, /* no special CustomBitMap */ }; Here's how the screen is opened: if (( Screen = (struct Screen *)OpenScreen(&NewScreen) ) = = NULL) exit(FALSE); Because this window will open in a custom screen, you must change the initialization of the NewWindow data slightly. The Type declaration should be changed from WBENCHSCREEN to CUSTOMSCREEN. Also, you previously set the Screen variable to NULL because you wanted the window to open in the Workbench screen. Now, you must set this variable to point to the new custom screen:
17
NewWindow.Type = CUSTOMSCREEN; NewWindow.Screen = Screen; After you close the window, close the screen, too: CloseScreen(Screen); The program now opens a custom screen and then opens a window in that screen.
18
/* This is the declaration of a pre-initialized NewScreen data block. * It often requires less work and uses less code space to * pre-initialize data structures in this fashion. */ struct NewScreen NewScreen = { 0, /* the LeftEdge should be equal to zero */ 0, /* TopEdge */ 320, /* Width (low-resolution) */ 200, /* Height (non-interlace) */ 2, /* Depth (4 colors will be available) */ 0, 1, /* the DetailPen and BlockPen specifications */ NULL, /* no special display modes */ CUSTOMSCREEN, /* the screen type */ &MyFont, /* use my own font */ "My Own Screen", /* this declaration is compiled as a text pointer */ NULL, /* no special screen gadgets */ NULL, /* no special CustomBitMap */ }; main() { struct Screen *Screen; struct NewWindow NewWindow; struct Window *Window; LONG i; /* Open the Intuition library. The result returned by this call is * used to connect your program to the actual Intuition routines * in ROM. If the result of this call is equal to zero, something * is wrong and the Intuition you requested is not available, so * your program should exit immediately */ IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", INTUITION_REV); if (IntuitionBase = = NULL) exit(FALSE);
19
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", GRAPHICS_REV); if (GfxBase = = NULL) exit(FALSE); if ((Screen = (struct Screen *)OpenScreen(&NewScreen)) == NULL) exit(FALSE); NewWindow.LeftEdge = 20; NewWindow.TopEdge = 20; NewWindow.Width = 300; NewWindow. Height = 100; NewWindow.DetailPen = 0; NewWindow.BlockPen = 1; NewWindow.Title = "A Simple Window"; NewWindow.Flags = WINDOWCLOSE | SMART REFRESH | ACTIVATE | WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH; NewWindow.IDCMPFlags = CLOSEWINDOW; NewWindow.Type = CUSTOMSCREEN; NewWindow.FirstGadget = NULL; NewWindow.CheckMark = NULL; NewWindow.Screen = Screen; NewWindow.BitMap = NULL; NewWindow.MinWidhh = 100; NewWindow.MinHeight = 25; NewWindow.MaxWidth = 640; NewWindow.MaxHeight = 200; if ((Window = (struct Window *)OpenWindow(&NewWindow) ) = = NULL) exit(FALSE); Move(Window->RPort, 20, 20); Text(Window->RPort, "Hello World", 11); Wait(1 << Window- >UserPort->mp_SigBit); CloseWindow(Window); CloseScreen(Screen); exit(TRUE); }
The display created by the final version looks like figure 2-3.
20
21
22
Chapter 3
SCREENS
Screens are the basis for all Intuition displays. They set up the environment for overlapping windows and they give you easy access to all the Amiga display modes and graphics features. In this chapter you will learn how to use the standard screens provided by Intuition and how to create your own custom screens.
Screens 23
About Screens
The screen is Intuition's basic unit of display. By using an Intuition screen, you can create a video display with any combination of the many Amiga display modes. Certain basic parameters of the video display (such as fineness of vertical and horizontal resolution, number of colors, and color choices) are defined by these modes. By combining modes, you can have many different types of displays. For example, the display may show eight different colors in low-resolution mode or 32 colors in interlaced mode (high resolution of lines). For a description of all the different display modes, see the "Custom Screens" section below. Every other Intuition display component is defined with respect to the screen in which it is created. Each screen's data structure contains definitions that describe the modes for the particular screen. Windows inherit their display parameters from the screens in which they open, so a window that opens in a given screen always has the same display modes and colors as that screen. If your program needs to open windows that differ from one another in their display characteristics, you can open more than one screen. Screens are always the full width of the display. This is because the Amiga hardware allows very flexible control of the video display, but imposes certain minor restrictions. Sometimes it is not possible to change display modes in the middle of a scan line. Even when it is possible, it is usually aesthetically unpleasant or visually jarring to do so. To avoid these problems, Intuition imposes its own display restriction, allowing only one screen (one collection of display modes) per video line. Because of this, screens can be dragged vertically but not horizontally. This allows screens with different display modes to overlap, but prevents any changes in display mode within a video line. Screens provide display memory, which is the RAM in which all imagery is first rendered and then translated by the hardware into the actual video display. The Amiga graphics structure that describes how rendering is done into display memory is called a RastPort. The RastPort also has pointers into the actual display memory locations. The screen's display memory is also used by Intuition for windows and other high-level display components that overlay the screen. Application programs that open custom screens can use the screen's display memory in any way they choose. Screens are rectangular in shape. When they first open they usually cover the entire surface of the video display, although they can be shorter than the height of the display. Like windows, screens can be moved up or down and arranged at different depths by using special control mechanisms called gadgets. Unlike windows, however, screens cannot be made larger or smaller, and they cannot be moved left or right.
24 Screens
The dragging and depth-arrangement gadgets reside in the title bar at the top of all Intuition screens. In the title bar there may also be a line of text identifying the screen and its windows. Figure 3-1 shows a screen with open windows. The depth-arrangement gadgets (front gadget and back gadget) are at the extreme right of the screen title bar. The drag gadget (for moving the screen) occupies the entire area of the screen title bar not occupied by other gadgets. The user changes the front-to-back order of the displayed screens by using a controller (such as a mouse) or the keyboard cursor control keys to move the intuition pointer within one of the depth-arrangement gadgets. When the user clicks the left mouse button (known as the select button), the screen's depth arrangement is changed.
Figure 3-1: A Screen and Windows The user moves the entire screen up or down on the video display by moving the pointer within the drag gadget, holding down the left mouse button while moving the pointer, and finally releasing the button when the screen is in the desired location. The screen's title bar is also used to display a window's menus when the user asks to see them. Typically, when the user presses the right mouse button (the menu button), a list of menu topics called a menu list appears across the title bar. Figure 3-2 shows a screen after the user has displayed the menu list.
Screens 25
Figure 3-2: Screen and Windows with Menu List Displayed By further mouse movement and mouse button manipulation, the user can see a list of menu items and subitems for each of the topics in the menu list. The menu list, menu items, and subitems that are displayed pertain to the currently active window, which is the window receiving the user's input. Only one window is active at any time. The screen containing the active window can be thought of as the active screen. Because there is only one active window, there can be only one active menu list at a time. The menu list appears on the title bar of the active screen. Menus are handled by the Intuition menu system. See chapter 6, "Menus," for more information about putting menus together and attaching them to windows. Both you and the user will find working with screens much like working with windows-for you, the data structures and the functions for manipulating screens and windows are similar. For the user, moving and arranging screens will require the same steps as moving and arranging windows. However, the user will be less aware of screens than of windows, since user input and application output occur mostly through windows. There are two kinds of screens - standard screens supplied by Intuition and custom screens created by you.
26 Screens
Standard Screens
Standard screens differ from custom screens in three basic ways. o Standard screens close and disappear if all their windows are closed. Only the Workbench standard screen (described below) differs in this regard. You can think of the Workbench as the default screen even if all its windows close, it remains open. If the Workbench isn't already open when all other screens close, it will open then. o Standard screens are opened differently. No function need be called to explicitly open a standard screen. You simply specify the screen type in the window structure; if the screen is not already open, Intuition opens it. This is contrasted with custom screens, which you must explicitly open before opening a window in the screen. o You are free to design and change the characteristics of your custom screen practically any way you choose, but you should not change the colors, display modes, and other parameters of standard screens. These parameters have been predefined so that more than one application may open windows in a standard screen and be able to depend upon constant display characteristics. For instance, a business package that runs in a standard screen may expect the colors to be reasonable for a dither pattern in a graph. If you change the colors, that program's graphics display will not be able to share the screen with you, which defeats the purpose of standard screens. All of Intuition's standard screens are the full height and width of the video display area. Intuition manages standard screens and any program may open its windows in any of the standard screens. An application can display more than one window in a standard screen at the same time, and more than one application can open a window in a standard screen at the same time. The standard screens currently available are: o Workbench o Others, as described in appendix B: "Intuition Include File."
Screens 27
WORKBENCH
The Workbench is the Intuition standard screen. It is both a screen and an application. It is a high-resolution (640 pixels x 200 lines) four-color screen. The default colors are blue for the background, white and black for details, and orange for the cursor and pointer (see figure 33).
Figure 3-3: The Workbench Screen and the Workbench Application The Workbench screen is used by both the Amiga Command Line Interface (CLI) and the Workbench tool. If you want to use the Workbench as a screen for the windows of your program, you just specify a window type of WBENCHSCREEN in the data structure called NewWindow, which you initialize when opening a window. Any application program can use the Workbench screen for opening its windows. Developers of text-oriented applications are especially encouraged to open in the Workbench screen. This is convenient for the user because many windows will open in the same standard screen, requiring less movement between screens. Using the Workbench screen is very memoryefficient, because you will not be allocating the memory for your own custom screen. Besides your own custom screen, the Workbench screen is the only one that you can explicitly close. Also, the Workbench screen does not close when all the windows in it are closed, as do the other standard screens, and it automatically reopens when all other screens close down.
28 Screens
If your application needs more memory than what is available, it can attempt to reclaim the memory used by the Workbench screen by calling CloseWorkBench(). You should, however, call OpenWorkBench() as your program exits. It is good Intuition programming practice to always attempt to reopen the Workbench screen when your program is terminating, whether or not you called CloseWorkBench(). If all programs do this, it will help to present the user with as consistent and dependable an interface as possible, since the Workbench screen will be available as much as possible. The Workbench application program allows users to interact with the Amiga file system, using icons (small graphics images) to represent files. Intuition treats the Workbench application as a special case, communicating with it in extraordinary ways. For example, you can open or close the Workbench screen by calling the Intuition functions OpenWorkBench() and CloseWorkBench(), even though the Workbench tool may have open windows in the screen. You have access to a body of library functions that allows you to create and manipulate .the Workbench application's objects and iconography. The functions in the library allow you to create disk files that the user can handle within the context of the Workbench program. For more information about the Workbench library, see the AmigaDOS Developer's Manual. The user can change the colors of the Workbench screen via the Preferences program. For more information about Preferences, see chapter 11, "Other Features."
Custom Screens
Typically, you create your own screen when you need a specific kind of display that is not offered as one of the standard screens or when you want to modify the screen or its parameters directly-as in changing colors or directly modifying the Copper list or display memory. The Copper is the display-synchronized coprocessor that handles the actual video display by directly affecting the hardware registers. For example, you might need a display in which you can have movable sprite objects. Alternatively, you might have your own display memory that you want to use for the screen's display memory or you may want to allow the user to play with the colors of a display that you've created. If you want to do these sorts of things, you'll have to create a custom screen; such operations not allowed in standard screens. Custom screens do not close automatically when all windows in them close (as system standard screens do, except for the Workbench). If you have opened a custom screen, you must call CloseScreen() before your program exits. Otherwise, your screen stays around forever.
Screens 29
You can create two kinds of custom screens: one that is entirely managed by Intuition or one that uses the Amiga graphics primitives to write directly into the display memory or otherwise directly modify the screen display characteristics. If the second kind of screen is used, you must take on some of the responsibility of managing the display.
30 Screens
First, Intuition does not save background screen information when a window is opened, sized, or moved. Screen areas that are subsequently revealed are restored to a blank background color, obliterating any data you write into the display memory area of your screen. Second, menus are protected from data being output to the windows behind them but not from data being output to screens. When a menu is on the screen, all underlying windows are locked against graphical output to prevent such output from trashing the menu display. Menus cannot, however, lock graphical output to the display memory of a screen. Therefore, be careful about writing to a screen that has or can have menus displayed in it. You can easily overstrike the menus and obliterate the information contained in them. In summary, keep in mind that the user can modify the display by moving things around (by using window gadgets) or making things appear and disappear (menus and requesters). If you want to write directly to a custom screen's display memory, you have to design the pieces carefully so that they interact without conflict. If you want complete control of the screen display memory and are willing to give up some windowing capabilities (such as menus and window sizing and dragging), you should use a custom screen. If you want to control the display memory and run windows and menus in the `custom screen, you need to deal with the hazards. Always bear in mind that playing with screen displays in this way requires an intricate knowledge of how screens and windows work, and you should not attempt it lightheartedly. What if you want a screen with your own display memory, one you can manipulate any a way you choose, but you still want access to all the windowing and menu capabilities without worry? A special kind of window satisfies all of these needs-the Backdrop window, which always stays in the background and can be fashioned to fill the entire display area. Writing to this kind of window is almost as flexible as writing directly to display memory and requires only a little more overhead in memory management and performance. Menus and ordinary windows can safely reside over this window. You can also cause the screen's title bar to disappear behind a Backdrop window by calling the ShowTitle() function, thereby filling the entire video display with your display memory. This is the Intuition-blessed way to fill the entire display and still exist in an Intuition environment. For more information about setting up Backdrop windows, see chapter 4, "Windows." When you are using the graphics primitives (functions) in your custom screen, the functions sometimes require pointers to the graphics display memory structures that lie beneath the Intuition display. These graphics structures are the RastPort, ViewPort, and View. For more information and details about how to get the pointers into the display memory, see chapter 9, "Images, Line Drawing, and Text."
Screens 31
Screen Characteristics
The following characteristics apply to both standard screens and custom screens. Keep in mind, however, that you should not change the characteristics of any of the standard screens.
DISPLAY MODES
You can use any or all of the following display modes in your custom screens. The windows that open in a screen .inherit the screen's display modes and colors. There are two modes of horizontal display: low resolution and high resolution. In lowresolution mode, there are 320 pixels across a horizontal line. In high-resolution mode, there are 640 pixels across. A pixel is the smallest addressable part of the display and corresponds to one bit in a bit-plane. Twice as much data is displayed in high-resolution mode. Lowresolution mode gives you twice as many potential colors, 32 instead of 16. There are two modes of vertical display: interlaced and non-interlaced. You can have 200 vertical lines of display in non-interlaced mode and 400 lines in interlaced mode. Twice as much data is displayed in interlaced mode. Typically, applications use non-interlaced mode, which requires half as much memory and creates a display that does not have the potential for flickering, as interlaced displays tend to do. Intuition supports interlaced mode because some applications will want to use it; for instance, a computer-aided design package running on a high-phosphor-persistence monitor will want to use it. In sprite mode, you can have up to eight small moving objects on the display. You define sprites with a simple data structure and move them by specifying a series of x,y coordinates. Sprites can be up to sixteen bits wide and any number of lines tall, can have three colors (plus transparent), and pairs of sprites can be joined to create a fifteen-color (plus transparent) sprite. They are also reusable vertically, so you can really have more than eight at one time. The Amiga GELS system described in the Amiga ROM Kernel Manual provides just such a multiplexing, or interleaving, of sprites for you. Chapter 4, "Windows," contains a brief description of a sprite used as a custom pointer. Dual-playfield mode is a special display mode that allows you to have two display memories. This gives you two separately controllable and separately scrollable entities that you can display at the same time, one in front of the other. With this mode, you can have some really interesting displays, because wherever the front display has a pixel that selects color register 0, that pixel is displayed as if it were transparent. You can see through these transparent pixels into the background display. In the background
32 Screens
display, wherever a pixel selects color register 0, that pixel is displayed in whatever color is in color register 0. Hold-and-modify mode gives you extended color selection. If you want to use sprites, dual playfields, or hold-and-modify mode, you should read about all of their features in the Amiga ROM Kernel Manual.
The maximum number of bit-planes in a screen depends upon two of the display modes dual playfields and hold-and-modify. For a normal display you can have from one to five bitplanes. For dual play fields, you can have from two to six bit-planes, which are divided between the two playfields. For hold-and-modify mode you need six bit-planes.
Screens 33
The color registers are also used for the "pen" colors. If you specify a depth of 5, for instance, then you also have 32 choices (in low-resolution mode) for the DetailPen and BlockPen fields in the structure. DetailPen is used for details such as gadgets and title bar text. BlockPen is used for block fills, such as all of the title bar area not taken up by text and gadgets.
TYPE STYLES
When you open a custom screen, you can specify a text font for the text in the screen title bar and the title bars of all windows that open in the screen. A font is a specification of type size and type style. The system default font is called "Topaz." Topaz is a fixed-width font and comes in two sizes: o Eight display lines tall with 80 characters per line in a 640-pixel high-resolution display (40 characters in low resolution). o Nine display lines tall with 64 characters per line in a high-resolution display (32 characters in low resolution). On a television screen, you may not be able to see all 640 pixels across a horizontal line. On any reasonable television, however, a width of 600 pixels is a safe minimum, so you should be able to fit 60 columns of the large Topaz font. Note that font is a Preferences item and the user can choose either the 80- or 60-column (8- or 9-line) default, whichever looks best on his or her own monitor (see figure 3-4). You can use or ignore the user's choice of default font size. See chapter 11, "Other Features," for more information about Preferences items.
34 Screens
Figure 3-4: Topaz Font in 60-column and 80-column Types If you want the default Topaz font in the default size currently selected by the user, set the Font field in the screen structure to NULL. If you want some other font, you specify it by creating a TextAttr structure and setting the screen's Font field to point to the structure. See the Amiga ROM Kernel Manual for more information about text support primitives.
Screens 35
In setting the TopEdge and Height fields, you must take into consideration a minor limitation of this release of Intuition and the graphics library. The bottom line of the screen cannot be above the bottom line of the video display. Therefore, the top position plus the height should not be such that the bottom line of the screen will be higher than the bottom line of the video display. To illustrate, a display can look like figure 3-5, but not like figure 3-6.
36 Screens
SCREEN TITLE
The screen title is used for two purposes: to identify the screen like an identification tab n a file folder and to designate which window is the active one. Although the initial screen title is set in the NewScreen structure, it can change according to the preferences of the windows that open in the screen. Each screen has two kinds of titles that can be displayed in the screen title bar: o A "default" title, which is specified in the NewScreen structure and is always displayed when the screen first opens. o A "current" title, which is associated with the currently active window. When the screen is first opened, the current title is the same as the default title. The current title depends upon the preferences of the currently active window.
Screens 37
Each window can have its own title, which appears in its own title bar, and its "screen title," which appears in the screen's title bar. When the window is the active window, it can display its screen title in the screen's title bar. The function SetWindowTitles() allows you to specify, change, or delete both the window's own title and its screen title. Screen title display is also affected by calls to ShowTitle(), which coordinates the display of the screen title and windows that overlay the screen title bar. Depending upon how you call this function, the screen's title bar can be behind or in front of any special Backdrop windows that open at the top of the screen. By default, the title bar is displayed in front of a Backdrop window when the screen is first opened. Non-Backdrop windows always appear in front of the screen title bar. You can change or eliminate the title of the active screen by calling SetWindowTitles().
CUSTOM GADGETS
You cannot attach custom gadgets directly to a screen. You can attach custom gadgets to a borderless backdrop window and monitor their activity through the window's input/output channels. See chapter 5, "Gadgets," for information about using custom gadgets.
38 Screens
o How many colors you want; the color you want for the background; the color for rendering text, graphics, and details such as borders; and the color for filling block areas such as the title bar. o Horizontal resolution (320 or 640 pixels in a horizontal line) and vertical resolution (200 in non-interlaced or 400 interlaced lines high). o The text font to use for this screen and all windows that open in this screen o Text to be displayed in the screen's title bar. o Whether you want your own display memory for this screen or you want Intuition to allocate the display memory for you.
NEWSCREEN STRUCTURE
Here are the specifications for the NewScreen structure: struct NewScreen { SHORT LeftEdge, TopEdge, Width, Height, Depth; UBYTE DetailPen, BlockPen; USHORT ViewModes; USHORT Type; struct TextAttr *Font; UBYTE *DefaultTitle; struct Gadget *Gadgets; struct BitMap *CustomBitMap; }; The meanings of the variables and flags in the NewScreen structure are as follows. LeftEdge Initial x position for the screen. This field is not currently used by Intuition; however, for upward compatibility, always set this field to 0. TopEdge Initial y position of the screen. Set this field to an integer or constant representing one of the lines on the screen.
Screens 39
Width
Width of the screen. Set this field to 320 for low-resolution mode or 640 for high-resolution mode.
Height
Height of the screen in number of lines. Set this field to up to 200 for non-interlaced mode and 400 for interlaced mode.
Depth
DetailPen, BlockPen DetailPen color register number for details such as gadgets and text in the title bar. BlockPen color register number for block fills, such as the title bar area. ViewModes These flags select display modes. You can set any or all of them: HIRES Selects high-resolution mode (640 pixels across). The default is 320 pixels across. INTERLACE Selects interlaced mode (400 lines). The default is 200 lines. SPRITES Set this flag if you are want to use sprites in the display. DUALPF Set this flag if you want two playfields. HAM Set this flag if you want hold-and-modify mode. Type Set this to CUSTOMSCREEN. You may also set the CUSTOMBITMAP flag if you want to use your own bit-map and display memory for this screen (see CustomBitMap below).
40 Screens
Font
A pointer to the default TextAttr structure for this screen and all Intuitionmanaged text that appears in the screen and its windows. Set this to NULL if you want to use the default Intuition font.
DefaultTitle A pointer to a null-terminated line of text that will be displayed in the screen's title bar; this should be set to NULL if you want a blank title bar. Nullterminated means that the last character in the text string is NULL. Gadgets This field is not used at this time. It should be set to NULL.
CustomBitMap A pointer to a BitMap structure, used if you want your own display memory to be used as the display memory for this screen. You inform Intuition that you want to supply your own display memory by setting the flag CUSTOMBITMAP in the Types variables above, creating a BitMap structure that points to your display memory and having this variable point to it.
SCREEN STRUCTURE
If you have successfully opened a screen by calling the OpenScreen() function, you receive a pointer to a Screen structure. The following list shows the variables of the Screen structure that may be of interest to you. This is not a complete list of the Screen variables; only the more useful ones are described. Also, most of these variables are for use by advanced programmers, so you may choose to ignore them for now. TopEdge Examine this to see where the user has positioned your screen.
MouseX, MouseY You can look here to see where the mouse is with respect to the upper left corner of your screen. ViewPort, RastPort, BitMap, Layerlnfo For hard-core graphics users, these are actual instances of these graphics structures (Note: not pointers to structures). For simple use of custom screens, these structures can be ignored. BarLayer This is the pointer to the Layer structure for the screen's title bar.
Screens 41
SCREEN FUNCTIONS
Here is a quick rundown of Intuition screen functions. For a complete description of these functions, see appendix A. Opening a Screen This is the basic function to open an Intuition custom screen according to the parameters specified in NewScreen. This function sets up the screen structure and substructures, does all the memory allocations, and links the screen's ViewPort into Intuition. OpenScreen (NewScreen) The argument is a pointer to an instance of a NewScreen structure. Showing a Screen Title Bar This function causes the screen's title bar to be displayed or concealed, according to your specification of the Showlt variable and the position of the various types of windows that may be opened in the screen. ShowTitle (Screen, Showlt) The screen's title bar can be behind or in front of any Backdrop windows that are opened at the top of the screen. The title bar is always concealed by other windows, no matter how this function sets the title bar. The variable Screen is a pointer to a Screen structure. Set the variable Showlt to Boolean TRUE or FALSE according to whether the title is to be hidden behind Backdrop windows. When Showlt is TRUE, the screen title bar is shown in front of Backdrop windows. When Showlt is FALSE, the screen title bar is always behind any window. Moving a Screen With this function, you can move the screen vertically. MoveScreen (Screen., DeltaX, DeltaY) Moves the screen in a vertical direction by the number of lines specified in
42 Screens
the DeltaY argument. (DeltaX is here for upward compatibility only and is currently ignored). Screen is a pointer to the screen structure. Changing Screen Depth Arrangement These functions change the screen's depth arrangement with respect to other displayed screens. ScreentoBack (Screen) Sends the specified screen to the back of the display. ScreentoFront (Screen) Brings the specified screen to the front of the display. Closing a Screen The following function unlinks the screen and ViewPort and deallocates everything. It ignores any windows attached to the screen. All windows should be closed first. Attempting to close a window after the screen is closed will crash the system. If this is the last screen displayed, Intuition attempts to reopen the Workbench. CloseScreen (Screen) The variable Screen is a pointer to the screen to be closed. Handling the Workbench These functions are for opening, closing, and modifying the Workbench screen. OpenWorkBench() This routine attempts to open the Workbench screen. If not enough memory exists to open the screen, this routine fails. Also, if the Workbench tool is active, it will attempt to reopen its windows. CloseWorkBench() This routine attempts to close the Workbench screen. If another
Screens 43
application (other than the Workbench tool) has windows opened in the Workbench screen, this routine fails. If only the Workbench tool has opened windows in the Workbench screen, the Workbench tool will close its windows and allow the screen to close. WBenchToFront(), WBenchToBack() If the Workbench screen is opened, calling these routines will cause it to be in front or in back of other screens, depending on which command is used. If the Workbench screen is closed, these routines have no effect. Advanced Screen and Display Functions These functions are for advanced users of Intuition and graphics. They are used primarily in programs that make changes in their custom screens (for instance, in the Copper instruction list). These functions cause Intuition to incorporate a changed screen and merge it with all the other screens in a synchronized fashion. For more information about these functions, see chapter 11, "Other Features." MakeScreen(Screen) This function is the Intuition equivalent of the lower-level MakeVPort() graphics library function. MakeScreen() performs the MakeVPort() call for you, synchronized with Intuition's own use of the screen's ViewPort. The variable Screen is a pointer to the screen that contains the ViewPort that you want remade. RethinkDisplay() This procedure performs the Intuition global display reconstruction, which includes massaging some of Intuition's internal state data, rethinking all of the Intuition screen ViewPorts and their relationship to one another, and, finally, reconstructing the entire display by merging the new screens into the Intuition View structure. This function calls the graphics primitives MrgCop() and Load View(). RemakeDisplay() This routine remakes the entire Intuition display. It performs a MakeVPort() (graphics primitive) on every Intuition screen and then calls RethinkDisplay() to recreate the view.
44 Screens
Chapter 4
WINDOWS
In the last chapter, you learned about Intuition screens, the basic unit of display. This chapter covers the windows supported by those screens. The first half of the chapter provides a general description of windows-including the different ways of handling the I/O of the virtual terminal; preserving the display when windows get overlapped; how you open windows and define their characteristics; and how you get the pre-defined gadgets for shaping, moving, closing, and depth-arranging windows. This section also defines the different kinds of special windows that extend even further the capabilities of the Intuition windowing system. You will also see how you can customize your windows by adding individual touches like your own custom pointer.
Windows 45
In the second half of the chapter, you get all the details you need for designing your own windows-an overview of the process of creating and opening a window, the specification for the window structure, and brief descriptions of the functions you can use for windows.
About Windows
The windows you open can be colorful, lively, and interesting places for the user to work. You can use all of the standard Amiga graphics, text, and animation primitives (functions) in every one of your windows. You can also use the quick and easy Intuition structures and functions for rendering images, text, and lines into your windows. The special Intuition features that go along with windows, like the gadgets and menus, can be visually exciting as well. Each window can open an Intuition Direct Communications Message Port (IDCMP), which offers a direct communication channel with the underlying Intuition software, or the window can open a console device for input and output. Either of these communication methods turns the window into a visual representation of a virtual terminal, where your program can carry on its interaction with the user as if it had the entire machine and display to itself. Your program can open more than one window and treat each separately as a virtual terminal. Both you and the user deal with each individual window as if it were a complete terminal. The user has the added benefit of being able to arrange the terminals front to back, shrink and expand them, or overlap them. Windows are rectangular display areas whose size and location can be adjusted in many ways. The user can shape windows by making them wider or longer or both to reveal more of the information being output by the program. He can also shrink windows into long, narrow strips or small boxes to reveal other windows or to make room for other windows to open. Multiple windows can be overlapped, and the user can bring a window up front or send it to the bottom of the stack with a click of the mouse button. While the user is doing all this shaping and rearranging and stacking of windows, your program need not pay any attention. To the program, there is nothing out there but a user with a keyboard and a mouse (or, in place of a mouse, there could be a joystick, a graphics tablet, or practically any other input device).
46 Windows
Figure 4-1: A High-resolution Screen and Windows Your program can open as many of these virtual terminal windows as the memory configuration of your Amiga will allow. Each window opens in a specific screen, and several windows may open in the same screen. Even windows opened by different programs may coexist in the same screen. Your program can open windows for any purpose. For example, different windows of an application can represent: o Different interpretations of an object, such as the same data represented as a bar chart and a pie chart. o Related parts of a whole, such as the listing and output of a program. o Different parts of a document or separate documents being edited simultaneously. You open a window by specifying its structure and issuing a call to a function that opens windows. After that, you can output to the user and receive input while Intuition manages all the user's requests to move, shape, and depth-arrange the window. Intuition lets you know if the user makes a menu choice, chooses one of your own custom gadgets, or wants to close the window. If you need to know when the user changes the window's size or moves the pointer, Intuition will tell you about that, too.
Windows 47
Custom gadgets, menus, input/output, and controllers are dealt with in later chapters. The balance of this section deals with some important concepts you'll need to know before attempting to open your own windows.
WINDOW INPUT/OUTPUT
You can choose from two different paths for input and two for output. Each path satisfies particular needs. The two paths for user input are as follows: o Intuition Direct Communications Message Ports (IDCMPs). The message ports give you mouse (or other controller) events, keyboard events, and Intuition messages in their most raw form; in addition, these ports supply the way for your program to send messages to Intuition. o Console device. The console ports give you processed input data, including key-codes translated to ASCII characters and Intuition event messages converted to ANSI escape sequences. If you wish, you can also get raw (untranslated) input through the console device. There are also two paths for program output: o Text is output through the console device, which formats and supplies special text primitives and text functions, such as automatic line wrapping and scrolling. o Graphics are output through the general-purpose Amiga graphics primitives, which provide rendering functions such as area fill and line-drawing and animation functions. If you use the console device for input, output, or both, you need to open it after opening your window. If you want the IDCMP for input, you specify one or more of the IDCMP flags in the NewWindow structure. This automatically sets up a pair of message ports, one for Intuition and one for you. Although the IDCMP does not offer text formatting or character positioning, it has many special features that you may want, and it requires less RAM and less processing overhead. For more information about I/O methods read chapter 8, "Input and Output Methods."
48 Windows
Windows 49
any outstanding Intuition messages or verifying that the user really meant to close the window, and then call CloseWindow(). If the user closes the last window in a standard screen other than the Workbench screen, the screen closes also. When the active window is closed, the previously active window may become the active window. The window (call it window A) that was active when this one was opened will become the active window. If window A is already closed, then the window (if any) that was active when window A opened will become the active window, and so on.
50 Windows
If you use a Borderless window that does not cover the entire display, be aware that its lack of borders may cause visual confusion on the screen. Since windows and screens share the same color palette, borders are often the only way of distinguishing a window from the background. Set the BORDERLESS flag in the NewWindow structure to get this window type. Gimmezerozero Window Type The unique feature of a Gimmezerozero window is that there are actually two "planes" to the window: a larger, outer plane in which the window title, gadgets, and border are placed; and a smaller, inner plane (also called the inner window) in which you can draw freely without worrying about the window border and its contents. The top left coordinates of the inner window are always (0,0), regardless of the size or contents of the outer window; thus the name "Gimmezerozero." The area in which you can draw is formally defined as the area within the variables BorderLeft, BorderTop, BorderRight, and BorderBottom. These variables are computed by Intuition when the window is opened. To draw in normal windows with the graphics primitives (for instance to draw a line from the top left to somewhere else in the window), you have to start the line away from the window title bar and borders. Otherwise, you risk drawing the line over the title bar and any gadgets that may be in the borders. In a Gimmezerozero window, you can just draw a line from (0,0) to some other point in the window without worrying about the window borders. The Gimmezerozero window uses more RAM than other window types and degrades performance in the moving and sizing of windows. There can be a noticeable performance lag, especially when several Gimmezerozero windows are open at the same time. There are some special variables in the Window structure that pertain only to Gimmezerozero windows. The GZZMouseX and GZZMouseY variables can be examined to discover the position of the mouse relative to the inner window. The GZZWidth and GZZHeight variables can be used to discover the width and height of the inner window. The console device gives you another kind of encumbrance-free window. If you are using the console device, any formatted text you output goes into an inner window automatically; you need not worry about gadgets. Therefore, you do not need a Gimmezerozero window just for the purpose of text output. See chapter 8, "Input and Output," for more information about this aspect of the console device.
Windows 51
Requesters in a Gimmezerozero window appear relative to the inner window. If you are bringing up requesters in the window, you may wish to take this into consideration when deciding where to put them. See chapter 7, "Requesters and Alerts," for more information about requester location. To specify a Gimmezerozero window, set the GIMMEZEROZERO flag in the window structure's flags. All system gadgets you attach to this type of window will go into the outer window automatically; however, if you are attaching custom gadgets and you want the gadgets to appear in the border (not in the inner window), be sure to set the GZZGADGET flag in your gadget structures. If you do not, Intuition will draw custom gadgets in the display of the inner window. Backdrop Window Type The Backdrop window, as its name implies, always opens in the back of the Intuition screen. Its great advantage is that other windows can overlap it and be depth-arranged without ever going behind the Backdrop window. Because of this characteristic, you can use the Backdrop window as a primary display surface while opening other auxiliary windows on top of it. The Backdrop window is like normal windows except that: o It always opens behind all other windows (including other Backdrop windows that you might already have opened). o The only system gadget you can attach is the close-window gadget. (You can attach your own gadgets as usual.) o Normal windows in the same screen open in front of all Backdrop windows and always stay in front of them. No amount of depth arranging will ever send a nonBackdrop window behind a Backdrop window. You might want to use a Backdrop window, for example, in a simulation program in which the environment is rendered in the Backdrop window while the simulation controls exist in normal windows that float above the environment. Another example is a sophisticated graphics program where the primary work surface is on the Backdrop window while auxiliary tools are made available in normal windows in front of the work surface. You can often use a Backdrop window instead of drawing directly into the display memory of a custom screen. If you want to draw in your background with the graphics primitives, you may even prefer a Backdrop window to a custom screen because you do not run the danger of writing to the window at the wrong time and trashing a menu
52 Windows
that is being displayed. In fact, if you also set the BORDERLESS flag and you create a window that is the full-screen width and height, you get a window that fills the entire screen and stays in the background. If you also specify no gadgets, there will be no borders. Finally, if you add a call to ShowTitle() with an argument of FALSE, the window will conceal the screen title. All of these steps result in a window that fills the entire video display, has no borders, and stays in the background. To use the Backdrop feature, you set the BACKDROP flag in the window structure. SuperBitMap Window SuperBitMap is both a window type and a way of preserving and redrawing the display. This window is like other windows except that you get your own bit-map instead of using the one belonging to the screen. The windowing system displays some portion of the window's bitmap in the screen's raster according to the dimensions and limits you specify and the user's actions. You can make the bit-map any size as long as the window sizing limits are set accordingly. This window is handy when you want to give the user the flexibility of scrolling around and revealing any portion of the bit-map. You can do this because the entire bit-map is always available to be displayed. To get this type of window, set the SUPERBITMAP flag in the window structure and set up a BitMap structure. You probably want to set the GIMMEZEROZERO flag also, so that the borders and gadgets will be rendered in a separate bit-map. You need to be certain that the size-limiting variables in the window structure are properly set, considering the size of the bit-map and how much of it you want to display. For complete information about SuperBitMap, see "Setting Up a SuperBitMap Window" later in this chapter.
WINDOW GADGETS
The easiest way for a user to communicate with a program running under Intuition is through the use of window gadgets. There are two basic kinds of window gadgets system gadgets that are predefined and managed by Intuition and your own custom application gadgets.
Windows 53
System Gadgets System gadgets are supplied to allow the user to manage the following aspects of window display: size and shape of windows, location of windows on the screen, and depth arrangement. Also, there is a system gadget for the user to tell the application when he or she is ready to close the window. These gadgets save you a lot of work because, with the exception of the close gadget, your program never has to pay any attention to what the user does with them. On the other hand, if you want to be notified when the user sizes the window because of some special drawing you may be doing in the window, Intuition will let you know. For more information, read about the IDCMP verify functions in chapter 8, "Input and Output Methods." In the window structure, you define the starting location and starting size of a window and a maximum and minimum height and width for sizing the window. When the window opens, it appears in the location and in the size you have specified. After that, however, the user normally has the option of shaping the window within the limits you have set, moving it about on the screen and sending it into the background behind all the other displayed windows or bringing it into the foreground. To give the user this freedom, plus the ability to request that the window be closed, you can attach system gadgets to the window. The graphic representations of these gadgets are predefined, and Intuition always displays them in the same standard locations in the window borders. In the window structure, you can set flags to request that all, some, or none of these system gadgets be attached to your window. The system gadgets and their locations in the window are: o A sizing gadget in the lower right of the window. With the sizing gadget, the user can stretch or shrink the height and width of the window. You set the maximum and minimum limits for sizing. You can specify whether this gadget is located in the right border or bottom border, or in both borders. o Two depth-arrangement gadgets in the upper right of the window. One sends the window behind all other displayed windows (back gadget) and the other brings the window to the front of the display (front gadget) o A drag gadget, which occupies every part of the window title bar not taken up by other gadgets. The drag gadget allows the user to move the window to a new location on the screen. A title in the title bar does not interfere with drag gadget operation. o A close gadget in the upper left of the window, which allows the user to request that the window be closed.
54 Windows
Figure 4-2 shows how all the system window gadgets look and where they are located in the window borders.
Figure 4-2: System Gadgets for Windows Application Gadgets Four types of application gadgets are available-proportional, Boolean, string, and integer. You can use application gadgets to request various kinds of input from the user, and that input can affect the application in any way you like. You design gadgets as text and graphic images to go anywhere in the window. For application gadgets, you define a data structure for each one and create a linked list of these structures. To attach your list of gadgets to a window, set a pointer in the NewWindow structure to point to the first gadget in the list. For details about creating gadgets, see chapter 5, "Gadgets."
Windows 55
WINDOW BORDERS
Intuition offers you several possibilities for handling window borders. You can take advantage of the fancy border features, such as automatic double border lines around the window and automatic padding of borders to allow for gadgets. If you'd rather, you can eliminate borders completely, or you can use the Gimmezerozero window, which gives you all the border features and then lets you ignore them. The actual border lines are drawn around the perimeter of the window and are mostly distinct from the border area in which border gadgets are placed. Intuition automatically draws a double border around a window unless you ask for something different. This nominal border consists of an outer line around the entire window, rendered in the BlockPen color, and within this a second line, rendered in the DetailPen color. The two "pen" colors are defined in the NewWindow structure. The default minimum thickness of the border areas depends upon certain parameters set in the definition of the underlying screen, certain choices the user has made with Preferences, and the default font. If the window is not a special Borderless window, the borders will be at least the default thickness. Intuition adjusts the size of a window's border areas to accommodate system gadgets or your own application gadgets. You can find the thickness of the border areas in the variables BorderLeft, BorderTop, BorderRight, and BorderBottom. These variables are computed when the window is opened and can be found in the Window structure. You may want to use them if you are drawing lines in the window with graphics primitives, which require you to specify a set of coordinates as the beginning and ending points for the line. In a typical window, you cannot specify a line from (0,0) to (50,50) because you may draw a line over the window title bar. Instead, you would use the border variables to specify a line from (0+BorderLeft, 0+BorderTop) to (50+BorderLeft), 50+BorderTop). This may look clumsy, but it offers a way of avoiding a Gimmezerozero window, which-although much more convenient to userequires extra memory and impacts performance. For the top border, in addition to the system gadgets and your own gadgets, you can specify a window title. The window title bar does not appear unless you specify one of the following: o o A window title. Any of the system gadgets for window dragging, window depth arranging, or window closing.
56 Windows
Usually, borders are drawn automatically and adjusted within the dimensions you spec :y in the NewWindow structure. In the special Borderless and Gimmezerozero windows, however, borders are handled differently. A Borderless window has no drawn borders and no automatic border spacing or padding. If you have system gadgets or your own gadgets with a border flag set, borders may be visually defined by the gadgets. A Gimmezerozero window places the borders and gadgets in their own bit-map, separate from the window's bit-map. This means you can draw freely across the entire surface of the window without worry about scribbling over the gadgets. You can specify whether or not your application gadgets reside in the borders, and in which border, by setting a flag in the Gadget structure. See chapter 5, "Gadgets," for more information about gadgets and how to place them where you want them.
Windows 57
Simple Refresh With the Simple Refresh redrawing method, Intuition does not need to remember anything about windows that are overlapped. For the most part, the program is responsible for redrawing the window. If the user sizes the window larger on either axis or reveals a window that was overlapped, the program must redraw the display. However, if the user merely drags the window around, Intuition preserves it and redisplays it in the new location. Simple Refresh tends to be slower than other methods, but it is memoryefficient, since no RAM is consumed in saving the obscured portions of a window. Simple Refresh uses the screen's display memory for the window's display.
58 Windows
Smart Refresh With the Smart Refresh redrawing method, Intuition keeps all information about the window in RAM, whether the window is currently concealed or is up front. If the user reveals a window that was overlapped, Intuition recreates the display. If the sizing gadget is attached, the application can still recreate a portion of the display when the user makes the window larger. Smart Refresh uses the screen's display memory for the window display and requires extra buffers for the off-screen portions of the window (portions not currently being displayed). Smart Refresh uses more display memory but redraws the display faster than Simple Refresh.
Windows 59
SuperBitMap This is both a special type of window and a method of redrawing the display. When you choose this method of redrawing, you get your own bit-map to use as display memory instead of using the screen's display memory. You make this bit-map as large as the window can get (or larger). You never have to worry about redisplay after the window is uncovered because the entire display is always there in RAM. For more information about SuperBitMap, see the "Special Windows" section in this chapter.
60 Windows
The program finds out that the window needs refreshing via either source of input, the IDCMP or the console device. A message of the class REFRESHWINDOW arrives at the IDCMP, telling the program that the window needs to be refreshed. Every time the program learns that it should refresh a window, it must take some action, even if it is just the acceptable minimum action described below. When the program is asked to refresh a window, before actually starting to refresh it the program should call the Intuition function BeginRefresh(). This function makes sure that refreshing is done in the most efficient way, only redrawing those portions of the window that really need to be redrawn. The rest of the rendering commands are discarded. After BeginRefresh() is called, the program should redraw its display. Then, call EndRefresh() to restore the state of the internal structures. Even if you don't want the program to redraw immediately, you should make sure the program at least calls Begin/EndRefresh() each time it is asked to refresh a window. This helps Intuition and the layer library keep things sorted and organized. If you are opening a window that you will never care to refresh, no matter what happens to or around it, then you can avoid calling BeginRefresh() and EndRefresh() by setting the NOCAREREFRESH flag in the NewWindow structure when you open your window.
WINDOW POINTER
The active window contains a pointer to allow the user to make selections from menus, choose gadgets, and so on. The user moves the pointer around with a mouse controller, other kinds of controllers, or the keyboard cursor keys. Pointer Position If your program needs to know about pointer movements, you can either look at the position variables or arrange to receive broadcasts each time the pointer moves. The position variables MouseX and MouseY always contain the current pointer x and y coordinates, whether or not your window is the active one. If you elect to receive broadcasts, you get a set of x,y coordinates each time the pointer moves. These coordinates are relative to the upper left corner of your window and are reported in the resolution of your screen, even though the pointer's visible resolution is always in low-resolution mode (note that the pointer is actually a sprite).
Windows 61
If your window is a Gimmezerozero window, you can examine the variables GZZMouseX and GZZMouseY to find the position of the mouse relative to the upper left corner of the inner window. To get broadcasts about pointer movements, either InputEvents or message-port messages, you must set the REPORTMOUSE flag in your window structure. Thereafter, whenever your window is active, you'll get a broadcast every single time the pointer moves. This can be a lot of messages, so be prepared to handle them efficiently. If you want to change whether or not you are following mouse movements, you can call ReportMouse(). You can also get broadcasts about pointer movements by setting the flag FOLLOWMOUSE in your application gadget structures. If this flag is set in a gadget, the current pointer position is reported as long as that gadget is selected by the user. This can result in a lot of messages, too. Custom Pointer You can set up your window with a custom pointer to replace the default arrow pointer. To define the pointer, set up a sprite data structure (sprites are one of the generalpurpose Amiga graphics structures). To place your custom pointer in the window, call SetPointer(). To remove your custom pointer from the window, call ClearPointer(). Both of these functions take effect immediately if yours is the active window. Also, you can change the colors of the Intuition pointer. The Intuition pointer is always sprite 0. To change the colors of sprite 0, call the graphics library routine SetRGB4(). Refer to chapter 12, "Style," for more information about this. See the last section of this chapter for a complete example of a custom pointer.
62 Windows
WINDOW COLORS
The number of colors you can use for the window display and the actual colors that will appear in the color registers are defined by the screen in which the window opens. In the window structure, you specify two color register numbers ("pens"), one for the border outline, text and gadgets and one for block fills (such as the title bar). These pen colors are also a function of the screen. You can specify different colors for the pens than those used by the screen or you can use the screen's pen colors.
WINDOW DIMENSIONS
In the NewWindow structure, you define the dimensions and the starting location of your window on the screen. If you are letting the user change the size and shape of the window, you also need to specify the minimum size to which the window can shrink and the maximum size to which it can grow. If you do not ask that the window sizing gadget be attached to the window, then you need not initialize any of these maximum and minimum variables. In setting all these size dimensions, bear in mind the horizontal and vertical resolutions of the screen in which you are opening the window. If you want to change the sizing limits after you have opened the window, you can call WindowLimits() with the new values.
Windows 63
Using Windows
To create a window, follow these steps: 1. Initialize a NewWindow structure. 2. When you are ready to display the window, call OpenWindow() with a pointer to the NewWindow structure. 3. After you call OpenWindow(), the NewWindow structure is no longer needed. When creating a NewWindow structure, you need to decide on: o The screen in which the window will appear. o The window's characteristics: o Which system gadgets you want. o Preservation method for the window display. o Special window features Gimmezerozero, Borderless, Backdrop, or SuperBitMap. o Type of input from the Intuition Direct Communications Message Ports (if any) o Pointer movement broadcasts. o Other characteristics, such as starting position and size and color of the pens used to draw borders and fill blocks. o Custom images, such as a custom "check mark" for the menus or a custom pointer.
64 Windows
NEWWINDOW STRUCTURE
Here are the specifications for the NewWindow structure: struct NewWindow { SHORT LeftEdge, TopEdge; SHORT Width, Height; UBYTE DetailPen, BlockPen; ULONG IDCMPFlags; ULONG Flags; struct Gadget *FirstGadget; struct Image *CheckMark; UBYTE *Title; struct Screen *Screen; struct BitMap *BitMap; SHORT MinWidth, MinHeight; SHORT MaxWidth, MaxHeight; USHORT Type; }; The fields in the NewWindow structure are explained below. Some of the fields contain variables to which you need to assign a value, some contain flag bits to set or unset, and some are pointers to other structures. LeftEdge, TopEdge, Width and Height These fields describe where your window will first appear on the screen and how large it will be initially. These dimensions are relative to the top left corner of the screen, which has the coordinates (0,0): LeftEdge The initial x position, which represents the offset from the first pixel on the line, pixel 0. TopEdge The initial y position, which represents how many lines down from the top (line 0) you want the window to begin. Width Height The initial width in pixels. The initial height in lines.
DetailPen and BlockPen These fields contain the "pen" numbers used to render details of the window. The
Windows 65
colors associated with the pens are a function of the screen. If you supply a value of -1 for either of these, you will get the screen's value for that pen by default. DetailPen The pen number (or -1) for the rendering of window details like gadgets or text in the title bar BlockPen The pen number (or -1) for window block fills (like the title bar) and the outer rim of the window border. Flags You can set any of the following flags. To get system gadgets, you set the applicable flags. They are: WINDOWSIZING This flag allows the user to change the size of the window. Intuition places the window's sizing gadget in the lower right of your window. By default, the right border is adjusted to accommodate the sizing gadget, but you can change this with the following two flags, which work in conjunction with WINDOWSIZING. The sizing gadget can go in either the right or bottom border (or both) of the window. o o The SIZEBRIGHT flag, which is the default, puts the sizing gadget in the right border. The SIZEBBOTTOM flag puts the sizing gadget in the bottom border. You might wish to set this flag to put the sizing gadget in the bottom border if you want all possible horizontal bits-for instance, for 80-column textand are willing to sacrifice vertical space.
WINDOWDEPTH This flag allows the user to change the window's depth arrangement with respect to all other currently displayed windows. Intuition places the window deptharrangement gadgets in the upper right of the window. Setting this flag selects both the UPFRONT gadget to bring the window into the foreground and the DOWNBACK gadget to send it behind other currently displayed windows. WINDOWCLOSE When the user selects this gadget, Intuition transmits a message to your application. It is up to the application to call CloseWindow() when ready. Setting this flag attaches the standard close gadget to the upper left of the window.
66 Windows
WINDOWDRAG This flag turns the entire title bar of the window into a drag gadget, allowing the user to move the window into a different position on the screen by placing the pointer anywhere in the window title bar and moving the mouse or other controller. NOTE: Even if you do not specify a text string in the Text variable shown below, a title bar appears if you use any one of the system gadgets WINDOWDRAG, WINDOWDEPTH, or WINDOWCLOSE. If no text is provided, the title bar is blank. GIMMEZEROZERO Set this flag if you want a Gimmezerozero window. The following three flags determine how Intuition preserves the display when an overlapped window is uncovered by the user. You must select one of the following: SIMPLE_REFRESH When this flag is set, every time a portion of the window is revealed the appliccation program must redraw its display. SMART_REFRESH When this flag is set, the only time you have to redraw your display is when the window's sizing gadget is used to make the window larger. NOTE: If you open a SMART_REFRESH window without asking for the sizing gadget, then Intuition never tells you to redraw this window. SUPER_BITMAP Setting this flag means you are allocating and maintaining your own bit-map and display register. You must also set the BitMap field to point to your own BitMap structure. BACKDROP Set this flag if you want a Backdrop window. REPORTMOUSE This flag sets the window to receive pointer movements as x,y coordinates. Also see the description of the IDCMP flag, MOUSEMOVE, in chapter 8, "Input and Output Methods."
Windows 67
BORDERLESS This flag creates a window with none of the default border padding and border lines. NOTE: Be careful when you set this flag. It may cause visual confusion on the screen. Also, there may still be some borders if you have selected some of the system gadgets, supplied text for the window's title bar, or specified that any of your custom gadgets go in the borders. ACTIVATE When this flag is set, the window automatically becomes active when it is opened. NOTE: Use this flag carefully. It-can change where the user's input is going. NOCAREREFRESH Set this flag if you do not want to receive messages telling you to refresh your window. RMBTRAP Set this flag if you do not want any menu operations at all for your window. Whenever the user presses the right mouse button while this window is active, the program will receive normal MOUSEBUTTON events. IDCMPFIags The IDCMPFlags are listed and described in appendix A for the OpenWindow() function and in chapter 8, "Input and Output Methods." If any of these flags are set, Intuition creates a pair of message ports and uses them selectively for sending input to the task opening this window instead of using the console device. Gadgets This is a pointer to the first in the linked list of custom Gadget structures that you want included in the window. CheckMark This is a pointer to an instance of a custom image to be used when menu items selected by the user are to be checkmarked. If you just want to use the default checkmark (9), set this field to NULL. Text This is a pointer to a null-terminated text string, which becomes the window title and is displayed in the window title bar. Intuition draws the text using the colors in the DetailPen and BlockPen fields and displays as much as possible of the window
68 Windows
title, depending upon the current width of the title bar. You get the screen's default font. NOTE: The window title is not an instance of IntuiText; it is simply a string ending in a NULL. Type This contains the screen type for this window. The currently available types are WBENCHSCREEN and CUSTOMSCREEN. NOTE: If you choose CUSTOMSCREEN, you must have already opened your custom screen via a call to OpenScreen(), and you must copy that pointer into the Screen field immediately below. Screen If your type is one of the standard screens, then this argument is ignored. If Type is CUSTOMSCREEN, this is a pointer to your custom screen structure. BitMap If you specify SUPERBITMAP as the refresh type, this flag must be a pointer to your own BitMap structure. If you specify some other refresh type, Intuition ignores this field. The following four variables are used to set the minimum and maximum size to which you allow the user to size the window. If you do not set the flag WINDOWSIZING, then these variables are ignored by Intuition. If you set any of these variables to 0, that means you want to use the initial setting for that dimension. For example, if MinWidth is 0, Intuition gives this variable the same value as the opening Width of the window. NOTE: To change the limits after the window is opened, call WindowLimits(). MinWidth The minimum width for window sizing, in pixels. MinHeight The minimum height for window sizing, in lines. MaxWidth The maximum width for window sizing, in pixels.
Windows 69
WINDOW STRUCTURE
If you have successfully opened a window by calling the OpenWindow() function, you receive a pointer to a Window structure. This section describes some of the more useful variables of the Window structure. A complete description of the Window structure is given in appendix B. LeftEdge, TopEdge, Width and Height As the user moves and sizes your window, these variables will change to reflect the new parameters. MouseX, MouseY, GZZMouseX, GZZMouseY These variables always reflect the current position of the Intuition pointer, whether or not your window is currently the active one. The GZZMouse variables reflect the position of the pointer relative to the inner window of Gimmezerozero windows and the offset into normal windows after taking the borders into account. ReqCount You can examine this variable to discover how many requesters are currently displayed in the window. WScreen This variable points to the data structure for this window's screen. If you have opened this window in a custom screen of your own making, you should already know the address of the screen. However, if you have opened this window in one of the standard screens, this variable will point you to that screen's data structure. RPort This variable is a pointer to this window's RastPort. You may need the address of the RastPort when using the graphics, text, and animation functions. BorderLeft, BorderTop, BorderRight, BorderBottom These variables describe the current size of the respective borders that surround the window.
70 Windows
BorderRPort With Gimmezerozero windows, this variable points to the RastPort for the outer window, in which the border gadgets are kept. UserData This is a memory location that is reserved for your use. You can attach your own block of data to the window structure by setting this variable to point to your data.
WINDOW FUNCTIONS
Here's a quick rundown of Intuition functions that affect windows. For a complete description of these functions, see appendix A. Opening the Window Use the following function to open a window: OpenWindow (NewWindow) NewWindow is a pointer to a NewWindow structure. This pointer is required by many of the other functions listed below. Menus Use the following functions to attach and remove menus: SetMenuStrip(Window, Menu) This function attaches menus to a window, manages the display of windows, and reports to the application when the user makes a menu choice. ClearMenuStrip(Window) This function removes the menu strip from a window. After this is done, the user can no longer access menus for this window. If you have called SetMenuStrip(), you should call ClearMenuStrip() before closing your window.
Windows 71
See chapter 6, "Menus," for complete information about setting up your menus. Changing Pointer Position Reports Although you decide when opening the window whether or not you want broadcasts about pointer position, you can change this later with the following function: ReportMouse(Window, Boolean) This function determines whether or not mouse movements in this window are reported. Closing the Window After the user selects the close gadget, the program can do whatever it needs to do to clean up and then actually close the window with the CloseWindow (Window) function. This function closes a window. If its screen is a standard screen (but not the WorkBench) that would be empty without the window, this function closes the screen as well. Requesters in the Window The following two functions allow requesters to become active: Request (Requester, Window) This function activates a requester in the window. SetDMRequest (Window, Requester) This function sets up a requester that the user can bring up in the window by clicking the menu button twice. These two functions disable requesters: EndRequest (Requester, Window) This function removes a requester from the window.
72 Windows
ClearDMRequest (Window, Requester) This function clears the double-click requester, so that the user can no longer access it. Custom Pointers The following functions apply if you have a custom pointer: SetPointer (Window, Pointer, Height, Width, Xoffset, Yoffset) This function sets up the window with a sprite definition for a custom pointer. If the window is active, the change takes place immediately. ClearPointer (Window) This function clears the sprite definition from the window and resets to the default Intuition pointer. Changing the Size Limits The following function changes the limits for window sizing: WindowLimits (Window, MinWidth, MinHeight, MaxWidth, MaxHeight) This function changes the maximum and minimum sizing of the window from the initial dimensions in the NewWindow structure. If you do not want to change a dimension, set the corresponding argument to 0. Outof-range numbers are ignored. If the user is currently sizing the window, new limits take effect after the user releases the select button. Changing the Window or Screen Title The following function changes the window title after the window has already been displayed: SetWindowTitles (Window, WindowTitle, ScreenTitle) This function changes the window title (and screen title, if this is the
Windows 73
active window) immediately. WindowTitle or ScreenTitle can be -1, 0, or a null-terminated string: -1 0 string Refresh Procedures The following functions allow you to refresh your window in an optimized way: BeginRefresh (Window) This function initializes Intuition and layer library internal states for optimized refresh. After you call this procedure, you may redraw your entire window. Only those portions that need to be refreshed will actually be redrawn; the other drawing commands will be discarded. EndRefresh (Window) After you've refreshed your window, call EndRefresh() to restore the internal states of Intuition and the layer library. Programmatic Control of Window Arrangement These functions allow you to modify the arrangement of your window as if the user were activating the associated system window gadgets: MoveWindow (Window, DeltaX, DeltaY) This function allows you to move the window to a new position in the screen. SizeWindow (Window, DeltaX, DeltaY) You can change the size of your window with a call to this procedure. Do not change this title. Leave a blank title bar Change to the title given in this string.
74 Windows
WindowToFront (Window) This function causes your window to move in front of all other windows in this screen. WindowToBack (Window) This function causes your window to move behind all other windows in this screen.
Windows 75
AllocRaster (width, height) The arguments width and height are the maximum dimensions of the array in bits. The sample code fragment below shows how you can use these functions in defining the bitmap for your SuperBitMap window: #define WIDTH 640 #define HEIGHT 200 #define DEPTH 3 struct BitMap BitMap; InitBitMap(&BitMap, DEPTH, WIDTH, HEIGHT); for (i = 0; i < DEPTH; i++) if ((BitMap.Planes[i] = AllocRaster(WIDTH, HEIGHT)) = = 0) Panic("Hey! No memory for allocating planes!");
An extra requirement is imposed on sprite data (and Image data). It must be located in chip memory, which is memory that can be accessed by the special Amiga hardware chips. Chip memory is in the lower 512 Kbytes of RAM. In expanded machines (the Amiga can be expanded up to 8,000 Kbytes), the Amiga chips still cannot address memory locations greater than the 512-Kbyte limit. In hexadecimal notation, 512 K spans memory addresses $00000 to $7FFFF. To write a program that will survive in any possible configuration of Amiga hardware, you are obliged to ensure that your sprite and Image data resides in this chip memory. You can make sure that your data is in chip memory by using the ATOM tool on the file containing the data. The loader will then automatically load that portion of your program into chip memory. See the AmigaDOS User's Manual for information about ATOM and the loader.
76 Windows
As of the time of this writing, the only way to check whether your data is in chip memory is by comparing its load address after it has been loaded into Amiga memory. If the address of the end of your data is less than $80000, you are safe. If the address is equal to or greater than $80000, you must allocate chip memory and copy your data into the new location. To allocate chip memory, call the Exec function AllocMem() with MEMF_CHIP as the requirements argument. The Sprite Data Structure A sprite data structure is made up of words of data. In a pointer sprite, the first two words and the last four words are all Os. All the other words define the appearance of the pointer, two words for each line. For example, the data structure for a sprite shaped like an "X" is shown below.
Windows 77
/* The sprite image for the "X" should have these colors: * 130000031 * 213000313 * 021303130 * 002101300 * 0000. 0000 the dot is a zero that marks the pointer hot spot * 002101300 * 021202130 * 212000213 * 120000021 */ #define XPOINTER_WIDTH 9 #define XPOINTER HEIGHT 9 #define XPOINTER_XOFFSET -4 #define XPOINTER YOFFSET -4 USHORT XPointer[] = { 0x0000, 0x0000, /* one word each for position and control */ 0xC180, 0x4100, 0x6380, 0xA280, 0x3700, 0x5500, 0x1600, 0x2200, 0x0000, 0x0000, 0x1600, 0x2200, 0x2300, 0x5500, 0x4180, 0xA280, 0x8080, 0x4100, 0x0000, 0x0000, };
This example sprite creates an Intuition pointer that looks like the one shown in figure 4-6.
78 Windows
Figure 4-6: The X-Shaped Custom Pointer Attaching the Pointer to the Window You call SetPointer() with the following arguments: Window This is a pointer to the window that is to receive this pointer definition. Pointer This is a pointer to the data definition of a sprite. Height This specifies the height of the pointer; it can be as tall as you like. Width This specifies the width of the sprite (must be less than or equal to 16). XOffset, YOffset These arguments specify the horizontal and vertical offsets for your pointer from Intuition's idea of the current position of the pointer. For instance, if you specify offsets of 0 for both, the top left corner of your image is placed at the pointer position. If you specify an Xoffset of -7, your sprite is centered over the pointer position. If you specify an Xoffset of -15, the right edge of your sprite is over the pointer position.
Windows 79
80 Windows
Chapter 5
GADGETS
This chapter describes the workhorses of Intuition-the multipurpose input devices called gadgets. Most of the user's input to an Intuition application can take place through the gadgets in your screens, windows, and requesters. Gadgets are also used by Intuition itself for handling screen and window movement and depth arrangement, as well as window sizing and closing.
Gadgets 81
About Gadgets
Gadgets can make the user's interaction with your application consistent, easy, and fun. There are two kinds of gadgets: predefined system gadgets and custom application gadgets. The system gadgets help to make the user interface consistent. They are used for dragging and arranging the depth of screens and for dragging, sizing, closing and arranging the depth of windows. Since they always have the same imagery and always reside in the same location, they make it easy for the user to manipulate the windows and screens of any application. Application gadgets add power and fun to Intuition-based programs. These gadgets can be used in a multitude of ways in your programs. You can design your own gadgets for your windows and requesters. There are four basic types of application gadgets: o Boolean gadgets elicit true/false or yes/no kinds of answers from the user. o Proportional gadgets are flexible devices that you use to get some kind of proportional setting from the user or to simply display proportional information. With the proportional gadget, you can use imagery furnished by Intuition or design any kind of image you want for the slider or knob used to pick a proportional setting. o String gadgets are used to get text from the user. A number of editing functions are available for users of string gadgets. o The integer gadget is a special class of string gadget that allows the user to enter integer values only. Although system gadgets are always in the borders of windows and screens, your own gadgets can go anywhere in windows or requesters and can be any size or shape. Application gadgets are not directly supported in screens. Placing a gadget in a backdrop window allows you to receive gadget-related messages through that window's input/out channels. See chapter 8, "Input and Output Methods," for details. You can choose from the following ways of highlighting gadgets to emphasize that the gadget has been selected: o Alternate image or alternate border. o A box around the gadget. o Color change.
82 Gadgets
You can elect to have your gadgets change in size as the user sizes the window so that they remain proportional to the size of the window. Also, window gadgets can be located relative to one of the window's borders so that they move with the borders as the user shapes or sizes the window. If you want the gadget in the border, as are the system gadgets, Intuition can adjust the border size accordingly. Typically, the user selects a gadget by moving the pointer within an area called the .select box; you, define the dimensions of this area. Next, the user takes some action that varies according to the type of gadget. For a Boolean gadget, the user may simply choose an action by clicking the mouse button. For a string or integer gadget, a cursor appears and the user enters some data from the keyboard. For a proportional gadget, the user might either move the knob with the mouse or click the mouse button to move the knob by a set increment. Although you attach a list of predefined application gadgets when you define a window or requester structure, you can make changes to this list later. You can enable or disable gadgets, add or remove gadgets, modify the internal states of gadgets, and redraw some or all of the gadgets in the list. When one of your application gadgets is selected by the user, your program learns about it from either the IDCMP or the console device. See chapter 8, "Input and Output Methods," for details about these messages.
System Gadgets
Intuition automatically attaches system gadgets to every screen. For windows, you specify which system gadgets you want. The system gadgets for screens are for dragging and depth arrangement. The system gadgets for windows for are dragging, depth arrangement, sizing, and closing. System gadgets have fixed, standard locations in screens and windows, as shown in table 5-1 (see also figure 5-1).
Gadgets 83
Table 5-1: System Gadget Placement in Windows and Screens System Gadget Sizing Dragging Depth arrangers Close Location Lower right Entire title bar in all areas not used by other gadgets Top right Top left
Your program need never know that the user selected a system gadget (with the exception of the close gadget); you can attach these gadgets to your windows and let Intuition do the work of responding to the user's wishes.
84 Gadgets
SIZING GADGET
When the user selects the window-sizing gadget, Intuition is put into a special state. The user is allowed to elongate or shrink a rectangular outline of the window until the user achieves the desired new shape of the window and releases the select button. The window is then reestablished in the new shape, which may involve asking the application to redraw part of its display. For more information about the application's responsibilities in sizing, see the discussion about preserving the display in chapter 4, "Windows." You attach the sizing gadget to your window by setting the WINDOWSIZING flag in the Flags variable of the NewWindow structure when you open your window. If you are using the IDCMP for input, you can elect to receive a message when the user attempts to size the window. A special IDCMP flag, SIZEVERIFY, allows you to hold off window sizing until you are ready for it. See chapter 8, "Input and Output Methods," for more information about SIZEVERIFY.
DEPTH-ARRANGEMENT GADGETS
The depth arrangers come in pairs one for bringing the window or screen to the front of the display and one for sending the window or screen to the back. Notice that the actual depth arrangement of windows and screens is transparent to your program. The only time you might learn about it even indirectly is when Intuition notifies your program that it needs to refresh its display. You attach the depth arrangement gadgets to your window by setting the WINDOWDEPTH flag in the Flags variable of the NewWindow structure when you open your window. You get screen depth arrangement gadgets automatically with every screen you open.
DRAGGING GADGET
The dragging gadgets are also known as drag bars because they occupy the entire title bar area that is not taken up by other gadgets. Users can slide screens up and down, much as some classroom blackboards can be moved, to reveal more pertinent information. They can slide windows around on the surface of the screen to arrange the display any way they want.
Gadgets 85
In dragging a window, the user actually drags a rectangular outline of the window to the new position and releases the select button. The window is then reestablished in its new position. As in window sizing, this may involve asking the application to redraw part of its display. If you want the window drag gadget, set the WINDOWDRAG flag in the Flags variable of the NewWindow structure when you open your window. You get the screen drag gadget automatically with every screen you open.
CLOSE GADGET
The close gadget is a special case among system gadgets, because Intuition notifies your program about the user's intent but doesn't actually close the window. When the user selects the close gadget, Intuition modifies some internal states and then broadcasts a message to your program. It is then up to the program to call CloseWindow() when ready. You may want or need to take some actions before the window closes; for instance, you may want to bring up a requester to verify that the user really wants to close that window. To get the window close gadget, set the WINDOWCLOSE flag in the Flags variable of the NewWindow structure when you open your window.
Application Gadgets
Intuition gadgets imitate real-life gadgets. They are the switches, knobs, controllers, gauges, and keys of the Intuition environment. You can create almost any kind of gadget that you can imagine, and you can have it do just about anything you want it to do. You can create any visual imagery that you like for your gadgets, including combining text with hand-drawn imagery or supplying coordinates for drawing lines. You can also choose a highlighting method to change the appearance of the gadget after it is selected. All of this flexibility gives you the freedom to create gadgets that mimic real devices, such as light switches or joysticks, as well as the freedom to create devices that satisfy your own unique needs.
86 Gadgets
RENDERING GADGETS
You can draw your gadgets by hand, specify a series of lines for a simple line gadget, or have no imagery at all.
Hand-drawn Gadgets
Because you are allowed to supply a hand-drawn image, there is no limit to the designs you can create for your gadgets. You can make them simple and elegant or whimsical and outrageous. You design the imagery using one of Amiga's many art tools and then translate your design into an instance of an Image structure. Figure 5-2 shows an example of a gadget made of hand-drawn imagery. It also shows how you can use an alternate image when the gadget is selected.
Figure 5-2: Hand-drawn Gadget Unselected and Selected You incorporate a hand-drawn image into your gadget by setting the GADGIMAGE flag in the gadget variable Flags to indicate that this gadget should be rendered as an Image. Then you put the address of your Image structure into the gadget variable GadgetRender.
Gadgets 87
For more information about creating an Image structure, see chapter 9, "Images, Line Drawing, and Text."
Line-Drawn Gadgets
You can also create simple designs for gadgets by specifying a series of lines to be drawn as the imagery of your gadget. These lines can go around or through the select box of your gadget, and you can specify more than one group of lines, each with its own color and drawing mode. You create line-drawn imagery for your gadget by first deciding on the color and placement of the lines. Figure 5-3 shows an example of a gadget that uses line-drawn imagery. It also shows an example of the complement-mode method of highlighting a gadget when it is selected. Furthermore, it shows additional text that has been included in the gadget imagery.
Figure 5-3: Line-drawn Gadget - Unselected and Selected After deciding on the placement and color of your lines, you create an instance of a Border structure to describe your design. You incorporate the Border structure of your line-drawn imagery into your gadget by not setting the GADGIMAGE flag in the gadget's Flags variable, thus specifying that this is a Border, not an Image. Also, you put the address of your Border structure into the gadget variable GadgetRender.
88 Gadgets
For more information about creating a Border structure, see chapter 9, "Images, Line Drawing, and Text."
Gadgets 89
90 Gadgets
o In the window-dragging gadget, the LeftEdge and TopEdge are always absolute in relation to the top left corner of the window. Also, Height is always an absolute quantity. Width of the gadget, however, is defined to be zero. When Width is combined with the effect of the GRELWIDTH flag, the dragging gadget is always as wide as the window. o Assume that you are designing a program that has several requesters, and each requester has a pair of "OK" and "CANCEL" gadgets in the lower left and lower right corners of the requester. You can design "OK" and "CANCEL" gadgets that can be used in any of the requesters simply by virtue of their positions relative to the lower left and lower right corners of the requester. Regardless of the size of the requesters, these gadgets appear in the same relative positions. The GRELRIGHT, GRELBOTTOM, GRELWIDTH, and GRELHEIGHT flags are set in the Flags field of the Gadget structure.
Gadgets 91
The FOLLOWMOUSE, GADGIMMIEDIATE, and RELVERIFY flags are all set in the Activation field of the Gadget structure.
MUTUAL EXCLUDE
NOTE: As of the time this was published, this feature had not been implemented. If a gadget is selected and a bit has been set in the MutualExclude variable of the gadget, the gadget corresponding to that bit (for example, bit 0 set refers to the first gadget in the gadget list, bit 2 to the third, and so on) becomes disabled. Intuition sets or clears the appropriate bits in the disabled gadgets and changes the display to reflect the new state of affairs. It is up to your program to note internally, as needed, that the other gadgets have been disabled. Note that there is no reason to limit yourself to 32 gadgets in the gadget list. However, the mutual exclude feature works only on the first 32 gadgets in a list.
92 Gadgets
GADGET HIGHLIGHTING
You can change the appearance of a selected gadget to let the user know that the gadget has indeed been selected. You select a highlighting method by setting one of the highlighting bits in Flags. Note that you must specify one of the highlighting values. If you do not want any highlighting, set the GADGHNONE bit. The methods of highlighting after selection are described below.
Gadgets 93
An Image or Border structure contains a set of coordinates that specifies its location when displayed. Intuition renders the image or border relative to the top left corner of the gadget's select box. For information about how to create an Image or Border structure, see chapter 9, "Images, Line Drawing, and Text."
94 Gadgets
Note the following two flags, which have an effect upon toggle-selection: o You need to set the TOGGLESELECT flag in the Activation field of the Gadget structure if you want the gadget to be toggle-selected o The SELECTED flag in Gadget structure Flags determines the initial and current on/off selected state of a toggle-selected gadget. If SELECTED is set, the gadget will be highlighted. You can set the SELECTED flag before submitting the gadget to Intuition if you like. The program can examine this flag at any time to determine whether the user has selected this gadget. If a Boolean gadget is selected by the user, the application will hear about it. If it is never selected, the application will never know. In this respect, Boolean gadgets differ from string or proportional gadgets, which always are set to some value, even if that value is the one initialized by you.
Gadgets 95
o The HorizPot and VertPot variables contain the actual proportional values. The word pot is short for potentiometer, which is an electrical analog device that can be used to adjust some variable value. The proportional gadget pots enable the user or program to set how much of the total data is visible or available. Because they represent fractional parts of a whole, the values in these variables ranges from 0 to (almost) 1. The data, then, ranges from none visible or available to all of it visible or available. There are two pot variables because proportional gadgets are adjustable on the horizontal axis or the vertical axis or both. For example, a gadget that allows the user to center the screen on the video display or to center his gunsights on a fleeing enemy must be adjustable on both axes. Pot variables are typically initialized to 0 and change while the user is playing with the gadget. You can initialize the pot variables to whatever you want. In the case of the color gadgets, you might want to initialize them to some current color. The program may read the values in the pots at any time after it has submitted the gadget to the user via Intuition. The values will always have the current settings as adjusted by the user. o The HorizBody and VertBody variables describe the increment, or typical step value, by which the pot variables change. For example, the proportional gadgets for color mixing might allow the user to add or subtract a color by 1/16 of the full value each time, as there are 16 possible settings for each RGB (red, green, blue) component of a color on the Amiga. The proportional gadget for centering the screen might allow the user to move the screen vertically a line at a time, or you may choose to set the step increment to a large number of lines, leaving the fineresolution tuning to the use of the gadget's knob. Body variables are also used in conjunction with the auto-knob (described below) to display for the user how much of the total quantity of data is directly available. For instance, if the user is working on a text file that is fifteen lines long, and five lines of the file are currently visible in the window, then you can graphically represent the total size of the file by setting the body variable to one-third (0xFFFF / 3 = 0x5555). In this case, the auto-knob would fill one-third of the container (the gadget box), which represents the proportion of the visible text lines to the total number of text lines. Also, the user can tell at a glance that clicking the mouse button with the cursor in the container (not on the knob) will advance the text file by one-third in any direction, to the next "window" of data. You can set the two body variables to the same or different increments. When the user clicks the mouse button in the container, your pot variables are adjusted by the amount set in the body variables. o The knob is the object actually manipulated by the user to change the pot variables by the increments specified in the body variables. The knob is directly analogous to proportional controls, such as the volume knob on a radio, if the Intuition knob is
96 Gadgets
restricted to one axis of movement. If the knob is free to move on both axes, it is more analogous to, say, a control-stick of an airplane. The user can move the knob by placing the pointer on it and dragging it on the vertical or horizontal axis or by moving the pointer near it (within the select box) and clicking the mouse button. With each click, the pot variable is increased or decreased by one increment, defined by the settings of the body variables. The current position of the knob reflects the pot value. For instance, in the color-selection gadget, the knob slides in a long narrow container. As the user moves the knob to the right, more of that color is added. When the knob is halfway along the container, the value in HorizPot is also halfway. For a picture of this color selection gadget, see the Preferences display in figure 11-2. You can design your own imagery for the knob or use Intuition's handy auto-knob. The auto-knob is a rectangle that can move on either axis and changes its length or height according to the current body settings. The auto-knob also proportionally changes in size when the user sizes the window. Therefore, you can place an autoknob in a proportional gadget that adjusts its size relative to the size of a window, and the auto-knob will always be proportionally correct. For example, consider a proportional gadget with auto-knob being used as a scroll bar in the right border of a window. If the VertBody variable is set to show that one-third of a text file is being displayed in the window, the auto-knob fills one-third of the container. If the user makes the window (and therefore the container) larger, the auto-knob gets larger, too, so that it still visually represents one-third. For an example of such a scroll bar, see figure 5-4. This is yet another visual aid for the user, one that helps make the user interface of the Amiga as intuitive to use as possible. o The container is the area in which the knob can move. It is actually the select box of the gadget. The size of the container, like that of any other gadget select box, can be relative to the size of the window.
The pot variable is a 16-bit word that contains a value ranging from 0 to 0xFFFF. This value range represents a fixed-point fraction that ranges from 0 to (almost) 1. You need to convert the current setting of the pot variable to a number that you can use. The proportional gadget example below shows how to do this conversion.
Gadgets 97
/************************************************************* * * Conversion of a pot variable * **************************************************************/ #define MAXSECONDS 4 /* an arbitrary assignment */ #define MILLION 1000000 /* a real assignment */ LONG RealTime; SHORT Seconds, MicroSeconds; The next line converts the 16-bit fraction into a 32-bit intermediate value that expresses integer and fractional parts of the constant MAXSECONDS. The integer portion is in the upper 16 bits, and the fractional remainder is in the lower 16. RealTime = (PropInfo.HorizPot + 1) * MAXSECONDS; This line gets the number of seconds, which is the integer portion: Seconds = RealTime > > 16; Because the lower 16 bits represent only a fraction, this value must be multiplied by some other meaningful constant if it is to mean something real. Because the fractional portion represents microseconds, and there are a million microseconds to the second, multiply the fraction by one million. Then, in the integer portion (the upper 16 bits), you will find the whole number of millionths of a second contained in RealTime. (By the way, in the lower 16 bits of the multiplication, which are shifted away into the bottomless bit bucket, is a fraction representing the fractional part of a millionth of a second contained in RealTime. To be technically accurate, you should test whether this fraction is greater than or equal to 0x8000 (one-half) and round your MicroSeconds result up if it is.) MicroSeconds = ((RealTime & 0xFFFF) * MILLION) > > 16; You set up a proportional gadget as you do any other gadget, except for the extra Proplnfo data structure (shown below under "Using Application Gadgets"). Carry out the following procedures to set up the Proplnfo structure: o If you want the auto-knob, set the AUTOKNOB flag and set GadgetRender to point to an Image. In this case, you do not initialize the Image structure. If you want your own knob imagery instead, GadgetRender points to a real Image or Border structure.
98 Gadgets
o Set either or both of the FREEHORIZ and FREEVERT flags according to the direction(s) you want the knob to move. o Initialize either or both of the HorizPot and VertPot variables to their starting values. o Set either or both of the HorizBody and VertBody variables to the increment you want. If there is no data to show or the total amount displayed is less than the area in which to display it, set the body variables to the maximum (0xFFFF). o The remaining variables and flags are used by Intuition. In the Gadget structure, set the GadgetType field to PROPGADGET and set the SpecialInfo field to point to an instance of a Proplnfo structure. After the gadget is displayed, your program can call ModifyProp() to change the flags and the pot and body variables. The gadget's internal state will be recalculated and the imagery will be redisplayed to show the new state. If the program receives a message saying that the user has played with this gadget, the program can examine the KNOBHIT flag in the Proplnfo structure. This flag indicates whether the user hit the knob or hit in the container but not on the knob itself. If the flag is set, the user hit the knob and moved it.
Gadgets 99
Because there is only one active gadget at a time, all string gadgets can share the same undo buffer as long as the undo buffer is as large as the largest input buffer. You specify the size of the container into which the user types the string. Like the container for the proportional gadget, the container for the string gadget is its select box. As the user types text into a string gadget, the characters appear in the gadget's container. You can change the justification of the string as it is displayed in the container. The default is left justification. If the flag STRINGCENTER is set, the text is centerjustified; if STRINGRIGHT is set, the text is right-justified. An important and useful feature of the string gadget is that you can supply a buffer to contain more text than will fit in the container. This allows the program to get text strings from the user that are much longer than the visible portion of the buffer. Intuition maintains the cursor position and scrolls the text in the container as needed. You can initialize the input buffer to any starting value, as long as the initial string is terminated with a null. If you want to initialize the buffer to the null string (no characters), you must put a null character in the first position of the buffer. After the gadget is deselected by the user (either by hitting the RETURN key or by using the mouse to select some other operation), the program can examine this buffer to discover the current string. String gadgets feature "auto-insert," which allows the user to insert ASCII characters wherever the cursor is. The simple editing functions shown in table 5-2 are available to the user.
100 Gadgets
Table 5-2: Editing Keys and Their Functions Key(s) < or > SHIFT < or > DEL BACKSPACE RETURN Function Move the cursor around the current string. Move the cursor to the beginning or end of current string. Delete the character under the cursor. Delete the character to left of cursor. Terminate input and deselect the gadget. If the RELVERIFY activation flag is set, the program is notified that the user has selected this gadget. Undo (cancel) the last editing change to the string. Clears the input buffer. The undo buffer is left undisturbed.
You can supply any type of image for the rendering of this gadget Image, Border, or no image at all. For this release of Intuition, you must specify that the highlighting is of type GADGHCOMP (complementary), and you cannot supply an alternate image for highlighting. The string gadget inherits the input attributes and the font of the screen in which it appears. If you have not done anything fancy, the strings will appear in the default font with simple ASCII key translations. If you are using the console device for input, you can set up alternate key-mapping any way you like. If you do, Intuition will use your key map. See the Amiga ROM Kernel Manual for more information about the console device and key-mapping. For a string gadget, you set the GadgetType field to STRGADGET in the Gadget structure. Also set the SpecialInfo field to point to an instance of a Stringlnfo structure. This structure contains buffer and container information.
Gadgets 101
102 Gadgets
If the scroll bar goes in the right border of the window, you may wish to place the system sizing gadget in the right border by setting the flag SIZEBRIGHT in the NewWindow structure. Remember that the sizing gadget has to fit in either the right or the bottom border. If you are going to cause the right edge border to be wide enough to accommodate a scroll bar, then you might as well put the sizing gadget there, too.
Gadgets 103
GADGET STRUCTURE
Here is the general specification for a Gadget structure: struct Gadget { struct Gadget *NextGadget; SHORT LeftEdge, TopEdge, Width, Height; USHORT Flags; USHORT Activation; USHORT GadgetType; APTR GadgetRender; APTR SelectRender; struct IntuiText *GadgetText; LONG MutualExclude; APTR SpecialInfo; USHORT GadgetlD; APTR UserData; };
The variables and flags in the Gadget structure are explained below. NextGadget This is a pointer to the next gadget in the list. The last gadget in the list should have a NextGadget value of NULL. LeftEdge, TopEdge, Width, Height These variables describe the location and dimensions of the select box of the gadget. Both location and dimensions can be either absolute or relative to the edges and size of the window, screen, or requester that contains the gadget. LeftEdge and TopEdge are relative to one of the corners of the display element, according to how GRELRIGHT and GRELBOTTOM are set in the Flags variable (see below). Width and Height can be either absolute dimensions or a negative increment to the width and height of a requester, screen, or alert or the current width and height of a window, according to how the GRELWIDTH and GRELHEIGHT flags are set (see below).
104 Gadgets
Flags The Flags field is shared by your program and Intuition. See the section below called "Flags" for a complete description of all the flag bits. Activation This field is used for information about some gadget attributes. See the "Activation Flags" section below for a description of the various flags. GadgetType This field contains information about gadget type and in what sort of display element the gadget is to be displayed. You must set one of the following flags to specify the type: BOOLGADGET Boolean gadget type. STRGADGET String gadget type. For an integer gadget, also set the LONGINT flag. See the "Flags" section below. PROPGADGET Proportional gadget type. 'The following flags tell Intuition if the gadget is for a requester or a Gimmezerozero window: GZZGADGET If this gadget is for a Gimmezerozero window, setting this flag puts the gadget in the special bit-map for gadgets and borders (and out of your inner window). If you do not set this flag, the gadget will go into your inner window. If the destination of this gadget is not a Gimmezerozero window, clear this bit. REQGADGET Set this bit if this is a requester gadget; otherwise, clear it. GadgetRender This is a pointer to the Image or Border structure containing the graphics of this gadget. If this field is set to NULL, no rendering will be done. NOTE: To tell Intuition what sort of data is pointed to by this variable, set or clear the Flag bit, GADGIMAGE.
Gadgets 105
SelectRender This field contains a pointer to an alternate Image or Border for highlighting. NOTE: You specify that you want SelectRender by setting the GADGHIMAGE flag. You specify which type, Image or Border, by setting the same GADGIMAGE bit that you set for GadgetRender above. SelectRender must point to the same data type as GadgetRender. GadgetText If you want text printed after this gadget is rendered, set this field to point to an IntuiText structure. The offsets in the IntuiText structure are relative to the top left of the gadget's select box. Set this field to NULL if the gadget has no associated text. MutualExclude When this feature is implemented, you will use these bits to describe which, if any, of the other gadgets are mutually excluded by this one. Currently, Intuition ignores this field. SpecialInfo If this is a proportional gadget, this variable points to an instance of a Proplnfo data structure. If this is a string or integer gadget, this variable points to a Stringlnfo data structure. The structure contains the special information needed by the gadget. If the gadget is not of type proportional, string, or integer, this variable is ignored. GadgetlD This variable is strictly for your own use. Assign any value you would like here. This variable is ignored by Intuition. Typical uses in C are in switch and case statements, and in assembly language, table lookup. UserData A pointer to any general data you would care to associate with this particular gadget. This variable is ignored by Intuition.
106 Gadgets
FLAGS
The following are the flags you can set in the Flags variable of the Gadget structure. GADGHIGHBITS Combinations of these bits describe what type of highlighting you want when the user has selected this gadget. There are four highlighting methods to choose from. You must set one of the four flags below. GADGHCOMP This flag complements all of the bits contained within this gadget's select box. GADGHBOX This flag draws a box around this gadget's select box. GADGHIMAGE This flag displays an alternate Image or Border. GADGHNONE Set this flag if you want no highlighting. GADGIMAGE Use this bit if you have not set GadgetRender to NULL. Set this flag if the gadget should be rendered as an Image; clear the flag if it is a Border. This bit is also used by SelectRender. GRELBOTTOM Set this flag if the gadget's TopEdge variable describes an offset relative to the bottom of the display element containing it. Clear this flag if TopEdge is relative to the top. GRELRIGHT Set this flag if the gadget's LeftEdge variable describes an offset relative to the right edge of the display element containing it. Clear this flag if LeftEdge is relative to the left edge. GRELWIDTH Set this flag if the gadget's Width variable describes an increment to the width of the display element containing the gadget. Clear this flag if Width is an absolute value.
Gadgets 107
GRELHEIGHT Set this flag if the gadget's Height variable describes an increment to the height of the display element containing the gadget. Clear this flag if Height is an absolute value. SELECTED Use this flag to preselect the on/off selected state for a toggle-selected gadget. If the flag is set, the gadget starts off being on and is highlighted. If the flag is clear, the gadget starts off in the unselected state. GADGDISABLED If this flag is set, this gadget is disabled. If you want to enable or disable a gadget later on, you can change the current state with the routines OnGadget() and OffGadget(). You do not need to use this flag if you want the gadget to always remain enabled.
ACTIVATION FLAGS
Here are the flags you can set in the Activation variable of the Gadget structure: TOGGLESELECT When this bit is set, the on/off state of the gadget (and its imagery) toggles each time it is hit. You preset the selection state with the gadget Flag SELECTED (see above); the program later discovers the selected state by examining SELECTED. GADGIMMEDIATE Set this bit if you want the program to know immediately when the user selects this gadget. RELVERIFY This is short for "release verify." Set this bit if you want this gadget selection broadcast to your program only if the user still has the pointer positioned over this gadget when releasing the select button. ENDGADGET This flag pertains only to gadgets attached to requesters. To make a requester go away, the user must select a gadget that has this flag set. See chapter 7, "Requesters and Alerts," for more information about requester gadget considerations.
108 Gadgets
FOLLOWMOUSE When the user selects a gadget that has this flag set, the program will receive mouse position broadcasts every time the mouse moves at all. You can use the following flags in window gadgets to adjust the size of a window's borders when you want to tuck your own window gadgets out of the way into the window border: RIGHTBORDER If this flag is set, the width and position of this gadget are used in deriving the width of the window's right border. LEFTBORDER If this flag is set, the width and position of this gadget are used in deriving the width of the window's left border. TOPBORDER If this flag is set, the height and position of this gadget are used in deriving the height of the window's top border. BOTTOMBORDER If this flag is set, the height and position of this gadget are used in deriving the height of the window's bottom border. The following flags apply to string gadgets: STRINGCENTER If this flag is set, the text in a string gadget is center-justified when rendered. STRINGRIGHT If this flag is set, the text in a string gadget is right-justified when rendered. LONGINT If this flag is set, the user can construct a 32-bit signed integer value in a normal string gadget. You must also preset the string gadget input buffer by putting an initial integer string in it. ALTKEYMAP This flag specifies that you have an alternate keymap. You also need to put a pointer to the keymap in the Stringlnfo structure variable AltKeyMap.
Gadgets 109
Proplnfo Structure
This is the special data required by the proportional gadget. struct Proplnfo { USHORT Flags; USHORT HorizPot; USHORT VertPot; USHORT HorizBody; USHORT VertBody; USHORT CWidth; USHORT CHeight; USHORT HPotRes, VPotRes; USHORT LeftBorder; USHORT TopBorder; }; The meanings of the fields in this structure are as follows: Flags In the Flags variable, these general-purpose flag bits can be specified: AUTOKNOB Set this if you want to use the auto-knob. FREEHORIZ If this is set, the knob can move horizontally. FREEVERT If this is set, the knob can move vertically. KNOBHIT This is set by Intuition when this knob is hit by the user.
110 Gadgets
PROPBORDERLESS Set this if you want your proportional gadget to appear without a border drawn around its container. Initialize these variables before the gadget is added to the system; then look here for the current settings: HorizPot Horizontal quantity percentage. VertPot Vertical quantity percentage. These variables describe what percentage of the entire body of the stuff is actually shown at one time: HorizBody Horizontal body. VertBody Vertical body. Intuition sets and maintains the following variables: CWidth Container real width. CHeight Container real height. HPotRes, VPotRes Pot increments. LeftBorder Container real left border. TopBorder Container real top border.
Gadgets 111
Stringlnfo Structure
This is the special data required by the string gadget. struct Stringlnfo { UBYTE *Buffer; UBYTE *UndoBuffer; SHORT BufferPos; SHORT MaxChars; SHORT DispPos; SHORT UndoPos; SHORT NumChars; SHORT DispCount; SHORT CLeft, CTop; struct Layer *LayerPtr; LONG LongInt; struct KeyMap *AltKeyMap; }; The meanings of the fields in this structure are given below. You initialize the following variables and Intuition maintains them: Buffer This is a pointer to a buffer containing the start and final string. The string you write into this buffer must be null-terminated. UndoBuffer This is an optional pointer to a buffer for undoing the current entry. If you are supplying an undo buffer, the memory location should be as large as the buffer for the start and final string. Because only one string gadget can be active at a time under Intuition, all of your string gadgets can share the same undo buffer. However, the undo buffer must be large enough to hold the largest buffer for starting and final strings. MaxChars This must be set to the maximum number of characters that will fit in the buffer, including the terminating NULL. BufferPos This specifies the initial character position of the cursor in the buffer.
112 Gadgets
DispPos This specifies the buffer position of the first displayed character. Intuition initializes and maintains these variables for you: UndoPos This specifies the character position in the undo buffer. NumChars This specifies the number of characters currently in the buffer. DispCount This specifies the number of whole characters visible in the container. CLeft, CTop This specifies the top left offset of the container. LayerPtr This specifies the Layer containing this gadget. LongInt After the user has finished entering an integer, you can examine this variable to discover the value if this is an integer string gadget. AltKeyMap This variable points to your own alternate keymap; you must also set the ALTKEYMAP bit in the Activation flags of the gadget.
Gadgets 113
GADGET FUNCTIONS
These are brief descriptions of the functions you can use to manipulate gadgets. For complete descriptions see Appendix A, "Intuition Function Calls."
114 Gadgets
Gadget points to the gadget to be disabled. Ptr points to a Window structure. Requester points to a requester or is NULL. Redraw the Gadget Display The following function redraws all of the gadgets in the gadget list of a window or requester, starting with the specified gadget. You might want to use this if you have modified the imagery of your gadgets and want to display the new imagery. You might also use it if you think some graphic operation has trashed the imagery of the gadgets. RefreshGadgets(Gadgets, Ptr, Requester) Gadgets points to the gadget where the redrawing should start. Ptr points to the Window structure. Requester points to a requester or is NULL. Modifying a Proportional Gadget Use the following function to modify the current parameters of a proportional gadget. ModifyProp(Gadget, Ptr, Requester, Flags, HorizPot, VertPot, HorizBody, VertBody) This function modifies the parameters of a proportional gadget. The gadget's internal state is recalculated and the imagery is redisplayed.
Gadgets 115
116 Gadgets
Chapter 6
MENUS
This chapter shows how to set up the menus that let the user choose from your program's commands and options. The Intuition menu system handles all of the menu display from menu data structures that you set up. If you wish, some or all of your menu selections can be graphic images instead of text.
Menus 117
About Menus
Intuition's menu system provides you with a convenient way to group together and display the functions and options that your application presents to the user. For instance, in a wordprocessor environment, menus may provide the following functions: o Access to text files. o Edit functions. o Search and replace facilities. o Formatting capabilities. o Multiple fonts. o A general help facility. In a game, menus may provide the user with choices about how to: o Load a new game or save the current one. o Get hints. o Bring up special information windows. o Set the difficulty level. o Auto-annihilate the enemy. Menu commands are either actions or attributes. Actions are represented by verbs and attributes by adjectives. An attribute stays in effect until canceled, while a command is executed and then forgotten. You can set up menus so that some attribute items are mutually exclusive (selecting an attribute cancels the effects of one or more other attributes), or you can allow a number of attributes to be in effect at the same time. For example, an adventure game might have a menu list for things that the hero is holding in his hand. He could hold several small, lightweight objects, but holding the heavy sword excludes holding anything else. In a database program, you might be able to choose to send a report to a file, to the window, or to a printer. You could, for example, send it to both a window and a printer, while the "file" option excludes the other two. After you set up a linked list of menu structures (called a menu strip) and attach the list to a window, the menu system handles the menu display. Using this list and any graphic images you have designed, the menu system displays the menu bar text that appears across the screen title bar when requested by the user. It also creates the lists of menu items and sub-menus that appear at the user's request. The application does not
118 Menus
have to worry about menus until Intuition sends a message with news that the user has selected a menu item. This message gives the application the number of the selected item. You can enable and disable menus and menu items during the display of the window and make changes to the menus you previously attached to a window. Disabling an item prevents the user from selecting it, and disabled items are ghosted to look different from enabled items. Menu items can be graphic images or text. When the user positions the pointer over an item, the item can be highlighted through a variety of techniques and can have a check mark placed next to it. Next to the menu items, you can display command-key alternatives. To activate the menu system, the user presses the mouse menu button (or an appropriate command-key sequence) to display the menu bar in the screen title area. The menu bar displays a list of topics (called menus) that have menu items associated with them (see figure 6-1).
Figure 6-1: Screen with Menu Bar Displayed When the user moves the mouse pointer to a topic in the menu bar, a list of menu items appears below the topic name. To select an item, the user moves the mouse pointer in the list of menu items while holding down the menu button, releasing the button when the pointer is over the desired item. If an item has a subitem list, moving the pointer over the item reveals a list of subitems. The user moves the pointer over one of the
Menus 119
subitems and makes a selection in the same way as an item is selected. If there is a command-key sequence alternative, the user can make menu selections with the keyboard instead of the mouse. Furthermore, the user can select multiple items by: o Pressing and releasing the mouse select button without releasing the menu button. This selects that item and keeps the user in "menu state" so that other items can be selected. o Holding down both mouse buttons and moving the pointer over several items. This is called drag-selecting.
120 Menus
Figure 6-2: Example Item Box The item box must start no further right than the leftmost position of the menu header's select box. It must end no further left than the rightmost position of the menu header's select box. The top edge of the menu box must overlap the screen's title bar by one line. The subitem box must overlap its item's select box somewhere.
Menus 121
122 Menus
You can initialize the state of an attribute item by presetting the item's CHECKED flag. If this flag is set when you submit your menu strip to Intuition, then the item is considered to be already selected and the checkmark will be drawn. You can use the default Intuition checkmark (9) or you can design your own and set a pointer to it in the NewWindow structure when you open a window. See chapter 4, "Windows," for details about supplying your own checkmark. If your items are going to be checkmarked, you should leave sufficient blank space at the left edge of your select box for the checkmark imagery. If you are taking advantage of the default checkmarks, you should leave CHECKWIDTH amount of blank pixels on high-resolution screens and LOWCHECKWIDTH amount of blank pixels on lowresolution screens. These are defined constants describing the pixel width in high and low resolution. They define the space required by the standard checkmarks (with a bit of space for aesthetic purposes). If you would normally place the LeftEdge of the image within the item's select box at 5, and you decide that you want a checkmark to appear with the item, then you should start the item at 5+CHECKWIDTH instead. You should also make your select box CHECKWIDTH wider than it would be without the checkmark.
MUTUAL EXCLUSION
You can choose to have some of your attribute items, when selected, cause other items to become unselected. This is known as mutual exclusion. For example, if you have a list of menu items describing the available type sizes for a particular font, the selection of any type size would mutually exclude all other type sizes. You use the MutualExclude variable in the Menultem structure to specify other menu items to be excluded when the user selects an item. Exclusion also depends upon the CHECKED and CHECKIT flags of the MenuItem, as explained below. o If CHECKIT is set, this item is an attribute item that can be selected and unselected. If CHECKED is not set, then this item is available to be selected. If the user selects this item, the CHECKED flag is set and the user cannot then reselect this item. If the item is selected, the CHECKED flag will be set, and the checkmark will be drawn to the left of the item. o If CHECKIT is not set, this is an action item-not an attribute item. The CHECKED flag is ignored and the checkmark will never be drawn. Mutual exclusion affects only attribute items. o If an item is selected that has bits set in the MutualExclude field, the CHECKIT and CHECKED flags are examined in the excluded items. If any item is currently CHECKED, its checkmark is erased.
Menus 123
o Mutual exclusion is an active event. It pertains only to items that have the CHECKIT flag set. Attempting to exclude items that do not have the CHECKIT flag set has no effect. It is up to you to note internally as needed that excluded items have been disabled and deselected. In the MutualExclude field, bit 0 refers to the first item in the item list, bit 1 to the second, bit 2 to the third, and so on. In the adventure game example described earlier, in which carrying the heavy sword excludes carrying any other items, the MutualExclude fields of the four items would look like this: Heavy sword Stiletto Rope Canteen 0xFFFE 0x0001 0x0001 0x0001
"Heavy Sword" is the first item on the list. You can see that it excludes all items except the first one. All of the other items exclude only the first item, so that carrying the rope excludes carrying the sword, but not the canteen.
124 Menus
When items have alternate key sequences, the menu boxes show a special AMIGA key icon rendered about one character span plus a few pixels from the right edge of the menu select box and the command-key used with the AMIGA key rendered immediately to the right of the AMIGA key image, at the rightmost edge of the menu select box (see figure 6-4). If you want to show a command-key sequence for an item, you should make sure that you leave blank space at the right edge of your select box and imagery. You should leave COMMWIDTH amount of blank space on high-resolution screens, and LOWCOMMWIDTH amount of space on low-resolution screens.
Figure 6-4: Menu Items with Command Key Shortcuts See chapter 12, "Style Notes," for suggested command key sequences.
Menus 125
You use the routines OnMenu() and OffMenu() to enable and disable individual subitems, items or whole menus. These routines check if the user is using the menus and whether the menus need to be redrawn to reflect the new states.
126 Menus
while (MenuNumber != MENUNULL) { Item = ItemAddress(MenuStrip, MenuNumber); /* process this item */ MenuNumber = Item->NextSelect; } The number given in the MENUPICK message describes the ordinal position of the Menu in your linked list, the ordinal position of the Menultem beneath that Menu, and (if applicable) the ordinal position of the subitem beneath that MenuItem. Ordinal means the successive number of the linked items, starting from 0. To discover the Menus and Menultems that were selected, you should use the following macros: Use MENUNUM(num) to extract the ordinal menu number from the value. Use ITEMNUM(num) to extract the ordinal item number from the value. Use SUBNUM(num) to extract the ordinal subitem number from the value. MENUNULL is the constant describing "no menu selection made." Likewise, NOMENU, NOITEM, and NOSUB are the null states of the parts. For example: if (number == MENUNULL) then no menu selection was made, else MenuNumber = MENUNUM(number); ItemNumber = ITEMNUM(number); SubNumber = SUBNUM(number); if there were no subitems attached to that item, SubNumber will equal NOSUB. The menu number received by the program describes either MENUNULL or a valid menu selection. If it is a valid selection, it will always have at least a menu number and a menu item number. Users can never "select" the menu text itself, but they always select at least an item within a menu. Therefore, the program always gets one menu specifier and one menu item specifier. If a given menu item has a subitem, a subitem specifier will also be received. Just as it is not possible to select a menu, it is not possible to select a menu item that has a list of subitems. The user must select one of the options in the subitem list before the program ever hears about it as a valid selection. If the user enters a command-key sequence, Intuition checks to see if the sequence is associated with a current menu item. If so, Intuition sends the menu item number to the program with the active window just as if the user had made the selection using the mouse buttons. The function ItemAddress() translates a menu number into an item address.
Menus 127
128 Menus
0 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 | | | | | > Menu number 0 | | | > Menu item number 0x25 = 37 | > Subitem number 1 Again, it is never safe to examine these numbers directly. Use the macros described above if you want to design sanely and assure upward compatibility.
Menu-verify
Menu-verify is one of the Intuition verification functions. These functions allow you to make sure that your program is prepared for some event before it takes place. Using menu-verify, Intuition allows all windows in a screen to verify that they are prepared for menu operations before the operations begin. In general, you would want to use this if the program is doing something special to the display of a custom screen, and you want to make sure it is completed before menus are rendered. Any window can access the menu-verify feature by setting the MENUVERIFY flag in the NewWindow structure when opening the window. When your program gets a message of class MENUVERIFY, menu operations will not proceed until the program replies to the message. The active window gets special menu-verify treatment. It is allowed to see the menuverify message before any other window and has the option of canceling menu operations altogether. You could use this, for instance, to examine where the user has positioned the mouse when the right button was pressed. If the pointer is in the menu bar area, then you can let normal menu operations proceed. If the pointer is below the menu bar, then you can use the right button event for some non-menu purpose.
Menus 129
Your program can tell whether or not it is in the active window by examining the code field of the MENUVERIFY message. If the code field is equal to MENUWAITING, your window is not the active one and Intuition is simply waiting for you to verify that menu operations may continue. However, if the code field is equal to MENUHOT, your window is the active one and it gets to decide whether or not menu operations should proceed. If the program does not want them to proceed, it should change the code field of the message to MENUCANCEL before replying to the message. This will cause Intuition to cancel the menu operations. No Menu Operations - Right Mouse Button Trap By setting the RMBTRAP flag in the NewWindow structure when you open your window, you select that you do not want any menu operations at all for your window. Whenever the user presses the right button while your program's window is active, the program will receive right button events as normal MOUSEBUTTON events.
REQUESTERS AS MENUS
You may, in some cases, want to use a requester instead of a menu. A requester can function as a "super-menu" because you can attach a requester to the double-click of the mouse menu button. This allows users to bring up the requester on demand. With a requester, however, the user must make some response before resuming input to the window. See chapter 7, "Requesters and Alerts," for more information.
Using Menus
Follow these steps to design and use menus: 1. Design the menu structures and link them together into a menu strip. 2. Submit the menu strip to Intuition, which attaches the strip to a window. 3. Arrange for your program to respond to Intuition's menu selection messages.
130 Menus
To create the menu structures, you need to choose: o The menu names that appear in the screen title bar. o The menu items that appear when the user selects a menu, including: o o o o o Each menu item's position in the list. Text or a graphic image for each menu item. Highlighting method for this item when the user positions the pointer over it. Any equivalent command-key sequence. Which items have subitems. For the subitems, you make the same decisions as for the menu items.
Menu strips are constructed of three components: menus, menu items, and subitems. They use two data types: Menu and Menultem. Subitems are of the Menultem data type. Menu is the data type that describes the basic unit of the menu strip. The menu strip is made up of a linked list of Menus. Each Menu is the header or topic name for a list of Menultems that can be selected by the user. The user never selects just a Menu, but rather a Menu and at least one of its Menultems. The Menu structure contains the following: o The menu bar text that appears across the screen's title bar when the menu button is pressed. o The position for the menu bar text. o A pointer to the next in the list of Menus. o A pointer to the first in a linked list of Menultems.
Menus 131
The Menultem structure contains the following: o The location of the item (with respect to the select box of its Menu). o A pointer to text or a graphics image. o Highlighting method when the user positions the pointer over this item. o Any equivalent command sequence. o The select box for the item (used to detect selection and for some of the highlighting modes). o Other items mutually excluded by the selection of this one (if any). o A pointer to the first in a linked list of subitems (if any). o The menu number of the next selected item (if any). When more than one item has been selected, this field provides the link. The third menu component, the subitem, uses the same data structure as the menu item. Subitems are identical to menu items except that the subitem's location is relative to its menu item's select box and the subitem's subitem link is ignored.
MENU STRUCTURES
The specifications for the menu structures are given below. Menus are the headers that show in the menu bar, and Menultems are the items and subitems that can be chosen by the user. Menu Structure Here is the specification for a Menu structure:
132 Menus
struct Menu { struct Menu *NextMenu; SHORT LeftEdge, TopEdge, Width, Height; USHORT Flags; BYTE *MenuName; struct Menultem *Firstltem; }; The variables in the Menu structure have the following meanings: NextMenu This variable points to the next Menu header in the list. The last Menu in the list should have a NextMenu value of NULL. LeftEdge, TopEdge, Width, Height These fields describe the select box of the header. Currently, any values you may supply for TopEdge and Height are ignored by Intuition, which uses instead the screen's TopBorder for the TopEdge and the height of the screen's title bar for the Height. This will change someday when menu headers are allowed to be either textual or graphical and are allowed to appear anywhere in the menu title bar. LeftEdge is relative to the LeftEdge of the screen plus the screen's left border width, so if you say LeftEdge is 0, Intuition puts this header at the leftmost allowable position. Flags The flag space is shared by your program and Intuition. The flags are: MENUENABLED This flag indicates whether or not this Menu is currently enabled. You set this flag before you submit the menu strip to Intuition. If this flag is not set, the menu header and all menu items below it will be disabled, and the user will not be able to select any of the items. After you submit the strip to Intuition, you can change whether your menu is enabled or disabled by calling OnMenu() or OffMenu(). MIDRAWN This flag indicates whether or not this Menu's items are currently displayed to the user.
Menus 133
MenuName This is a pointer to a null-terminated character string that is printed on the screen's title bar starting at the LeftEdge of this Menu's select box and at the TopEdge just below the screen title bar's top border. Firstltem This points to the first item in the linked list of this Menu's items (Menultem structures). Menultem Structure Here is the specification for a Menultem structure (used both for items and subitems): struct Menultem { struct Menultem *Nextltem; SHORT LeftEdge, TopEdge, Width, Height; USHORT Flags; LONG MutualExclude APTR ItemFill; BYTE Command; struct Menultem *SubItem; USHORT NextSelect; }; The fields have the following meanings: Nextltem This field is a pointer to the next item in the list. The last item in the list should have a Nextltem value of NULL. LeftEdge, TopEdge, Width, Height These fields describe the select box of the Menultem. The LeftEdge is relative to the LeftEdge of the Menu. The TopEdge is relative to the topmost position Intuition allows. TopEdge is based on the way the user has the system configured which font, which resolution, and so on. Use 0 for the topmost position.
134 Menus
Flags The flag space is shared by your program and Intuition. See "Menultem Flags" below for a description of the flag bits. MutualExclude This LONG word refers to the items that may be on the same "plane" as this one (maximum of 32 items). You use these bits to describe which if any of the other items are mutually excluded by this one. This does not mean that you cannot have more than 32 items in any given plane, just that only the first 32 can be mutually excluded. ItemFill This points to the data used in rendering this Menultem. It can point to either an instance of an IntuiText structure with text for this Menultem or an instance of an Image structure with image data. Your program tells Intuition what sort of data is pointed to by this variable by either setting or clearing the Menultem flag bit ITEMTEXT. See "Menultem Flags" below for more information about ITEMTEXT. SelectFill If you select the Menultem highlighting mode HIGHIMAGE (in the Flags variable), Intuition substitutes this alternate image for the original rendering described by ItemFill. SelectFill can point to either an Image or an IntuiText, and the flag ITEMTEXT describes which. Command This variable is storage for a single alphanumeric character. If the Flag COMMSEQ is set, the user can hold down the right AMIGA key on the keyboard (to mimic using the right mouse menu button) and press the key for this character as a shortcut for using the mouse to select this item. If the user does this, Intuition transmits the menu number for this item to your program. It will look to your program exactly as if the user had selected a menu item using menus and the pointer. SubItem If this item has a subitem list, this variable should point to the first subitem in the list. Note that if this item is a subitem, this variable is ignored. NextSelect This field is filled in by Intuition when this item is selected by the user. If this item is selected by the user, your program should process the request and then check the NextSelect field. If the NextSelect field is equal to MENUNULL, no other items
Menus 135
were selected; otherwise, there is another item to process. See "Menu Numbers and Menu Selection Messages" above for more information about user selections. MenuItem Flags Here are the flags that you can set in the Flags field of the Menultem structure: CHECKIT You set this flag to inform Intuition that this item is an attribute item and you want a checkmark to precede this item if the flag CHECKED is set. See the section "Action/Attribute Items and the CheckMark" above for full details. CHECKED Set the CHECKIT flag above if you want this item to be checked when the user selects it. When you first submit the menu strip to Intuition, set this bit to specify whether or not this item is currently a selected one. Thereafter, Intuition maintains this bit based on effects from the item list's mutual exclusions. ITEMTEXT You set this flag if the representation of this item (pointed to by the ItemFill field and possibly by SelectFill) is text and points to an IntuiText; you clear it if the item is graphic and points to an Image. COMMSEQ If the flag is set, this item has an equivalent command-key sequence (see the Command field above). ITEMENABLED This flag describes whether or not this item is currently enabled. If an item is not enabled, its image will be ghosted and the user will not be able to select it. Set this flag before you submit the menu strip to Intuition. Once you have submitted your menu strip to Intuition, you enable or disable items only by using OnMenu() or OffMenu(). If this item has subitems, all of the subitems are disabled when you disable this item. HIGHFLAGS An item can be highlighted when the user positions the pointer over the item. These bits describe what type of highlighting you want, if any. You must set one of the following bits according to the type of highlighting you want: HIGHCOMP This complements all of the bits contained by this item's select box.
136 Menus
HIGHBOX This draws a box outside this item's select box. HIGHIMAGE This displays the alternate imagery in SelectFill (textual or image). HIGHNONE This specifies no highlighting. The following two flags are used by Intuition: ISDRAWN Intuition sets this flag when this item's subitems are currently displayed to the user and clears it when they are not. HIGHITEM Intuition sets this flag when this item is highlighted and clears it when the item is not highlighted.
MENU FUNCTIONS
There are menu functions for attaching and clearing menu strips, for enabling and disabling menus or menu items, and for finding a menu number. Attaching and Removing a Menu Strip The following functions attempt to attach a menu strip to a window or clear a menu strip from a window: SetMenuStrip(Window, Menu) Menu is a pointer to the first menu in the menu strip. This procedure sets the menu strip into the window. ClearMenuStrip(Window) This procedure clears any menu strip from the window.
Menus 137
Enabling and Disabling Menus and Items You can use the following functions to enable and disable items after a menu strip has been attached to the window. If the item component referenced by MenuNumber equals NOITEM, the entire menu will be disabled or enabled. If the item component equates to an actual component number, then that item will be disabled or enabled. You can enable or disable whole menus, just the menu items, or just single subitems. o To enable or disable a whole menu, set the item component of the menu number to NOITEM. This will disable all items and any subitems. o To enable or disable a single item and all subitems attached to that item, set the item component of the menu number to your item's ordinal number. If your item has a subitem list, set the subitem component of the menu number to NOSUB. If your item has no subitem list, the subitem component of the menu number is ignored. o To enable or disable a single subitem, set the item and subitem components appropriately. OnMenu(Window, MenuNumber) This function enables the given menu or menu item. OffMenu(Window, MenuNumber) This function disables the given menu or menu item. Getting an Item Address This function finds the address of a menu item when given the item number: ItemAddress(MenuStrip, MenuNumber) MenuStrip is a pointer to the first menu in the menu strip.
138 Menus
Chapter 7
Requesters are menu-like information exchange boxes that can be displayed in windows by the system or by application programs. You can also have requesters that the user can bring up on demand. They are called requesters because the user has to "satisfy the request" before continuing input through the window. Alerts are similar to requesters but are reserved for emergency messages.
About Requesters
Requesters (see figure 7-1) are like menus in that both menus and requesters offer options to the user. Requesters, however, go beyond menus. They become "super menus" because you can place them anywhere in the window, design them to look however you want, and bring them up in the window whenever your program needs to elicit a response from the user-and they come replete with any kind of gadgets you care to use. The most fundamental differences between requesters and menus are that requesters require a response from the user and that while the requester is in the window, the window locks out all user input. The requirement of a user response is virtually the only restriction placed on your program's use of requesters.
Figure 7-1: Requester Deluxe Requester Display Requesters can be brought up in a window in three different ways. o System requesters are invoked by the operating system; your program has no control over these. For example, someone using a text editor might try to save a file to disk when there is no disk in the drive. The system requester comes up and makes sure the user understands the situation by demanding a response from the user.
o You can bring up the regular application requesters whenever your program needs input from the user. o You can attach a requester to a double-click of the mouse menu button. Users can bring up this "double-menu request" whenever they need the particular option supplied by the requester. Once a requester is brought up in an window, all further input to the program from that window is blocked. This is true even if the user has brought up the requester. The requester remains in the window and input remains blocked until the user satisfies the request by choosing one of the requester gadgets. You decide which of your gadgets meets this criterion. While the requester is in the window, the only input the program receives from that window is made up of broadcasts when the user selects a requester gadget. Even though the window containing the requester is locked for input, the user can work in another application or even in a different window of your application and respond to the requester later. A window with an unsatisfied requester is not blocked for program output. Nothing prevents your program from writing to the window. You must use caution, however, since the requester obscures part of the display memory of the window. Fortunately, there are several ways to monitor the comings and goings of requesters, which your program can use to ensure that it can safely bring up an application requester. (See "IDCMP Features" below.) In displaying any kind of requester (except the super-simple yes-or-no kind created with AutoRequest()), you can specify the location in two ways. You can select either a constant location that is an offset from the top left corner of the window or a location relative to the current location of the pointer. Displaying the requester relative to the pointer can get the user's attention immediately and closely associates the requester with whatever the user was doing just before the requester came up in the window. You can nest several application requesters in the same window, and the system may present requesters of its own that become nested with the application requesters. These are all satisfied in reverse sequence; the last requester to be displayed must be satisfied first. Application Requesters In adding requesters to your program, you have several options. You can supply a minimum of information and let Intuition do the work of rendering the requester or you can design a completely custom requester, drawing the background, borders, and gadgets yourself and submitting the requester to Intuition for display.
You can select a requester rendered by Intuition in two ways. If the requester is complex and you want to attach gadgets and have some custom features, you initialize a requester for general usage. In the requester structure, you supply the gadget list, borders, text, and size of the rectangle that encloses the requester. Intuition will allocate the buffers, construct a bitmap that lasts for the duration of the display, and render the requester in the window on demand from your program or the user. Alternatively, if the requester requires only a simple yes or no answer from the user, you can use the special AutoRequest() function that builds the requester, displays it, and waits for the user's response. On the other hand, you can design your own custom requester with your own handdrawn image for the background, gadgets, borders, and text. You get your own bit-map with a custom requester, so you can design the imagery pixel by pixel if you wish, using any of the Amiga art creation tools. When you have completed the design, you submit it to Intuition for display as usual. Consistency and style are the only restrictions imposed on designing your own requester. The gadgets should look like gadgets and the gadget list should correspond to your images (particularly the gadget select boxes, to avoid confusing the user). You should always provide a safe way for the user to back out of a requester without taking any action that affects the user's work. This is very important. A user's action or response to a requester can be as simple as telling the requester to go away. Because the user's action consists of choosing a requester gadget, there must be one or more gadgets that terminate the requester. Another Option As an option to bringing up a requester, you can flash your screen in a complementary color (binary complement, that is see the "Images, Line Drawing, and Text" chapter for an explanation). This is handy if you want to notify the user of an event that is not serious enough to warrant a requester and to which the user does not really need to respond. For instance, the user might be trying to choose an unavailable function from a menu or trying to use an incorrect command-key sequence. If the event is a little more serious, you can flash all the screens simultaneously. See the description of DisplayBeep() in chapter 11, "Other Features."
RENDERING REQUESTERS
There are two ways of having complex requesters rendered-you can supply Intuition with enough information to do the rendering for you, or you can supply your own completely customized bit-map image. You fill in the Requester structure differently according to which rendering method you have chosen. If you want Intuition to render the requester for you, you need to supply regular gadgets, a "pen" color for filling the requester background, and one or more text structures and border structures. For custom bit-map requesters, you draw the gadgets yourself, so you supply a valid list of gadgets, but the text and image information in the gadget structures can be set to NULL, because it will be ignored. Other gadget information select-box dimensions, highlighting, and gadget type is still relevant. The select-box information is especially important since the select box must have a well-defined correspondence with the gadget imagery that you supply. The basic idea here is to make sure that the user understands your requester imagery and gadgetry. The fields that define borders, text, and pen color are ignored and can be set to NULL.
DOUBLE-MENU REQUESTERS
A double-menu requester is exactly like other requesters with one exception: it is displayed only when the user double-clicks the mouse menu button. You give the user the ability to bring up a double-menu requester by calling SetDMRequest(). After the user brings up one of these requesters, window input is block as if your program or Intuition had brought up the requester. A message stating that a requester has been brought up in your window is entered into the input stream. if you want to stop the user from bringing up a double-menu requester (for instance, if you want to modify it or simply throw it away), you can unlink it from the window by calling ClearDMRequest().
GADGETS IN REQUESTERS
Each requester gadget should have the REQGADGET flag net in its GadgetType variable. Each requester must have at least one gadget that satisfies the request and allows input to begin again. For each gadget that ends the interaction and removes the requester, you set the ENDGADGET flag in the gadget Activation field. Every time one of the requester gadgets is selected, Intuition examines the ENDGADGET flag; if the flag is set, the requester is erased from the screen and unlinked from the window's active-requester list. Algorithmic (Intuition-rendered) and custom bit-map requesters differ in how their gadgets are rendered. In algorithmic requesters, you supply regular gadgets just like the application gadgets in windows or screens. In custom bitmap requesters, the gadgets are part of the bitmap that you supply for display. Even in custom bit-map requesters, however, you must supply a list of gadgets, because you must still define the select box, highlighting, and gadget type for each gadget even though the gadget image information is ignored.
REQSET With this flag set, your program will receive a message when the first requester opens in your window. REQCLEAR With this flag set, your program will receive a message when the last requester is cleared from the window. You set these flags when you call ModifyIDCMP() or create a NewWindow structure. See chapter 8, "Input and Output Methods," for further information about these IDCMP flags.
Figure 7-2: A Simple Requester Made with AutoRequest() The AutoRequest() function calls BuildSysRequest() to construct the simple requester. Your program can call BuildSysRequest() directly if you want the program to use the simple requester and to monitor the requester itself. All gadgets created by Build SysRequest() have the following gadget flags set: BOOLGADGET It is a Boolean TRUE or FALSE gadget. RELVERIFY The program receives a broadcast if this gadget is activated. REQGADGET This flag specifies that this is a requester gadget. TOGGLESELECT This flag specifies that this is a toggle-select type of gadget.
Using Requesters
To create and use a requester, follow these steps: 1. Declare or allocate a Requester structure. 2. Fill out the Requester with your specifications for gadgets, text, borders, and imagery. 3. If you are using the IDCMP for input, decide whether to use the special functions provided. 4. Display the requester by calling either Request() or SetDMRequest().
REQUESTER STRUCTURE
To create a requester structure, follow these steps: 1. Fill in the values you need in the structure. 2. Set up a gadget list. 3. Supply a BitMap structure if this is a custom requester. The specification for a Requester structure follows. struct Requester { struct Requester *OlderRequest; SHORT LeftEdge, TopEdge; SHORT Width, Height; SHORT RelLeft, RelTop; struct Gadget *ReqGadget; struct Border *ReqBorder; struct IntuiText *ReqText; USHORT Flags; UBYTE BackFill; struct Layer *RegLayer; UBYTE req.ad 1[32] struct BitMap *ImageBMap; struct Window *RWindow; UBYTE RegPad2[36] };
Here are the meanings of the fields in the Requester structure: NOTE: See "Intuition Rendering" and "Custom Bit-Map Rendering" below for information about how the initialization of the structure differs according to how the requester is rendered. OlderRequest This is a link maintained by Intuition, which points to requesters that were rendered before this one. LeftEdge, TopEdge Initialize these if the requester is to appear relative to the upper left corner of the window (as contrasted to the POINTREL method, where the requester is rendered relative to the pointer). Width, Height These fields describe the size of the entire requester rectangle, containing all the text and gadgets. RelLeft, RelTop Initialize these if the requester is to appear relative to the current position of the pointer. Also, set the POINTREL flag. ReqGadget This field is a pointer to the first in a linked list of gadget structures. There must be at least one gadget with the ENDGADGET flag set to terminate the requester. ReqBorder This field is a pointer to an optional Border structure for the drawing lines around and within your requester. ReqText This field is a pointer to an IntuiText structure containing text for the requester. Flags You can set these flags: POINTREL Set this flag to specify that you want the requester to appear relative to the pointer (rather than offset from the upper left corner of your window).
PREDRAWN Set this flag if you are supplying a custom BitMap structure for the requester and ImageBMap points to the structure. Intuition uses these flags: REQOFFWINDOW Set by Intuition if the requester is currently active but is positioned offwindow. REQACTIVE This flag is set or cleared by Intuition based on whether or not this requester is currently being used. SYSREQUEST This flag is set by Intuition if this is a system-generated requester. BackFill Pen number for filling the requester rectangle before anything is drawn into the rectangle. ReqLayer This contains the address of the Layer structure used in rendering the requester. ImageBMap This flag is a pointer to the custom bit-map for this requester. If you are not supplying a custom bit-map for this requester, Intuition ignores this variable. If you are supplying a custom bit-map, the PREDRAWN flag must be set. RWindow This is a system variable. ReqPad1, ReqPad2 These are reserved for system use. The following sections describe the differences in the Requester structure between requesters rendered by Intuition and custom-bit-map requesters.
Requesters Rendered by Intuition The following notes apply to requesters rendered by Intuition. o ReqGadget is a pointer to the first in a list of regular gadgets to be rendered in the requester box. Take care not to specify gadgets that extend beyond the requester rectangle that you describe in the Width and Height fields, for Intuition does no boundary checking. o ReqBorder is a pointer to a Border structure for your requester. The lines specified in this structure can go anywhere in the requester; they are not confined to the perimeter of the requester. o ReqText is a pointer to an IntuiText structure. This is for general text in the requester. o BackFill is the pen number to be used to fill the rectangle of your requester before any drawing takes place. For example, the following Requester structure allows Intuition to do the rendering. struct Requester MyRequest = { NULL, /* OlderRequester maintained by Intuition */ 20, 20, 200, 100, /* LeftEdge, TopEdge, Width, Height */ 0, 0, /* RelLeft, RelTop */ &BoolGadget, /* First gadget */ NULL, /* ReqBorder */ &MyText /* ReqText */ NULL, /* Flags */ 2, /* BackFill */ NULL, /* ReqLayer */ {NULL}, /* pad */ {NULL}, /* BitMap */ NULL, /* RWindow */ {NULL}, /* pad */ };
Custom Bit-Map Rendering These notes apply to custom bit-map requesters. o ReqGadget points to a valid list of gadgets, which are real gadgets in every way except that the gadget text and imagery information are ignored (and can be NULL). The select box, highlighting, and gadget type data is still pertinent. You must make sure there is a well-defined correspondence between the gadgets' select boxes and the requester imagery that you supply. o The ReqBorder, ReqText, and BackFill variables are ignored and can be set to NULL. o The ImageBMap pointer points to your own BitMap of imagery for this requester. o You should set the flag PREDRAWN.
NegativeFlags These are flags for the IDCMP for negative external events that will satisfy the request. Width, Height These specify the size of the rectangle enclosing the requester.
REQUESTER FUNCTIONS
A brief rundown of the requester functions follows. Submitting a Requester for Display The following function submits regular requesters to Intuition for display: Request(Requester, Window) This function displays a requester in the specified window. Double-menu Requesters The following functions affect double-menu requesters: SetDMRequest(Window, Requester) This function attaches a requester to the double click of the mouse menu button. ClearDMRequest(Window, Requester) This function unlinks the requester from the window and stops the user from bringing it up. Removing a Requester from the Display EndRequest(Requester, Window) This function erases a requester invoked by the user or application and resets the window. It removes only the one requester named.
The Easy Yes-or-No Requester The following function automatically builds, displays, and gets a negative or positive response from a requester: AutoRequest (Window, BodyText, PositiveText, NegativeText PositiveFlags, NegativeFlags, Width, Height) This function builds a requester from the arguments supplied, displays the requester, and returns TRUE or FALSE.
Alerts
Alerts are for emergency messages. There are two types: system alerts and application alerts. System and application alerts display absolutely essential messages and should be reserved for critical communications in situations that require the user to take some immediate action; for instance, when the application has experienced a fatal error or the system has or is to crash. System alerts are managed entirely by Intuition. (See figure 7-3 for an example of an alert.)
Figure 7-3: The "Out of Memory" Alert The sudden display of an alert is a jarring experience for the user, and the system stops and holds its breath, while the alert is displayed. For these reasons, you should use alerts only when there is no other recourse. If you can, use requesters with warning messages instead. The alert display Iran it black background and red border, a 6.1 pixel resolution, and can be as tall as needed to display your text. The alert appears at the top of the video display. If the rest of' the display is still healthy, it is pushed down low enough to show the alert. If this is a fatal alert and the system is going down, the alert takes over the entire display.
There are two types of alerts: RECOVERY-ALERT, and DEADEND ALERT. o RECOVERY-ALERT displays your text and flashes the alert's border outline while waiting for the user to respond. This alert is optimistic and presumes that the system can continue operations after the alert is satisfied. It returns TRUE if the user presses the left mouse button in response to your message. Otherwise it returns FALSE. o DEADEND_ALERT prints your text and returns FALSE immediately. The Boolean function DisplayAlert() creates and displays an alert message. Your message will most likely get out to the screen regardless of the current state of the machine (with the exception of catastrophic hardware failures). If the user presses one of the mouse buttons, the display returns to its original state, if possible. DisplayAlert() also displays the Amiga system alert messages. DisplayAlert() needs three arguments: an AlertNumber, a pointer to a string, and a number describing the required display height. o AlertNumber is a LONG value. Here you set bits specifying whether this is a RECOVERYALERT or a DEADEND_ALERT. o The String argument points to an AlertMessage string that is made up of one or more substrings. Each substring contains the following: o The first component is a 16-bit x coordinate and an 8-bit y coordinate describing where on the alert display you want the string to appear. The y coordinate describes the location of the text baseline. The second component is the text itself. The string must be null-terminated (it ends with a zero byte). The last component is the continuation byte. If this byte is zero, this is the last substring in the message. If this byte is non-zero, there is another substring in this alert message.
o o
o The last argument, Height, tells Intuition how many display lines are required for your alert display.
Chapter 8
From the Intuition point of view, information flows through the system in the following steps (see figure 8-1):
o Information originates from somewhere in the user's cranial area. o From there, it flows through biological output devices such as fingers and into electro-mechanical input devices such as keyboards, mice, graphics tablets, and light pens. These input devices create input signals that enter the Amiga through several different ports. o Inside, these input signals are merged into a coherent stream of input events. o This input stream is examined and manipulated by several entities, including Intuition. Intuition gazes deeply into the essence of every event it sees. Sometimes it consumes events, other times it adds to the stream, and often it sits lazily by, watching the stream flow through its fourth dimension. o Finally, application programs receive the input stream and take action based on the data contained therein. The result of the action often involves creating output, which is presented to the user via a video monitor. o The user's eye input devices detect the information being displayed on the video output device. The eyes, and some still-mysterious merge mechanism, translate the data into signals that are transmitted to the brain, thus completing the cycle.
o The console device gives you "cooked" input data, including key-code conversions to ASCII and conversions to ANSI escape sequences (Intuition-generated events, such as CLOSEWINDOW, will be translated into escape sequences). When you want your program to present visual information to the user via your window or screen, you can choose from three methods. The one you choose depends on your particular needs. These three methods are: o Creating imagery by sending your output directly to the graphics, text, and animation primitives of the Amiga ROM kernel. You can use these for rendering functions like line drawing, area fill, specialized animation, and output of unformatted text. This is the most elementary method. o Using the Intuition-supplied support functions for rendering text, graphical imagery, and line drawing. These provide many of the same functions as the deeper ROM routines, but these routines do the clerical work of saving, initializing, and restoring states. Also, the image functions provide a new method of object-oriented rendering. o Outputting text via the console device, which formats text with special text primitives such as ClearEndOfLine() and text functions such as automatic line-wrapping and scrolling. For string output, if you want to do anything more than the simplest text rendering, you should use the console device. This gives you nicely formatted text with little fuss. Note that the console device is mentioned both as a source for input and as a mechanism for output. It is convenient to do both input and output via the console device only. In particular, text-only programs can open the console and do all their I/O there without ever learning anything about windows, bit-maps, or message ports. Use of the console device for most text-only applications is encouraged, since it requires less work on your part and simplifies the I/O logic of your programs. On the other hand, opening a console device consumes a fair amount of RAM (currently about 1.5K). If you do not need the console device or are willing to forego its features, it may be better for you to open the IDCMP for input and do your graphics rendering directly through the Intuition and graphics primitives. Under some conditions (for instance, when you have a complex program doing lots of different things), you might want to open both the console device and the IDCMP for input. There is no rule for deciding which mechanism you should use. After you read this chapter, you'll be able to decide for yourself. The following description of how I/O flow works with (and around) your program is actually a super-simplified model of how system-wide I/O really works, but it is a true representation of I/O at the microcosmic level of your program.
In the illustrations that follow, the input device is found at the top of the diagram. In this device mouse, keyboard, and other input events are merged into a single stream of input events, which is then submitted to Intuition for further processing.
Figure 8-2: Input from the IDCMP, Output through the Graphics Primitives
Figure 8-2 shows an example of a program after it has opened the IDCMP. This will be the typical configuration for games or other applications that are willing to process input data themselves. The IDCMP allows you to configure the events that are important to you. Your program can, for instance, learn about gadget events and get notification that it should stop writing to its window (the IDCMP flags SIZEVERIFY and REQVERIFY), but the program may not want to learn about other mouse or keyboard events. If you set up the program to learn about raw keyboard events through the IDCMP, note that the key codes received come straight from the keyboard to the program. These keycodes are as raw as they get, although the IDCMP also provides the special Qualifier field to assist your translations. Alternatively, you can receive keyboard events translated into ASCII (or some other standard). Messages sent via the IDCMP are instances of the structure IntuiMessage. When you open the IDCMP, you
must monitor the message port supplied by Intuition. Figure 8-3 illustrates the flow of information when the only the console is opened. This will be the typical configuration for text-only applications and applications that want the simplest I/O possible. Refer to the Amiga ROM Kernel Manual for details on opening a console device and performing I/O through it.
Figure 8-3: Input and Output through the Console Device Figure 8-4 shows a complex program that needs the features of both the console device and the IDCMP. An example might be a program that needs ASCII input and formatted output and the IDCMP verification functions (for example, to verify that it has finished writing to the window before the user can bring up a requester).
Figure 8-4: Full-system Input and Output (a Busy Program) Figure 8-5 shows an application that has opened a window with neither a console nor an IDCMP. This window gets no input, and the application can write to the window only via the graphics primitives. You might want to do this if your program has opened other windows that do I/O and you want special graphics-only windows (for instance, to monitor RAM usage or watch the clock) that you will close later. If the user selects a window that has no console or IDCMP, further input is discarded until a different window is selected.
The IDCMP consists of a pair of message ports, which are allocated and initialized by Intuition on your request: one port for you and one port for Intuition. These are standard Exec message ports, used to allow interprocess communications in the Amiga multitasking environment. To open these ports automatically, you set IDCMP flags in the NewWindow structure. To open or close them later, you call ModifyIDCMP(), which allocates or deallocates message ports or changes which events will be broadcast to your program through the IDCMP. Once the IDCMP is opened, you can receive many different flavors of information directly from Intuition, based on which flags you have set. As with much of Intuition, all of the "grunt work" with message ports is done for you, leaving you free to concentrate on more global issues. If you have a message port that you have already created, you can have Intuition use that port to communicate with you. This is described below. CAUTION: If you attempt to close the IDCMP, either by calling ModifyIDCMP() or by closing the window, without first having Reply()'d to all of the messages sent out by Intuition, Intuition will reclaim and deallocate those messages without waiting for a Reply() from you. If you attempt to Reply() after the close, you will get to watch the Amiga FIREWORKS DISPLAY mode. To learn more about message ports and message passing, please refer to the Amiga ROM Kernel Manual. INTUIMESSAGES The IntuiMessage data type is an Exec Message that has been extended to include Intuitionspecific information. The ExecMessage field in the IntuiMessage is used by Exec to manage the transmission of the message. The Intuition extensions of the IntuiMessage are used to transmit all sorts of information to your program. Here is what the IntuiMessage looks like: struct IntuiMessage { struct Message ExecMessage; ULONG Class; USHORT Code; USHORT Qualifier; APTR IAddress; SHORT MouseX, MouseY; ULONG Seconds, Micros; struct Window *IDCMP Window; struct IntuiMessage *SpecialLink; };
IntuiMessages contain the following components: ExecMessage The data in this field is maintained by Exec. It is used for linking the message into the system and broadcasting it to a message port. Class This is a ULONG variable whose bits correspond directly with the IDCMP flags. Code This is a USHORT variable whose bits contain special values, such as menu numbers or special code values, set by Intuition. The meaning of this field is directly tied to the Class (above) of this message. Often, there is no special meaning for the code field, and it is merely a copy of the code of the InputEvent initially sent to Intuition by the input device. When this message is of class RAWKEY, this field has the raw key code generated by the keyboard device. When this message is of class VANILLAKEY, this field has the translated character. Qualifier This contains a copy of the ie_Qualifier field that is transmitted to Intuition by the input device. This field is useful if your program handles raw key codes, since the Qualifier tells the program, for instance, whether or not the SHIFT key or CTRL key is currently pressed. MouseX and MouseY Every IntuiMessage you receive will have the mouse coordinates in these variables. The coordinates are relative to the upper left corner of your window. Seconds and Micros These ULONG values are copies of the current system clock time in seconds and microseconds. Microseconds range from zero up to one million minus one. The 32 bits allocated to the Seconds variable means that the Amiga clock can run for 139 years before wrapping around to zero again. IAddress This has the address of some Intuition object, such as a gadget or a screen, when the message concerns, for example, a gadget selection or screen operation. IDCMPWindow This contains the address of the window to which this message pertains.
IDCMP FLAGS
You specify the information you want Intuition to send you via the IDCMP by setting the IDCMP flags. You can set them either in the NewWindow structure when opening a window or when calling ModifyIDCMP() to change the IDCMP specifications. The following is a specification of the IDCMP functions and flags. Mouse flags: MOUSEBUTTONS This flag causes reports about mouse-button up and down events to be sent to you, if these transitions do not mean something to Intuition. When your program receives a MOUSEBUTTONS class of event, it can examine the Code field to discover which button was pressed or released. The Code field will be equal to SELECTDOWN, SELECTUP, MENUDOWN, or MENUUP. NOTE: If the user clicks the mouse button over a gadget, Intuition deals with it and your program does not hear about it. Also, the only way your program can learn about menu button events in this way is by setting the RMBTRAP flag in the window. See chapter 4, "Windows," for more information. MOUSEMOVE Reports about mouse movements are sent in the form of x and y coordinates. This can mean a lot of messages, so your program should reply to them swiftly. See the section called "An Example of the IDCMP," below. NOTE: This works only if the REPORTMOUSE flag is set in the NewWindow structure or if some gadget is selected with the FOLLOWMOUSE flag set. DELTAMOVE When this flag is set, mouse movements are reported as deltas (amount of change from the last position) rather than as absolute positions. This flag works in conjunction with the MOUSEMOVE flag. Note that delta mouse movements are reported even after the Intuition pointer has reached the limits of the display.
Gadget flags: GADGETDOWN Your program will receive a message of this class. when the user selects a gadget that was created with the GADGIMMEDIATE flag set. GADGETUP When the user releases a gadget that was created with the flag RELVERIFY set, your program will receive a message of this class. CLOSEWINDOW If the user has selected your window's close gadget, the message telling the program about it will be of this class. Menu flags: MENUPICK This flag indicates that the user has pressed the menu button. If a menu item was selected, the menu number of the menu item can be found in the Code field of the IntuiMessage. If no item was selected, the Code field will be equal to MENUNULL. MENU VERIFY This is a special verification mode which, like the others, allows your program to verify that it has finished drawing to your window before Intuition allows the users to start menu operations. This is a special kind of verification, however, in that any window in the entire screen that has this flag set will have to respond so that menu operations may proceed. Also, the active window of the screen is allowed to cancel the menu operation. This is unique to MENUVERIFY. Please refer to chapter 6, "Menus," for a complete description. See the "Verification Functions" section below for some things to consider when using this flag.
Requester flags: REQSET Set this flag to receive a message when the first requester opens in a window. REQCLEAR Set this flag to receive a message when the last requester is cleared from the window. REQVERIFY Set this flag if you want your application to make sure that other rendering to its window has ceased before a requester is rendered in the window. This includes requiring the system to get your approval before opening a system requester in your window. With this flag set, Intuition sends the application a message that a requester is pending, and then Wait()s for the application to Reply() before drawing the requester in the window. If several requesters open in the window, Intuition asks the application to verify only the first one. After that, Intuition assumes that all output is being held off until all the requesters are gone. You can set the REQCLEAR flag to find out when all requesters are removed from the window. Once the application receives a message of the type REQCLEAR, it is safe to write to the window until another REQVERIFY is received. You can also check the INREQUEST flag of the window, although this is not as safe a method because of the asynchronous nature of any multitasking environment. See the "Verification Functions" section below for some things to consider when using this flag. Window flags: NEWSIZE Intuition sends your program a message after the user has resized the window. After receiving this, the program can examine the size variables in the window structure to discover the new size of the window. REFRESHWINDOW A message is sent to the application whenever your window needs refreshing. This flag makes sense only with windows for which the SIMPLE_REFRESH or SMART REFRESH type of refresh has been selected. SIZEVERIFY You set this flag if your program is drawing to the window in such a way that the drawing must be finished before the user sizes the window. If the user tries to size the window, a message is sent to the application and Intuition will Wait() until the program replies.
See the "Verification Functions" section below for some things to consider when using this flag. ACTIVEWINDOW and INACTIVEWINDOW Set these flags to discover when your window becomes activated or inactivated. Other flags: VANILLAKEY This is the raw keycode RAWKEY event translated into the current default. character keymap of the console device. In the USA, the default keymap is ASCII characters. When you set this flag, you will get IntuiMessages with the Code field containing a character representing the key struck on the keyboard. RAWKEY Keycodes from the keyboard are sent in the Code field. They are raw keycodes, so you may want the program to process them. The Qualifier field contains the information generated by the input device about this key. NEWPREFS When the user changes the system Preferences by using the Preferences tool, or when some other routine causes the system Preferences to change, you can make sure your program finds out about it by setting this flag. When your program gets a message of class NEWPREFS, it can call the procedure GetPrefs() to get the new Preferences. NOTE: Everyone who sets this flag will learn about these events, not just the active window. DISKINSERTED and DISKREMOVED When the user inserts or ejects any disk with any drive, the program will be told about the event if either or both of these flags are set. NOTE: Everyone who sets these flags will learn about these events, not just the active window. INTUITICKS This gives you simple timer events from Intuition when your window is the active one; it may help you avoid opening and managing the timer device. With this flag set, you will get only one queued-up INTUITICKS message at a time. If Intuition notices that you've been sent an INTUITICKS message and haven't replied to it, another message will not be sent. Intuition receives timer events ten times a second (approximately).
Verification Functions SIZEVERIFY, REQVERIFY, and MENUVERIFY are exceptional in that Intuition sends an IntuiMessage and then waits, by calling the Exec message port function Wait(), for the application to reply that it is all right to proceed. The application replies by calling the Exec message passing function ReplyMsg(). The implication is that the user requested some operation but the operation will not happen immediately and, in fact, will not happen at all until your application says it is safe. Because this delay can be frustrating and intimidating, you should strive to make the delay as short as possible. Your program should always reply to a verification message as immediately as possible. You can overcome these problems by setting up a separate task to monitor the IDCMP and respond to incoming IntuiMessages immediately. This is recommended whenever you are planning heavy traffic through the IDCMP, which occurs when you have set many IDCMP flags.
1. Define the window with the variable IDCMPFlags set to NULL, which means no ports will be opened. 2. Set the UserPort variable of the window to any valid port of your own choosing. 3. Call ModifyIDCMP() with the flags set as you wish. When Intuition sees that the UserPort variable is non-null, it will assume that the variable points to a valid message port. When Intuition sees that the WindowPort variable is still NULL, a message port will be created. 4. Later, before calling CloseWindow(), set UserPort equal to NULL. Intuition will delete the WindowPort and will detect that the UserPort is not there to be deleted.
FOREVER { /* Wait until some message arrives at the port */ Wait(1 << MyWindow->UserPort->mp_SigBit); /* Now, one or more messages have arrived. Respond to all of them. * First, set up to accumulate mouse moves (rather than responding * to each one as it comes in) */ MouseMoved = FALSE; while (message = GetMsg(MyWindow->UserPort)) { /* First, gather some relevant information and then reply right away!*/ class = message->Class; code = message->Code; address = message->IAddress; x = message->MouseX; y = message- >MouseY; ReplyMsg(message); if (class = = MOUSEMOVE) MouseMoved = TRUE; else (ProcessMessage(class, code, address, x, y)); } /* If the mouse moved during the loop, respond to it now*/ if (MouseMoved) ProcessMove(x, y); }
o Opening the console as an AmigaDOS file. Doing console input and output via AmigaDOS file-handling is simple and convenient. Also, you get special line-edit capabilities when opening an AmigaDOS console. Opening a console as an AmigaDOS file has, however, two limitations. File I/O requires more processing overhead than going straight to the console device. Also, your program must be in an AmigaDOS environment (AmigaDOS must be active), which will not be the case for those of you who want your applications to take over the machine. o Opening the console device directly. When you open the console device directly, you have direct control over the parameters and use of the console input and output. Opening the console device directly is more involved than opening a file; you have to open the device and then send packets of information using a special data structure. Also, you do not have the special line-edit capabilities.
Reading from the Console Device When you want to read from or write to the console device, you use the same IOStdReq data structure information that was created by the call to OpenDevice(), with the following extra initializations: o Set the io_Data field to point to your buffer. A buffer is a block of memory that will be used to receive the characters from the console device. o Set the io_Length field of the IOStdReq equal to the number of bytes in your buffer. The console device will not write more bytes than this into the buffer. o Set the io_Command field to the constant CMD_READ. After you initialize the IOStdReq structure with your buffer information, you call either the SendIO() or DoIO() function to read in any characters that are waiting to be read. The difference between SendIO() and DoIO() is that SendIO() is asynchronous, which means that while the console device monitors the keyboard, the program does other processing and checks later to see whether or not the user has typed something. DoIO(), on the other hand, is synchronous, which means that when DoIO() is called control does not return to the program until the user has typed something. After the call to one of the input routines, your program can examine the io_Actual field to discover how many characters were actually written into your buffer. Writing Text to Your Window via the Console Device You can write characters to your window or do special formatting by writing control escape sequences to the console device. Control escape sequences are special sequences of characters that start with the "escape" character, which is a character with the byte value of 155 (that is 0x9B in hex). This character is also known as the control sequence introducer, or CSI. When you want to write to the console device, you use the same IOStdReq data structure information that was created by the call to OpenDevice(), with the following extra initializations: o Put the characters (and control escape sequences) you want written to your window into a buffer and put the address of the buffer into the io_Data field of the IOStdReq structure.
o Initialize the field io_Length with the number of characters that are found in the io_Data buffer. Alternatively, if your text is null-terminated, you can specify a length of -1 and let the console device figure out the length for you. o Set the io_Command field to CMD_WRITE. Text is written entirely within the non-border area of a window (it does not matter what sort of refresh mode the window has). When writing text with the console device, you never have to worry about the text being written over the gadget imagery in the borders of the window. Character-wrap is supported at edge-of-window boundaries. Character-wrap is a special feature of all of the console devices that allows the devices to behave like virtual terminals. When this feature is present, if a character to be written will not fit in the remaining space of the current line, the console device will write the character in the first position of the next line instead. Compare this with writing text directly into a window using the text primitives: if your character string reaches the boundary of the window, it will be written out in the invisible space beyond the window. The control escape sequences can be used for special text operations, such as LINE FEED, CLEAR END OF LINE, and cursor movements. The complete list of control functions available from the console device is quite long; refer to the Amiga ROM Kernel Manual.
You can see the current keymap table by using the CDAskKeyMap() routine, which returns a copy of the table. You can set your own keymap by calling the CDSetKeyMap() routine with your own table.
Chapter 9
Intuition provides two approaches to producing graphics images, lines, and text in displays. For quick and easy rendering, you can use Intuition's high-level data structures and functions. You are also free to use all of the lower-level Amiga graphics, animation, and text primitives. This chapter shows you how to use the Intuition structures and functions, but the Amiga primitives are a large topic in themselves and the discussion here can only point the way. You will find instructions for using the primitives in the Amiga ROM Kernel Manual.
have numerous gadgets of the same size, you can use the same Border coordinate pairs to draw a line around each gadget. An important fact about the illustration elements is that each can point to another of its own kind. You can link many of them together and have them all drawn with just one procedure call.
CREATING BORDERS
Although this data structure is called a Border, it is actually a general-purpose structure for drawing connected lines at any angles and rendering any arbitrary shape made up of groups of connected lines. It is called a border because that is how it started out. To define a Border, you specify the following: o A set of x and y offsets to the beginning point of the line. o A set of coordinate pairs for each vertex.
o Two colors and a drawing mode: o o o A color for the lines. A color that can be used for background areas enclosed within lines. One of several drawing modes.
o An optional pointer to another instance of Border. Border Coordinates Intuition draws lines between points that you specify as as sets of x,y coordinates. The Border variables LeftEdge and TopEdge contain offsets to the first pair of coordinates. The XY field contains a pointer to an array of coordinate pairs. All of these coordinates are offsets from the top left corner of the element that contains the line. Thus, you can define one line and use it in different display elements or use it many times in the same element. The first coordinate pair describes the starting point of the first line. Every coordinate pair after the first describes the ending point of the current line and, if there is another coordinate pair, the starting point of the next line. Here is an example. Consider a gadget whose select box is 140 pixels wide and 80 pixels high. The top left corner of the gadget's select box is located in a window at position (10,5). If the border's (LeftEdge, TopEdge) coordinates are (10,10), this results in an absolute base position of (10+10,5+10), or (20,15), as shown in figure 9-1. The (LeftEdge, TopEdge) coordinate pair defines the absolute base pixel for this border. All coordinate pairs of the border are relative to this paint. If the first set of coordinates in the array of coordinates is (0,5), the starting point of the first line will be at (20+0,15+5), or (20,20). If the next coordinate pair is (15,5), the end point of the first line will be at (20+15,15+5), or (35,20). A line will be drawn from absolute position (20,20) to absolute position (35,20). If there is one last coordinate pair, (15,0), the next point is at (20+15,15+0), or (35,15). A second line segment is drawn from (35,20) to (35,15).
Figure 9-1: Example of Border Relative Position For a border that is outside the select box of a gadget, you can specify negative offsets. For example, starting position (-1,-1) for a gadget border is just outside the gadget select box. Border Colors and Drawing Modes Intuition uses the current set of colors in the color register to draw the border and, optionally, to draw its background. As usual, the available colors depend upon the number of bit-planes used in the screen. For instance, if the screen has five bit-planes, then you can select from the colors in color registers 0 through 31. The lines are always drawn in the color in the FrontPen field. Two drawing modes pertain to border lines: JAM1, and XOR. To draw the line in your choice of color, use JAM1. You can choose to have the line "invert" the color of the pixels over which it is drawn by selecting the XOR drawing mode. If you use XOR mode, for every pixel the line is drawn over, the data bits of the pixel are changed to their binary complement. The complement is formed by reversing all the 0 bits and 1 bits in the binary representation of the color register number. In a three-bit-plane display, for example, color 6 is 110 in binary. If a pixel is color 6, it will be changed to the complement of 001 (binary), which is color 1.
Linking Borders Together The NextBorder field can point to another instance of a Border structure. This allows you to link borders together to describe complex line-drawn shapes. Having multiple borders allows you to draw multiple, distinct groups of lines, each with its own set of line segments and its own color and draw mode. For example, you may want a double border to make a requester stand out more from the surrounding display. You can define the inner border in a second Border structure and link it to the first structure by using this field. Border Structure Definition Here is the specification for a Border structure: struct Border { SHORT LeftEdge, TopEdge; SHORT FrontPen, BackPen, DrawMode; SHORT Count; SHORT *XY; struct Border *NextBorder }; The meanings of the fields in the Border structure are: LeftEdge, TopEdge This field gives the starting origin for the border as an offset from the top left of the containing element. LeftEdge is the x coordinate and TopEdge is the y coordinate for the top left bit of the image. This field can contain integers or constants. LeftEdge This field contains the number of pixels from the left edge of the containing element. TopEdge This field specifies the number of lines from the top line of the containing element.
FrontPen, BackPen, DrawMode FrontPen is the color used to draw the line. The pen color fields contain integers or constants that correspond to color registers. BackPen is currently unused. You set the DrawMode field to one of the following: JAM1 This specification uses FrontPen to draw the line and makes no change in the background. XOR This specification changes the background beneath the line to its binary complement. NextBorder This field is a pointer to another instance of a Border structure. Set this field to NULL if there is no other Border structure or if this is the last Border structure in the linked list. XY This field is a pointer to an array of coordinate pairs, one pair for each line. Count This field specifies the number of pairs in the array of coordinate pairs; the field contains an integer or constant.
CREATING TEXT
The IntuiText structure provides a simple way of writing text strings anywhere in your display. For example, an array of IntuiText strings is handy in creating menus. To define and display IntuiText, you specify the following: o Colors for the text and, optionally, for the text's background. o One of three drawing modes. o The starting location for the text.
o The default font or your own special font. o A pointer to another instance of IntuiText (if any). Text Colors and Drawing Modes As with border colors, Intuition uses the current set of colors in the color register to write the text and, optionally, to draw its background. As usual, the available colors depend upon the number of bit-planes used in the screen. For instance, if the screen has five bit-planes, you can select from the colors in color registers 0 through 31. The text is usually drawn in the color in the FrontPen field. Text characters in general are made of two areas: the character image itself and the background area surrounding the character image. In addition to the two drawing modes for borders, JAM1 and XOR, you also have JAM2. These modes are described in the following paragraphs. If you select JAM1 drawing mode, the text character images, but not the character background areas, will be drawn. The character image is drawn in FrontPen color. Because the background of a character is not drawn, the pixels of the destination memory around the character image are not disturbed. This is called overstrike. If you select JAM2 drawing mode, the character image is drawn in FrontPen and the character background is drawn in the color in the BackPen field. Using this mode, you completely cover any graphics that previously appeared beneath the letters. If the drawing mode is XOR, the character is drawn in the binary complement of the colors at its destination. The destination is the display memory where the text is drawn. FrontPen and BackPen are ignored. To form the complement, you reverse the all the 0 bits and 1 bits in the binary representation of the color register number. In a threebit-plane display, for example, color 6 is 110 in binary. The complement is 001 (binary), which is color 1.
Starting Location
The starting TopEdge for a text string is the topmost pixels of the tallest characters. Note that this is different from the baseline of the text. The baseline is the horizontal line on which the characters and punctuation marks rest. The system default fonts are designed to be both above and below the baseline. The descenders of letters (the part of certain letters that is usually below the writing line, like the tail on the lower-case "y") are rendered below the base line. Therefore, you need to allow for this in drawing text in the display. For more information about text imagery, refer to the Amiga ROM Kernel Manual. Fonts You can use the default font, as set by Preferences, or you can have your own custom font in a FontDesc structure and use the TextAttr field to point to the custom font. For more information about custom fonts, see the Amiga ROM Kernel Manual. IntuiText Structure Here is the specification for an IntuiText structure: struct IntuiText { UBYTE FrontPen, BackPen; UBYTE DrawMode; SHORT LeftEdge; SHORT TopEdge; struct TextAttr *ITextFont; UBYTE *IText; struct IntuiText *NextText; }
The meanings of the fields in the IntuiText structure are as follows. FrontPen, BackPen FrontPen is the color used to draw the text. BackPen is the color used to draw the background for the text, if JAM2 drawing mode is specified. These fields contain integers or constants that correspond to color register numbers. DrawMode This field specifies one of three drawing modes: JAM1 FrontPen is used to draw the text; background color is unchanged. JAM2 FrontPen is used to draw the text; background color is changed to the color in BackPen. XOR The characters are drawn in the complement of the background. LeftEdge This field specifies the starting position for the text as an offset from the left corner of the containing element. The field contains an integer or constant, which is the number of pixels from left edge of containing element. TopEdge This field specifies the starting position for the text as an offset from the top line of the display element. The field contains an integer or constant, which is the number of lines from the top line of the containing element. TextAttr This field is a pointer to a TextAttr structure containing your own font description. Set this to NULL if you want the default font. IText This field is a pointer to null-terminated text.
NextText This field is a pointer to another instance of IntuiText, if this text is part of a linked list of text strings. Set this field to NULL if this text is not part of a list or if it is the last structure in the list.
CREATING IMAGES
With an Image structure you can create graphics objects quickly and easily and display them almost anywhere. Images have an additional attribute that makes them even more economical with one minor change in the structure, you can display the same image in different colors within the same display element. To define and display an image, you specify the following: o The location of the image within the display element. o The width and height of the image and the data to create it. o The depth of the image that is, how many bit-planes are used to define it. o The bit-planes in the display element that are used to display the image. This determines the colors in the image. Image Location You specify a location for the image that places its top left corner as an offset from the top left corner of the element that contains the image. Defining Image Data To create the data for your image, you write is and 0s into a block of 16-bit memory words, which are located at sequentially increasing addresses. When the image is displayed, this sequential series of memory words is organized into a rectangular area, called a bit-plane. You can have up to six bit-planes in an image; they are drawn together when the image is displayed.
The color of each pixel in the image is directly related to the value in one or more memory bits, depending upon how many bit-planes there are in the image data and in which bit-planes of the screen or window you choose to display your image. The color of a given pixel is determined by one or more data bits. Each bit in the pixel is taken from the same position in each of the bit-planes used to define the image. For each pixel, the system combines all the bits in the same position to create a binary value that corresponds to one of the system color registers. This method of determining pixel color is called color indirection, because the actual color value is not in the display memory. Instead, it is in color registers that are located somewhere else in memory. If an image consists of only one bit-plane and is displayed in a one-bit-plane display, then: o Wherever there is a 0 bit in the image data, the color in color register 0 is displayed. o Wherever there is a 1 bit, the color in color register 1 is displayed. In an image composed of two bit-planes, the color of each pixel is obtained from a binary number formed by the values in two bits, one from bit-plane 0 and one from bit-plane 1. If bit-plane 0 contains all is and bit-plane 1 contains 0s and 1s, the pixels derive their colors from register 1 (binary 01) and register 3 (binary 11). You create your image data by giving Intuition a series of data words. Before specifying these numbers, you may find it helpful to lay out your image on graph paper, or to use one of the Amiga art tools to assist you. For example, figure 9-2 shows the layout for the system sizing gadget, which is a one-bit-plane image.
Figure 9-2: Intuition's High-resolution Sizing Gadget Image In hex notation, the data words of the sizing gadget image are defined as follows: USHORT SizeData[] = { 0xFFFF, 0xC0FF, 0xCCFF, 0x0003, 0xFCF3, 0xFCF3, 0xFCF3, 0xFC03, 0xFFFF, }; In the image data, you need to specify enough whole words to contain the image width. For example, an image 7 bits wide requires one word per line, whereas an image 17 bits wide requires two words per line. In the Width field of the Image structure, you specify the actual width in pixels of the widest part of the image, not how many pixels
contained in the words that define the image. The Height field contains the height of the image in pixels. Here is the actual Image structure of the system-sizing gadget. The last two fields in the structure, PlanePick and PlaneOnOff, are explained in the next section. struct Image Sizelmage = { 0, 0, /* left top */ 16, 9, 1, /* width, height, depth */ &SizeData[0], /* Address 0x1, 0x0, /* PlanePick, PlaneOnOff */ NULL, /* Nextlmage */ }; Picking Bit-Planes for Image Display You use the PlanePick and PlaneOnOff fields in the Image structure to specify which bitplanes of the containing window or screen are used to display the image. This gives you great flexibility in using Image structures. You can: o Draw an image into a screen or window of any depth (if you have designed it properly). o Make one image and display it in different colors. o Minimize the amount of memory needed to define a simple image that is destined for a display of multiple bit-planes. PlanePick "picks" the bit-planes of the containing window or screen RastPort that will receive the bit-planes of the image. PlaneOnOff specifies what to do with the window or screen bit-planes that are not picked to receive image data. For each display element plane that is "picked" to receive data, the next successive plane of image data is drawn there. For every bit-plane not picked to receive image data, you tell Intuition to fill the plane with 0s or is. For both variables, the binary form of the number you supply has a direct correspondence to the bit-planes of the window or screen containing the image. The lowest bit position corresponds to the lowest-numbered bit-plane. For example, for a window or screen with three bit-planes (consisting of Planes 0, 1, and 2), all the possible values for PlanePick or PlaneonOff and the planes picked are as follows.
PlanePick or PlaneOnOff 000 001 010 011 100 101 110 111
Planes Picked No planes Plane 0 Plane 1 Planes 0 and 1 Plane 2 Planes 0 and 2 Planes 1 and 2 Planes 0, 1, and 2
The system sizing gadget shown above has only one bit-plane of data. To display this gadget in plane 0 of a four-bit-plane window using color 1 for the image and color 0 for its background, you set PlanePick to 0001 (binary) and PlaneOnOff to 0000 (binary). These settings give Intuition the following instructions: o Display the data that describes the image in plane 0 of the destination RastPort. o For all of the other planes in the RastPort, set the bits in the area where the image is displayed to 0. Figure 9-3 illustrates the discussion in the preceding paragraphs.
Figure 9-3: Example of PlanePick and PlaneOnOff If you want the sizing gadget to be drawn in color 2 and its background drawn in color 0, you need to define pixels whose values are 0010 and 0000. To do this, simply change PlanePick to 0010. If you want color 3 for the sizing gadget and color 1 for its background, you need to define pixels with values 0011 and 0001. Therefore, plane 1 defines the image and plane 0 has to be all 1s. You can achieve this by setting PlanePick to 0010 and PlaneOnOff to 0001. If you want an image that is simply a filled rectangle, you need not supply any image data at all. You specify a Depth of zero, set Width and Height to any size you like, and set PlanePick to 0000 since there are no planes of image data to pick. Then, set PlaneOnOff to the color you want for the rectangle. To see how a gadget like this looks, refer to the "Requester Deluxe" illustration, figure 7-1, in chapter 7, "Requesters and Alerts."
Image Structure Here is the specification for an Image structure: struct Image { SHORT LeftEdge, TopEdge; SHORT Width, Height, Depth; SHORT *ImageData; UBYTE PlanePick, PlaneOnOff; struct Image *NextImage; };
The meanings of the fields in the Image structure are: LeftEdge, TopEdge These are offsets from the top left of the display element. These fields contain integers or constants: LeftEdge This field contains the number of pixels from the left edge of the display element. TopEdge This field contains the number of lines from the top line of the display element. Width This field contains the width of the actual image in pixels. The field contains an integer or constant. Height, Depth These fields specify the height of the image in planes needed to define the image. These fields contain integers or constants. ImageData This field is a pointer to the actual bits defining the image.
PlanePick, PlaneOnOff PlanePick tells which planes of the containing element you pick to receive planes of image data. PlaneOnOff tells what to do about the planes that are not picked. These fields represent bit-plane numbers. Image Example A more complex example of an image is presented below. The image shown in figure 9-4 belongs to one of the system depth-arrangement gadgets (the front gadget, which brings a window or screen to the front of the display).
Its data structure and data definition look like this: USHORT UpFrontData[] = { 0x3FFF, 0xFF3C, 0x3000, 0x3F3C, 0x3000, 0x033C, 0x303F, 0xF33C, 0x303F, 0xF33C, 0x303F, 0xF33C, 0x303F, 0xF33C, 0x3F3F, 0xF33C, 0x3F00, 0x033C, 0x3FFF, 0xFF3C, /**/ 0x0000, 0x0000, 0x0FFF, 0xC000, 0x0F00, 0x0000, 0x0F00, 0x0000, 0x0F00, 0x0000, 0x0F00, 0x0000, 0x0F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; struct Image UpFlmage = { 0, 0, /* left top */ 29, 10, 2, /* width, height, depth */ &UpFrontData[0], /* image data */ 0x3, 0x0, /* PlanePick, PlaneOnOff */ NULL, /* Nextlmage */ }; This gadget was designed to look good in a window or screen of any depth. PlanePick 0x3 (000011) picks planes 0 and 1 of the destination RastPort for planes 0 and 1 of the gadget. If this gadget is displayed in a window or screen of depth 1, only plane 0 of its data is displayed. Color 0 is used for the background and color I for the imagery.
If this gadget is displayed in a window or screen of depth 2 or more, both planes are displayed. The resulting colors are 0 for the background and 1 and 2 for the imagery. Image Memory An extra requirement is imposed on image data (and on sprite data). It must be located in chip memory, which is memory that can be accessed by the special Amiga hardware chips. Chip memory is in the lower 512 Kbytes of RAM. In expanded machines (the Amiga can be expanded up to 8,000 Kbytes), the Amiga chips still cannot address memory locations greater than the 512-Kbyte limit. In hexadecimal notation, 512 K spans memory addresses $00000 to $7FFFF. To write a program that will survive in any possible configuration of Amiga hardware, you are obliged to ensure that your image and sprite data resides in this chip memory. You can make sure that your data is in chip memory by using the ATOM tool on the file containing the data. The loader will then automatically load that portion of your program into chip memory. See the AmigaDOS User's Manual for information about ATOM and the loader. As of the time of this writing, the only way to check whether your data is in chip memory is by comparing its load address after it has been loaded into Amiga memory. If the address of the end of your data is less than $80000, you are safe. If the address is equal to or greater than $80000, you must allocate chip memory and copy your data into the new location. To allocate chip memory, call the Exec function AllocMem() with MEMF_CHIP as the requirements argument.
DrawImage (RPort, Image, LeftOffset, TopOffset) This function moves the Image data into the RastPort of the screen or window. RPort = pointer to the RastPort. Image = pointer to an Image structure. LeftOffset = offset added to the Image's x coordinate. TopOffset = offset added to the Image's y coordinate. DrawBorder (RPort, Border, LeftOffset, TopOffset) This function draws the vectors of the Border into the window or screen RastPort. RPort = pointer to the RastPort. Border = pointer to a Border structure. LeftOffset = offset added to each vector's x coordinate. TopOffset = offset added to each vector's y coordinate. PrintIText (RPort, IText, LeftOffset, TopOffset) This function prints IntuiText into the window or screen RastPort. RPort = pointer to the RastPort to receive the text. IText = pointer to an IntuiText structure. LeftOffset = offset added to IntuiText x coordinate. TopOffset = offset added to IntuiText y coordinate.
Obtaining the Width of a Text String IntuiTextLength (IText) IntuiTextLength (IText) This function returns the width of an IntuiText in pixels. Itext is a pointer to an instance of an IntuiText structure. Obtaining the Address of a View or ViewPort ViewAddress() This function returns the address of the Intuition View structure for any graphics, text, or animation primitive that requires a pointer to a View. ViewPortAddress (window) This function returns the address of the screen ViewPort associated with the specified window for any graphics, text, or animation primitive that requires a pointer to a ViewPort.
You can obtain a pointer to any window or screen RastPort or ViewPort by using instructions like those below: o Pointers to window RastPort and ViewPort: struct Window *MyWindow; struct RastPort *MyRPort; struct ViewPort *MyVPort; struct View *BigView; MyWindow = OpenWindow(...); MyRPort = MyWindow->RPort; MyVPort = ViewPortAddress(MyWindow); BigView = ViewAddress(); o Pointers to screen RastPort and ViewPort: struct Screen *MyScreen; struct RastPort *MyRPort; struct ViewPort *MyVPort; struct View *BigView; MyScreen = OpenScreen(...); MyRPort = &My Screen->RastPort; MyVPort = &MyScreen->ViewPort; BigView = ViewAddress(); The Intuition function ViewPortAddress() returns the address of a window's ViewPort. A View structure is a linked list of one or more ViewPorts. Intuition's View is a linked list of all the display structures that you use in your Intuition-based program. The function ViewAddress() returns the address of the Intuition View structure. When you use graphics primitives to draw directly into a window RastPort and you allow the user to size or move the window, the underlying screen display is destroyed. A blank background is displayed in the areas uncovered when the screen is sized or moved. If this is a problem for your program, you can overcome it by opening windows that cannot be moved or sized. If a graphics routine requires the allocation and initialization of other graphics mechanisms TmpRas structure, Gelslnfo, AreaFill buffers, UserCopperList or the like you set these up as usual as described in the Amiga ROM Kernel Manual.
Chapter 10
In the Intuition sytem, the mouse is the normal method of making selections. This chapter describes how users employ the mouse to interact with the system and your programs and how you can arrange for your program to use the mouse in other ways. It also describes the use of the keyboard as an alternate means of input.
Table 10-1: Mouse Activities Action Pressing a button Explanation Positioning the pointer while holding down a button. The action specified by the position of the pointer can continue to occur until the button is released, or alternatively may not occur at all until the button is released. Positioning the pointer and quickly pressing and releasing one of the mouse buttons. Positioning the pointer and pressing and releasing a mouse button twice. Positioning the pointer over some object, pressing a button, moving the mouse to a new location, and releasing the button.
The left mouse button is most often used for selection. The right mouse button is most often used for information transfer. The terms selection and information are intentionally left open to some interpretation, as it is impossible to imagine all the uses you will find for the mouse buttons. The selection/information paradigm can be crafted to cover
most interaction between the user and your program. You are encouraged, when designing mouse usage, to emphasize this model. It will help the user to understand and remember the elements of everyone's design. When the user presses the left button, Intuition examines the state of the system and the position of the pointer. Intuition uses this information to decide whether or not the user is trying to select some object, operation, or option. For example, the user positions the pointer over a gadget and then presses the left button to select that gadget. Alternatively, the user may position the pointer over a window and press the select button to activate the window. If the user moves the mouse while holding down the select button, this sometimes means that the user wants to select everything that the pointer moves over while the button is still pressed. The right mouse button is used to initiate and control information-gathering processes. Intuition uses this button most often for menu operations. Pressing the right button usually displays the active window's menu bar over the screen title bar. Moving the mouse while holding down the right button sometimes means that the user wishes to browse through all available information; for example, browsing through the menus. Double-clicking the right mouse button can bring up a special requester for extended exchange of information. This requester is called the double-menu requester, because of the double-click of the menu button required to reveal it, and because this requester is like a super menu through which a complex exchange of information can take place. Because the requester is used for the transfer of information, it is appropriate that this mechanism is called up by using the right button. Your program can receive mouse button and mouse movement events directly. If you are planning to handle mouse button events yourself, you should continue the selection/information model used by Intuition. You can combine mouse button activations and mouse movement to create compound instructions. Here is an example of how Intuition combines multiple mouse events. While the right button is pressed to reveal the menu items of the active window, the user can press the left button several times to select more than one option from the menus. Also, you can allow the user to move objects or select multiple objects by moving the mouse while holding down the buttons. As another example, consider the Workbench tool. To move an object on the Workbench screen, the user places the pointer within the object's icon, presses the left button, and moves the pointer. When the icon is in the desired location, the user releases the button. Dragging can have different effects, depending on the object being dragged. To move a window to another area of the screen, the user positions the pointer within the window's drag gadget and drags the window to a new position. To change the size of a window, the user positions the pointer within the size gadget and drags the window to some smaller or larger size. In drag selection, the user can hold down both buttons while in
menu mode and move the pointer across the menu display, making multiple selections with one stroke.
Mouse Messages
Mouse events are broadcast to your program via the IDCMP or the console device. See chapter 9, "Input and Output Methods," for information on how to receive communications. Simple mouse button activity not associated with any Intuition function will be reported in IntuiMessages as the event class MOUSEBUTTONS, with the codes SELECTDOWN, SELECTUP, MENUDOWN, and MENUUP to specify changes in the state of the left and right buttons, respectively. Mouse button activity over your gadgets is reported with a class of GADGETDOWN or GADGETUP, and the IAddress field (or EventAddress field of InputEvents) has the address of the selected gadget. Menu selections appear with a class of MENUPICK, with the menu number in the Code field. Your program receives mouse position changes in the event class MOUSEMOVE. The MouseX and MouseY position coordinates describe the position of the mouse relative to the upper left corner of your window. These coordinates are always in the resolution of the screen you are using, and may represent any pixel position in your screen, even though the hardware sprites can be positioned only on the even-numbered pixels of a high-resolution screen and on the even-numbered rows of an interlaced screen. To get mouse movement reported as deltas (amount of change from the last position) instead of as absolute positions, you can use the IDCMP flag, DELTAMOVE.
These special command keys (and their flags) are shown in table 10-2.
Explanation The associated Qualifier flag is the CONTROL flag. Please note that there are two separate ALT keys, one on each side of the space bar. These can be treated distinctly. Your program can detect which one was pressed by examining the LALT and RALT commands for the Left ALT and Right ALT keys respectively When this key is struck, its keycode is entered into the input stream as an actual keystroke. Shortcut methods for entering commandkey sequences starting with the ESC key. There are two Amiga keys, one on each side of the space bar. These, like the ALT keys, are distinctly identifiable. The Left AMIGA key is recognized by the Qualifier flag LCOMMAND, and the Right AMIGA key by RCOMMAND.
escape
ESC
function
F1 to F10
AMIGA
Fancy A
Certain command-key sequences starting with one of the AMIGA keys have special meaning to Intuition. Most notably, these involve shortcuts and alternatives to using the mouse, as described in the following section.
It is recommended that you abide by certain command-key standards to provide a consistent interface for Amiga users. Chapter 12, "Style," contains a complete list of the recommended standards.
Chapter 11
OTHER FEATURES
Style 211
o The other use is to do a series of memory allocations and abandon it in midstream easily, if you must. Say that you're doing a long series of allocations in a procedure (for example, the Intuition OpenWindow() procedure), and you detect some error condition, such as "out of memory." When aborting, you should free up any memory that you have already managed to allocate. These procedures allow you to free up that memory easily, without being required to keep track of how many allocations you have already done, the sizes of the allocations, and where the memory was allocated.
HOW TO REMEMBER
You create the "anchor" for the allocation master list by creating a variable that is a pointer to the data structure Remember and initializing that pointer to NULL. This variable is called the RememberKey. Whenever you call AllocRemember(), the routine actually does two memory allocations, one for the memory you want and the other for a copy of a Remember structure. The Remember structure is filled in with data describing your memory allocation, and it is linked into the master list to which your RememberKey points. Then, to free up any memory that has been allocated, all you have to do is call FreeRemember() with your RememberKey. See the Amiga ROM Kernel Manual for a description of the AllocMem() call and the values you should use for the Size and Flags variables.
Style 213
RememberSize This is the size of the memory remembered by this node. Memory This is a pointer to the memory remembered by this node.
AN EXAMPLE OF REMEMBERING
struct Remember *RememberKey; UBYTE *MemAPointer, *MemBPointer; RememberKey = NULL; MemAPointer = AllocRemember(&RememberKey, BUFSIZE, MEMF_CHIP); MemBPointer = AllocRemember(&RememberKey, BUFSIZE, MEMF_CHIP); /* Use the memory for various things ... */ /* and finally, give up the memory ... */ FreeRemember(&RememberKey, TRUE);
Preferences
Preferences is a program that lets the user see and change many system-wide parameters on the Amiga. Users can also edit the standard Intuition pointer image and colors. You have access to the Command Line Interface (CLI) through Preferences, by setting a flag that allows the CLI icon to be visible on the Workbench display. (See the AmigaDOS manuals for more information about the CLI.) The user invokes Preferences to make settings and your program can call GetPrefs() to find out what settings the user has made. In a system in which the user does not use Preferences, you can call GetDefPrefs() to find out the Intuition default Preference settings. If you are using the IDCMP for input, you can set the IDCMP flag NEWPREFS. With this flag set, your program will receive an IntuiMessage telling it that there is a new set of Preferences for it to examine. To get the new settings, the program then calls GetPrefs().
Developers of printer driver programs should always call GetPrefs() just before every print job. The user may change to a different printer and run Preferences to modify the printer settings. When Intuition is initialized (when the system is reset), you can call GetDefPrefs() to find the default Preferences settings that Intuition uses when it is first opened. Then, under AmigaDOS, Intuition is configured according to the set of Preferences that are saved on the start-up disk. Upon invoking the Preferences tool, the user is shown a screen full of gadgets and can change settings by selecting and playing with the gadgets. In some cases, a requester appears after the user selects a gadget. Figure 11-2 shows the main Preferences display.
Figure 11-2: Preferences Display One of the arguments to GetPrefs() and GetDefPrefs() is the size of the buffer you are supplying to receive the Preferences data. If you are interested only in the first few bits of data, you do not have to allocate a buffer large enough to hold the entire Preferences structure. For this reason, the most commonly used data has been grouped near the beginning of the structure. Preferences allows the user to change the following:
Style 215
o Date and time of day. o Key repeat speed the speed at which a key repeats when held down. o Key repeat delay the amount of delay before the key begins repeating. o Mouse speed how far the pointer moves when the user moves the mouse. o Double-click delay maximum time allowed between the two clicks of a mouse double-click. For information about how to test for double-click timeout, see the description of the DoubleClick() function in appendix A. o Text size size of the default font characters. The user can choose 60-column mode (60 characters on a line in high-resolution mode and 30 characters in lowresolution mode) or 80-column mode (80 characters on a line in high-resolution mode and 40 characters in low-resolution mode). The first variable in the Preferences structure is FontHeight, which is the height of the characters in display lines. If this is equal to the constant TOPAZ EIGHTY, the user has chosen the 80-column version. If it is equal to TOPAZ SIXTY, the user has chosen the 60-column version. The Preferences display in figure 11-2 shows TOPAZ SIXTY. o CLI allows access to the Command Line Interface for developers. o Display centering allows the user to center the image on the video display. o Baud rate the user can change the rate of data transmission to accommodate whatever device is attached to the serial connector. o Workbench colors the user can change any of the four colors in the Workbench display by adjusting the amounts of red, green, and blue in each color. o Printer the user can select from a number of printers supported by Amiga or can type in another printer name, depending upon which printers are supported by any application. The user can also indicate whether the printer is connected to the serial connector or the parallel connector. o Print characteristics the user can select paper size, right and left margin, continuous feed or single sheets, draft or letter quality, pitch, and line spacing. If the user chooses the "Graphic Select" gadget, a requester appears from which the user can select shade (gray-scale printing), aspect (normal or sideways), positive or reverse image, and threshold (for black and white printing, determines which colors are printed as white and which as black).
The Preferences settings can be written to a Workbench disk, so the user can save the settings for the next work session. The manual called Introduction to Amiga contains more information about Preferences from the user's standpoint.
PREFERENCES STRUCTURE
Here is the Preferences data structure: struct Preferences { BYTE FontHeight; UBYTE PrinterPort; USHORT BaudRate; struct timeval KeyRptSpeed, KeyRptDelay; struct timeval DoubleClick; USHORT PointerMatrix[POINTERSIZE]; BYTE XOffset, YOffset; USHORT color17, colorl8, colorl9; USHORT PointerTicks; USHORT color0, color1, color2, color3; BYTE ViewXOffset, ViewYOffset; WORD ViewInitX, ViewInitY; BOOL EnableCLI; USHORT PrinterType; UBYTE PrinterFilename[FILENAMESIZE]; USHORT PrintPitch; USHORT PrintQuality; USHORT PrintSpacing; UWORD PrintLeftMargin, USHORT PrintImage; USHORT PrintAspect; USHORT PrintShade; WORD PrintThreshold; USHORT PaperSize; UWORD PaperLength; USHORT PaperType; }; The meanings of the fields in the Preferences structure are as follows:
Style 217
FontHeight This variable will contain one of two constants: TOPAZ SIXTY or TOPAZ EIGHTY. These are the font heights required to cause the default Topaz font to be rendered in either 60- or 80-column mode wherever the default font is requested. PrinterPort This is set to either PARALLEL PRINTER or SERIAL PRINTER to describe which type of printer is attached to the printer port. BaudRate This can be set to any of these default baud rates. See appendix B for a complete list of the definitions you might find in this variable. KeyRptSpeed, KeyRptDelay These are timeval structures, which have two components, seconds and microseconds. KeyRptDelay describes how long the system hesitates before the input device starts repeating the keys. KeyRptSpeed describes the time between repeats of the key. DoubleClick This is a timeval structure that describes the maximum time allowable between clicks of the mouse button for the operation to be considered a double-click operation. See chapter 10, "Keyboard and Mouse," for details about doubleclicking. PointerMatrix [POINTERSIZE] This contains the sprite data for the Intuition pointer. XOffset, YOffset This describes the offsets from the upper left corner of the pointer image to the pointer's active spot. color17, color18, color19 These are the colors of the Intuition pointer. PointerTicks This describes how many ticks are required for the mouse to move one increment. This should always be a power of two. The Preferences tool allows it to be set to 1, 2, or 4. Setting it to greater than 4 is not advised. For instance, if PointerTicks is set to 32768, to move the pointer from the bottom to the top of the screen the user would have to move the mouse more than a mile.
color0, color1, color2, color3 These are the Workbench colors. ViewXOffset, ViewYOffset These describe the offset of the View from its initial start-up position. This configurable offset allows the user to position the display on his monitor. ViewInitX, ViewInitY These have copies of the initial View values, as created by the graphics library. EnableCLI This Boolean value describes whether or not the Workbench should display the CLI icon when the CLI tool is available. PrinterType These are the definitions of the available printer types. See appendix B for a complete list of the definitions you might find in this variable. PrinterFilename[FILENAMESIZE] The default name for the disk-based printer configuration file is kept in this buffer. PrintPitch, PrintQuality, PrintSpacing These describe the pitch, print quality, and page spacing for printer drivers. PrintLeftMargin, PrintRightMargin The character spacing of the print margins are described by these variables. Printlmage, PrintAspect, PrintShade The values of these variables tell printer drivers about the desired type of page imagery. PrintThreshold For simple black/white printer dumps, this describes the intensity threshold required to trigger a print of a pixel. PaperSize, PaperLength, PaperType These describe the user's choice of printer paper.
Style 219
PREFERENCES FUNCTIONS
Your program can use the following functions to check the current Preferences settings. GetPrefs(PrefBuffer, Size) Gets a copy of the current Preferences data. PrefBuffer - pointer to the memory buffer to receive the Preferences data Size - number of bytes to copy to the buffer GetDefPrefs(PrefBuffer, Size) Gets a copy of the default Preferences data. PrefBuffer - pointer to the memory buffer to receive the Preferences data Size - number of bytes to copy to the buffer
calling RethinkDisplay(), you may wish to call MakeScreen() to create the Copper instruction list for your own custom screens. Note that RethinkDisplay() can take several milliseconds to run, and it locks out all other tasks while it runs. This can seriously degrade the performance of the multitasking Executive, so do not use this routine lightly. The function RemakeDisplay reconstructs the entire Intuition display. It calls MakeScreen() for every screen in the system and then calls RethinkDisplay(). As with RethinkDisplay(), RemakeDisplay() can take several milliseconds to run, and it locks out all other tasks while it runs. This can seriously degrade the performance of the multitasking Executive, so do not use this routine lightly. To remake the Copper lists of your custom screen, call MakeScreen(). The only difference between MakeScreen() and the graphics library routine MakeVPort() is that Intuition synchronizes your call to MakeVPort() with any calls that it needs to make.
Style 221
Chapter 12
STYLE
This chapter describes some important aspects of Intuition style. If you adhere to these style notes, you will help to ensure that Intuition applications present a consistent interface to the user. Try to exercise all of the suggestions in this chapter.
Style 223
Menu Style
Always make sure that you use OffMenu() when an item becomes meaningless or nonfunctional. Do not ever let the user select something and then have the application do nothing in response. Always take away the user's ability to select that item. The pens you set when you open a window are used to render the menu bar and the items. If you are opening multiple windows, you might consider color-coding the window frames and menus.
PROJECT MENUS
If you are going to allow the user to select which project to work with, you should create a "Project" menu. For consistency, it is suggested that everyone create their menu strips with the Project menu as the leftmost menu. This menu should contain the items shown in table 12-1. If possible, the items should be in the order shown. Table 12-1: Project Menus Menu Item NEW OPEN SAVE SAVE AS PRINT PRINT AS QUIT
Function Creates a project Gets back a project previously saved Saves the current project to the disk Saves the current project using a different name Prints the entire project Prints part of a project or selects other than the default printer settings Stops the program (If the project was modified, ask if the user wants to save the work.)
224 Style
EDIT MENUS
If your application can perform edit-like functions, it is suggested that you create an "Edit" menu, which should appear to the right of the Project menu. It should contain the items shown in table 12-2. If possible, the items should be in the order shown in the table. Table 12-2: Edit Menus Menu Item
Function
Undoes the previous operation (if possible; if not, disable this option!) Removes the selected portion of the project and puts it in the Clipboard Puts a copy of the selected bit of the project in the Clipboard Puts a copy of the Clipboard into the project Removes the selected bit without putting it into the Clipboard
Gadget Style
When creating a list of gadgets, in a requester or perhaps a window, be sure to design bolder, more eye-catching imagery for the obvious or safe choice. For example, note how the CANCEL choice is highlighted in figure 12-1.
Style 225
Overlapping the select boxes of gadgets is in general not a good thing to do. This is especially true when it is not obvious to users which gadget they are selecting. Unless you are very careful, all sorts of weird things can happen and the gadgets will behave in unusual ways. As with menus, use OffGadget() to remove a gadget when it becomes meaningless or nonfunctional.
226 Style
Requester Style
This is easily the most important rule about requesters: always make sure that there is a safe way to exit from any requester. In figure 12-2, notice that the dire "ERASE DISK" requester can be cancelled; in fact, the "run away" option is rendered in bolder imagery. If, for instance, the user accidentally selected the ERASE DISK option from a menu, the CANCEL option saves the day. This is extremely important. We cannot emphasize this point strongly enough. When you design a requester with your own BitMap imagery, make sure that the imagery works well with the select boxes of the gadget list that you supply.
Style 227
Table 12-3: Selection Shortcuts Key Pressed with Left AMIGA Key I O P J K L N M
Function "Select a small piece to the right of the cursor," such as the next word "Select a bigger piece to the right of the cursor," such as the next sentence "Select an even bigger piece to the right of the cursor," such as the next paragraph "Select a small piece to the left of the cursor," such as the previous word "Select a bigger piece to the left of the cursor," such as the previous sentence "Select an even bigger piece to the left of the cursor," such as the previous paragraph Bring the Workbench to the front (this is automatically trapped by Intuition) Send the Workbench to the back (this is automatically trapped by Intuition)
Table 12-4 shows recommendations for standard information (menu) shortcuts (using the right AMIGA key to emulate usage of the right button of the mouse):
228 Style
Table 12-4: Information (Menu) Shortcuts Key Pressed with Right AMIGA Key X C P I B U P U S Cut Copy Paste Change font type to italic Change font type to bold Change font mode to underline Reset font characteristics to plain defaults Undo (cancel) Save
Function
Mouse Style
Intuition uses the left mouse button for selection and the right mouse button for information transfer. To help the user understand and remember the elements of every application, you are encouraged to follow this model. When the user presses the left button, Intuition examines the state of the system and the position of the pointer and uses this information to decide if the user is trying to select some object, operation, or option. For example, the user positions the pointer over a gadget and then presses the left button to select that gadget. If the user moves the mouse while holding down the select button, this sometimes means that the user wants to select everything that the pointer moves over while the button is still pressed. Most often, Intuition uses the right button for menu operations. Pressing the right button usually displays the active window's menu bar over the screen title bar. Moving the mouse while holding down the right button sometimes means that the user wishes to browse through all available information-for example, browsing through the menus. Double-clicking the right mouse button can bring up a special requester for extended exchange of information. Because this requester is used for the transfer of information, it is appropriate to use the right mouse button.
Style 229
If you are planning to handle mouse button events directly, you should follow the selection/information model described above.
230 Style
o Color 0 is transparent. o Color 1 of the sprite (hardware color register 17) is the color with medium intensity. o Color 2 of the sprite (hardware color register 18) is low intensity. o Color 3 of the sprite (hardware color register 19) is high intensity. Your pointer should be framed by either color 1 or color 3. Since the Intuition pointer is always hardware sprite zero, you can set the colors of the pointer by calling the SetRGB4() function on the ViewPort of any screen. An example of this follows:
struct Screen *MyScreen; SetRGB4(&MyScreen->ViewPort, 17, Red17, Green17, Blue17); SetRGB4(&MyScreen->ViewPort, 18, Red18, Green18, Blue18); SetRGB4(&MyScreen->ViewPort, 19, Red19, Green19, Blue19);
Style 231
232 Style
Appendix A
In this appendix, all of the Intuition functions are presented in alphabetical order. The description of each function follows the format shown below: NAME The name of the function and a one-line description of what it does. SYNOPSIS The correct form of the function call.
A-1
FUNCTION Everything the function does. RESULT The results, if any, returned by the function. BUGS All known bugs, limitations, and deficiencies. SEE ALSO References to related functions in this and other books, as well as references to the text of this book.
A-2
FUNCTION SUMMARY
AddGadget AllocRemember AutoRequest BeginRefresh BuildSysRequest ClearDMRequest ClearMenuStrip ClearPointer CloseScreen CloseWindow CloseWorkBench CurrentTime DisplayAlert DisplayBeep DoubleClick DrawBorder Drawlmage EndRefresh EndRequest FreeRemember FreeSysRequest GetDefPrefs GetPrefs InitRequester IntuiTextLength ItemAddress MakeScreen ModifyIDCMP ModifyProp MoveScreen Adds a gadget to the gadget list of the window. Calls AllocMem() and creates a link node Automatically builds and gets response from a requester Sets up a window for optimized refreshing Builds and displays a system requester Clears the DMRequest of the window Clears the menu strip from the window Clears the pointer definition from a window Closes an Intuition screen Closes an Intuition window Closes the Workbench screen Gets the current time values Creates a display of an alert message "Beeps" the video display Tests two time values for double-click timing Draws the specified border into the RastPort Draws the specified image into the RastPort Ends the optimized refresh state of the window Ends the request and resets the window Frees memory allocated by calls to AllocRemember() Frees up memory used by a call to BuildSysRequest() Gets a copy of the the Intuition default Preferences Gets the current setting of the Intuition Preferences Initializes a Requester structure Returns the length (pixel width) of an IntuiText Returns the address of the specified Menultem Does an Intuition-integrated MakeVPort() of a custom screen Modifies the state of the window's IDCMP Modifies the current parameters of a proportional gadget Attempts to move the screen by the delta amounts
A-3
MoveWindow OffGadget OffMenu OnGadget OnMenu OpenScreen OpenWindow OpenWorkBench PrintIText RefreshGadgets RemakeDisplay RemoveGadget ReportMouse Request RethinkDisplay ScreenToBack ScreenToFront SetDMRequest SetMenuStrip SetPointer SetWindowTitles ShowTitle SizeWindow ViewAddress ViewPortAddress WBenchToBack WBenchToFront WindowLimits WindowToBack WindowToFront
Asks Intuition to move a window Disables the specified gadget Disables the given menu or menu item Enables the specified gadget Enables the given menu or menu item Opens an Intuition screen Opens an Intuition window Opens the Workbench screen Prints the text according to the IntuiText argument Refreshes (redraws) the gadget display Remakes the entire Intuition display Removes a gadget from a window or a screen Tells Intuition whether or not to report mouse movement Activates a requester The grand manipulator of the entire Intuition display Sends the specified screen to the back of the display Brings the specified screen to the front of the display Sets the DMRequest of the window Attaches the menu strip to the window Sets a window with its own pointer Sets the window's titles for both window and screen Sets the screen title bar display mode Asks Intuition to size a window Returns the address of the Intuition View structure Returns the address of a window's ViewPort structure Sends the Workbench Screen in back of all screens Brings the Workbench Screen in front of all screens Sets the minimum and maximum limits of the window Asks Intuition to send this window to the back Asks Intuition to bring this window to the front
A-4
AddGadget NAME AddGadget Adds a gadget to the gadget list of the window or screen. SYNOPSIS Add Gadget(Pointer, Gadget, Position); A0 Al D0
AddGadget
FUNCTION Adds the specified gadget to the gadget list of the given window, linked in at the position in the list specified by the Position argument (that is, if Position = = 0, the gadget will be inserted at the head of the list, and if Position = = 1, the gadget will be inserted after the first gadget and before the second). If the Position you specify is greater than the number of gadgets in the list, your gadget will be added to the end of the list. This procedure returns the position at which your gadget was added. Calling AddGadget() does not cause your gadget to be displayed. The benefit of this is that you may add several gadgets without having the gadget list redrawn every time. The drawback is that you are obliged to call RefreshGadgets() to have your added gadgets displayed. NOTE: A relatively safe way to add the gadget to the end of the list is to specify a Position of -1. That way, only the 65,536th (and multiples of it) will be inserted at the wrong position. The return value of the procedure will tell you where it was actually inserted. NOTE: The system window and screen gadgets are initially added to the front of the gadget list. The reason for this is: if you position your own gadgets in some way that interferes with the graphical representation of the system gadgets, the system's gadgets will be "hit" first by the user. If you then start adding gadgets to the front of the list, you will disturb this plan, so beware. On the other hand, if you do not violate the design rule of never overlapping your gadgets, there is no problem. INPUTS Pointer = pointer to the window to get your gadget. Gadget = pointer to the new gadget. Position = integer position in the list for the new gadget (starting from zero as the first position in the list). RESULT Returns the position where the gadget was actually added.
A-5
AddGadget
A-6
AllocRemember NAME AllocRemember Calls AllocMem() and creates a link node. SYNOPSIS AllocRemember(RememberKey, Size, Flags); A0 D0 D1
AllocRemember
FUNCTION This routine calls the Exec AllocMem() function for you; it also links the parameters of the allocation into a master list, so that you can simply call the Intuition routine FreeRemember() at a later time to deallocate all allocated memory without being required to remember the details of the memory you have allocated. This routine has two primary uses: o Say that you are doing a long series of allocations in a procedure (such as the Intuition OpenWindow() procedure). If any one of the allocations fails for lack of memory, you need to abort the procedure. Abandoning ship correctly involves freeing up any memory you may have already allocated. This procedure allows you to free up that memory easily, without being required to keep track of how many allocations you have already done, what the sizes of the allocations were, or where the memory was allocated. Also, in the more general case, you may do all of the allocations in your entire program using this routine. Then, when your program is exiting, you can free it all up at once with a simple call to FreeRemember().
You create the "anchor" for the allocation master list by creating a variable that is a pointer to the Remember structure and initializing that pointer to NULL. This is called the RememberKey. Whenever you call AllocRemember(), the routine actually does two memory allocations, one for the memory you want and the other for a copy of a Remember structure. The Remember structure is filled in with data describing your memory allocation, and it is linked into the master list pointed to by your RememberKey. Then, to free up any memory that has been allocated, all you have to do is call FreeRemember() with your RememberKey. Please read the FreeRemember() function description. As you will see, you can choose to free just the link nodes and keep all the allocated memory for yourself, or you can elect to free both the nodes and your memory buffers. See the Amiga ROM Kernel Manual for a description of the AllocMem() call and the values you should use for the Size and Flags variables.
A-7
AllocRemember
AllocRemember
INPUTS RememberKey = the address of a pointer to a Remember structure. Before the first call to AllocRemember(), initialize this pointer to NULL. For instance: struct Remember *RememberKey; RememberKey = NULL; AllocRemember(&RememberKey, BUFSIZE, MEMF_CHIP); FreeRemember(&RememberKey, TRUE); Size = the size in bytes of the memory allocation. Please refer to the Exec AllocMem() function in the Amiga ROM Kernel Manual for details. Flags = the specifications for the memory allocation. Please refer to the Exec AllocMem() function in the Amiga ROM Kernel Manual for details. RESULT If the memory allocation is successful, this routine returns the byte address of your requested memory block. Also, the node to your block will be linked into the list pointed to by your RememberKey variable. If the allocation fails, this routine returns NULL and the list pointed to by RememberKey, if any, will be undisturbed. BUGS None. SEE ALSO FreeRemember(). The Exec AllocMem() function.
A-8
AutoRequest
AutoRequest
NAME AutoRequest Automatically builds and gets response from a requester. SYNOPSIS AutoRequest(Window, BodyText, PositiveText, NegativeText, A0 Al A2 A3 PositiveFlags, NegativeFlags, Width, Height); D0 D1 D2 D3 FUNCTION This procedure automatically builds a requester for you and then waits for a response from the user or the system to satisfy your request. If the response is positive, this procedure returns TRUE. If the response is negative, this procedure returns FALSE. This procedure first preserves the state of the IDCMP values of the window argument. Then it creates an IDCMPFlag specification by merging your PositiveFlags, NegativeFlags, and the IDCMP class GADGETUP. You may choose to specify no flags for either the PositiveFlags or NegativeFlags arguments. The IntuiText arguments and the Width and Height values are passed directly to the BuildSysRequest() procedure, along with your window pointer and the IDCMP flags. Please refer to BuildSysRequest() for a description of the IntuiText that you are expected to supply when calling this routine. It is an important but long-winded description that need not be duplicated here. If the BuildSysRequest() procedure does not return a pointer to a window, it will return TRUE or FALSE (not valid structure pointers) instead, and these BOOL values will be returned immediately. On the other hand, if a valid window pointer is returned, that window will have had its IDCMP ports and flags initialized according to your specifications. AutoRequest() then waits for an IDCMP message on the UserPort; this message will satisfy one of three requirements: o o o If the message is of a class that matches one of your PositiveFlags arguments (if you have supplied any), this routine returns TRUE. If the message class matches one of your NegativeFlags arguments (if you have supplied any), this routine returns FALSE. The only other possibility is that the IDCMP message is of class GADGETUP, which means that one of the two gadgets, as specified by the PositiveText and NegativeText arguments, was selected by the user. If the TRUE gadget was selected, TRUE is returned. If the FALSE gadget was selected, FALSE is returned.
A-9
AutoRequest
AutoRequest
When the dust has settled, this routine calls FreeSysRequest(), if necessary, to clean up the requester and any other allocated memory. INPUTS Window = pointer to a Window structure. BodyText = pointer to an IntuiText structure. PositiveText = pointer to an IntuiText structure. NegativeText = pointer to an IntuiText structure. PositiveFlags = flags for the IDCMP. NegativeFlags = flags for the IDCMP. Width, Height = the sizes required for the rendering of the requester. RESULT The return value is either TRUE or FALSE. See the text above for a complete description of the chain of events that might lead to either of these values being returned. BUGS None. SEE ALSO BuildSysRequest().
A-10
BeginRefresh NAME BeginRefresh Sets up a window for optimized refreshing. SYNOPSIS BeginRefresh(Window); A0
BeginRefresh
FUNCTION This routine sets up your window for optimized refreshing. It sets Intuition internal states and then sets up the layer underlying your window for a call to the layer library. There, the "clip rectangles" of the layer are reorganized in a fashion that causes any drawing performed in your window (until you call EndRefresh()) to occur only in the regions that need to be refreshed. The term "clip rectangles" refers to the division of your window into visible and concealed rectangles. For more information about clipping rectangles and the layer library, refer to the Amiga ROM Kernel Manual. For instance, if you have a SIMPLE REFRESH window that is partially concealed and the user brings it to the front, your program will receive a message asking it to refresh its display. If your program calls BeginRefresh() before doing any of the drawing, the layer that underlies your window will be arranged such that the only drawing that will actually take place will be that which goes to the newly revealed areas. This is very performance-efficient. After your program has performed its refresh of the display, it should call EndRefresh() to reset the state of the layer and, the window. Then the program may proceed with drawing to the window as usual. Your program learns that the window needs refreshing by receiving either a message of class REFRESHWINDOW through the IDCMP or an input event of class IECLASS_REFRESHWINDOW through the console device. Whenever the program is told that the window needs refreshing, it should call BeginRefresh() and EndRefresh() to clear the refresh-needed state, even if no drawing will be done. INPUTS Window = pointer to the Window structure that needs refreshing. RESULT None. BUGS None. SEE ALSO EndRefresh().
A-11
BuildSysRequest
SYNOPSIS BuildSysRequest(Window, BodyText, PositiveText, NegativeText, A0 Al A2 A3 IDCMPFlags, Width, Height); D0 D1 D2 FUNCTION This procedure builds a requester based on the supplied information. If all goes well and the requester is constructed, this procedure returns a pointer to the window in which the requester appears. That window will have the IDCMP UserPort and WindowPort initialized to reflect the flags found in the IDCMPFlags argument. The program may then Wait() on those ports to detect the user's response to your requester, which may include either selecting one of the gadgets or causing some other event to be noticed by Intuition (such as DISKINSERTED, for instance). After the requester is satisfied, your program should call the FreeSysRequest() procedure to remove the requester and free up any allocated memory. If it is not possible to construct the requester, this procedure will use the text arguments to construct a text string for a call to the DisplayAlert() procedure and then will return either TRUE or FALSE depending on whether DisplayAlert() returned FALSE or TRUE, respectively. If the Window argument you supply is equal to NULL, a new window will be created for you in the Workbench screen. If you want the requester created by this routine to be bound to a particular window, you should not supply a Window argument of NULL. The text arguments are used to construct the display. They are pointers to instances of the IntuiText structure. The BodyText argument should be used to describe the nature of the requester. As usual with IntuiText data, you may link several lines of text together, and the text may be placed in various locations in the requester. This IntuiText pointer will be stored in the ReqText variable of the new requester. The PositiveText argument describes the text that you want associated with the user choice of "Yes," "TRUE," "retry," or "good." If the requester is successfully opened, this text will be rendered in a gadget in the lower left of the requester; this gadget will have the GadgetID field set to TRUE. If the requester cannot be opened and the DisplayAlert() mechanism is used, this text will be rendered in the lower left corner of the alert display with additional text specify-
A-12
BuildSysRequest
BuildSysRequest
ing that the left mouse button will select this choice. This pointer can be set to NULL, which specifies that there is no TRUE choice that can be made. The NegativeText argument describes the text that you want associated with the user choice of "No," "FALSE," "cancel," or "bad." If the requester is successfully opened, this text will be rendered in a gadget in the lower right of the requester; this gadget will have the GadgetlD field set to FALSE. If the requester cannot be opened and the DisplayAlert() mechanism is used, this text will be rendered in the lower right corner of the alert display with additional text specifying that the right mouse button will select this choice. This pointer cannot be set to NULL. There must always be a way for the user to cancel this requester. The positive and negative gadgets created by this routine have the following features: o o o o BOOLGADGET RELVERIFY REQGADGET TOGGLESELECT
When defining the text for your gadgets, you may find it convenient to use the special definitions used by Intuition for the construction of the gadgets. These definitions include AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE and AUTOFRONTPEN. You can find these in your local intuition.h (or intuition.i) file. The Width and Height values describe the size of the requester. All of your BodyText must fit within the Width and Height of your requester. The gadgets will be created to conform to your sizes. IMPORTANT NOTE: For the preliminary release of this procedure, a new window is opened in the same screen as the one containing your window. However, with a forthcoming update of Intuition this will change; the requester will be opened in the window supplied as an argument to this routine, if possible. The primary implication of this will be that the IDCMP flags and ports will be disturbed by a call to this routine. To assure upward compatibility, it is your responsibility to make sure that the ports and IDCMPFlags of the window passed to the routine are protected before the call to this routine. INPUTS Window = pointer to a Window structure.
A-13
BuildSysRequest
PositiveText = pointer to an IntuiText structure. NegativeText = pointer to an IntuiText structure. IDCMPFlags = the IDCMP flags you want used for the initialization of the IDCMP of the window containing this requester. Width, Height = the size required to draw your requester. RESULT If the requester was successfully drawn in a window, the value returned by this procedure is a pointer to the window in which the requester was drawn. If, however, the requester cannot be drawn in the window, this routine will have called DisplayAlert() before returning and will pass back TRUE if the user pressed the left mouse button and FALSE if the user pressed the right mouse button. BUGS This procedure currently opens a window and then opens the requester within that window. Also, if DisplayAlert() is called, the PositiveText and NegativeText are not rendered in the lower corners of the alert. SEE ALSO FreeSysRequest(). DisplayAlert(). ModifyIDCMP(). The Executive's Wait() instruction. AutoRequest().
A-14
ClearDMRequest NAME ClearDMRequest Clears the DMRequest of the window. SYNOPSIS ClearDMRequest(Window); A0
ClearDMRequest
FUNCTION Attempts to clear the DMRequester from the specified window. The DMRequester is the special requester that you attach to the double-click of the menu button; the user can then bring up that requester on demand. This routine will not clear the DMRequester if it is active (in use by the user). If you want to change the DMRequester after having called SetDMRequest(), the correct way to start is by calling ClearDMRequest() until it returns a value of TRUE; then you can call SetDMRequest() with the new DMRequester. INPUTS Window = pointer to the structure of a window from which the DMRequest is to be cleared. RESULT If the DMRequest was not currently in use, this function zeroes out the DMRequest pointer in the window and returns TRUE. If the DMRequest was currently in use, this function does not change the pointer and returns FALSE. BUGS None. SEE ALSO SetDMRequest(). Request().
A-15
ClearMenuStrip NAME ClearMenuStrip Clears the menu strip from the window. SYNOPSIS ClearMenuStrip(Window); A0 FUNCTION Clears the menu strip from the window. INPUTS Window = pointer to a Window structure. RESULT None. BUGS None. SEE ALSO SetMenuStrip().
ClearMenuStrip
A-16
ClearPointer NAME ClearPointer Clears the pointer definition from a window. SYNOPSIS ClearPointer(Window); A0
ClearPointer
FUNCTION Clears the window of its own definition of the Intuition pointer. After ClearPointer() is called, every time this window is active the default Intuition pointer will be the pointer displayed to the user. If your window is active when this routine is called, the change will take place immediately. INPUTS Window = pointer to the structure of the window to be cleared of its pointer definition. RESULT None. BUGS None. SEE ALSO SetPointer().
A-17
CloseScreen
SYNOPSIS CloseScreen(Screen); A0 FUNCTION This function unlinks the screen, unlinks the ViewPort, and deallocates everything. It does not care whether or not there are still any windows attached to the screen and does not try to close any attached windows; in fact, it ignores them altogether. If this is the last screen, this function attempts to reopen Workbench. INPUTS Screen = pointer to the Screen structure to be cleared and deallocated. RESULT None. BUGS None. SEE ALSO OpenScreen().
A-18
CloseWindow
FUNCTION This function closes an Intuition window. It unlinks it from the system, unallocates its memory, and, if its screen is a system one that would be empty without the window, closes the system screen, too. A grim, foreboding note: if you are ever rude enough to CloseWindow() on a window that has an IDCMP without first having Reply()'d to all of the messages to the IDCMP port, Intuition in turn will be so rude as to reclaim and deallocate its messages without waiting for your permission. Another grim note: if you have added a menu strip to this window (via a call to SetMenuStrip()) you must be sure to remove that menu strip (via a call to ClearMenuStrip()) before closing your window. CloseWindow() does not check whether the menus of your window are currently being used when the window is closed. If this happens to be the case, as soon as the user releases the menu button the system will crash with pyrotechnics that are usually quite lovely. INPUTS Window = a pointer to a Window structure. RESULT None. BUGS None. SEE ALSO OpenWindow(). CloseScreen().
A-19
CloseWorkBench NAME CloseWorkBench Closes the Workbench screen. SYNOPSIS BOOL CloseWorkBench();
CloseWorkBench
FUNCTION This routine attempts to close the Workbench. If the Workbench is open, it tests whether or not any applications have opened windows on the Workbench and returns FALSE if so. Otherwise, it cleans up all special buffers, closes the Workbench screen, makes the Workbench program mostly inactive (it will still monitor disk activity), and returns TRUE. If the Workbench screen isn't open when this routine is called, TRUE is returned immediately. INPUTS None. RESULT TRUE if the Workbench screen is closed. FALSE if anything went wrong and the Workbench screen is still out there. BUGS None. SEE ALSO None.
A-20
CurrentTime NAME CurrentTime Gets the current time values. SYNOPSIS ULONG Seconds, Micros; CurrentTime(&Seconds, &Micros); D0 D1
CurrentTime
FUNCTION This function puts copies of the current time into the supplied argument pointers. This time value is not extremely accurate, nor is it of a very fine resolution. The time will be updated no more than sixty times a second and will typically be updated far fewer times a second. INPUTS Seconds = pointer to a ULONG variable to receive the current seconds value. Micros = pointer to a ULONG variable for the current microseconds value. RESULT Puts the time values into the memory locations specified by the arguments. BUGS None. SEE ALSO None.
A-21
DisplayAlert NAME DisplayAlert Creates a display of an alert message. SYNOPSIS DisplayAlert(AlertNumber, String, Height); D0 A0 D1 FUNCTION Creates an alert display with the specified message.
DisplayAlert
If the system can recover from this alert, it is a RECOVERY ALERT. The routine waits until the user presses one of the mouse buttons, after which the display is restored to its original state and a BOOL value is returned by this routine to specify whether or not the user pressed the left mouse button. If the system cannot recover from this alert, it is a DEADEND ALERT, and this routine returns immediately upon creating the alert display. The return value is FALSE. The AlertNumber is a LONG value, related to the value sent to the Alert() routine. The only bits that are pertinent to this routine, however, are the ALERT TYPE bits. These bits must be set to RECOVERY ALERT for alerts from which the system may safely recover or DEADEND ALERT for fatal alerts. These states are described in the paragraph above. A third type of alert, the DAISY ALERT, is used only by the Executive. The String argument points to an AlertMessage string. The AlertMessage string is composed of one or more substrings, each of which contains the following components: o First, a 16-bit x coordinate and an 8-bit y coordinate, describing where on the alert display you want this string to appear. The y coordinate describes the offset to the baseline of the text. o Then, the bytes of the string itself, which must be null-terminated (end with a byte of zero). o Lastly, the continuation byte, which specifies whether or not another substring follows this one. If the continuation byte is non-zero, there is another substring to be processed in this AlertMessage. If the continuation byte is zero, this is the last substring in the message. The last argument, Height, describes how many video lines tall you want the alert display to be.
A-22
DisplayAlert
DisplayAlert
INPUTS AlertNumber = the number of this AlertMessage. The only pertinent bits of this number are the ALERT TYPE bits. The rest of the number is ignored by this routine. String = pointer to the alert message string, as described above. Height = minimum display lines required for your message. RESULT A BOOL value of TRUE or FALSE. If this is a DEADEND ALERT, FALSE is always the return value. If this is a RECOVERY ALERT, the return value will be TRUE if the user presses the left mouse button in response to your message and FALSE if the user presses the right button. BUGS If the system is in more trouble than you think, the level of your alert may become DEADEND_ALERT without you ever knowing about it. SEE ALSO None.
A-23
DisplayBeep NAME DisplayBeep "Beeps" the video display. SYNOPSIS DisplayBeep(Screen); A0 FUNCTION
DisplayBeep
"Beeps" the video display by flashing the background color of the specified screen. If the Screen argument is NULL, every screen in the display will be beeped. Flashing all screens is not a polite thing to do, so this should be reserved for dire circumstances. Such a routine is supported because the Amiga has no internal bell or speaker. When the user needs to know of an event that is not serious enough to require the use of a requester, the DisplayBeep() function should be called. INPUTS Screen = pointer to a Screen structure. If NULL, every Intuition screen will be flashed. RESULT None. BUGS None. SEE ALSO None.
A-24
DoubleClick NAME DoubleClick Tests two time values for double-click timing. SYNOPSIS DoubleClick(StartSeconds, StartMicros, CurrentSeconds, D0 D1 D2 CurrentMicros); D3
DoubleClick
FUNCTION Compares the difference in the time values with the double-click timeout range that the user (using the Preferences tool or some other source) has configured into the system. If the difference between the specified time values is within the current double-click time range, this function returns TRUE; otherwise, it returns FALSE. These time values can be found in InputEvents and IDCMP messages. The time values are not perfect; however, they are precise enough for nearly all applications. INPUTS StartSeconds, StartMicros = the timestamp value describing the start of the doubleclick time period you are considering. CurrentSeconds, CurrentMicros = the timestamp value describing the end of the double-click time period you are considering. RESULT If the difference between the supplied timestamp values is within the double-click time range in the current set of Preferences, this function returns TRUE; otherwise, it returns FALSE. BUGS None. SEE ALSO CurrentTime().
A-25
DrawBorder NAME DrawBorder Draws the specified border into the RastPort. SYNOPSIS DrawBorder(RastPort, Border, LeftOffset, TopOffset); A0 Al D0 D1
DrawBorder
FUNCTION First, this function sets up the drawing mode and pens in the RastPort according to the arguments of the Border structure. Then, it draws the vectors of the Border argument into the RastPort, offset by the LeftOffset and TopOffset. This routine does Intuition window clipping as appropriate-if you draw a line outside of your window, your imagery will be clipped at the window's edge. If the NextBorder field of the Border argument is non-zero, the next Border is rendered as well (return to the top of this FUNCTION section for details). INPUTS RastPort = pointer to the RastPort to receive the border crossing. Border = pointer to a Border structure. LeftOffset = the offset that will be added to each vector's x coordinate. TopOffset = the offset that will be added to each vector's y coordinate. RESULT None. BUGS None. SEE ALSO None.
A-26
DrawImage NAME DrawImage Draws the specified Image into the RastPort. SYNOPSIS Drawlmage(RastPort, Image, LeftOffset, TopOffset); A0 Al D0 D1
DrawImage
FUNCTION First, this function sets up the drawing mode and pens in the RastPort according to the arguments of the Image structure. Then, it moves the image data of the Image argument into the RastPort, offset by the LeftOffset and TopOffset. This routine does Intuition window clipping as appropriate-if you draw an image outside of your window, your imagery will be clipped at the window's edge. If the Nextlmage field of the Image argument is non-zero, the next Image is rendered as well (return to the top of this section for details). INPUTS RastPort = pointer to the RastPort to receive the border crossing. Image = pointer to an Image structure. LeftOffset = the offset that will be added to the Image's x coordinate. TopOffset = the offset that will be added to the Image's y coordinate. RESULT None. BUGS None. SEE ALSO None.
A-27
EndRefresh NAME EndRefresh Ends the optimized refresh state of the window. SYNOPSIS EndRefresh(Window, Complete); A0 D0
EndRefresh
FUNCTION This function gets you out of the special refresh state of your window. It is called following a call to BeginRefresh(), which begins the special refresh state. While your window is in the refresh state, the only drawing that will be wrought in your window will be to those areas that were recently revealed and that need to be refreshed. After your program has done all the needed refreshing for this window, this routine is called to restore the window to its non-refreshing state. Then all rendering will go to the entire window as usual. The Complete argument is a Boolean TRUE or FALSE value used to describe whether or not the refreshing that has been done is all that needs to be done at this time. Most often, this argument will be TRUE. However, if, for instance, you have multiple tasks or multiple procedure calls that must run to completely refresh the window, each can call its own Begin/EndRefresh() pair with a Complete argument of FALSE, and only the last calls with a Complete argument of TRUE. INPUTS Window = pointer to the Window currently in optimized-refresh mode. Complete = Boolean TRUE or FALSE describing whether or not this window is completely refreshed. RESULT None. BUGS None. SEE ALSO BeginRefresh().
A-28
EndRequest NAME EndRequest Ends the request and resets the window. SYNOPSIS EndRequest(Requester, Window); A0 Al
EndRequest
FUNCTION This function ends the request by erasing the requester and resetting the window. Note that this does not necessarily clear all requesters from the window, only the specified one. If the window labors under other requesters, they will remain in the window. INPUTS Requester = pointer to the structure of the requester to be removed. Window = pointer to the Window structure with which this requester is associated. RESULT None. BUGS None. SEE ALSO None.
A-29
FreeRemember
FreeRemember
NAME FreeRemember Frees the memory allocated by calls to AllocRemember(). SYNOPSIS FreeRemember(RememberKey, ReallyForget); A0 D0 FUNCTION This function frees up memory allocated by the AllocRemember() function. It will free up just the Remember structures, which supply the link nodes that tie your allocations together, or it will deallocate both the link nodes and your memory buffers. If you want to deallocate just the Remember structure link nodes, you should set the ReallyForget argument to FALSE. However, if you want FreeRemember() to really forget about all the memory, including both the Remember structure link nodes and the buffers you requested via earlier calls to AllocRemember(), you should set the ReallyForget argument to TRUE. If you're not sure whether or not you want to ReallyForget, refer to figure 11-1. INPUTS RememberKey = the address of a pointer to a Remember structure. This pointer should either be NULL or be set to some value (possibly NULL) by a call to AllocRemember(). For example: struct Remember *RememberKey; RememberKey = NULL; AllocRemember(&RememberKey, BUFSIZE, MEW SHIP); FreeRemember(&RememberKey, TRUE); ReallyForget = a BOOL FALSE or TRUE describing, respectively, whether you want to free up only the Remember nodes or whether you want this procedure to really forget about all of the memory, including both the nodes and the memory buffers pointed to by the nodes. RESULT None. BUGS None. SEE ALSO AllocRemember().
A-30
FreeSysRequest
FreeSysRequest
NAME FreeSysRequest Frees up memory used by a call to BuildSysRequest(). SYNOPSIS FreeSysRequest(Window); A0 FUNCTION This routine frees up all memory allocated by a successful call to the BuildSysRequest() procedure. If BuildSysRequest() returned a pointer to a Window structure, then your program can Wait() for the message port of that window to detect an event that satisfies the requester. When you want to remove the requester, you call this procedure. It ends the requester and deallocates any memory used in the creation of the requester. NOTE: If BuildSysRequest() did not return a pointer to a window, you should not call FreeSysRequest(). INPUTS Window = a copy of the window pointer returned by a successful call to the BuildSysRequest() procedure. RESULT None. BUGS None. SEE ALSO BuildSysRequest(). The Executive's Wait() instruction. AutoRequest().
A-31
GetDefPrefs NAME GetDefPrefs Gets a copy of the Intuition default Preferences. SYNOPSIS GetDefPrefs(PrefBuffer, Size); A0 D0
GetDefPrefs
FUNCTION This function gets a copy of the Intuition default Preferences data. It writes the data into the buffer you specify. The number of bytes you want copied is specified by the Size argument. The default Preferences are those that Intuition uses when it is first opened. If no Preferences file is found, these are the preferences that are used. These would also be the start-up Preferences in an environment that does not use AmigaDOS. It is legal to take a partial copy of the Preferences structure. The more pertinent Preferences variables have been grouped near the top of the structure to facilitate the memory conservation that can be had by taking a copy of only some of the Preferences structure. INPUTS PrefBuffer = pointer to the memory buffer to receive your copy of the Intuition Preferences. Size = the number of bytes in your PrefBuffer the number of bytes you want copied from the system's internal Preference settings. RESULT Returns your Preferences pointer. BUGS None. SEE ALSO GetPrefs().
A-32
GetPrefs NAME GetPrefs Gets the current setting of the Intuition Preferences. SYNOPSIS GetPrefs (PrefBuffer, Size); A0 D0
GetPrefs
FUNCTION This function gets a copy of the current Intuition Preferences data and writes the data into the buffer you specify. The number of bytes you want copied is specified by the Size argument. It is legal to take a partial copy of the Preferences structure. The more pertinent Preferences variables have been grouped near the top of the structure to facilitate the memory conservation that can be had by taking a copy of only some of the Preferences structure. INPUTS PrefBuffer = pointer to the memory buffer to receive your copy of the Intuition Preferences. Size = the number of bytes in your PrefBuffer the number of bytes you want copied from the system's internal Preference settings. RESULT Returns a copy of your Preferences pointer. BUGS None. SEE ALSO GetDefPrefs().
A-33
InitRequester NAME InitRequester Initializes a Requester structure. SYNOPSIS InitRequester(Requester); A0 FUNCTION The original text for this function was:
InitRequester
This function initializes a requester for general use. After calling InitRequester(), you need fill in only those requester values that fit your needs. The other values are set to states that Intuition regards as NULL. All this routine actually does is fill the specified Requester structure with zeros. There is no requirement to call this routine before using a Requester structure. For the sake of backward compatibility, this function call remains, but its sole effect is, and is guaranteed to always be, a zero, a mystery, an enigma. INPUTS Requester = a pointer to a Requester structure. RESULT None. BUGS None. SEE ALSO None.
A-34
IntuiTextLength NAME IntuiTextLength Returns the length (pixel width) of an IntuiText. SYNOPSIS IntuiTextLength(IText); A0
IntuiTextLength
FUNCTION This routine accepts a pointer to an instance of an IntuiText structure and returns the length (the pixel width) of the string that is represented by that instance of the structure. All of the usual IntuiText rules apply. Most notably, if the Font pointer of the structure is set to NULL, you will get the pixel width of your text in terms of the current default font. INPUTS IText = pointer to an instance of an IntuiText structure. RESULT Returns the pixel width of the text specified by the IntuiText data. BUGS None. SEE ALSO None.
A-35
ItemAddress NAME ItemAddress Returns the address of the specified Menultem. SYNOPSIS ItemAddress(MenuStrip, MenuNumber); A0 D0
ItemAddress
FUNCTION This routine feels through the specified MenuStrip and returns the address of the item specified by the MenuNumber. Typically, you will use this routine to get the address of a MenuItem from a MenuNumber sent to you by Intuition after the user has played with your menus. This routine requires that the arguments be well defined. MenuNumber may be equal to MENUNULL, in which case this routine returns NULL. If MenuNumber does not equal MENUNULL, it is presumed to be a valid item number selector for your MenuStrip, which includes a valid menu number and a valid item number. If the item specified by the above two components has a subitem, the MenuNumber may have a subitem component too. Note that there must be both a menu number and an item number. Because a subitem specifier is optional, the address returned by this routine may point to either an item or a subitem. INPUTS MenuStrip = a pointer to the first menu in your menu strip. MenuNumber = the value that contains the packed data that selects the menu and item (and subitem). RESULT If MenuNumber = = MENUNULL, this routine returns NULL. Otherwise, this routine returns the address of the Menultem specified by MenuNumber. BUGS None. SEE ALSO The "Menus" chapter in this book (chapter 6) for more information about. MenuNumbers.
A-36
MakeScreen
MakeScreen
NAME MakeScreen Does an Intuition-integrated MakeVPort() of a custom screen. SYNOPSIS MakeScreen(Screen); A0 FUNCTION This procedure allows you to do a MakeVPort() for the ViewPort of your custom screen in an Intuition-integrated way. This allows you to do your own screen manipulations without worrying about interference with Intuition's usage of the same ViewPort. After calling this routine, you can call RethinkDisplay() to incorporate the new ViewPort of your custom screen into the Intuition display. INPUTS Screen = address of the Screen structure. RESULT None. BUGS None. SEE ALSO RethinkDisplay(). RemakeDisplay(). The graphics library's MakeVPort().
A-37
ModifyIDCMP NAME ModifyIDCMP Modifies the state of the window's IDCMP. SYNOPSIS ModifyIDCMP(Window, IDCMPFlags); A0 D0
ModifyIDCMP
FUNCTION This routine modifies the state of your window's IDCMP (Intuition Direct Communication Message Port). The state is modified to reflect your desires as described by the flag bits in the value IDCMPFlags. If the IDCMPFlags argument equals NULL, you are asking for the ports to be closed; if they are open, they will be closed. If you set any of the IDCMPFlags, this means that you want the message ports to be open; if not currently open, the ports will be opened. The four actions that might be taken are described below: o If there is currently no IDCMP in the given window and IDCMPFlags is NULL, nothing happens. o If there is currently no IDCMP in the given window and any of the IDCMPFlags are selected (set), the IDCMP of the window is created, including allocating and initializing the message ports and allocating a signal bit for your port. See "Input and Output Methods" (chapter 8) for full details. o If the IDCMP for the given window is opened and the IDCMPFlags argument is NULL, Intuition will close the ports, free the buffers, and free your signal bit. The current task must be the same one that was active when this signal bit was allocated. o If the IDCMP for the given window is opened and the IDCMPFIags argument is not NULL, this means that you want to change which events will be broadcast to your program through the IDCMP. NOTE: You can set up the Window->UserPort to any port of your own before you call ModifyIDCMP(). If IDCMPFlags is non-null but your UserPort is already initialized, Intuition will assume that it is a valid port with task and signal data preset and will not disturb your set-up; Intuition will just allocate the Intuition message port for your window. The converse is true as well; if UserPort is NULL when you call here with IDCMPFlags = = NULL, only the Intuition port will be deallocated. This allows you to use a port that you already have allocated:
A-38
ModifyIDCMP
ModifyIDCMP
o OpenWindow() with IDCMPFlags equal to NULL (open no ports). o Set the UserPort variable of your window to any valid port of your own choosing. o Call ModifyIDCMP() with IDCMPFlags set to what you want. o Then, to clean up later, set UserPort equal to NULL before calling CloseWindow() (leave IDCMPFlags alone). A grim, foreboding note: If you are ever rude enough to close an IDCMP without first having Reply()'d to all of the messages sent to the IDCMP port, Intuition will in turn be so rude as to reclaim and deallocate its messages without waiting for your permission. INPUTS Window = pointer to the Window structure containing the IDCMP ports. IDCMPFlags = the flag bits describing the new desired state of the IDCMP. RESULT None. BUGS None. SEE ALSO OpenWindow().
A-39
ModifyProp
ModifyProp
NAME ModifyProp Modifies the current parameters of a proportional gadget. SYNOPSIS ModifyProp(PropGadget, Pointer, Requester, A0 Al A2 Flags, HorizPot, VertPot, HorizBody, VertBody); D0 D1 D2 D3 D4 FUNCTION This routine modifies the parameters of the specified proportional gadget. The gadget's internal state is then recalculated and the imagery is redisplayed. The Pointer argument can point to either a Window or a Screen structure. Which one it actually points to is decided by examining the SCRGADGET flag of the gadget. If the flag is set, Pointer points to a Screen structure; otherwise, it points to a Window structure. The Requester variable can point to a Requester structure. If the gadget has the REQGADGET flag set, the gadget is in a requester and the Pointer must necessarily point to a window. If this is not the gadget of a requester, the Requester argument may be NULL. INPUTS PropGadget = pointer to the structure of a proportional gadget. Pointer = pointer to the structure of the "owning" display element of the gadget, which is a window or a screen. Requester = pointer to a Requester structure (this may be NULL if this is not a requester gadget). Flags = value to be stored in the Flags variable of the Proplnfo. HorizPot = value to be stored in the HorizPot variable of the Proplnfo. VertPot = value to be stored in the VertPot variable of the Proplnfo. HorizBody = value to be stored in the HorizBody variable of the Proplnfo. VertBody = value to be stored in the VertBody variable of the Proplnfo. RESULT None. BUGS None. SEE ALSO None.
A-40
MoveScreen NAME MoveScreen Attempts to move the screen by the delta amounts. SYNOPSIS MoveScreen(Screen, DeltaX, DeltaY); A0 D0 D1
MoveScreen
FUNCTION Attempts to move the specified screen. This movement must follow one constraint (only for the current release of the software): horizontal movements are ignored. If the DeltaX and DeltaY variables you specify would move the screen in a way that violates the above restriction, the screen will be moved as far as possible. INPUTS Screen = pointer to a Screen structure. DeltaX = amount to move the screen on the x axis. DeltaY = amount to move the screen on the y axis. RESULT None. BUGS None. SEE ALSO None.
A-41
MoveWindow NAME MoveWindow Ask Intuition to move a window. SYNOPSIS MoveWindow(Window, DeltaX, DeltaY); A0 D0 D1
MoveWindow
FUNCTION This routine sends a request to Intuition asking to move the window the specified distance. The delta arguments describe how far to move the window along the respective axes. Note that the window will not be moved immediately; it will be moved the next time Intuition receives an input event, which happens currently at a minimum rate of ten times per second and a maximum of sixty times a second. This routine does no error-checking. If your delta values specify some far corner of the universe, Intuition will attempt to move your window to the far corners of the universe. Because of the distortions in the space-time continuum that can result from this, as predicted by special relativity, the result is generally not a pretty sight. INPUTS Window = pointer to the structure of the window to be moved. DeltaX = signed value describing how far to move the window on the x axis. DeltaY = signed value describing how far to move the window on the y axis. RESULT None. BUGS None. SEE ALSO SizeWindow(). WindowToFront(). WindowToBack().
A-42
OffGadget NAME OffGadget Disables the specified gadget. SYNOPSIS OffGadget(Gadget, Pointer, Requester); A0 Al A2
OffGadget
FUNCTION This command disables the specified gadget. When a gadget is disabled, these things happen: o Its imagery is displayed ghosted. o The GADGDISABLED flag is set. o The gadget cannot be selected by the user. The Pointer argument must point to a Window structure. The Requester variable can point to a Requester structure. If the gadget has the REQGADGET flag set, the gadget is in a requester and Pointer must necessarily point to the window containing that requester. If this is not the gadget of a requester, the Requester argument may be NULL. NOTE: It is never safe to tinker with the gadget list yourself. Do not supply some gadget that Intuition has not already processed in the usual way. NOTE: If you have specified that this is a gadget of a requester, that requester must be currently displayed. INPUTS Gadget = pointer to the structure of the gadget that you want disabled. Pointer = pointer to a Window structure. Requester = pointer to a Requester structure (may be NULL if this is not a requester gadget list). RESULT None. BUGS None. SEE ALSO OnGadget().
A-43
OffMenu NAME OffMenu Disables the given menu or menu item. SYNOPSIS OffMenu(Window, MenuNumber); A0 D0
OffMenu
FUNCTION This command disables a subitem, an item, or a whole menu. If the base of the menu number matches the menu currently revealed, the menu strip is redisplayed. INPUTS Window = pointer to the Window structure. MenuNumber = the menu piece to be enabled. RESULT None. BUGS None. SEE ALSO OnMenu().
A-44
OnGadget NAME OnGadget Enables the specified gadget. SYNOPSIS OnGadget(Gadget, Pointer, Requester); A0 Al A2
OnGadget
FUNCTION This command enables the specified gadget. When a gadget is enabled, these things happen: o Its imagery is displayed normally (not ghosted). o The GADGDISABLED flag is cleared. o The gadget can thereafter be selected by the user. The Pointer argument must point to a Window structure. The Requester variable can point to a Requester structure. If the gadget has the REQGADGET flag set, the gadget is in a requester and Pointer must point to the Window containing the requester. If this is not the gadget of a requester, the requester argument may be NULL. NOTE: It is never safe to tinker with the gadget list yourself. Do not supply some gadget that Intuition has not already processed in the usual way. NOTE: If you have specified that this is a gadget of a requester, that requester must be currently displayed. INPUTS Gadget = pointer to the structure of the gadget that you want enabled. Pointer = pointer to a Window structure. Requester = pointer to a Requester structure (may be NULL if this is not a requester gadget list). RESULT None. BUGS None. SEE ALSO OffGadget().
A-45
OnMenu NAME OnMenu Enables the given menu or menu item. SYNOPSIS OnMenu(Window, MenuNumber); A0 D0
OnMenu
FUNCTION This command enables a subitem, an item, or a whole menu. If the base of the menu number matches the menu currently revealed, the menu strip is redisplayed. INPUTS Window = pointer to the window. MenuNumber = the menu piece to be enabled. RESULT None. BUGS None. SEE ALSO OffMenu().
A-46
OpenScreen NAME OpenScreen Opens an Intuition screen. SYNOPSIS OpenScreen(NewScreen); A0 where the NewScreen structure is initialized with:
OpenScreen
Left, Top, Width, Height, Depth, DetailPen, BlockPen, ViewModes, Type, Font, DefaultTitle, Gadgets FUNCTION This command opens an Intuition screen according to the specified parameters. It does all the allocations, sets up the screen structure and all substructures completely, and links this screen's ViewPort into Intuition's View of the world. Before you call OpenScreen(), you must initialize an instance of a NewScreen structure. NewScreen is a structure that contains all of the arguments needed to open a screen. The NewScreen structure may be discarded immediately after it is used to open the screen. The TextAttr pointer that you supply as an argument will be used as the default font for all Intuition-managed text that appears in the screen and its windows. This includes, but is not limited to, the text on the title bars of both the screen and windows. The SHOWTITLE flag is set to TRUE by default when a screen is opened. This causes the screen's title bar to be displayed when the screen first opens. To hide the title bar, you must call the routine ShowTitle(). INPUTS NewScreen = pointer to an instance of a NewScreen structure, which is initialized with the following information: LeftEdge = initial x position of your screen (should be zero for now). TopEdge = initial y position of the opening screen. Width = the width for this screen's RastPort. Height = the height for this screen's RastPort. Depth = number of bit-planes. DetailPen = pen number for details (such as gadgets or text in the title bar). BlockPen = pen number for block fills (such as the title bar). Type = screen type (for any screen not created by Intuition, this should be equal to CUSTOMSCREEN). Types currently supported include only CUSTOMSCREEN, which is your own screen.
A-47
OpenScreen
OpenScreen You may also set the Type flag CUSTOMBITMAP and then supply your own BitMap for Intuition to use, rather than having Intuition allocate the display memory for you.
ViewModes = the appropriate flags for the data type ViewPort.Modes. These might include: HIRES for this screen to be HIRES width. INTERLACE for the display to switch to interlaced mode. SPRITES for this screen to use sprites. DUALPF for dual-playfield mode. Font = pointer to the default TextAttr structure for this screen and all windows that open in this screen. DefaultTitle = pointer to a line of text that will be displayed along the screen's title bar. The text will be null-terminated. If this argument is set to NULL, no text will be produced. Gadgets = this should be set to NULL. CustomBitMap = If you're not supplying a custom BitMap, this value is ignored. However, if you have your own display memory that you want used for this screen, the CustomBitMap argument should point to the BitMap that describes your display memory. See the "Screens" chapter and the Amiga ROM Kernel Manual for more information about BitMaps. RESULT If all is well, the routine returns the pointer to your new screen. If anything goes wrong, the routine returns NULL. BUGS None. SEE ALSO OpenWindow(). ShowTitle().
A-48
OpenWindow NAME OpenWindow Opens an Intuition window. SYNOPSIS OpenWindow(NewWindow); A0 where the NewWindow structure is initialized with:
OpenWindow
Left, Top, Width, Height, DetailPen, BlockPen, Flags, IDCMPFlags, Gadgets, CheckMark, Text, Type, Screen, BitMap, MinWidth, MinHeight, MaxWidth, MaxHeight FUNCTION This command opens an Intuition window of the given height, width, and depth, including the specified system gadgets as well as any of your own. It allocates everything you need to get going. Before you call OpenWindow(), you must initialize an instance of a NewWindow structure, which contains all of the arguments needed to open a window. The NewWindow structure may be discarded immediately after it is used to open the window. If Type = = CUSTOMSCREEN, you must have opened your own screen already via a call to OpenScreen(). Then Intuition uses your Screen argument for the pertinent information needed to get your window going. On the other hand, if Type = = one of Intuition's standard screens, your Screen argument is ignored. Instead, Intuition will check to see whether or not that screen already exists; if it does not, it will be opened first before Intuition opens your window in the standard screen. If the flag SUPER_BITMAP is set, the BitMap variable must point to your own BitMap. The DetailPen and the BlockPen are used for system drawing; for instance, the title bar is first filled using the BlockPen, and then the gadgets and text are drawn using DetailPen. You can supply special pens for your window, or you can use the screen's pens instead (by setting either of these arguments to -1). INPUTS NewWindow = pointer to an instance of a NewWindow structure, which is initialized with the following data: LeftEdge = the initial x position for your window. TopEdge = the initial y position for your window. Width = the initial width of this window.
A-49
OpenWindow
DetailPen = pen number (or -1) for the drawing of window details (such as gadgets or text in the title bar). BlockPen = pen number (or -1) for window block fills (such as the title bar). Flags = specifiers for your requirements of this window, as follows. o System gadgets you want attached to your window: o WINDOWDRAG allows this window to be dragged. o WINDOWDEPTH lets the user depth-arrange this window. o WINDOWCLOSE attaches the standard close gadget. o WINDOWSIZING allows this window to be sized. If you ask for the WINDOWSIZING gadget, you must specify one or both of the flags SIZEBRIGHT and SIZEBBOTTOM below; if you do not, the default is SIZEBRIGHT. See the following SIZEBRIGHT and SIZEBBOTTOM items for extra information. o SIZEBRIGHT is a special system gadget flag that you set to specify whether or not you want the right border adjusted to account for the physical size of the sizing gadget. The sizing gadget must, after all, take up room in either the right or the bottom border (or both, if you like) of the window. Setting either this or the SIZEBBOTTOM flag selects which edge will take up the slack. This will be particularly useful to applications that want to use the extra space for other gadgets (such as a proportional gadget and two Booleans done up to look like scroll bars) or, for instance, applications that want every possible horizontal bit and are willing to lose lines vertically. NOTE: If you select WINDOWSIZING, you must select either SIZEBRIGHT or SIZEBBOTTOM or both. If you select neither, the default is SIZEBRIGHT. o SIZEBBOTTOM is a special system gadget flag that you set to specify whether or not you want the bottom border adjusted to account for the physical size of the sizing gadget. For details, refer to SIZEBRIGHT above. NOTE: If you select WINDOWSIZING, you must select either SIZEBRIGHT or SIZEBBOTTOM or both. If you select neither, the default is SIZEBRIGHT. o GIMMEZEROZERO produces easy but expensiye output. o Type of window raster you want: o SIMPLE REFRESH o SMART REFRESH o SUPER-BITMAP
A-50
OpenWindow o o
OpenWindow BACKDROP specifies whether or not you want this window to be one of Intuition's special backdrop windows. See BORDERLESS as well. REPORTMOUSE specifies whether or not you want the program to "listen" to mouse movement events whenever its window is active. If you want to change whether or not your window is listening to the mouse after you have opened your window, you can call ReportMouse(). Whether or not your window is listening to the mouse is also affected by gadgets, because they can cause the program to get mouse movement reports. The reports (either InputEvents or messages on the IDCMP) that you get will have the x,y coordinates of the current mouse position, relative to the upper left corner of your window (GIMMEZEROZERO notwithstanding). This flag can work in conjunction with the IDCMP flag called MOUSEMOVE, which allows your program to listen via the IDCMP. BORDERLESS should be set if you want a window with no default border padding. Your window may have border padding anyway, depending on the gadgetry you have requested for the window, but you will not get the standard border lines and spacing that come with typical windows. This is a good way to take over the entire screen, since you can have a window cover the entire width of the screen using this flag. This will work particularly well in conjunction with the BACKDROP flag (see above), because it allows you to open a window that fills the entire screen. NOTE: This is not a flag that you want to set casually, since it may cause visual confusion on the screen. The window borders are the only dependable visual division between various windows and the background screen. Taking away the border takes away that visual cue, so make sure that your design does not need it before you proceed. ACTIVATE is the flag you set if you want this window to automatically become the active window. The active window is the one that receives input from the keyboard and mouse. It is usually a good idea to have the window you open when your application first starts up be an ACTIVATED one, but all others opened later should not be ACTIVATED. (If the user is off doing something with another screen, for instance, your new window will change where the input is going, which would have the effect of yanking the input rug from under the user.) Please use this flag thoughtfully and carefully. RMBTRAP, when set, causes the right mouse button events to be trapped and broadcast as events. Your program can receive these events through either the IDCMP or the console.
A-51
OpenWindow
OpenWindow
IDCMPFlags = IDCMP is the acronym for Intuition Direct Communications Message Port. It is Intuition's sole acronym, given in honor of all hackheads who love to mangle our brains with maniacal names; fashioned especially cryptic and unpronounceable to make them squirm with sardonic delight. Here's to you, my chums. Meanwhile, I still opt (and argue) for simplicity and elegance. If any of the IDCMP flags is selected, Intuition will create a pair of message ports and use them for direct communications with the task that is opening this window (as compared with broadcasting information via the console device). See the "Input and Output Methods" chapter of this book (chapter 8) for complete details. You request an IDCMP by setting any of these flags. Except for the special "verify" flags, every other flag you set tells Intuition that if a given event occurs that your program wants to know about, Intuition should broadcast the details of that event through the IDCMP rather than via the console device. This allows a program to interface with Intuition directly, rather than going through the console device. Remember, if you are going to open both an IDCMP and a console, it will be far better to get most of the event messages via the console. Reserve your usage of the IDCMP for special performance cases; that is, when you are not going to open a console for your window and yet you do want to learn about a certain set of events (for instance, CLOSEWINDOW); another example is SIZEVERIFY, which is a function that you get only through the use of the IDCMP (because the console does not give you any way to talk to Intuition directly). On the other hand, if the IDCMPFlags argument is equal to zero, no IDCMP is created and the only way you can learn about any window event for this window is via a console opened for this window. For instance, you have no way to SIZEVERIFY. If you want to change the state of the IDCMP after you have opened the window (including opening or closing the IDCMP), you call the routine ModifyIDCMP(). The flags you can set are explained below: o REQVERIFY is a flag that, like SIZEVERIFY and MENUVERIFY (see below), specifies that you want to make sure that your graphical state is quiescent before something extraordinary happens, such as the drawing of a rectangle of graphical data in your window. If you are drawing in that window, you probably will wish to make sure that you have ceased drawing before the user is allowed to bring up the DMRequest you have set up. The same goes for when the system has a requester for the user. Set this flag to ask for that verification step. REQCLEAR is the flag you set to get notification when the last
A-52
OpenWindow
OpenWindow requester is cleared from your window and it is safe for you to start output again (presuming that you are using REQVERIFY). REQSET is a flag that you set to receive a broadcast when the first requester is opened in your window. Compare this with REQCLEAR above. This function is distinct from REQVERIFY. REQSET merely tells your program that a requester has opened, whereas REQVERIFY requires the program to respond before the requester is opened. MENUVERIFY is the flag you set to have Intuition stop and wait for your program to finish all graphical output to the window before drawing the menus. Menus are currently drawn in the most memoryefficient way, which involves interrupting output to all windows in the screen before the menus are drawn. If you need to finish your graphical output before this happens, you can set this flag to make sure that you do. SIZEVERIFY is used when the program sends output to the window that depends on a knowledge of the current size of the window. If the user wants to resize the window, you may want to make sure that any queued output completes before the sizing takes place (critical text, for instance). To do so, set this flag. Then, when the user wants to size, Intuition will send the program the SIZEVERIFY message and Wait() until the program replies that it is all right to proceed with the sizing. NOTE: Saying that Intuition will Wait() until your program replies is really saying that the user will wait until the program replies, which suffers the great negative potential of user-unfriendliness. Remember to use this flag sparingly, and, as always with any IDCMP message your program receives, reply promptly! After the user has sized the window, your program can find out about it by using NEWSIZE. NEWSIZE is the flag that tells Intuition to send an IDCMP message after the user has resized your window. At this point, you could examine the size variables in your Window structure to discover the new size of the window. REFRESHWINDOW, when set, will cause a message to be sent whenever your window needs refreshing. This flag makes sense only with SIMPLE_REFRESH and SMART_REFRESH windows. MOUSEBUTTONS will make sure your program receives reports about mouse-button up/down events. NOTE: Only the events that mean nothing to Intuition are reported. If the user clicks the select button over a gadget, Intuition deals with it without sending any message. MOUSEMOVE works only if you set the REPORTMOUSE flag (see above) or if one of your gadgets has the flag FOLLOWMOUSE set.
A-53
OpenWindow
OpenWindow Then all mouse movements will be reported through the IDCMP.
GADGETDOWN specifies that when the user "selects" a gadget you have created with the GADGIMMEDIATE flag set, the fact will be broadcast through the IDCMP. o GADGETUP specifies that when the user "releases" a gadget that you have created with the RELVERIFY flag set, the fact will be broadcast through the IDCMP. o MENUPICK specifies that MenuNumber data be sent to your program. o CLOSEWINDOW specifies that the CLOSEWINDOW event be broadcasted through the IDCMP rather than the console device. o RAWKEY specifies that all RAWKEY events be transmitted via the IDCMP. Note that these are absolutely raw keycodes, which you will have to massage before using. Setting this and the MOUSE flags effectively eliminates the need to open a console device to get input from the keyboard and mouse. Of course, in exchange you lose all of the console features, most notably the "cooking" of input data and the systematic output of text to your window. o VANILLAKEY is the raw keycode RAWKEY event translated into the current default character keymap of the console device. In the USA, the default keymap is ASCII characters. When you set this flag, you will get IntuiMessages where the Code field has a character representing the key struck on the keyboard. o INTUITICKS gives you simple timer events from Intuition when your window is the active one; it may help you avoid opening and managing the timer device. With this flag set, you will get only one queuedup INTUITICKS message at a time. If Intuition notices that you've been sent an INTUITICKS message and haven't replied to it, another message will not be sent. o Intuition receives timer events ten times a second (approximately). o Set ACTIVEWINDOW and INACTIVEWINDOW to discover when your window becomes activated or inactivated. Gadgets = a pointer to the first of a linked list of your own gadgets that you want attached to this window. Can be NULL if you have no gadgets of your own. CheckMark = a pointer to an instance of the Image structure that contains the imagery you want used when any of your Menultems is to be checkmarked. If you do not want to supply your own imagery and prefer to use Intuition's own checkmark, set this argument to NULL. o
A-54
OpenWindow
OpenWindow
Text = a null-terminated line of text that will appear on the title bar of your window (may be NULL if you want no text). Type = the screen type for this window. If this equals CUSTOMSCREEN, you must have already opened a custom screen (see text above). Types available include: o WBENCHSCREEN o CUSTOMSCREEN Screen = if your type is one of Intuition's standard screens, this argument is ignored. However, if type = = CUSTOMSCREEN, this must point to the structure of your own screen. BitMap = if you have specified SUPERBITMAP as the type of raster you want for this window, this value points to a instance of the BitMap structure. However, if the raster type is not SUPERBITMAP, this pointer is ignored. MinWidth, MinHeight, MaxWidth, MaxHeight = the size limits for this window. These must be reasonable values, which is to say that the minimums cannot be greater than the current size, nor can the maximums be smaller than the current size. If they are, they are ignored. Any one of these can be initialized to zero, which means that that limit will be set to the current dimension of that axis. The limits can be changed after the window is opened by calling the WindowLimits() routine. If you have not requested the WINDOWSIZING option, these variables are ignored and you do not have to initialize them. RESULT If all is well, this command returns a pointer to the structure of your new window. If anything goes wrong, it returns NULL. BUGS ACTIVATE is currently advisory only. The user is able to do things that will prevent your window from becoming the active one when it opens. SEE ALSO OpenScreen(). ModifyIDCMP(). SetWindowTitles(). WindowLimits().
A-55
OpenWorkBench NAME OpenWorkBench Opens the Workbench screen. SYNOPSIS BOOL OpenWorkBench();
OpenWorkBench
FUNCTION This routine attempts to reopen the Workbench. If the Workbench screen reopens successfully, this routine returns TRUE; if something goes wrong, it returns FALSE. Even though this routine does return a BOOL value, you can ignore the return value if you want. INPUTS None. RESULT TRUE if the Workbench screen opened successfully or was already opened. FALSE if anything went wrong and the Workbench screen is not open. BUGS None. SEE ALSO None.
A-56
PrintIText NAME PrintIText Prints the text according to the IntuiText argument. SYNOPSIS PrintIText(RastPort, IText, LeftEdge, TopEdge); A0 Al D0 D1
PrintIText
FUNCTION This routine prints the IntuiText into the specified RastPort. It sets up the RastPort as specified by the IntuiText values, then prints the text into the RastPort at the IntuiText x,y coordinates offset by the left/top arguments. This routine does Intuition window-clipping as appropriate. If you print text outside of your window, your characters will be clipped at the window's edge. If the NextText field of the IntuiText argument is non-zero, the next IntuiText is drawn as well (return to the top of this FUNCTION section for details). INPUTS RastPort = pointer to the RastPort destination of the text. IText = pointer to an IntuiText structure. LeftEdge = left offset of the IntuiText into the RastPort. TopEdge = top offset of the IntuiText into the RastPort. RESULT None. BUGS None. SEE ALSO None.
A-57
RefreshGadgets NAME RefreshGadgets Refreshes (redraws) the gadget display. SYNOPSIS RefreshGadgets(Gadgets, Pointer, Requester); A0 A1 A2
RefreshGadgets
FUNCTION This routine refreshes (redraws) all of the gadgets in the gadget list, starting from the specified gadget. The Pointer argument points to a Window structure. The Requester variable can point to a Requester structre. If the first gadget in the list has the REQGADGET flag set, the gadget list refers to gadgets in a requester and Pointer must necessarily point to a window. If these are not the gadgets of a requester, the Requester argument may be NULL. There are two main reasons why you might want to use this routine. First, you have modified the imagery of the gadgets in your display and you want the new imagery to be displayed. Second, if you think that some graphic operation you just performed trashed the gadgetry of your display, this routine will refresh the imagery. The Gadgets argument can be a copy of the FirstGadgets variable in either the Screen or Window structure that you want refreshed; the effect of this will be that all gadgets will be redrawn. However, you can selectively refresh just some of the gadgets by starting the refresh part way into the list for instance, redrawing your window non-GIMMEZEROZERO gadgets only, which you have conveniently grouped at the end of your gadget list. NOTE: It is never safe to tinker with the gadget list yourself. Do not supply some gadget list that Intuition has not already processed in the usual way. NOTE: If you have specified that this is the gadget list of a requester, that requester must be currently displayed. INPUTS Gadgets = pointer to the first structure in the list of gadgets wanting refreshment. Pointer = pointer to a Window structure. Requester = pointer to a Requester structure (may be NULL if this is not a requester gadget list).
A-58
RefreshGadgets
RefreshGadgets
A-59
RemakeDisplay NAME RemakeDisplay Remakes the entire Intuition display. SYNOPSIS RemakeDisplay();
RemakeDisplay
FUNCTION This is the big one. This procedure remakes the entire Intuition display. It calls MakeScreen() for every screen in the system and then it calls RethinkDisplay(), which rethinks the relationships of the screens to one another and then rethinks the display Copper lists. WARNING: This routine can take several milliseconds to run, so do not use it lightly. RethinkDisplay() (called by this routine) does a Forbid() on entry and a Permit() on exit, which can seriously degrade the performance of the multitasking Executive. INPUTS None. RESULT None. BUGS None. SEE ALSO RethinkDisplay().
A-60
RemoveGadget NAME RemoveGadget Removes a gadget from a window. SYNOPSIS USHORT RemoveGadget(Pointer, Gadget); A0 Al
RemoveGadget
FUNCTION This routine removes the given gadget from the gadget list of the specified window. It returns the ordinal position of the removed gadget. If the gadget pointer points to a gadget that is not in the appropriate list, -1 is returned. If there are no gadgets in the list, -1 is returned. If you remove the 65,535th gadget from the list, -1 is returned. NOTE: The gadget's imagery is not erased by this routine. INPUTS Pointer = pointer to the window from which the gadget is to be removed. Gadget = pointer to the gadget to be removed. The gadget itself describes whether this gadget should be removed from the window. RESULT Returns the ordinal position of the removed gadget. If the gadget was not found in the appropriate list or if there are no gadgets in the list, -1 is returned. BUGS None. SEE ALSO AddGadget().
A-61
ReportMouse
ReportMouse
NAME ReportMouse Tells Intuition whether or not to report mouse movement. SYNOPSIS ReportMouse(Window, Boolean); A0 D0 FUNCTION This routine tells Intuition whether or not to broadcast mouse movement events to this window when it is active. The Boolean value specifies whether to start or stop broadcasting position information of mouse-movement. If the window is active, mouse-movement reports start coming immediately after this command. This routine will change the current state of the FOLLOWMOUSE function of a currently-selected gadget, too. Note that calling ReportMouse() when a gadget is selected will only temporarily change whether or not mouse movements are reported while the gadget is selected; the next time the gadget is selected, its FOLLOWMOUSE flag is examined anew. Note also that calling ReportMouse() when no gadget is currently selected will change the state of the window's REPORTMOUSE flag but will have no effect on any gadget that may be subsequently selected. The ReportMouse() function is first performed when OpenWindow() is first called. If the flag REPORTMOUSE is included among the options, all mousemovement events are reported to the opening task and will continue to be reported until ReportMouse() is called with a Boolean value of FALSE. If REPORTMOUSE is not set, no mouse-movement reports will be broadcast until ReportMouse() is called with a Boolean value of TRUE. INPUTS Window = pointer to a Window structure associated with this request. Boolean = TRUE or FALSE value specifying whether to turn this function on or off. RESULT None. BUGS None. SEE ALSO None.
A-62
Request
FUNCTION This routine links in and displays a requester in the specified window. This routine ignores the window's REQVERIFY flag. INPUTS Requester = pointer to the structure of the requester to be displayed. Window = pointer to the structure of the window into which this requester goes. RESULT If the requester is successfully opened, TRUE is returned. If the requester could not be opened, FALSE is returned. BUGS None. SEE ALSO None.
A-63
RethinkDisplay
RethinkDisplay
NAME RethinkDisplay The grand manipulator of the entire Intuition display. SYNOPSIS RethinkDisplay(); FUNCTION This function performs the Intuition global display reconstruction. This includes massaging internal-state data, rethinking all of the ViewPorts and their relationship to one another, and, finally, reconstructing the entire display based on the results of all this rethinking. The reconstruction of the display includes calls to the graphics library to perform MrgCop() and LoadView() for all of Intuition's screens. You may perform a MakeScreen() on your custom screen before calling this routine. The results will be incorporated in the new display. WARNING: This routine can take several milliseconds to run, so do not use it lightly. RethinkDisplay() does a Forbid() on entry and a Permit() on exit, which can seriously degrade the performance of the multitasking Executive. INPUTS None. RESULT None. BUGS None. SEE ALSO MakeScreen(). RemakeDisplay(). The graphics library's MrgCop() and LoadView(). Exec's Forbid() and Permit().
A-64
ScreenToBack
ScreenToBack
NAME ScreenToBack Sends the specified screen to the back of the display. SYNOPSIS ScreenToBack(Screen); A0 FUNCTION This routine sends the specified screen to the back of the display. INPUTS Screen = pointer to a Screen structure. RESULT None. BUGS None. SEE ALSO ScreenToFront().
A-65
ScreenToFront
ScreenToFront
NAME ScreenToFront Brings the specified screen to the front of the display. SYNOPSIS ScreenToFront(Screen); A0 FUNCTION This routine brings the specified screen to the front of the display. INPUTS Screen = a pointer to a Screen structure. RESULT None. BUGS None. SEE ALSO ScreenToBack().
A-66
SetDMRequest NAME SetDMRequest Sets the DMRequest of the window. SYNOPSIS SetDMRequest(Window, DMRequester); A0 Al
SetDMRequest
FUNCTION This routine attempts to set the DMRequester in the specified window. The DMRequester is the special requester that you attach to the double-click of the menu button, allowing the user to bring up this requester on demand. This routine will not set the DMRequester if it is already set and is currently active (in use by the user). To change the DMRequester after having called SetDMRequest(), you start by calling ClearDMRequest() until it returns a value of TRUE. Then you can call SetDMRequest() with the new DMRequester. INPUTS Window = pointer to the structure of the window into which the DMRequest is to be set. DMRequester = a pointer to a Requester structure. RESULT If the current DMRequest was not in use, the DMRequester pointer is set in the window and this routine returns TRUE. If the DMRequest was currently in use, this routine does not change the pointer and returns FALSE. BUGS None. SEE ALSO ClearDMRequest(). Request().
A-67
SetMenuStrip NAME SetMenuStrip Attaches the menu strip to the window. SYNOPSIS SetMenuStrip(Window, Menu); A0 Al
SetMenuStrip
FUNCTION This routine attaches the menu strip to the window. If the user presses the menu button after this routine is called, this specified menu strip will be displayed and accessible. NOTE: You should always design your menu strip changes to be two-way operations; every menu strip you add to your window should be cleared sometime. Even in the simplest case, when you will have just one menu strip for the lifetime of your window, you should always clear the menu strip before closing the window. If you already have a menu strip attached to this window, the correct procedure for changing to a new menu strip involves calling ClearMenuStrip() to clear the old menu strip first. The sequence of events should be: 1. OpenWindow(). 2. Zero or more iterations of: o o SetMenuStrip(). ClearMenuStrip().
3. CloseWindow(). INPUTS Window = pointer to a Window structure. Menu = pointer to the first Menu structure in the menu strip. RESULT None. BUGS None. SEE ALSO ClearMenuStrip().
A-68
SetPointer NAME SetPointer Sets a window with its own pointer. SYNOPSIS SetPointer (Window, Pointer, Height, Width, XOffset, YOffset); A0 Al D0 D1 D2 D3
SetPointer
FUNCTION This routine sets up the window with the sprite definition for the pointer. Then, whenever the window is active, the pointer image will change to the sprite's version of the pointer. If the window is active when this routine is called, the change takes place immediately. The XOffset and YOffset arguments are used to offset the top left corner of the hardware sprite imagery from what Intuition regards as the current position of the pointer. Another way of describing it is as the offset from the "hot spot" of the pointer to the top left corner of the sprite. For instance, if you specify offsets of zero, zero, then the top-left corner of your sprite image will be placed at the pointer position. On the other hand, if you specify an XOffset of -7 (remember, sprites are 16 pixels wide), your sprite will be centered over the pointer position. If you specify an XOffset of -15, the right edge of the sprite will be over the pointer position. INPUTS Window = pointer to the structure of the window to receive this pointer definition. Pointer = pointer to the data definition of a sprite. Height = the height of the pointer. Width = the width of the sprite (must be less than or equal to 16). XOffset = the offset for your sprite from the pointer position. YOffset = the offset for your sprite from the pointer position. RESULT None. BUGS None. SEE ALSO ClearPointer().
A-69
SetWindowTitles
SetWindowTitles
NAME SetWindowTitles Sets the window's titles for both the window and the screen. SYNOPSIS SetWindowTitles(Window, WindowTitle, ScreenTitle); A0 Al A2 FUNCTION This routine allows you to set the text that appears in the window and/or screen title bars. The window title appears at all times in the window title bar. The window's screen title appears at the screen title bar whenever this window is active. When this routine is called, your window title will be changed immediately. If your window is active when this routine is called, the screen title will be changed immediately. You can specify a value of -1 (negative one) for either of the title pointers. This designates that you want Intuition to leave the current setting of that particular title alone, modifying only the other one. Of course, you could set both to -1. Furthermore, you can set a value of 0 for either of the title pointers. Doing so specifies that you want no title to appear (the title bar will be blank). INPUTS Window = pointer to your Window structure. WindowTitle = pointer to a null-terminated text string; this pointer can also be set to either -1 (negative one) or 0 (zero). ScreenTitle = pointer to a null-terminated text string; this pointer can also be set to either -1 (negative one) or 0 (zero). RESULT None. BUGS None. SEE ALSO OpenWindow(). ShowTitle().
A-70
ShowTitle NAME ShowTitle Sets the screen title bar display mode. SYNOPSIS ShowTitle(Screen, ShowIt); A0 D0
ShowTitle
FUNCTION This routine sets the SHOWTITLE flag of the specified screen and then coordinates the redisplay of the screen and its windows. The screen title bar can appear either in front of or behind Backdrop windows. NonBackdrop windows always appear in front of the screen title bar. You specify whether you want the screen title bar to be in front of or behind the screen's Backdrop windows by calling this routine. The ShowIt argument should be set to either TRUE or FALSE. If TRUE, the screen's title bar will be shown in front of Backdrop windows. If FALSE, the title bar will be located behind all windows. When a screen is first opened, the default setting of the SHOWTITLE flag is TRUE. INPUTS Screen = pointer to a Screen structure. ShowIt = Boolean TRUE or FALSE describing whether to show or hide the screen title bar. RESULT None. BUGS None. SEE ALSO SetWindowTitles().
A-71
SizeWindow NAME SizeWindow Asks Intuition to size a window. SYNOPSIS SizeWindow(Window, DeltaX, DeltaY); A0 D0 D1
SizeWindow
FUNCTION This routine sends a request to Intuition asking to size the window by the specified amounts. The delta arguments describe how much to size the window along the respective axes. Note that the window will not be sized immediately. It will be sized the next time Intuition receives an input event, which happens currently at a minimum rate of ten times per second and a maximum of sixty times a second. You can discover when your window has finally been sized by setting the NEWSIZE flag of the IDCMP of your window. See the "Input and Output Methods" chapter of this book (chapter 8) for a description of the IDCMP. This routine does no error-checking. If your delta values specify some far corner of the universe, Intuition will attempt to size your window to the far corners of the universe. Because of the distortions in the space-time continuum that can result from this, as predicted by special relativity, the result is generally not a pretty sight. INPUTS Window = pointer to the structure of the window to be sized. DeltaX = signed value describing how much to size the window on the x axis. DeltaY = signed value describing how much to size the window on the y axis. RESULT None. BUGS None. SEE ALSO MoveWindow(). WindowToFront(). WindowToBack().
A-72
ViewAddress NAME ViewAddress Returns the address of the Intuition View structure. SYNOPSIS ViewAddress();
ViewAddress
FUNCTION This routine returns the address of the Intuition View structure. If you want to use any of the graphics, text, or animation primitives in your window and that primitive requires a pointer to a View, this routine will return the address of the View for you. INPUTS None. RESULT Returns the address of the Intuition View structure. BUGS It would be hard for this routine to have a bug. SEE ALSO All of the graphics, text, and animation primitives.
A-73
ViewPortAddress
ViewPortAddress
NAME ViewPortAddress Returns the address of a window's ViewPort structure. SYNOPSIS ViewPortAddress(Window); A0 FUNCTION This routine returns the address of the ViewPort structure associated with the specified window. This is actually the ViewPort of the screen within which the window is displayed. If you want to use any of the graphics, text, or animation primitives in your window and that primitive requires a pointer to a ViewPort structure, you can use this call. INPUTS Window = pointer to the Window structure for which you want the ViewPort address. RESULT Returns the address of the window's ViewPort structure. BUGS It would be hard for this routine to have a bug. SEE ALSO All of the graphics, text, and animation primitives.
A-74
WBenchToBack
WBenchToBack
NAME WBenchToBack Sends the Workbench screen in back of all screens. SYNOPSIS WBenchToBack(); FUNCTION This routine causes the Workbench screen, if it is currently opened, to go to the background. This does not "move" the screen up or down; it affects only the depth arrangement of the screen. If the Workbench screen was opened, this function returns TRUE; otherwise, it returns FALSE. INPUTS None. RESULT If the Workbench screen was opened, this function returns TRUE; otherwise, it returns FALSE. BUGS None. SEE ALSO WBenchToFront().
A-75
WBenchToFront
WBenchToFront
NAME WBenchToFront Brings the Workbench screen in front of all screens. SYNOPSIS WBenchToFront(); FUNCTION This routine causes the Workbench screen, if it is currently opened, to come to the foreground. This does not "move" the screen up or down; it affects only the depth arrangement of the screen. If the Workbench screen was opened, this function returns TRUE; otherwise, it returns FALSE. INPUTS None. RESULT If the Workbench screen was opened, this function returns TRUE; otherwise, it returns FALSE. BUGS None. SEE ALSO WBenchToBack().
A-76
WindowLimits
WindowLimits
NAME WindowLimits Sets the minimum and maximum limits of the window. SYNOPSIS WindowLimits(Window, MinWidth, MinHeight, MaxWidth, MaxHeight); A0 D0 D1 D2 D3 FUNCTION This routine allows you to adjust the minimum and maximum limits of the window's size. Until this routine is called, the window's size limits are equal to the initial limits specified by the call to OpenWindow(). If you do not want to change any one of the dimensions, set the limit argument for that dimension to zero. If any limit argument is equal to zero, that argument is ignored and the initial setting of that parameter remains undisturbed. If any argument is out of range (minimums greater than the current size, maximums less than the current size), that limit will be ignored, though the others will still take effect if they are in range. If any argument is out of range, the return value from this procedure will be FALSE. If all arguments are valid, the return value will be TRUE. If the user is currently sizing this window, the new limits will not take effect until after the sizing is completed. INPUTS Window = pointer to a Window structure. MinWidth, MinHeight, MaxWidth, MaxHeight = the new limits for the size of this window. If a limit is set to zero, it will be ignored and that setting will be unchanged. RESULT Returns TRUE if everything was in order. If a parameter was out of range (minimums greater than current size, maximums less than current size), FALSE is returned, and the errant limit request is not fulfilled (though the valid ones will be). BUGS None. SEE ALSO OpenWindow()
A-77
WindowToBack NAME WindowToBack Asks Intuition to send this window to the back. SYNOPSIS WindowToBack(Window); A0
WindowToBack
FUNCTION This routine sends a request to Intuition asking to send the window in back of all other windows in the screen. Note that the window will not be depth arranged immediately; it will be arranged the next time Intuition receives an input event, which happens currently at a minimum rate of ten times per second and a maximum of sixty times a second. Remember that Backdrop windows cannot be depth-arranged. INPUTS Window = pointer to the structure of the window to be sent to the back. RESULT None. BUGS None. SEE ALSO MoveWindow(). SizeWindow(). WindowToFront().
A-78
WindowToFront
WindowToFront
NAME WindowToFront Asks Intuition to bring this window to the front. SYNOPSIS WindowToFront(Window); A0 FUNCTION This routine sends a request to Intuition asking to bring the window in front of all other windows in the screen. Note that the window will not be depth-arranged immediately. It will be arranged the next time Intuition receives an input event, which happens currently at a minimum rate of ten times per second and a maximum of sixty times a second. Remember that Backdrop windows cannot be depth arranged. INPUTS Window = pointer to the structure of the window to be brought to front. RESULT None. BUGS None. SEE ALSO MoveWindow(). SizeWindow(). WindowToBack().
A-79
A-80
Appendix B
This appendix contains the Intuition "include" file, which contains the definitions of all the Intuition data types and structures, constants, and macros. You include this file in all Intuition-based applications.
B-1
#ifndef INTUITION_INTUITION_H #define INTUITION_INTUITION_H TRUE /***intuition.h ************************************************************* * Commodore-Amiga, Inc.. * * intuition.h main include for c programmers * * Modification History * date : author : Comments * ------------------------------------------------* 1-30-85 -=RJ=created this file! * 10-03-85 Support for HP printers * ************************************************************************/ #ifndef INTUITION_INTUITIONBASE_H #include "intuition/intuitionbase.h" #endif #ifndef GRAPHICS_GFX_ #include "graphics/gfx.h" #endif #ifndef GRAPHICS_CLIP_ H #include "graphics/clip.h" #endif #ifndef GRAPHICS_VIEW_ H #include "graphics/view.h" #endif #ifndef GRAPHICS_RASTPORT_H #include "graphics/rastport.h" #endif #ifndef GRAPHICS_LAYERS_H #include "graphics/layers.h" #endif #ifndef GRAPHICS_TEXT_H #include "graphics/text.h" #endif #ifndef EXEC PORTS H #include "exec/ports.h" #endif #ifndef DEVICES-TIMER H #include "devices/timer.h" #endif
B-2
#ifndef DEVICES INPUTEVENT_H #include "devices/inputevent.h" #endif /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* = = = Border = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* Data type Border, used for drawing a series of lines which is intended for * use as a border drawing, but which may, in fact, be used to render any * arbitrary vector shape. * The routine DrawBorder sets up the RastPort with the appropriate * variables, then does a Move to the first coordinate, then does Draws * to the subsequent coordinates. * After all the Draws are done, if NextBorder is non-zero we call DrawBorder * recursively. */ struct Border { SHORT LeftEdge, TopEdge; /* initial offsets from the origin*/ UBYTE FrontPen, BackPen; /* pen numbers for rendering*/ UBYTE DrawMode; /* mode for rendering */ BYTE Count; /* number of XY pairs */ SHORT *XY; /* vector coordinate pairs relative to LeftTop*/ struct Border *NextBorder; /* pointer to any other Border too */ };
/* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = =*/ /* = = = Gadget = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = =*/ /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = =*/ struct Gadget { struct Gadget *NextGadget; /* next gadget in the list */ SHORT LeftEdge, TopEdge; /* "hit box" of gadget */ SHORT Width, Height; /* "hit box" of gadget */ USHORT Flags; /* see below for list of defines */ USHORT Activation; /* see below for list of defines */ USHORT GadgetType; /* see below for defines */ /* appliprog can specify that the gadget be rendered as either as Border * or an Image. This variable points to which (or equals NULL if there's * nothing to be rendered about this gadget) */ GadgetRender;
APTR
B-3
APTR struct
/* appliprog can specify "highlighted" imagery rather than algorithmic * this can point to either border or image data */ SelectRender; IntuiText *GadgetText; /* text for this gadget */
LONG
/* by using the MutualExclude word, the appliprog can describe * which gadgets mutually-exclude which other ones. The bits * in MutualExclude correspond to the gadgets in object containing * the gadget list. If this gadget is selected and a bit is set * in this gadget's MutualExclude and the gadget corresponding to * that bit is currently selected (e.g.., bit 2 set and gadget 2 * is currently selected) that gadget must be unselected. * Intuition does the visual unselecting (with checkmarks) and * leaves it up to the program to unselect internally */ MutualExclude; /* set bits mean this gadget excludes that gadget */ /* pointer to a structure of special data required by proportional, * string and integer gadgets */ SpecialInfo; GadgetlD; UserData; /* user-definable ID field */ /* ptr to general-purpose user data (ignored by In) */
/* -- FLAGS SET BY THE APPLIPROG ----------------------------------------------------------*/ /* combinations in these bits describe the highlight technique to be used */ #define GADGHIGHBITS 0x0003 #define GADGHCOMP 0x0000 /* complement the select box */ #define GADGHBOX 0x0001 /* draw a box around the image */ #define GADGHIMAGE 0x0002 /* blast in this alternate image */ #define GADGHNONE 0x0003 /* don't highlight */ /* set this flag if the GadgetRender and SelectRender point to Image imagery, * clear if it's a Border */ #define GADGIMAGE 0x0004 / * combinations in these next two bits specify to which corner the gadget's * Left & Top coordinates are relative. If relative to Top/Left, * these are "normal" coordinates (everything is relative to something in * this universe) #define GRELBOTTOM 0x0008 /* set if rel to bottom, clear if rel top */ #define GRELRIGHT 0x0010 /* set if rel to right, clear if to left */ /* set the GRELWIDTH bit to spec that Width is relative to width of screen */ #define GRELWIDTH 0x0020 /* set the GRELHEIGHT bit to spec that Height is rel to height of screen */
B-4
#define GRELHEIGHT
0x0040
/* the SELECTED flag is initialized by you and set by Intuition. It * specifies whether or not this gadget is currently selected/highlighted */ #define SELECTED 0x0080 /* the GADGDISABLED flag is initialized by you and later set by Intuition * according to your calls to On/OffGadget(). It specifies whether or not * this gadget is currently disabled from being selected */ #define GADGDISABLED 0x0100 /* --- These are the Activation flag bits------------------------------------------------------------*/ /* RELVERIFY is set if you want to verify that the pointer was still over * the gadget when the select button was released */ #define RELVERIFY 0x0001 /* The flag GADGIMMEDIATE, when set, informs the caller that the gadget * was activated when it was activated. This flag works in conjunction with * the RELVERIFY flag */ #define GADGIMMEDIATE 0x0002 /* The flag ENDGADGET, when set, tells the system that this gadget, when * selected, causes the requester or AbsMessage to be ended. Requesters or * Abmessages that are ended are erased and unlinked from the system */ #define ENDGADGET 0x0004
/* the FOLLOWMOUSE flag, when set, specifies that you want to receive * reports on mouse movements (i.e.., you want the REPORTMOUSE function for * your window). When the gadget is deselected (immediately if you have * no RELVERIFY) the previous state of the REPORTMOUSE flag is restored * You probably want to set the GADGIMMEDIATE flag when using FOLLOWMOUSE, * since that's the only reasonable way you have of learning why Intuition * is suddenly sending you a stream of mouse movement events. If you don't * set RELVERIFY, you'll get at least one Mouse Position event. /* #define FOLLOWMOUSE 0x0008 /* if any of the BORDER flags are set in a gadget that's included in the * gadget list when a window is opened, the corresponding border will * be adjusted to make room for the gadget */ #define RIGHTBORDER 0x0010 #define LEFTBORDER 0x0020 #define TOPBORDER 0x0040 #define BOTTOMBORDER 0x0080
B-5
#define TOGGLESELECT #define STRINGCENTER #define STRINGRIGHT #define LONGINT #define ALTKEYMAP
/* this bit for toggle-select mode */ /* should be a Stringlnfo flag, but it's OK*/ /* should be a Stringlnfo flag, but it's OK*/ /* this string gadget is actually LONG Int */ /* this string has an alternate keymap */
/* - - - GADGET TYPES - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - -*/ /* These are the gadget type definitions for the variable GadgetType * gadget number type MUST start from one. NO TYPES OF ZERO ALLOWED. * first comes the mask for gadget flags reserved for gadget typing */ #define GADGETTYPE 0xFC00 /* all gadget global type flags (padded) */ #define SYSGADGET 0x8000 /* 1 = SysGadget, 0 = AppliGadget */ #define SCRGADGET 0x4000 /* 1 = ScreenGadget, 0 = WindowGadget */ #define GZZGADGET 0x2000 /* 1 = gadget for GIMMEZEROZERO borders */ #define REQGADGET 0x1000 /* 1 = this is a requester gadget */ /* system gadgets */ #define SIZING 0x0010 #define WDRAGGING 0x0020 #define SDRAGGING 0x0030 #define WUPFRONT 0x0040 #define SUPFRONT 0x0050 #define WDOWNBACK 0x0060 #define SDOWNBACK 0x0070 #define CLOSE 0x0080 /* application gadgets */ #define BOOLGADGET 0x0001 #define GADGET0002 0x0002 #define PROPGADGET 0x0003 #define STRGADGET 0x0004 /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* = = = Image = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* This is a brief image structure for very simple transfers of * image data to a RastPort */ struct Image { SHORT LeftEdge; /* starting offset relative to some origin */ SHORT TopEdge; /* starting offsets relative to some origin */ SHORT Width; /* pixel size (though data is word-aligned) */ SHORT Height, Depth; /* pixel sizes */ USHORT *ImageData; /* pointer to the actual word-aligned bits */
B-6
/* The PlanePick and PlaneOnOff variables work much the same way as the * equivalent GELS Bob variables. It's a space-saving * mechanism for image data. Rather than defining the image data * for every plane of the RastPort, you need define data only * for the planes that are not entirely zero or one. As you * define your imagery, you will often find that most of the planes * ARE just as color selectors. For instance, if you're designing * a two-color gadget to use colors two and three, and the gadget * will reside in a five-plane display, bit-plane zero of your * imagery would be all ones, bit-plane one would have data that * describes the imagery, and bit-planes two through four would be * all zeroes. Using these flags allows you to avoid wasting all * that memory in this way: first, you specify which planes you * want your data to appear in using the PlanePick variable. For * each bit set in the variable, the next "plane" of your image * data is blitted to the display. For each bit clear in this * variable, the corresponding bit in PlaneOnOff is examined. * If that bit is clear, a "plane" of zeroes will be used. * If the bit is set, ones will go out instead. So, for our example: * Gadget.PlanePick = 0x02; * Gadget.PlaneOnOff = 0x01; * Note that this also allows for generic gadgets, such as the * system gadgets, which will work in any number of bit-planes. * Note also that if you want an Image that is only a filled * rectangle, you can get this by setting PlanePick to zero * (pick no planes of data) and set PlaneOnOff to describe the pen * color of the rectangle. */ UBYTE PlanePick, PlaneOnOff; /* if the Nextlmage variable is not NULL, Intuition presumes that * it points to another Image structure with another Image to be * rendered */ Image *Nextlmage;
struct
/* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* = = = IntuiMessage = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ struct IntuiMessage { struct Message ExecMessage; /* the Class bits correspond directly with the IDCMP Flags, except for the * special bit LONELYMESSAGE (defined below) */ ULONG Class;
B-7
/* the Code field is for special values like MENU number */ USHORT Code; /* the Qualifier field is a copy of the current InputEvent's Qualifier */ USHORT Qualifier; /* IAddress contains particular addresses for Intuition functions, like * the pointer to the gadget or the screen */ APTR IAddress; /* When getting mouse movement reports, any event you get will have the * the mouse coordinates in these variables. the coordinates are relative * to the upper left corner of your window (GIMMEZEROZERO notwithstanding) */ SHORT MouseX, MouseY; /* The time values are copies of the current system clock time. Micros * are in units of microseconds, seconds are in seconds. */ ULONG Seconds, Micros; /* The IDCMPWindow variable will always have the address of the window of * this IDCMP */ Window *IDCMPWindow; /* system-use variable */ IntuiMessage *SpecialLink;
struct struct };
/* IDCMP Classes */ #define SIZEVERIFY #define NEWSIZE #define REFRESHWINDOW #define MOUSEBUTTONS #define MOUSEMOVE #define GADGETDOWN #define GADGETUP #define REQSET #define MENUPICK #define CLOSEWINDOW #define RAWKEY #define REQVERIFY #define REQCLEAR #define MENUVERIFY #define NEWPREFS #define DISKINSERTED #define DISKREMOVED #define WBENCHMESSAGE
0x00000001 0x00000002 0x00000004 0x00000008 0x00000010 0x00000020 0x00000040 0x00000080 0x00000100 0x00000200 0x00000400 0x00000800 0x00001000 0x00002000 0x00004000 0x00008000 0x00010000 0x00020000
B-8
#define ACTIVEWINDOW 0x00040000 #define INACTIVEWINDOW 0x00080000 #define DELTAMOVE 0x00100000 #define VANILLAKEY 0x00200000 #define INTUITICKS 0x00400000 /* NOTEZ-BIEN:0x80000000 is reserved for internal use */ /* The IDCMP Flags do not use this special bit, which is cleared when * Intuition sends its special message to the task, and set when Intuition * gets its message back from the task. Therefore, I can check here to * find out fast whether or not this message is available for me to send. */ #define LONELYMESSAGE 0x80000000 /* --- IDCMP Codes ----------------------------------------------------------------*/ /* This group of codes is for the MENUVERIFY function */ #define MENUHOT 0x0001 /* IntuiWants verification or MENUCANCEL */ #define MENUCANCEL 0x0002 /* HOT Reply of this cancels Menu operation */ #define MENUWAITING 0x0003 /* Intuition simply wants a ReplyMsg() ASAP */ /* This group of codes is for the WBENCHMESSAGE messages */ #define WBENCHOPEN 0x0001 #define WBENCHCLOSE 0x0002 /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = */ /* = = = IntuiText = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = */ /* IntuiText is a series of strings that start with a screen location * (always relative to the upper left corner of something) and then the * text of the string. The text is null-terminated */ struct IntuiText { UBYTE FrontPen, BackPen; /* the pen numbers for the rendering */ UBYTE DrawMode; /* the mode for rendering the text */ SHORT LeftEdge; /* relative start location for the text */ SHORT TopEdge; /* relative start location for the text */ struct TextAttr *ITextFont; /* if NULL, you accept the default */ UBYTE *IText; /* pointer to null-terminated text */ struct IntuiText *NextText; /* continuation to TxWrite another text */ };
B-9
/* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = */ /* = = = Menu = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = */ struct Menu { struct Menu *NextMenu; /* same level */ SHORT LeftEdge, TopEdge; /* position of the select box */ SHORT Width, Height; /* dimensions of the select box */ USHORT Flags; /* see flag definitions below */ BYTE *MenuName; /* text for this Menu Header */ struct MenuItem *Firstltem; /* pointer to first in chain */ /* These mysteriously-named variables are for internal use only */ SHORT JazzX, JazzY, BeatX, BeatY; }; /* FLAGS SET BY BOTH THE APPLIPROG AND INTUITION */ #define MENUENABLED 0x0001 /* whether or not this menu is enabled */ /* FLAGS SET BY INTUITION */ #define MIDRAWN 0x0100 /* this menu's items are currently drawn
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = MenuItem = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ struct Menultem { struct Menultem *Nextltem; /* pointer to next in chained list SHORT LeftEdge, TopEdge; /* position of the select box */ SHORT Width, Height; /* dimensions of the select box USHORT Flags; /* see the defines below */ LONG APTR MutualExclude; ItemFill; /* set bits mean this item excludes that */ /* points to Image, IntuiText, or NULL */
/* When this item is pointed to by the cursor and the items highlight * mode HIGHIMAGE is selected, this alternate image will be displayed */ SelectFill; /* points to Image, IntuiText, or NULL */ Command; Menultem *SubItem; /* only if appliprog sets the COMMSEQ flag */ /* if non-zero, this item has a subitem */
USHORT };
/* The NextSelect field represents the menu number of next selected * item (when user has drag-selected several items) */ NextSelect;
B-10
/* FLAGS SET BY THE APPLIPROG */ #define CHECKIT 0x0001 #define ITEMTEXT 0x0002 #define COMMSEQ 0x0004 #define MENUTOGGLE 0x0008 #define ITEMENABLED 0x0010
/* whether to check this item if selected */ /* set if textual, clear if graphical item */ /* set if there's an command sequence */ /* set to toggle the check of a menu item */ /* set if this item is enabled */
/* these are the SPECIAL HIGHLIGHT FLAG state meanings */ #define HIGHFLAGS 0x00C0 /* see definitions below for these bits */ #define HIGHIMAGE 0x0000 /* use the user's "select, image" */ #define HIGHCOMP 0x0040 /* highlight by complementing the select box */ #define HIGHBOX 0x0080 /* highlight by "boxing" the selectbox */ #define HIGHNONE 0x00C0 /* don't highlight */ /* FLAGS SET BY BOTH APPLIPROG AND INTUITION */ #define CHECKED 0x0100 /* if CHECKIT, then set this when selected */ /* FLAGS SET BY INTUITION */ #define ISDRAWN 0x1000 #define HIGHITEM 0x2000 #define MENUTOGGLED 0x4000 /* this item's subs are currently drawn */ /* this item is currently highlighted */ /* this item was already toggled */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = NewScreen = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ struct NewScreen { SHORT LeftEdge, TopEdge, Width, Height, Depth; /* screen dimensions */ UBYTE USHORT USHORT struct UBYTE struct DetailPen, BlockPen; ViewModes; Type; TextAttr *Font; *DefaultTitle; Gadget *Gadgets; /* for bar/border/gadget rendering */ /* the modes for the ViewPort (and View) */ /* the screen type (see defines below) */ /* this screen's default text attributes */ /* the default title for this screen */ /* not used; should be NULL*/
/* If you are opening a CUSTOMSCREEN and already have a BitMap * that you want used for your screen, you set the flags CUSTOMBITMAP in * the Types variable and you set this variable to point to your BitMap * structure. The structure will be copied into your screen structure,
B-11
struct };
* after which you may discard your own BitMap if you want */ BitMap *CustomBitMap;
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = NewWindow = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ struct NewWindow { SHORT LeftEdge, TopEdge; /* screen dimensions of window */ SHORT Width, Height; /* screen dimensions of window */ UBYTE ULONG ULONG DetailPen, BlockPen; IDCMPFlags; Flags; /* for bar/border/gadget rendering */ /* user-selected IDCMP flags */ /* see Window struct for defines */
struct
/* You supply a linked-list of gadgets for your window. * This list DOES NOT include system gadgets. You get the standard * system window gadgets by setting flag-bits in the variable Flags (see * the bit definitions under the window structure definition) */ Gadget *FirstGadget;
/* The CheckMark is a pointer to the imagery that will be used when * rendering Menultems of this window that want to be checkmarked * if e this is equal to NULL, you'll get the default imagery */ struct Image *CheckMark; UBYTE *Title; /* the title text for this window */ /* The Screen pointer is used only if you've defined a CUSTOMSCREEN and * want this window to open in it. If so, you pass the address of the * custom screen structure in this variable. Otherwise, this variable * i.e. s ignored and doesn't have to be initialized. */ Screen *Screen; /* SUPER-BITMAP window? If so, put the address of your BitMap structure * in this variable. If not, this variable is ignored and doesn't have * to be initialized */ BitMap *BitMap; /* The values describe the minimum and maximum sizes of your windows. * These matter only if you've chosen the WINDOWSIZING gadget option,
struct
struct
B-12
SHORT SHORT
* which means that you want to let the user change the size of * this window. You describe the minimum and maximum sizes that the * window can have by setting these variables. You can initialize * any one of these to zero, which will mean that you want to duplicate * the setting for that dimension (if MinWidth == 0, MinWidth will be * set to the opening width of the window). * You can change these settings later using SetWindowLimits(). * If you haven't asked for a SIZING gadget, you don't have to * initialize any of these variables. */ MinWidth, MinHeight; /* minimums */ MaxWidth, MaxHeight; /* maximums */ /* The type variable describes the screen in which you want this window to * open. The type value can either be CUSTOMSCREEN or one of the * system standard screen types such as WBENCHSCREEN. See the * type definitions under the Screen structure */ Type;
USHORT };
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = Preferences = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* these are the definitions for the printer configurations */ #define FILENAME SIZE 30 /* Filename size */ #define POINTERSIZE (1 + 16 + 1)*2 /* Size of Pointer data buffer */ /* These defines are for the default font size. These actually describe the * height of the default fonts. The default font type is the topaz * font, which is a fixed-width font that can be used in either * eighty-column or sixty-column mode. The Preferences structure reflects * which is currently selected by the value found in the variable FontSize, * which may have either of the values defined below. These values actually * are used to select the height of the default font. By changing the * height, the resolution of the font changes as well. */ #define TOPAZ EIGHTY 8 #define TOPAZ_SIXTY 9 struct Preferences { /* the default font height */ BYTE FontHeight; /* height for system default font */ /* constant describing what's hooked up to the port */
B-13
UBYTE USHORT struct struct struct USHORT BYTE BYTE USHORT USHORT USHORT USHORT USHORT USHORT USHORT USHORT BYTE BYTE WORD BOOL USHORT UBYTE USHORT USHORT USHORT UWORD UWORD USHORT USHORT USHORT WORD USHORT UWORD USHORT
PrinterPort;
/* the baud rate of the port */ BaudRate; /* baud rate for the serial port */ /* various timing rates */ timeval KeyRptSpeed; timeval KeyRptDelay; timeval DoubleClick; /* repeat speed for keyboard */ /* Delay before keys repeat */ /* Interval allowed between clicks */
/* Intuition Pointer data */ PointerMatrix[POINTERSIZE]; /* Definition of pointer sprite */ XOffset; /* XOffset for active `bit' */ YOffset; /* Y-Offset for active `bit' */ color17; /***********************************/ color18; /* Colors for sprite pointer*/ color19; /***********************************/ PointerTicks; /* Sensitivity of the pointer*/ /* Workbench screen colors */ color0; color1; color2; color3; /***********************************/ /* Standard default colors */ /* Used in the Workbench */ /***********************************/
/* positioning data for the Intuition View */ ViewXOffset; /* Offset for top lefthand corner */ ViewYOffset; /* X and Y dimensions */ ViewInitX, ViewInitY; /* View initial offset values */ EnableCLI; /* CLI availability switch */ /* printer type */ /* file for printer */
/* print format and quality configurations */ PrintPitch; /* print pitch */ PrintQuality; /* print quality */ PrintSpacing; /* number of lines per inch */ PrintLeftMargin; /* left margin in characters */ PrintRightMargin; /* right margin in characters */ PrintImage; /* positive or negative */ PrintAspect; /* horizontal or vertical */ PrintShade; /* b&w, half-tone, or color */ PrintThreshold; /* darkness ctrl for b/w dumps */ /* print paper descriptors */ PaperSize; /* paper size */ PaperLength; /* paper length in number of lines */ PaperType; /* continuous or single sheet */
B-14
BYTE };
padding[50];
/* PrinterPort */ #define PARALLEL PRINTER 0x00 #define SERIAL PRINTER 0x01 /* BaudRate */ #define BAUD_110 #define BAUD_300 #define BAUD_1200 #define BAUD_2400 #define BAUD_4800 #define BAUD_9600 #define BAUD_19200 #define BAUD_MIDI /* PaperType */ #define FANFOLD #define SINGLE /* PrintPitch */ #define PICA #define ELITE #define FINE /* PrintQuality */ #define DRAFT #define LETTER /* PrintSpacing */ #define SIX_LPI #define EIGHT LPI 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x00 0x80 0x000 0x400 0x800 0x000 0x100 0x000 0x200 0x00 0x01 0x00 0x01 0x00 0x01 0x02
/* Print Image */ #define IMAGE_POSITIVE #define IMAGE_NEGATIVE /* PrintAspect */ #define ASPECT_HORIZ #define ASPECT_VERT /* PrintShade */ #define SHADE_BW #define SHADE_GREYSCALE #define SHADE_COLOR /* PaperSize */ #define US_LETTER #define US_LEGAL 0x00 0x10
B-15
/* PrinterType */ #define CUSTOM_NAME 0x00 #define ALPHA _P_101 0x01 #define BROTHER_15XL 0x02 #define CBM_MPS1000 0x03 #define DIAB_630 0x04 #define DIAB_ADV_D25 0x05 #define DIAB_C_150 0x06 #define EPSON 0x07 #define EPSON_JX_80 0x08 #define OKIMATE_20 0x09 #define QUME_LP_20 0x0A /* new printer entries, 3 October 1985 */ #define HP_LASERJET 0x0B #define HP LASERJET_PLUS 0x0C /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = PropInfo = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* This is the special data required by the proportional gadget * typically, this data will be pointed to by the gadget variable SpecialInfo */ struct PropInfo { USHORT Flags; /* general-purpose flag bits (see defines below) */ /* You initialize the pot variables before the gadget is added to * the system. Then you can look here for the current settings * any time, even while user is playing with this gadget. To * adjust these after the gadget is added to the system, use * ModifyProp(); the pots are the actual proportional settings, * where a value of zero means zero and a value of MAXPOT means * that the gadget is set to its maximum setting. USHORT HorizPot; /* 16-bit FixedPoint horizontal quantity percentage */ USHORT VertPot; /* 16-bit FixedPoint vertical quantity percentage */ /* The 16-bit FixedPoint Body variables describe what percentage of * the entire body of stuff referred to by this gadget is actually * shown at one time. This is used with the AUTOKNOB routines, * to adjust the size of the AUTOKNOB according to how much of * the data can be seen. This is also used to decide how far * to advance the pots when user hits the container of the gadget. * For instance, if you were controlling the display of a 5-line * window of text with this gadget, and there was a total of 15
B-16
* lines that could be displayed, you would set the VertBody value to * (MAXBODY / (TotalLines / DisplayLines)) = MAXBODY / 3 * Therefore, the AUTOKNOB would fill 1/3 of the container, and * if user hits the container outside of the knob, the pot would * advance 1/3 (plus or minus). If there's no body to show, or * the total amount of displayable info is less than the display area, * set the body variables to the MAX. To adjust these after the * gadget is added to the system, use ModifyProp(); */ USHORT HorizBody; /* horizontal Body */ USHORT VertBody; /* vertical Body */ /* these are the variables that Intuition sets and maintains */ USHORT CWidth; /* container width (with any relativity absoluted) */ USHORT CHeight; /* container height (with any relativity absoluted) */ USHORT HPotRes, VPotRes; /* pot increments */ USHORT LeftBorder; /* container borders */ USHORT TopBorder; /* container borders */ /*---- FLAG BITS ---------------------------------------------------------*/ #define AUTOKNOB 0x0001 /* this flag says give me the auto-knob */ #define FREEHORIZ 0x0002 /* if set, the knob can move horizontally */ #define FREEVERT 0x0004 /* if set, the knob can move vertically */ #define PROPBORDERLESS 0x0008 /* if set, no border will be rendered */ #define KNOBHIT 0x0100 /* set when this knob is hit */ #define KNOBHMIN #define KNOBVMIN #define MAXBODY #define MAXPOT 6 4 0xFFFF 0xFFFF /* minimum horizontal size of the knob */ /* minimum vertical size of the knob */ /* maximum body value */ /* maximum pot value */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = Remember = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* This structure is used for remembering what memory has been allocated to * date by a given routine, so that a premature abort or systematic exit * can deallocate memory cleanly, easily, and completely struct Remember { struct Remember *NextRemember; ULONG RememberSize; UBYTE *Memory; };
B-17
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = =Requester = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ struct Requester { /* The ClipRect and BitMap are used for rendering the requester */ struct Requester *OlderRequest; SHORT LeftEdge, TopEdge; /* dimensions of the entire box */ SHORT Width, Height; /* dimensions of the entire box SHORT RelLeft, RelTop; /* for pointer relativity offsets struct Gadget *ReqGadget; /* pointer to a list of gadgets struct Border *ReqBorder; /* the box's border struct IntuiText *ReqText; /* the box's text */ USHORT Flags; /* see definitions below /* pen number for back-plane fill before draws */ UBYTE BackFill; /* Layer in place of clip rect */ struct Layer *ReqLayer; UBYTE ReqPad1[32]; /* If the BitMap plane pointers are non-zero, this tells the system * that the image comes predrawn (if the appliprog wants to define * its own box, in any shape or size it wants!); this is OK by * Intuition as long as there's a good correspondence between * the image and the specified gadgets */ BitMap *ImageBMap; /* points to the BitMap of PREDRAWN imagery */ Window *RWindow; /* added; points back to window */ ReqPad2[36];
/* FLAGS SET BY THE APPLIPROG */ #define POINTREL 0X0001 /* if POINTREL set,TopLeft is relative to pointer */ #define PREDRAWN 0x0002 /* if ReqBMap points to predrawn requester imagery */ /* FLAGS SET BY BOTH THE APPLIPROG AND INTUITION /* FLAGS SET BY INTUITION */ #define REQOFFWINDOW 0x1000 /* part of one of the gadgets was off-window */ #define REQACTIVE 0x2000 /* this requester is active */ #define SYSREQUEST 0x4000 /* this requester caused by system */ #define DEFERREFRESH 0x8000 /* this requester stops a refresh broadcast */
B-18
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = Screen = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ struct Screen { struct Screen *NextScreen; /* linked list of screens */ struct Window *FirstWindow; /* linked list of screen's windows */ SHORT SHORT SHORT USHORT UBYTE UBYTE BYTE BYTE struct struct struct struct struct struct UBYTE LeftEdge, TopEdge; Width, Height; MouseY, MouseX; Flags; *Title; *DefaultTitle; /* parameters of the screen */ /* parameters of the screen */ /* position relative to upper left */ /* see definitions below */ /* null-terminated title text */ /* for windows without ScreenTitle */
/* Bar sizes for this screen and all windows in this screen */ BarHeight, BarVBorder, BarHBorder, MenuVBorder, MenuHBorder; WBorTop, WBorLeft, WBorRight, WBorBottom; TextAttr *Font; /* this screen's default font */
/* the display data structures for this screen */ ViewPort ViewPort; /* describing the screen's display */ RastPort RastPort; /* describing screen rendering */ BitMap BitMap; /* auxiliary graphexcess baggage Layer_Info Layerlnfo; /* each screen gets a Layerlnfo */ Gadget *FirstGadget; DetailPen, BlockPen; /* only system gadgets are supported */ /* for bar/border/gadget rendering */
USHORT struct
/* The following variable(s) are maintained by Intuition to support the * DisplayBeep() color-flashing technique. */ SaveColor0; /* This layer is for the screen and menu bars */ Layer *BarLayer;
UBYTE *ExtData; UBYTE *UserData; /* general-purpose pointer to user data extension */ /* --- FLAGS SET BY INTUITION ------------------------------------------- */ /* The SCREENTYPE bits are reserved for describing various screen types * available under Intuition.
B-19
#define SCREENTYPE 0x000F /* all the screens types available */ /* --- the definitions for the screen type -------------------------------------------- */ #define WBENCHSCREEN 0x0001 /* Ta Da! The Workbench */ #define CUSTOMSCREEN 0x000F /* for that special look */ #define SHOWTITLE 0x0010 /* this gets set by a call to ShowTitle()*/ #define BEEPING 0x0020 /* set when screen is beeping */ #define CUSTOMBITMAP 0x0040 /* if you are supplying your own BitMap */ */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = StringInfo= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* this is the special data required by the string gadget * typically, this data will be pointed to by the gadget variable SpecialInfo */ struct Stringlnfo { /* you initialize these variables, and then Intuition maintains them */ UBYTE *Buffer; /* the buffer containing the start and final string */ UBYTE *UndoBuffer; /* optional buffer for undoing current entry */ SHORT BufferPos; /* character position in buffer */ SHORT MaxChars; /* max number of chars in buffer (including NULL) */ SHORT DispPos; /* buffer position of first displayed character */ /* Intuition initializes and maintains these variables for you */ SHORT UndoPos; /* character position in the undo buffer */ SHORT NumChars; /* number of characters currently in buffer */ SHORT DispCount; /* number of whole characters visible in container */ SHORT CLeft, CTop; /* topleft offset of the container */ struct Layer *LayerPtr; /* the RastPort containing this gadget */ /* You can initialize this variable before the gadget is submitted to * Intuition, and then examine it later to discover what integer * the user has entered (if the user never plays with the gadget, * the value will be unchanged from your initial setting) */ LongInt; /* If you want this gadget to use your own console keymapping, you * set the ALTKEYMAP bit in the Activation flags of the gadget, and then * set this variable to point to your keymap. If you don't set the * ALTKEYMAP, you'll get the standard ASCII keymapping. KeyMap *AltKeyMap;
LONG
struct };
B-20
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = Window = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ struct Window { struct Window *NextWindow; /* for the linked list in a screen */ SHORT SHORT SHORT SHORT SHORT ULONG struct UBYTE struct struct SHORT struct struct LeftEdge, TopEdge; Width, Height; MouseY, MouseX; MinWidth, MinHeight; MaxWidth, MaxHeight; Flags; Menu *MenuStrip; *Title; Requester *FirstRequest; Requester *DMRequest; ReqCount; Screen *WScreen; RastPort *RPort; /* screen dimensions of window */ /* screen dimensions of window */ /* relative to upper left of window */ /* minimum sizes */ /* maximum sizes */ /* see below for defines */ /* the strip of menu headers */ /* the title text for this window */ /* all active requesters */ /* double-click requester */ /* count of reqs blocking window */ /* this window's screen */ /* this window's very own RastPort */
BYTE struct
/* The border variables describe the window border. If you specify * GIMMZEROZERO when you open the window, then the upper-left of the * ClipRect for this window will be upper-left of the BitMap (with correct * offsets when in SuperBitMap mode; you MUST select GIMMEZEROZERO when * using SuperBitMap). If you don't specify ZeroZero, then you save * memory (no allocation of RastPort, Layer, ClipRect and associated * Bitmaps), but you also must offset all your writes by BorderTop, * BorderLeft and do your own mini-clipping to prevent writing over the * system gadgets */ BorderLeft, BorderTop, BorderRight, BorderBottom; RastPort *BorderRPort; /* You supply a linked list of gadgets for your window. * This list DOES NOT include system gadgets. You get the standard * window system gadgets by setting flag-bits in the variable Flags (see * the bit definitions below) */ Gadget *FirstGadget;
struct
B-21
struct
/* these are for opening/closing the windows */ Window *Parent, *Descendant; /* Sprite data information for your own pointer; * set these AFTER you open the window by calling SetPointer() */ *Pointer; /* sprite data */ PtrHeight; /* sprite height (not including sprite padding) */ PtrWidth; /* sprite width (must be less than or equal to 16) */ XOffset, YOffset; /* sprite offsets */ /* The IDCMP Flags and user's and Intuition's message ports */ IDCMPFIags; /* user-selected flags */ MsgPort *UserPort, *WindowPort; IntuiMessage *MessageKey; DetailPen, BlockPen; /* for bar/border/gadget rendering */
/* The CheckMark is a pointer to the imagery that will be used when * rendering Menultems of this window that want to be checkmarked * if this is equal to NULL, you'll get the default imagery */ struct UBYTE Image *CheckMark; *ScreenTitle; /* if non-null, screen title when window is active*/
SHORT SHORT
/* These variables have the mouse coordinates relative to the * inner window of GIMMEZEROZERO windows. This is compared with the * MouseX and MouseY variables, which contain the mouse coordinates * relative to the upper left corner of the window, GIMMEZEROZERO * notwithstanding */ GZZMouseX; GZZMouseY; /* These variables contain the width and height of the inner window of * GIMMEZEROZERO windows. */ GZZWidth; GZZHeight; *ExtData; *UserData; /* general-purpose pointer to user data extension */
struct };
/* This pointer keeps a duplicate of what * Window.RPort->Layer is supposed_ to be pointing at. */ Layer *WLayer;
B-22
/* --FLAGS REQUESTED (NOT DIRECTLY SET THOUGH) BY THE APPLIPROG -- */ #define WINDOWSIZING 0x0001 /* include sizing system-gadget? */ #define WINDOWDRAG 0x0002 /* include dragging system-gadget? */ #define WINDOWDEPTH 0x0004 /* include depth arrangement gadget? */ #define WINDOWCLOSE 0x0008 /* include close-box system-gadget? */ #define SIZEBRIGHT 0x0010 /* size gadget uses right border */ #define SIZEBBOTTOM 0x0020 /* size gadget uses bottom border */ /* --- refresh modes -------------------------------------------------------------------- */ /* combinations of the REFRESHBITS select the refresh type */ #define REFRESHBITS 0x00C0 #define SMART REFRESH 0x0000 #define SIMPLE REFRESH 0x0040 #define SUPER BITMAP 0x0080 #define OTHER_REFRESH 0x0000 #define BACKDROP #define REPORTMOUSE #define GIMMEZEROZERO #define BORDERLESS #define ACTIVATE 0x0100 0x0200 0x0400 0x0800 0x1000 /* this is an ever-popular Backdrop window */ /* set this to hear about every mouse move */ /* make extra border stuff */ /* set this to get a window sans border */ /* when window opens, it's the active one */ /* this window is the active one */ /* this window is in request mode */ /* this window is active with its menus on */
/* FLAGS SET BY INTUITION */ #define WINDOWACTIVE 0x2000 #define INREQUEST 0x4000 #define MENUSTATE 0x8000
/* --- Other user flags --------------------------------------------------------------------- */ #define RMBTRAP 0x00010000 /* Catch RMB events for your own */ #define NOCAREREFRESH 0x00020000 /* not to be bothered with REFRESH */ /* --- Other Intuition Flags---------------------------------------------------------------- */ #define WINDOWREFRESH 0x01000000 /* window is currently refreshing */ #define WBENCHWINDOW 0x02000000 /* WorkBench tool ONLY window */ #define WINDOWTICKED 0x04000000 /* only one timer tick at a time */ #define SUPER UNUSED 0xFCFC0000 /* bits of Flag unused yet */
B-23
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = =Miscellaneous = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = MACROS= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ #define MENUNUM(n) #define ITEMNUM(n) #define SUBNUM(n) #define SHIFTMENU(n) #define SHIFTITEM(n) #define SHIFTSUB(n) (n & 0x1F) ((n > > 5) & 0x003F) ((n > > 11) & 0x001F) (n & 0x1F) ((n & 0x3F) < < 5) ((n & 0x1F) < < 11)
/* = = = MENU STUFF = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ #define NOMENU 0x001F #define NOITEM 0x003F #define NOSUB 0x00lF #define MENUNULL 0xFFFF /* = = = =RJ='s peculiarities = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ #define FOREVER for(;;) #define SIGN(x) ( ((x) > 0) - ((x) < 0) ) #define NOT ! /* These defines are for the COMMSEQ and CHECKIT menu stuff. If CHECKIT, * I'll use a generic width (for all resolutions) for the CheckMark. * If COMMSEQ, likewise I'll use this generic stuff */ #define CHECKWIDTH 19 #define COMMWIDTH 27 #define LOWCHECKWIDTH 13 #define LOWCOMMWIDTH 16 /* These are the AlertNumber defines. if you are calling DisplayAlert() * the AlertNumber you supply must have the ALERT_TYPE bits set to one * of these patterns */ #define ALERT_ TYPE 0x80000000 #define RECOVERY_ALERT 0x00000000 /* the system can recover from this */ #define DEADEND_ALERT 0x80000000 /* no recovery possible, this is it */ /* When you're defining IntuiText for the positive and negative gadgets * created by a call to AutoRequest(), these defines will get you * reasonable-looking text. The only field without a define is the Itext * field; you decide what text goes with the gadget */ #define AUTOFRONTPEN 0 #define AUTOBACKPEN 1
B-24
#define AUTODRAWMODE #define AUTOLEFTEDGE #define AUTOTOPEDGE #define AUTOITEXTFONT #define AUTONEXTTEXT
/* ---RAWMOUSE Codes and Qualifiers (Console OR IDCMP) ------------------------------ */ #define SELECTUP (IECODE_LBUTTON I IECODE_UP_PREFIX) #define SELECTDOWN (IECODE_LBUTTON) #define MENUUP (IECODE_RBUTTON IECODE_UP PREFIX) #define MENUDOWN (IECODE_RBUTTON) #define ALTLEFT (IEQUALIFIER_LALT) #define ALTRIGHT (IEQUALIFIER_RALT) #define AMIGALEFT (IEQUALIFIER_LCOMMAND) #define AMIGARIGHT (IEQUALIFIER_RCOMMAND) #define AMIGAKEYS (AMIGALEFT AMIGARIGHT) #define CURSORUP #define CURSORLEFT #define CURSORRIGHT #define CURSORDOWN #define KEYCODE_Q #define KEYCODE_X #define KEYCODE _N #define KEYCODE_M 0x4C 0x4F 0x4E 0x4D 0x10 0x32 0x36 0x37
#endif
B-25
B-26
Appendix C
INTERNAL PROCEDURES
This appendix discusses the more esoteric and internal Intuition functions. These functions are definitely not for the casual user. Using these functions can seriously alter the user's environment, which is potentially a hazardous thing to do. You have more leeway when using these functions in a machine environment in which you have taken complete control of the Amiga and do not intend to allow other tasks to coexist with yours. However, if you intend to have your program run in the multitasking environment, please use these routines thoughtfully. The effects on other people's programs and on the users understanding of the normal course of events can be dramatic at best, and can cause serious loss of data and loss of the user's confidence in using the Amiga.
C-1
With that caveat aside, here are the functions covered in this appendix: SetPrefs() This routine allows you to set Intuition's internal state of the Preferences. AlohaWorkbench() This routine allows the Workbench tool to make its presence and departure known to Intuition. Intuition() This is the main entry point into Intuition, where input events arrive and are dispatched.
SetPrefs()
This routine configures Intuition's internal data states according to the specified Preferences structure. Normally, this routine is called only by: o The Preferences program itself after the user has changed the Preferences. The Preferences program also saves the user's Preferences data into a disk file named devs:system-configuration. o AmigaDOS when the system is being booted up. AmigaDOS opens the devs:systemconfiguration file and passes the information found there to the SetPrefs() routine. This way, the user can create an environment and have that environment restored every time the system is booted. Note that the intended use for the SetPrefs() call is entirely to serve the user. You should never use this routine to make your programming or design job easier at the cost of yanking the rug out from beneath the user. The synopsis of this function is: SetPrefs(Preferences, Size, RealThing) Preferences - a pointer to a Preferences structure
C-2
Size - the number of bytes contained in your Preferences structure. Typically, you will use "sizeof(struct Preferences)" for this argument. RealThing - a Boolean TRUE or FALSE designating whether or not this is an intermediate or final version of the Preferences. The difference is that final changes to Intuition's preferences causes a global broadcast of NEWPREFS events to every application that is listening for this event. Intermediate changes may be used, for instance, to update the screen colors while the user is playing with the color gadgets. Refer to chapter 11, "Other Features," for information about the Preferences structure and the standard Preferences procedure calls.
AlohaWorkbench()
In Hawaiian, "aloha" means both hello and goodbye. The AlohaWorkbench() routine allows the Workbench program to inform Intuition that it has become active and that it is shutting down. If the Workbench program is active, Intuition is able to tell it to open and close its windows when someone uses the Intuition OpenWorkBench() and CloseWorkBench() functions to open or close the Workbench screen. If the Workbench program is not active, presumably it has no opened windows, so there is no need for this communication. This routine is called with one of two kinds of arguments-either a pointer to an initialized message port (which designates that Workbench is active and communications can take place), or NULL to designate that the Workbench tool is shutting down. When the message port is active, Intuition will send IntuiMessages to it. The messages will have the Class field set to WBENCHMESSAGE. The Code field will equal either WBENCHOPEN or WBENCHCLOSE, depending on whether the Workbench application should open or close its windows. Intuition assumes that Workbench will comply, so as soon as the message is replied to, Intuition proceeds with the expectation that the windows have been opened or closed accordingly. The procedure synopsis is: AlohaWorkbench(WBPort) WBPort - a pointer to an initialized MsgPort structure in which the special communications are to take place.
C-3
Intuition()
This is Intuition's main entry point. All of Intuition's I/O operations originate here. The input stream flows into Intuition at this portal. This routine accepts a single argument: a pointer to a linked list of InputEvent structures. These events have all the real-time state information that Intuition needs to create its art. Refer to the Amiga ROM Kernel Manual for more information about InputEvent structure and the operation of the input device. When Intuition() exits, it returns a pointer to a linked list of InputEvent structures. This list of InputEvents has no dependable correspondence to the list that was initially submitted to Intuition(). Intuition may add events to the list and extract events from the list. This list of events is normally intended for the console device. If you are considering feeding false input events to Intuition, please think again. If you are running in an environment in which you have taken over the machine, it is probably safe to fool Intuition in a controlled way. If you are running in a multitasking environment, however, especially one in which the input device is still feeding input events directly into the stream, you can easily cause more harm than good. You may not be able to anticipate the things that could go wrong when other programs try to exist in an environment that you are modifying. If you are determined to feed false input events to Intuition, it is much safer to add an input handler to the system than to call Intuition(). Add the input handler to the system at a priority higher than Intuition's; the input queue priority of Intuition is 50, so a priority of 51 will suffice. This will allow your program to see all input events before Intuition sees them. You can filter the input events, allowing Intuition to see only those events that you want it to see. Also, you can add synthesized events to the input event stream. This allows you to fool Intuition in an honest, system-integrated way. For example, say that you want to position the pointer yourself but you want to let the user interact with the rest of the system as usual. If you see mouse movement events, you can filter them out and not let Intuition see them. At the same time, you can create mouse movement events of your own. On the other hand, if you see keyboard events you can leave them undisturbed. See the Amiga ROM Kernel Manual for details about the input-handler queue. An important note is that Intuition() is sometimes required to call the Exec Wait() function. Normally, Intuition() is called from within the input device's task, so the input device enters the wait state when these situations arise. If you call Intuition() directly, your task may have to wait. The obvious problem here is the classic lockout problem your task cannot create the required response because your task has forced
C-4
itself to wait, which will cause the system to freeze. The best way to get around this is to have a separate task that calls Intuition() and does nothing more. The synopsis of this function is: Intuition(InputEvent) InputEvent - a pointer to the first in a linked list of InputEvent structures.
C-5
C-6
Glossary
Active screen Active window Alert The screen containing the active window. The window receiving user input. Only one window is active at a time. Information exchange device displayed by the system or the application when serious problems occur or when immediate action is necessary. Two command keys on the keyboard to the left and right of the Amiga keys. An image or border used in gadget highlighting. When the gadget is selected, the alternate image or border is substituted for the original image or border. Two command keys on the keyboard to the left and right of the space bar. The Amiga disk operating system. A custom gadget created by the developer. The special automatic knob for proportional gadgets; changes its shape according to the current proportional settings. A window that stays anchored to the back of the display. The complete definition of a display in memory, consisting of one or more bit-planes and information about how to organize the rectangular display. A contiguous series of memory words, treated as if it were a rectangular shape.
Bit-plane
G-1
Body variables Boolean gadget Border area Border line Borderless window Buffer Checkmark
Proportional gadget variables that contain the increment by which the pot variables may change. A simple yes-or-no gadget. The area containing border gadgets. The default double-line drawn around the perimeter of all windows, except Borderless windows. A window with no drawn border lines. An area of continuous memory, typically used for storing blocks of data such as text strings. A small image that appears next to a menu item showing that the user has selected that item. By default, the checkmark is .J , but a custom image can be substituted. See Command Line Interface. To quickly press and release a mouse button. A Workbench file used to store the last data cut (removed) from a project. Causing a graphical rendering to appear only in some bounded area, such as only within the non-concealed areas of a window. To remove a window or screen from the display. Gadget in the upper left corner of a screen or window that the user selects to request that a window or screen be closed. The method used by Amiga for coloring individual pixels, in which the binary number formed from all the bits that define a given pixel refers to one of the 32 color registers. Each of the 32 color registers can be set equal to any of 4,096 colors. The set of colors available in a screen.
Color palette
G-2
One of 32 hardware registers containing colors that you can define. A set of adjoining pixels that forms a vertical line on the video display. Keys that combine with alphanumeric keys to create command key sequences, which substitute for making selections with the mouse buttons. The conventional interface to system commands and utilities. The binary complement of a color, used as a method of gadget highlighting and in flashing the screen. To complement a binary number means to change all the is to Os and all the Os to is. A communication path for both user input and program output. Especially recommended for input/output of text-only applications. Part of a proportional gadget; the area within which the knob or slider can move; the select box of the gadget. Special sequences of characters that start with the "Escape" character. A hardware device, such as a mouse or a light pen, used to move the pointer or furnish some other input. A pair of numbers shown in the form (x,y), where x is an offset from the left side of the display or display component and y is an offset from the top. Display-synchronized coprocessor that handles the Amiga video display. See Copper. The arrow keys, which can be used as a substitute for using the mouse to move the pointer. The grouping together of the components required to define some data element.
Console device
G-3
Depth
Depth-arrangement gadgets Gadgets in the title bar of a screen or window used to send the screen or window to the back of the display or bring it up front. Disable Display Display field Display memory To make something unavailable to the user. To put up a screen, window, requester, alert, or any other graphics object on the video display. One complete scanning of the video beam from top to bottom of the video display screen. The RAM that contains the information for the display imagery; the hardware translates the contents of the display memory into video signals. Display parameters set in the definition of a screen. The modes are high or low horizontal resolution, interlaced or noninterlaced vertical resolution, sprite mode, and dualplayfield mode. To quickly press and release a mouse button twice. A requester that the user can open by double-clicking the mouse menu button. To move an icon, gadget, window, or screen by placing the pointer over the object to be moved and holding down the selection button while moving the mouse. The portion of a window or screen title bar that contains no other gadgets, used for moving a window or screen around on the video display. A display mode that allows you to manage two separate display memories, giving you two separately controllable displays at the same time. A menu for text processing that includes various text-editing functions. To make something available to the user; a menu item or gadget that is enabled can be selected by the user.
Display modes
Drag gadget
Dual-playfield mode
G-4
Low-level primitives that comprise the Amiga multitasking operating system. A technique for selecting more than one menu item at a time. To put a color or pattern within an enclosed area. A mechanism for selecting an option or detecting a state; a name representing a bit to be set or cleared. A set of letters, numbers, and symbols that share the same basic design. Any of the control devices provided within a window, screen, or requester; employed by users to change what is being displayed or to communicate with an application or with Intuition. Display less distinctly (overlay an area with a faint pattern of dots) to indicate that something, such as a gadget or a window, is not available or not active. The new outline of a window that shows briefly when the user is dragging or sizing a window. A window with a separate bit-map for the window border. A file that is included at the beginning of a C program and contains definitions of data types and structures, constants, and macros. A horizontal display mode in which 640 pixels are displayed across a horizontal line. To modify the display of a selected menu item or gadget in a way that distinguishes it from its non-selected state. A method of gadget selection in which the gadget is unselected as soon as the select button is released. A display mode that gives you extended color selection up to 4,096 colors on the screen at one time. The characteristic of a color that is determined by the color's position in the color spectrum.
Ghost
G-5
Icon IDCMP
A visual representation of an object in the Workbench, such as a program, file, or disk. "Intuition Direct Communications Message Ports"; the primary communication path for user input to an application. Gives mouse and keyboard events and Intuition events in raw form. Provides a path for communicating to Intuition. To set up an Intuition component with certain default parameters. The message created by the input device whenever a signal is detected at one of the Amiga input ports. A vertical display mode in which 400 lines are displayed from top to bottom of the video display. The input message created by Intuition for application programs; the message is the medium in this case. Translation table used by the console device to translate keycodes into normal characters. Part of a proportional gadget; the user manipulates the knob to set a proportional value. A collection of predefined functions that can be used by any program. A collection of like objects linked together by having a pointer variable in one contain the address of the next; the last object in the list has a next-pointer of NULL. A horizontal display mode in which 320 pixels are displayed. across a horizontal line. A category that has menu items associated with it. One of the entries in the menu list displayed in the screen title bar. A strip in the screen title bar that shows the menu list when the user holds down the menu button. The right-hand button on the mouse.
Initialize Input event Interlaced mode IntuiMessage KeyMap Knob Library Linked list
G-6
Menu item Menu list Menu shortcut Menu title Message ports Mouse Multitasking Mutual exclusion Non-interlaced mode Null-terminated Offset Open Option Parallel port Pen
One of the choices in a menu; the options presented to the user. List of menus displayed in the screen title bar when the user holds down the menu button. An alternate way of choosing a menu item by pressing a key on the keyboard while holding down the right AMIGA key. See Menu. A software mechanism managed by the Amiga Exec that allows intertask communications. A controller device used to move the pointer and make selections. A system in which many tasks can be operating at the same time, with no task forced to be aware of any other task. The principle that says that selecting a menu item (or gadget) can cause other menu items (or gadgets) to become deselected. A display mode in which 200 lines are displayed from top to bottom of the video display. A string that ends with a byte of zero; text strings must be nullterminated. A position in the display that is relative to some other position. For the user, to display a window. For an application, to display a window or screen. A feature that, once selected, persists until it is deselected. A connector on the back of the Amiga used to attach printers and other add-ons. A variable containing a color register number used for drawing lines or filling background.
G-7
Short for "picture element." The smallest addressable element in the video display. Each pixel is one dot of color. One of the basic elements in Amiga graphics; the background for all the other display elements. A small object, usually an arrow, that moves on the display when the user moves the mouse (or the cursor keys). It is used to choose menu items, open windows, and drag and select other objects. Proportional gadget proportional values. variables that contain the actual
A program that allows the user to change various settings of an Amiga. To keep overlapped portions of the display in hidden memory buffers. Amiga low-level library functions. A menu for opening and saving project files. A gadget used to display a proportional value or get a proportional setting from the user. Consists of a knob or slider and a container. Random access (volatile) memory. The area in memory where the bit-map is located. The data structure that defines the general parameters of display memory. To recreate a display that was hidden and is now revealed. To draw or write into display memory. A rectangular information exchange region in a window. When a requester appears, the user must select a gadget in the requester to close the requester before doing anything else in the window.
G-8
On a video display, the number of pixels that can be displayed in the horizontal and vertical directions. A full-width area of the display with a set color palette, resolution, and other display modes. Windows open in screens. To move the contents of display memory within a window. A proportional gadget with which the user can display different parts of the display memory. To pick a gadget or menu item. The sensitive area of a gadget or menu item. When the user moves the pointer within a gadget's select box, the gadget becomes selected. The left-hand button on a mouse. An option that is currently in effect. A quick way to select a gadget by pressing some key while holding down the left Amiga key. A connector on the back of the Amiga used to attach modems and other serial add-ons. A quick way, from the keyboard, to choose a menu item or select a gadget. A method of refreshing window display in which concealed areas are redrawn by the program when they are revealed To change the dimensions of a window or screen. A gadget for the user to change the size of a window or a screen. Part of a proportional gadget; used to pick a value within a range by dragging the slider or by moving the slider by increments with clicks of a mouse button.
Select button Selected option Selection shortcut Serial port Shortcut Simple Refresh Size Sizing gadget Slider
G-9
Smart Refresh
A method of refreshing window display in which Intuition keeps information about concealed areas in off-display buffers and refreshes the display from this information. If the window is sized, the program may have to recreate the display. A small, easily movable graphic object. You can have multiple sprites in a window at the same time. A display mode that allows you to have sprites in your windows. A gadget that prompts the user to enter a text string or an integer. See data structure. An additional menu that appears when some menu items are chosen by the user. A method of window refresh where the display is recreated from a separate bit-map area. A window with its own bit-map; doesn't use the screen's bitmap. Predefined gadgets for windows and screens; for screens, dragging and depth arranging; for windows, dragging, depth arranging, sizing, and closing. Operating system module or application program. Each task appears to have full control over its own virtual 68000 machine. In programs containing text and in string gadgets, a marker that indicates your position in the text. A strip at the top of a screen or window that contains gadgets and an optional name for the screen or window. A method of gadget selection in which the gadget remains selected when the user releases the select button and does not become deselected until the user picks it again. An application program.
Sprite Sprite mode String gadget Structure Submenu SuperBitMap refresh SuperBitMap window System gadgets
Tool
G-10
The default system font. It is a fixed-width font in two sizes: 60 columns wide and 8 lines tall; 80 columns wide and 9 lines tall. A special color register definition that allows a background color to show through. Used in dual-playfield mode. A variation of a typeface, such as italic or bold. See Font. A text editing function that reverses an action. The message port created for you when you request IDCMP functionality. Your program receives messages from Intuition via this port. A line segment. Everything that appears on the screen of a video monitor or television. The graphics library data structure used to create the Intuition display. The graphics library data structure used to create and manage the Intuition screen. An Intuition window; it accepts input from the user and displays output from the application. Rectangular display in a screen that accepts input from the user and displays output from the application. The message port created for you when you request IDCMP functionality. You respond to messages from Intuition via this port. A program to manipulate AmigaDOS disk file objects. The primary Intuition screen.
G-11
Index
Active screen, 26 Active window, 49 AddGadget(), 92, 114 Alerts creating, 155 display, 154 types of, 155 AllocMem(), 77, 212 AllocRaster(), 76 AllocRemember(), 212, 214 AllocSignal(), 171 Alternate (ALT) keys, 207 AMIGA keys as command keys, 207 in command-key sequences, 124 in Workbench shortcuts, 208 Application gadgets (also see gadgets), 55, 86 Assembly language, 222 AutoRequest(), 140, 142, 145, 151, 153 Backdrop window, 52-53 Beeping, 221 BeginRefresh(), 61, 74 BitMap allocating memory for, 75 in SuperBitMap windows, 53 preparing, 75 Bit-planes in image display, 192 in screens, 33 Boolean gadgets, 94-95 Border variables, 51 Border structure, 184-85 Borderless window, 50-51 Borders color of, 56, 183 coordinates of, 182 defining, 181 DrawBorder(), 180, 199
drawing modes for, 183 gadgets in, 92 in Borderless windows, 50 in Gimmezerozero windows, 51-52 linking, 184 thickness of, 56 window, 56-57 window variables for, 56-57 BuildSysRequest(), 146 CDAskKeyMap(), 177 CDSetKeyMap(), 177 Character-wrap, 176 CHECKED and CHECKIT in checkmark, 122 in mutual exclusion, 123 Checkmark in menus, 122-24 Chip memory, 76-77, 198 ClearDMRequest(), 73, 144,152 ClearMenuStrip(), 71, 120, 126, 137 ClearPointer(), 62, 73 Close gadget, 86 Close(), 174 CloseScreen(), 29, 43 CloseWindow(), 50, 66, 86, 172 CloseWorkBench(), 29, 44, 230 Color in Borders, 184 in Images, 190, 193 in IntuiText, 186 in screens, 33 in windows, 63 of Workbench, 216 Command keys sequence events, 206 sequences of, 124-25 style, 227 Complementing, 93 Console device
I-1
character-wrap, 176 for input, 160 in text output, 160, 175 IOStdReq, 174-76 keymap, 176 using directly reading from, 175 writing to windows, 175 using through AmigaDOS, 174 Control (CTRL) key, 207 Copper in custom screens, 29 CurrentTime(), 221 Custom gadgets in screens, 38 in windows, 47 Custom pointer, 76-77 Custom screens closing, 29 managed by applications, 30 managed by Intuition, 30 rendering in, 31 using the Copper in, 29 Depth in Images, 194 in screens, 33 Depth-arrangement gadgets, 85 Display user settings, 216 Display element, 180 Display memory pointers into, 200 RastPort, 24 screen, 24 Display modes in custom screens, 32 set by screen, 24 DisplayAlert(), 155 DisplayBeep(), 142, 221 DoIO(), 175 DoubleClick(), 216 Dragging gadget, 25, 85-86 DrawBorder(), 180, 199 DrawGList(), 222 DrawImage(), 180, 199 Dual-playfield mode, 32 EndRefresh(), 61, 74
EndRequest(), 72,152 Escape (ESC) key, 207 Flashing the display, 221 Fonts custom, 35 default, 35 in creating text, 187 in string gadgets, 101 Topaz, 35 user settings of, 216 FreeRemember(), 212, 214 Function keys, 207 Gadget style, 226 Gadget structure, 104-109 Gadgets Boolean type hit select, 94-95 toggle select, 94-95 combining types, 102-103 enabling and disabling, 94 Gadget structure, 104-109 hand-drawn, 87 highlighting, 93 in window borders, 92 integer type, 102 line-drawn, 88 pointer broadcasts, 91 proportional type auto-knob, 97 body variables, 96 changing variables of, 99 components of, 95-99 container, 97 example of, 98 knob, 96-97 pot variables, 96-98 Proplnfo structure, 110-11 setting up, 98 select box absolute dimensions, 90 location of, 90 relative dimensions, 90 selection of, 89-92 steps in creating, 103 string type buffers, 99-100 editing functions, 101
I-2
font, 101 Stringlnfo structure, 112-13 without imagery, 89 GetDefPrefs(), 215, 220 GetPrefs(), 170, 214, 220 Ghosting, 49 Gimmezerozero window gadgets in, 52 requesters in, 52 Gimmezerozero window type, 51-52 Graphics Amiga primitives in screens, 30-31 in windows, 48, 51-52, 56 using, 200-201 images, 189-98 lines, 181-84 special Intuition functions, 199 Header files, 10 Hello World, 18 Highlighting gadgets, 93 High-resolution mode, 32 Hold-and-modify mode, 33 IDCMP allocating ports, 171 closing, 165 example of, 172 flags, 167-71 IntuiMessages, 165-66 message ports, 165 monitor task, 171-72 opening, 165 requester features, 145 UserPort, 171 verification functions, 171 WindowPort, 171 Illustration data types, 180 Images data for, 189-92 data memory, 198 defining, 189 displaying, 181, 192 DrawImage(), 180, 199 example of, 196 Image structure, 195 in gadgets, 87, 98-99
location of, 189 PrintIText, 180, 199 InitBitMap(), 75 InitRequester(), 147 Inner window in Gimmezerozero windows, 51 with the console device, 51 Input device, 159 Input event, 159 Input stream, 159 Input/output console device, 173-77 IDCMP, 164 in complex programs, 162 in game programs, 161 in text programs, 162 Input device, 159 input stream, 159 paths, 159 Integer gadgets, 102 Interlaced mode, 32 IntuiMessage structure, 165-66 IntuiMessages, 165-66 IntuiText structure, 187-89 IntuiTextLength(), 200 IOStdReq structure, 174-76 ItemAddress(), 127, 138 Key repeat, 216 Keyboard ALT keys, 207 AMIGA keys, 124, 207-8 as alternate to mouse, 208 command keys, 207 CTRL key, 207 ESC key, 207 Keymap, 176 Library opening, 10 Lines and Border structure, 184 colors of, 183 coordinates of, 182 defining, 181 displaying, 181 drawing modes for, 183 in gadgets, 181 linking, 184
I-3
LoadView(), 220 Low-resolution mode, 32 MakeScreen(), 44, 221 MakeVPort(), 221 Memory allocation of, 212 deallocation of, 212 for images, 198 for special chips, 76-77 for sprites, 198 Remember structure, 213 RememberKey, 213 special chips, 198 Menu boxes item in, 120-22 subitem in, 121 Menu commands action type, 122-23 actions, 118 attribute type, 122-23 attributes, 118 Menu items command key shortcuts, 208 enabling and disabling, 125-26 Menu messages from user selection, 125-27 MENUCANCEL, 130 MENUHOT, 130 MENUNULL, 127, 128 MENUPICK, 125, 127 MENUVERIFY, 129 MENUWAITING, 130 Menu numbers accessing of, 126-29 functioning of, 126-29 Menu operations intercepting MenuVerify, 129 RMBTRAP, 130 Menu selection by user, 120 Menu strips changing, 126 removing, 120 submitting, 120 Menu style edit menus, 225
project menus, 224 Menu system activating, 119 Menu structure, 133-34 MenuItem structure, 134-37 Menus and mutual exclusion, 122-24 and requesters, 130 checkmark, 122 command-key sequences, 124-25 designing, 131 enabling and disabling, 125-26 Menu structure, 133-34 MenuItem structure, 134-37 menu-strip, 131 menu-verify function, 129 selection from, 126-27 Message ports, 165, 171 Messages about gadget selection, 91 about pointer movements, 62. IDCMP, 165 menu selection, 126 menus, 129-30 mouse, 206 with verification functions, 171 ModifyIDCMP(), 145, 165, 167, 171-72 ModifyProp(), 99, 115 Monitor task IDCMP, 171-72 Mouse basic activities of, 204 combining buttons and movement, 205 dragging with, 205 keyboard as alternate to, 208 left (select) button, 204 messages, 206 right (information transfer) button, 205 style, 229 user setting of double-click, 216 speed, 216 Mouse button philosophy, 204 Move(), 18 MoveScreen(), 43 MoveSprite(), 222 MoveWindow(), 74
I-4
MrgCop(), 220 Mutual exclusion in gadgets, 192 in menus, 122-24 NewScreen structure, 38-41 NewWindow structure, 65-69 Non-interlaced mode, 32 OffGadget(), 94, 108, 114-15, 226 OffMenu(), 126, 133, 136, 138, 224 OnGadget(), 94, 108, 114 OnMenu(), 126, 133, 136, 138 OpenDevice(), 173, 175 Open(), 174 OpenLibrary(), 10, 18 OpenScreen(), 11, 38, 42, 49 OpenWindow(), 11, 49, 64, 71, 171 OpenWorkBench(), 29, 43, 230 Philosophy user interface, 1, 8 Pixel, 32 PlaneOnOff, 192-94 PlanePick, 192-94 Pointer attaching to window, 79 broadcasts, 61 colors, 62 custom, 62, 76-77 in gadget selection, 89-92 position in Gimmezerozero windows, 51 position in windows, 61-62 variables, 61-62 Preferences getting user settings, 214 structure, 217-19 Preserving the display Simple Refresh, 58 Smart Refresh, 59 SuperBitMap, 60 Printer characteristics, 216 Printers, 216 PrintIText(), 180, 199 Proplnfo structure, 99, 110-11 Proportional gadgets, 95-99 RastPort structure, 200 Read(), 174 RefreshGadgets(), 115 RemakeDisplay(), 45, 221
Remember structure, 213 Remembering, 211 RemoveGadget(), 92, 114 Reply(), 165, 169 ReplyMsg(), 171 ReportMouse(), 62, 72 Requester structure, 147-51 Requesters application type, 142 as menus, 130 as super menus, 140 custom bit-map type, 151 designing, 143, 147 display position, 143 displaying, 140-41, 143 double-menu, 144 gadgets in, 144 IDCMP features, 145 Intuition-rendered type, 150 pointer in, 143 removing, 144 rendering, 143 simple, 145-46, 151 structure, 147-51 user-requested, 144 Request(), 72, 147, 152 RethinkDisplay(), 44, 220 Screen structure, 41 Screens active, 26 and display modes, 32 color of, 33 custom, 29 depth of, 33 depth-arranging gadget in, 85 dragging gadget in, 85 gadgets in custom gadgets, 38 system gadgets, 25 height and width of, 35-36 location limits of, 36 NewScreen structure, 38 Screen structure, 41 standard, 27 starting location of, 35-36 title current, 37
I-5
default, 37 effect of Backdrop window on, 38 Workbench, 28 ScreentoBack(), 43 ScreentoFront(), 43 SendIO(), 175 SetDMRequest(), 72, 144, 147, 152 SetMenuStrip(), 71, 120, 126, 137 SetPointer(), 62, 73, 76, 79 SetRGB4(), 33, 62, 231 SetWindowTitles(), 38, 73-74 Shortcuts in menus, 228 in selection, 227 ShowTitle(), 31, 38, 42, 53 Simple Refresh, 58 SizeWindow(), 74 Sizing gadget, 85 Smart Refresh, 60-61 SpecialInfo structures, 110-13 Sprite mode, 32 Sprite pointer colors, 230 Sprites data memory, 76 data structure, 77-78 in pointer, 62 in windows and screens, 222 String gadgets, 99-101 Stringlnfo structure, 99, 112-13 Structures Border, 184-85 Gadget, 104-109 Image, 195 IntuiMessage, 165-66 IntuiText, 187-89 IOStdReq, 174-76 Menu, 133-34 MenuItem, 134-37 NewScreen, 38-41 NewWindow, 65-69 Preferences, 217-19 Proplnfo, 110-11 RastPort, 200 Remember, 213 Requester, 147-51 Screen, 41
SpecialInfo, 110-13 sprite, 77-78 Stringlnfo, 112-13 View, 200 ViewPort, 200 Window, 70-71 SuperBitMap refresh, 60 SuperBitMap window setting up the BitMap, 75-76 SuperBitMap window type, 53 System gadgets in screens, 25 in windows, 54 placement of, 83-84 Text colors of, 186 defining, 185 displaying, 181, 187 drawing modes, 186 fonts, 187 input/output of, 160, 175 IntuiText structure, 187-89 linking, 187 PrintIText(), 180, 199 user settings, 216 TextAttr structure, 35 Text(), 18 Time getting current values, 221 Title screen, 37-38 window, 51, 56 Title bar screen, 25 window, 56 Topaz font, 34 Type styles, 34-35 User settings Preferences, 214 Verification functions IDCMP, 171 ViewAddress(), 200, 201 View address of, 200 remaking, 220 ViewPortAddress(), 200, 201 ViewPort
I-6
address of, 200 remaking, 220 Virtual display memory, 57 Virtual terminal, 2, 46 Virtual terminal windows, 47 Wait(), 14, 169, 171 WBenchToBack(), 44 WBenchToFront(), 44 Window structure, 70-71 WindowLimits(), 63, 69, 73 Windows activating, 49 and screen title, 37-38 application gadgets in, 55 Backdrop type, 52-53 border gadgets, 92 Borderless type, 50-51 close gadget in, 86 closing, 49-50 colors in, 63 depth-arranging gadget in, 85 dimensions of limits on, 63 starting, 63 dragging gadget in, 85 Gimmezerozero type, 51-52 graphics and text in, 62 input/output in, 48 location of, 65 NewWindow structure, 65-69 opening, 49 pens in, 63 pointer, 61-62 preserving the display, 57-60 refreshing the display NOCAREREFRESH, 61 Simple Refresh, 58, 60 Smart Refresh, 59 SuperBitMap, 60 sizing gadget in, 85 special types of, 50 SuperBitMap type, 53 system gadgets in, 54-55 Window structure, 70-71 WindowToBack(), 75 WindowToFront(), 75 Workbench
as a screen, 28 as an application program, 29 color of, 28, 216 library, 29 shortcut key functions, 208 Write(), 174
I-7