TweetFollow Us on Twitter

MACINTOSH C CARBON
MACINTOSH C CARBON: A Hobbyist's Guide To Programming the Macintosh in C
Version 1.0
© 2001 K. J. Bricknell
Go to Contents Go to Program Listing

CHAPTER 13

OFFSCREEN GRAPHICS WORLDS, PICTURES, CURSORS, AND ICONS

Offscreen Graphics Worlds

Introduction

An offscreen graphics world may be regarded as a virtual screen on which your application can draw a complex image without the user seeing the various steps involved. When your application draws into an offscreen graphics world, it draws into a part of memory not used by the video device. Thus the drawing process remains hidden from the user. When the drawing is completed, your application can copy the image from the offscreen graphics world to the active window using the CopyBits, CopyMask, or CopyDeepMask functions.

One of the key advantages of using an offscreen graphics world is speed. Copying a complex image from an offscreen graphics world to the active window is much faster than performing all the steps necessary to draw the image on-screen.

Creating an Offscreen Graphics World

The NewGWorld function is used to create an offscreen graphics world:

QDErr  NewGWorld(GWorldPtr *offscreenGWorld,short PixelDepth,const Rect *boundsRect,
                 CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags)

Returns: A result code: noErr (no error); paramErr (illegal parameter);
cDepthErr (invalid pixel depth).
offscreenGWorld

Pointer to the created offscreen graphics world.

PixelDepth

Pixel depth of the offscreen graphics world. Possible depths are 0, 1, 2, 4, 8, 16, and 32 bits per pixel. Specifying 0 sets the pixel depth to equal the greatest depth of those screens whose boundary rectangles intersect the rectangle passed in the boundRect parameter. 0 also causes NewGWorld to use the GDevice structure for this deepest device rather than create a new one.

boundsRect

The offscreen pixel maps's boundary and port rectangle. Applications typically pass in the port rectangle of the window to which the image in the offscreen graphics world will be copied.

cTable

Handle to a ColorTable structure. May be NULL.

aGDevice

Handle to a GDevice structure. This is used only when noNewDevice is passed in the flags parameter. NewGWorld will attach this GDevice structure to the offscreen graphics world. Should be NULL if 0 is passed in the PixelDepth parameter.

flags

Any combination of pixPurge (make base address of pixel image purgeable), noNewDevice (do not create offscreen GDevice structure), useTempMem (create base address for offscreen pixel image in temporary memory, and keepLocal (keep offscreen pixel image in main memory) may be passed in this parameter.

Calling NewGWorld results in the creation of a new offscreen graphics port. The function returns, in the offscreenGWorld parameter, a pointer of type GWorldPtr which points to the graphics port:

     typedef CGrafPtr GWorldPtr;

NewGWorld also establishes a link to an existing GDevice structure, or creates a new GDevice structure and establishes a link to that.

Passing 0 in the PixelDepth parameter, a window's port rectangle in the boundsRect parameter, NULL in both the cTable and aGDevice parameters, and 0 in the flags parameter:

  • Allows QuickDraw to optimise the CopyBits, CopyMask, and CopyDeepMask functions used to copy the image into the window's port rectangle.

  • Results in the default behaviour of NewGWorld, meaning that the base address of the offscreen pixel image is unpurgeable, memory in the application heap is used, and graphics accelerators can cache the offscreen pixel image.

Setting the Graphics Port

Before drawing into the offscreen graphics port, you should save the current graphics port and the current device's GDevice structure by calling GetGWorld. The offscreen graphics port should then be made the current port by a call to SetGWorld. After drawing into the offscreen graphics world, you should call SetGWorld to restore the saved graphics port as the current graphics port.

SetGWorld takes two parameters (port and gdh). If the port parameter is of type CGrafPtr, the current port is set to the port specified in the port parameter and the current device is set to the device specified in the gdh parameter. If the port parameter is of type GWorldPtr, the current port is set to the port specified in the port parameter, the gdh parameter is ignored, and the current device is set to the device linked to the offscreen graphics world.

Preparing to Draw Into an Offscreen Graphics World

After setting the offscreen graphics world as the current port, you should use the GetGWorldPixMap function to get a handle to the offscreen pixel map. This is required as the parameter in a call to the LockPixels function, which you must call before drawing to, or copying from, an offscreen graphics world.

LockPixels prevents the base address of an offscreen pixel image from being moved while you draw into it or copy from it. It returns true if the base address is not purgeable, or if the base address has not been purged by the Memory Manager. If LockPixels returns false, (meaning that the base address of the offscreen pixel image has been purged) your application must call the UpdateGWorld function to reallocate the offscreen pixel image and then reconstruct it.

As a related matter, note that the baseAddr field of the PixMap structure for an offscreen graphics world contains a handle, whereas the baseAddr field for an onscreen pixel map contains a pointer. Accordingly, the GetPixBaseAddr function must be used to obtain a pointer to the PixMap structure for an offscreen graphics world.

Copying an Offscreen Image into a Window

After drawing the image in the offscreen graphics world, your application should call SetGWorld to set the active window as the current graphics port preparatory to copying the image to that port.

Your application copies the image from the offscreen graphics world into the target window using CopyBits (or, if masking is required, CopyMask or CopyDeepMask). Note that CopyBits, CopyMask and CopyDeepMask expect their source and destination parameters to be pointers to bit maps, not pixel maps. (These functions date from the era of black-and-white Macintoshes, which is why they expect a pointer to a bitmap. By looking at certain information in the graphics ports, CopyBits, CopyMask, and CopyDeepMask can establish that you have passed the functions a handle to a pixel map rather than the base address of a bitmap.)

You must leave the pixel image locked while you are drawing into an offscreen graphics world or copying an image from it, and you should call UnlockPixels when you are finished the copying or drawing operation. (Calling UnlockPixels will assist in preventing heap fragmentation.)

Updating an Offscreen Graphics World

If, for example, you are using an offscreen graphics world to support the window updating process, you can use UpdateGWorld to carry certain changes affecting the window (resizing the window, changes to the pixel depth of the screen, etc.) through to the offscreen graphics world. Calling UpdateGWorld obviates the necessity to recreate the offscreen graphics world and redraw its contents.

Disposing of an Offscreen Graphics World

You should call DisposeGWorld when your application no longer needs the offscreen graphics world.

Pictures

Introduction

QuickDraw provides a set of functions that allow your application to record a number of drawing commands and subsequently play the recording back. The collection of drawing commands is called a picture.

You begin defining a picture by calling the function OpenCPicture. Your subsequent drawing commands are collected in a data structure of type Picture. The picture defined within this data structure may be drawn by calling the function DrawPicture.

The OpenCPicture function creates pictures in the extended version 2 format, which allows your application to specify resolutions for pictures.

The Picture Structure

The Picture structure is as follows:

     struct Picture
     {
       short  picSize;   // For a version 1 picture: its size.
       Rect   picFrame;  // Bounding rectangle for the picture.
     };
     typedef struct Picture Picture;
     typedef Picture *PicPtr;
     typedef PicPtr *PicHandle;

Field Descriptions

picSize

This field is irrelevant for version 2 format and extended version 2 format pictures.

To determine the size of a picture in memory, use the Memory Manager function GetHandleSize.

To determine the size of a picture in a file of type 'PICT', use File Manager function PBGetFInfo.

To determine the size of a picture in a resource of type 'PICT', use the Resource Manager function MaxSizeResource.

picFrame

The picture's bounding rectangle. When you draw into a differently sized rectangle, DrawPicture uses this rectangle to scale the picture.

...

Compact drawing commands and picture comments constitute the rest of the structure, which is of variable length.

Opcodes: Drawing Commands and Picture Comments

The variable length field in a Picture structure contains data in the form of opcodes, which DrawPicture uses to determine what objects to draw or what mode to change for subsequent drawing. Opcodes can also specify picture comments, which are created using PicComment. A picture comment contains data or commands for special processing by output devices, such as PostScript printers.

You typically use QuickDraw commands when drawing to the screen and picture comments to include any special drawing commands for printers.

'PICT' Files, Resources, and Scrap Format

File Manager and Resource Manager functions are used to read pictures from, and write pictures to, a disk. Scrap Manager functions are used to read pictures from, and write pictures to, the scrap. (See Chapter 20.)

A picture can be stored as a 'PICT' resource in the resource fork of any file type. A picture can also be stored in the data fork of a file of type 'PICT'. The first 512 bytes of the data fork of a 'PICT' file are a header that your application can use for its own purposes.

The Scrap Manager maintains a storage area to hold the last data cut or copied by the user. This area is called the scrap. If your application supports cut, copy, and paste operations, it necessarily reads data from, and writes data to, the scrap. There are two standard scrap data formats, one of which is 'PICT'.

Creating Pictures

As previously stated, you use the OpenCPicture function to begin defining a picture. You pass information to OpenCPicture in the form of an OpenCPicParams structure:

     struct OpenCPicParams
     {
       Rect   srcRect;    // Optimal bounding rectangle.
       Fixed  hRes;       // Best horizontal resolution.
       Fixed  vRes;       // Best vertical resolution.
       short  version;    // Set to -2.
       short  reserved1;  // (Reserved.  Set to 0.)
       long   reserved2;  // (Reserved.  Set to 0.)
     };
     typedef struct OpenCPicParams OpenCPicParams;

This structure provides a simple mechanism for specifying resolutions when creating images. For example, applications that create pictures from scanned images can specify resolutions higher than 72 dpi.

You call ClosePicture to complete the collection of drawing (and picture comment) commands that define your picture.

Clipping Region

Before calling OpenCPicture, you should always use ClipRect to specify an appropriate clipping region. If you fail to do this, OpenCPicture will use the clipping region contained in the current graphics port object. By default, this region is very large (the size of the coordinate plane). In this circumstance, if you scale the picture when drawing it, the clipping region can become invalid and your picture will not be drawn. By the same token, if your application has previously set the clipping region for some other purpose, part of your drawing may be clipped.

Ordinarily, you should set the clipping region to equal the port rectangle of the current graphics port before recording a picture.

Opening and Drawing Pictures

You can retrieve pictures saved in 'PICT' files using File Manager functions. (The demonstration program at Chapter 18 shows how to read pictures from, and save pictures to, files of type 'PICT'.) You can retrieve pictures saved in the resource forks of other file types using the GetPicture function. You can retrieve pictures stored in the scrap using the Carbon Scrap Manager function GetScrapFlavorData.

When the picture is retrieved, you can call DrawPicture to draw the picture. The second parameter passed in the DrawPicture function is the destination rectangle, which should be specified in coordinates local to the current graphics port. DrawPicture shrinks or stretches the picture as necessary to make it fit into this rectangle.

When you are finished using a picture stored as a 'PICT' resource, you should use the resource Manager function ReleaseResource to release its memory.

Saving Pictures

To save a picture in a 'PICT' file, you should use the appropriate File Manager functions.2 (Remember that the first 512 bytes of a 'PICT' file are reserved for your application's own purposes.) To save pictures in a 'PICT' resource, you should use the appropriate Resource Manager functions. To place a picture in the scrap (for example, to respond to the user choosing the Copy command to copy a picture to the clipboard), you should use the Carbon Scrap Manager function PutScrapFlavorData.

Gathering Picture Information

GetPictInfo may be used to gather information about a single picture, and GetPixMapInfo may be used to gather colour information about a single pixel map or bit map. Each of these functions returns colour and resolution information in a PictInfo structure. A PictInfo structure can also contain information about the drawing objects, fonts, and comments in a picture.

Cursors

Introduction

A cursor is a 16-by-16 pixel image defined in a black-and-white cursor ('CURS') or colour cursor ('crsr') resource.

Cursor Movement, Hot Spot, Visibility, and Shape

Cursor Movement

Cursor movement is not the responsibility of your application. When the mouse is moved by the user, low-level interrupt-driven mouse functions move the cursor on the screen.

Cursor Hot Spot

A cursor's hot spot is that part of the cursor that actually points to an object on the screen. Mouse clicks only have an effect on that object when the hot spot, not the cursor as a whole, is over the object. Fig 1 illustrates two cursors and their hot spot points. Note that the hot spot is a point, not a bit.

Cursor Visibility

Generally speaking, your application should always make the cursor visible. There are, however, exceptions to this rule. For example, in a text-editing application, the cursor should be made invisible, and the insertion point made to blink, when the user begins entering text. In such cases, the cursor should be made visible again only when the user moves the mouse.

Cursor Shape

Your application should change the shape of the cursor in the following circumstances:

  • To indicate that the user is over a certain area of the screen. When the cursor is in the menu bar, for example, it should usually have an arrow shape. When the user moves the cursor over a text document, the cursor shape should be changed to the I-beam shape.

  • To provide feedback to the user indicating that a time-consuming operation is in progress. For example, if an operation will take a second or two, you should provide feedback to the user by changing the cursor to the wristwatch cursor (on Mac OS 8/9) or wait cursor (Mac OS X) (see Fig 2). If the operation will take several seconds and the only options available to the user are to stop the operation, wait until it is completed, or switch to another application, you should display an animated cursor (on Mac OS 8/9 or wait cursor (on Mac OS X).

    If the operation takes longer than several seconds, you should display a dialog with a progress indicator. (See Chapter 25.)

Non-Animated Cursors

System 'CURS' and 'crsr' Resources

The System file in the System Folder contains a number of 'CURS' and 'crsr' resources. The following constants represent the 'CURS' resource IDs for the basic cursors shown at Fig 2:

Constant

Value

Description

iBeamCursor 1

Used in text editing.

crossCursor 2

Often used for manipulating graphics.

plusCursor 3

Often used for selecting fields in an array.

watchCursor 4

Used when a short operation is in progress.

The following lists the 'CURS' and 'crsr' resource IDs for the additional cursors shown at Fig 3:

Constant

Value

Description

- -20488

Contextual menu arrow cursor.

- -20487

Alias arrow cursor.

- -20486

Copy arrow cursor.

- -20452

Resize left cursor.

- -20451

Resize right cursor.

- -20450

Resize left/right cursor.


- -20877

Pointing hand cursor.

- -20876

Open hand pointer.

- -20875

Close hand pointer.

Custom 'CURS' and 'crsr' Resources

To create custom cursors, you need to define 'CURS' or 'crsr' resources in the resource file of your application.

Changing Cursor Shape

Your application is responsible for setting the initial appearance of the cursor and for changing the appearance of the cursor as appropriate for your application.

Methodology 1

One method for changing cursor shape involves first getting a handle to the relevant cursor (either a custom cursor or one of the system cursors shown at Figs 2 and 3) by specifying its resource ID in a call to GetCursor or GetCCursor. GetCursor returns a handle to a Cursor structure. GetCCursor returns a handle to a CCrsr structure. The address of the Cursor or CCrsr structure is then used in a call to SetCursor or SetCCursor to change the cursor shape.

Methodology 2

Mac OS 8.5 introduced a new method for setting the cursor. You must pass one of the following constants, which are of type ThemeCursor, in the inCursor parameter of the function SetThemeCursor:

Constant

Value

Comments

kThemeArrowCursor 0

 

kThemeCopyArrowCursor 1

 

kThemeAliasArrowCursor 2

 

kThemeContextualMenuArrowCursor 3

 

kThemeIBeamCursor 4

 

kThemeCrossCursor 5

 

kThemePlusCursor 6

 

kThemeWatchCursor 7

Can animate.

kThemeClosedHandCursor 8

 

kThemeOpenHandCursor 9

 

kThemePointingHandCursor 10

 

kThemeCountingUpHandCursor 11

Can animate.

kThemeCountingDownHandCursor 12

Can animate.

kThemeCountingUpAndDownHandCursor 13

Can animate.

kThemeSpinningCursor 14

Can animate.

kThemeResizeLeftCursor 15

 

kThemeResizeRightCursor 16

 

kThemeResizeLeftRightCursor 17

 

Changing Cursor Shape in Response to Mouse-Moved Events

Most applications set the cursor to the I-beam shape when the cursor is inside a text-editing area of a document, and they change the cursor to an arrow when the cursor is inside the scroll bars. Your application can achieve this effect by requesting that the Event Manager report mouse-moved events if the user moves the cursor out of a region you specify in the mouseRgn parameter to the WaitNextEvent function. Then, when a mouse-moved event is detected in your main event loop, you can use SetCursor, SetCCursor, or SetThemeCursor, to change the cursor to the appropriate shape.

Changing Cursor Shape in Response to Resume Events

Your application also needs to set the cursor shape in response to resume events, normally by setting the arrow cursor.

Hiding Cursors

You can remove the cursor image from the screen using HideCursor. You can hide the cursor temporarily using ObscureCursor or you can hide the cursor in a given rectangle by using ShieldCursor. To display a hidden cursor, use ShowCursor. Note, however, that you do not need to explicitly show the cursor after your application uses ObscureCursor because the cursor automatically reappears when the user moves the mouse again.

Animated Cursors - Mac OS 8/9

Methodology 1

Mac OS 8.5 introduced a new function (SetThemeAnimatedCursor) for animating a specified cursor type. You must pass one of the following constants, which are of type ThemeCursor, in the inCursor parameter of SetThemeAnimatedCursor:

Constant

Value

kThemeWatchCursor 7
kThemeCountingUpHandCursor 11
kThemeCountingDownHandCursor 12
kThemeCountingUpAndDownHandCursor 13
kThemeSpinningCursor 14

Methodology 2

Another methodology requires:

  • A series of 'CURS' (or 'crsr') resources that make up the "frames" of the animation.

  • An 'acur' resource, which collects and orders the 'CURS' frames into a single animation, specifying the IDs of the resources and the sequence for displaying them in the animation.

System 'acur', and 'CURS' Resources

The System file contains an 'acur' resource (ID -6079), together the associated eight 'CURS' resources, for an animated watch cursor. It also contains eight 'CURS' resources (IDs -20701 to -20708) for an animated spinning (beach ball) cursor and six 'CURS' resources (IDs -20709 to -20714) for an animated counting hand cursor.

Custom 'acur' and 'CURS' Resources

Fig 4 shows the structure of a compiled 'acur' resource, and an 'acur' resource and one of its associated 'CURS' resources being created using Resorcerer.

Creating the Animated Cursor

The following are the steps required to create the animated cursor:

  • If you do not intend to use the system-supplied 'acur' and associated 'CURS' resources:

    • Create a series of 'CURS' resources that make up the "frames" of the animation.

    • Create an 'acur' resource.
  • Load the 'acur' resource into a structure which replicates the structure of an 'acur' resource, for example:
         typedef struct
         {
           short       numberOfFrames;
           short       whichFrame;
           CursHandle  frame[];
         } animCurs, *animCursPtr, **animCursHandle;
    

  • Load the 'CURS' resources using GetCursor and assign handles to the resulting Cursor structures to the elements of the frame field.

  • At the desired interval, call SetCursor to display each cursor, that is, each "frame", in rapid succession, returning to the first frame after the last frame has been displayed.

Animated Cursor - Mac OS X

When the Mac OS X wait (spinning) cursor appears automatically, it means that the application has stopped calling an event handling API for more than a certain period of time (about two seconds).

Your application can also turn the wait cursor on and off using the QuickDraw function QDDisplayWaitCursor. Passing true in the forceWaitCursor parameter turns the cursor on and passing false resumes automatic operation. The function keeps track of nested calls.

Icons

Icons and the Finder - Icon Families

As stated at Chapter 9, the Finder uses icons to graphically represents objects, such as files and directories. Chapter 9 also introduced the subject of icon families, and stated that your application should provide the Finder with a family of specially designed icons for the application file itself and for each of the document types created by the application.

Other Icons - Icons, Colour Icons and Small Icons

Other icon types are the icon, colour icon, and small icon. Note that the Finder does not use or display these icon types.

Icon ('ICON')

The icon is a black-and-white icon defined in an 'ICON' resource, which contains a 32-by-32 pixel bit map. Icons do not need a mask because they are always displayed on a white background.

Colour Icon ('cicn')

The colour icon is defined in a 'cicn' resource, which includes a pixel map, a bit map, and a mask. You can use a 'cicn' resource to define a colour icon with any width and height and with a bit depth up to 8. Fig 5 shows an 8-bit 32 by 32 pixel 'cicn' resource being created using Resorcerer.

Small Icon ('SICN')

The small icon is a black-and-white icon defined in a 'SICN' resource. Small icons are 12 by 16 pixels even though they are stored in a resource as 16-by-16 pixel bitmaps. Small icons are of doubtful utility in the Carbon era and will not be considered further.

Typically, only the Finder and Navigation Services use small icons.

Icons in Windows, Menus, and Alert and Dialogs

The icons provided by your application for the Finder (or the default system-suppled icons used by the Finder if your application does not provide its own icons) are displayed on the desktop. Your application can also display icons in its menus, dialogs and windows.

Icons in Windows

You can display icons of any kind in your windows using the appropriate Icon Utilities functions.

Icons in Menus

The Menu Manager allows you to display icons of resource types 'ICON' (icon) and 'cicn' (colour icon) in menu items. The procedure is as follows:

  • Create the icon resource with a resource ID between 257 and 511. Subtract 256 from the resource ID to get a value called the icon number. Specify the icon number in the Icon field of the menu item definition.

  • For an icon ('ICON'), specify 0x1D in the keyboard equivalent field of the menu item definition to indicate to the Menu Manager that the icon should be reduced to fit into a 16-by-16 pixel rectangle. Otherwise, specify a value of 0x00, or a value greater than 0x20, in the keyboard equivalent field to cause the Menu Manager to expand the item's rectangle so as to display the icon at its normal 32-by-32 pixel size. (A value greater than 0x20 in the keyboard equivalent field specifies the item's Command-key equivalent.)

  • For a colour icon ('cicn'), specify 0x00 or a value greater than 0x20 in the keyboard equivalent field. The Menu Manager automatically enlarges the enclosing rectangle of the menu item according to the rectangle specified in the 'cicn' resource. (Colour icons, unlike icons, can be any height or width.)

When the menu is displayed, the Menu Manager first looks for a 'cicn' resource with the resource ID calculated from the icon number and displays that icon if it is found. If a 'cicn' resource is not found,the Menu Manager searches for an 'ICON' resource and plots it in either a 32-by-32 pixel rectangle or a 16-by-16 bit rectangle, depending on the value in the menu item's keyboard equivalent field.

Icons in Alerts and Dialogs

The Dialog Manager allows you to display icons of resource types 'ICON' (icon) and 'cicn' (colour icon) in Mac OS 8/9 alerts and in dialogs. You can display the icon alone or within an image well.

To display the icon alone, the procedure is to define an item of type Icon and provide the resource ID of the icon in the item list ('DITL') resource for the dialog. This will cause the Dialog Manager to automatically display the icon whenever you display the alert or dialog using Dialog Manager functions.

To display the icon within an image well, include an image well control in the alert or dialog's item list and assign the resource ID of the icon to the control's minimum value field.

If you provide a colour icon ('cicn') resource with the same resource ID as an icon ('ICON') resource, the Dialog Manager displays the colour icon instead of the black-and-white icon.

On Mac OS 8/9, you would ordinarily use the Alert function (which does not automatically draw a system-supplied alert icon in the alert), or the StandardAlert function with kAlertPlainAlert passed in the inAlertType parameter, when you wish to display an alert containing your own icon (for example, in your application's About... alert). If you invoke an alert using the NoteAlert, CautionAlert, or StopAlert functions, or with the StandardAlert function with an alert type constant of other than kAlertPlainAlert passed in the inAlertType parameter, the Dialog Manager draws the system-supplied black-and-white icon as well as your icon. Since your icon is drawn last, you can obscure the system-suppled icon by positioning your icon at the same coordinates.

Drawing and Manipulating Icons

The Icon Utilities allow your application (and the system software) to draw and manipulate icons of any standard resource type in windows and, subject to the limitations and requirements previously described, in menus and dialogs.

You need to use Icon Utilities functions only if:

  • You wish to draw icons in your application's windows.

  • You wish to draw icons which are not recognised by the Menu Manager and the Dialog Manager in, respectively, menu items and dialogs.

Preamble - Icon Families, Suites, and Caches

Icon Families

You can define individual icons of resource types 'ICON' and 'cicn' that are not part of an icon family and use Icon Utilities functions to draw them as required. However, to display an icon effectively at a variety of sizes and bit depths, you should provide an icon family in the same way that you provide icon families for the Finder. The advantage of providing an icon family is that you can then leave it to functions such as PlotIconID, which are used to draw icons, to automatically determine which icon in the icon family is best suited to the specified destination rectangle and current display bit depth.

Icon Suites

Some Icon Utilities functions take as a parameter a handle to an icon suite. Typically, an icon suite comprises of one or more handles to icon resources from a single icon family which have been read into memory. The GetIconSuite function may be used to get a handle to an icon suite, which can then be passed to functions such as PlotIconSuite to draw that icon in the icon suite best suited to the destination rectangle and current display bit depth.

An icon suite can contain handles to all of the six icon resources that an icon family can contain. Alternatively, it can contain handles to only a subset of those resources.

When you create an icon suite from icon family resources, the associated resource file should remain open while you use Icon Utilities functions.

Drawing an Icon Directly From a Resource

To draw an icon from an icon family without first creating an icon suite, use the PlotIconID function. PlotIconID determines, from the size of the specified destination rectangle and the current bit depth of the display device, which icon to draw. The icon drawn is as follows:

Destination Rectangle Size

Icon Drawn

Width or height greater than or equal to 32.

The 32-by-32 pixel icon with the appropriate bit depth.

Less than 32 by 32 pixels and greater than 16 pixels wide or 12 pixels high.

The 16-by-16 pixel icon with the appropriate bit depth.

Icon Stretching and Shrinking

PlotIconID may stretch or shrink the icon to fit depending on the size of the destination rectangle,. To draw icons without stretching them, PlotIconID requires that the destination rectangle have the same dimensions as one of the standard icons.

Icon Alignment and Transform

In addition to destination rectangle and resource ID parameters, PlotIconID takes alignment and transform parameters. Icon Utilities functions can automatically align an icon within its destination rectangle. (For example, an icon which is taller than it is wide can be aligned to either the right or left of its destination rectangle.) These functions can also transform the appearance of the icon in standard ways analogous to Finder states for icons.

Variables of type IconAlignmentType and IconTransformType should be declared and assigned values representing alignment and transform requirements. Constants, such as kAlignAbsoluteCenter and kTransformNone, are available to specify alignment and transform requirements.

Getting an Icon Suite and Drawing One of Its Icons

The GetIconSuite function, with the constant kSelectorAllAvailableData passed in the third parameter, is used to get all icons from an icon family with a specified resource ID and to collect the handles to the data for each icon into an icon suite. An icon from this suite may then be drawn using PlotIconSuite which, like PlotIconID, takes destination rectangle, alignment and transform parameters and stretches or shrinks the icon if necessary.

Drawing Specific Icons From an Icon Family

If you need to plot a specific icon from an icon family rather than use the Icon Utilities to automatically select a family member, you must first create an icon suite that contains only the icon of the desired resource type together with its corresponding mask. Constants such as kSelectorLarge4Bit (an icon selector mask for an 'icl4' icon) are used as the third parameter of the GetIconSuite call to retrieve the required family member. You can then use PlotIconSuite to plot the icon.

Drawing Icons That Are Not Part of an Icon Family

To draw icons of resource type 'ICON' and 'cicn' in menu items and dialogs, you use Menu Manager and Dialog Manager functions such as SetItemIcon and SetDialogItem.

To draw resources of resource type 'ICON' and 'cicn' in your application's windows, you use the following functions:

Resource Type

Function to Get Icon

Functions to Draw Icon

'ICON' GetIcon PlotIconHandle
PlotIcon
'cicn' GetCIcon PlotCIconHandle
PlotCIcon

The functions in this list ending in Handle allow you to specify alignment and transforms for the icon.

Manipulating Icons

The GetIconFromSuite function may be used to get a handle to the pixel data for a specific icon from an icon suite. You can then use this handle to manipulate the icon data, for example, to alter its colour or add three-dimensional shading.

The Icon Utilities also include functions which allow you to perform an action on one or more icons in an icon suite and to perform hit testing on icons.

Main Constants, Data Types and Functions - Offscreen Graphics Worlds

Constants

Flags for GWorldFlags Parameter

pixPurgeBit         = 0  Set to make base address for offscreen pixel image purgeable.
noNewDeviceBit      = 1  Set to not create a new GDevice structure for offscreen world.
pixelsPurgeableBit  = 6  Set to make base address for pixel image purgeable.
pixelsLockedBit     = 7  Set to lock base address for offscreen pixel image.

Data Types

typedef CGrafPtr       GWorldPtr;
typedef unsigned long  GWorldFlags;

Functions

Creating, Altering, and Disposing of Offscreen Graphics Worlds

QDErr        NewGWorld(GWorldPtr *offscreenGWorld,short PixelDepth,
             const Rect *boundsRect,CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags);
GWorldFlags  UpdateGWorld(GWorldPtr *offscreenGWorld,short pixelDepth,
             const Rect *boundsRect,CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags);
void         DisposeGWorld(GWorldPtr offscreenGWorld);

Saving and Restoring Graphics Ports and Offscreen Graphics Worlds

void  GetGWorld(CGrafPtr *port,GDHandle *gdh);
void  SetGWorld(CGrafPtr port,GDHandle gdh);

Managing an Offscreen Graphics World's Pixel Image

PixMapHandle  GetGWorldPixMap(GWorldPtr offscreenGWorld);
Boolean       LockPixels(PixMapHandle pm);
void          UnlockPixels(PixMapHandle pm);
void          AllowPurgePixels(PixMapHandle pm);
void          NoPurgePixels(PixMapHandle pm);
GWorldFlags   GetPixelsState(PixMapHandle pm);
void          SetPixelsState(PixMapHandle pm,GWorldFlags state);
Ptr           GetPixBaseAddr(PixMapHandle pm);
Boolean       PixMap32Bit(PixMapHandle pmHandle);

Main Constants, Data Types and Functions - Pictures

Constants

Verbs for the GetPictInfo, GetPixMapInfo, and NewPictInfo calls

returnColorTable       = 0x0001  Return a ColorTable structure.
returnPalette          = 0x0002  Return a Palette structure.
recordComments         = 0x0004  Return comment information.
recordFontInfo         = 0x0008  Return font information.
suppressBlackAndWhite  = 0x0010  Do not include black and white.

Colour Pick Methods for the GetPictInfo, GetPixMapInfo, and NewPictInfo calls

systemMethod   = 0  System color pick method.
popularMethod  = 1  Most popular set of colors.
medianMethod   = 2  A good average mix of colors.

Data Types

Picture

struct Picture
{
  short  picSize;   // For a version 1 picture: its size.
  Rect   picFrame;  // Bounding rectangle for the picture
};
typedef struct Picture Picture;
typedef Picture *PicPtr;
typedef PicPtr *PicHandle;

OpenCPicParams

struct OpenCPicParams { Rect srcRect; // Optimal bounding rectangle. Fixed hRes; // Best horizontal resolution. Fixed vRes; // Best vertical resolution. short version; // Set to -2 short reserved1; // (Reserved. Set to 0.) long reserved2; // (Reserved. Set to 0.) }; typedef struct OpenCPicParams OpenCPicParams;

PictInfo

struct  PictInfo
{
  short          version;           // This is always zero, for now.
  long           uniqueColors;      // Number of actual colors in the picture(s)/pixmap(s).
  PaletteHandle  thePalette;        // Handle to the palette information.
  CTabHandle     theColorTable;     // Handle to the color table.
  Fixed          hRes;              // Maximum horizontal resolution for all the pixmaps.
  Fixed          vRes;              // Maximum vertical resolution for all the pixmaps.
  short          depth;             // Maximum depth for all the pixmaps (in the picture).
  Rect           sourceRect;        // Picture frame rectangle (contains the entire picture).
  long           textCount;         // Total number of text strings in the picture.
  long           lineCount;         // Total number of lines in the picture.
  long           rectCount;         // Total number of rectangles in the picture.
  long           rRectCount;        // Total number of round rectangles in the picture.
  long           ovalCount;         // Total number of ovals in the picture.
  long           arcCount;          // Total number of arcs in the picture.
  long           polyCount;         // Total number of polygons in the picture.
  long           regionCount;       // Total number of regions in the picture.
  long           bitMapCount;       // Total number of bitmaps in the picture.
  long           pixMapCount;       // Total number of pixmaps in the picture.
  long           commentCount;      // Total number of comments in the picture.
  long           uniqueComments;    // The number of unique comments in the picture.
  CommentSpecHandle  commentHandle; // Handle to all the comment information.
  long           uniqueFonts;       // The number of unique fonts in the picture.
  FontSpecHandle fontHandle;        // Handle to the FontSpec information.
  Handle         fontNamesHandle;   // Handle to the font names.
  long  reserved1;
  long  reserved2;
};
typedef struct PictInfo PictInfo;
typedef PictInfo *PictInfoPtr;
typedef PictInfoPtr *PictInfoHandle;

CommentSpec

struct CommentSpec
{
  short  count;  // Number of occurrences of this comment ID.
  short  ID;     // ID for the comment in the picture.
};
typedef struct CommentSpec CommentSpec;
typedef CommentSpec *CommentSpecPtr;
typedef CommentSpecPtr *CommentSpecHandle;

FontSpec

struct FontSpec
{
  short  pictFontID;  // ID of the font in the picture.
  short  sysFontID;   // ID of the same font in the current system file.
  long   size[4];     // Bit array of all the sizes found (1..127) (bit 0 means > 127).
  short  style;       // Combined style of all occurrances of the font.
  long   nameOffset;  // Offset into the fontNamesHdl handle for the font's name.
};
typedef struct FontSpec FontSpec;
typedef FontSpec *FontSpecPtr;
typedef FontSpecPtr *FontSpecHandle;

Functions

Creating and Disposing of Pictures

PicHandle  OpenCPicture(const OpenCPicParams *newHeader);
void       PicComment(short kind,short dataSize,Handle dataHandle);
void       ClosePicture(void);
void       KillPicture(PicHandle myPicture);

Drawing Pictures

void       DrawPicture(PicHandle myPicture,const Rect *dstRect)
PicHandle  GetPicture(Integer picID);

Collecting Picture Information

OSErr  GetPictInfo(PicHandle thePictHandle,PictInfo *thePictInfo,short verb,
       short colorsRequested,short colorPickMethod,short version);
OSErr  GetPixMapInfo(PixMapHandle thePixMapHandle,PictInfo *thePictInfo,short verb,
       short colorsRequested,short colorPickMethod,short version);
OSErr  NewPictInfo(PictInfoID *thePictInfoID,short verb,short colorsRequested,
       short colorPickMethod,short version);
OSErr  RecordPictInfo(PictInfoID thePictInfoID,PicHandle thePictHandle);
OSErr  RecordPixMapInfo(PictInfoID thePictInfoID,PixMapHandle thePixMapHandle);
OSErr  RetrievePictInfo(PictInfoID thePictInfoID,PictInfo *thePictInfo,
       short colorsRequested);
OSErr  DisposPictInfo(PictInfoID thePictInfoID);

Main Constants, Data Types and Functions - Cursors

Constants

iBeamCursor  = 1
crossCursor  = 2
plusCursor   = 3
watchCursor  = 4

Data Types

Cursor

struct Cursor
{
  Bits16  data;
  Bits16  mask;
  Point   hotSpot;
};
typedef struct Cursor Cursor;
typedef Cursor *CursPtr;
typedef CursPtr *CursHandle;

CCrsr

struct CCrsr
{
  short         crsrType;     // Type of cursor.
  PixMapHandle  crsrMap;      // The cursor's pixmap.
  Handle        crsrData;     // Cursor's data.
  Handle        crsrXData;    // Expanded cursor data.
  short         crsrXValid;   // Depth of expanded data (0 if none).
  Handle        crsrXHandle;  // Future use.
  Bits16        crsr1Data;    // One-bit cursor.
  Bits16        crsrMask;     // Cursor's mask.
  Point         crsrHotSpot;  // Cursor's hotspot.
  long          crsrXTable;   // Private.
  long          crsrID;       // Private.
};
typedef struct CCrsr CCrsr;
typedef CCrsr *CCrsrPtr;
typedef CCrsrPtr *CCrsrHandle;

Acur

struct Acur 
{
  short  n;       // Number of cursors (frames).
  short  index;   // (Reserved.)
  short  frame1;  // 'CURS' resource ID for frame #1.
  short  fill1;   // (Recerved.)
  short  frame2;  // 'CURS' resource ID for frame #2.
  short  fill2;   // (Reserved.)
  short  frameN;  // 'CURS' resource ID for frame #n.
  short  fillN;   // (Reserved.)
};
typedef struct Acur acur, *acurPtr, **acurHandle;

Functions

Initialising Cursors

void  InitCursor(void);
void  InitCursorCtl(acurHandle newCursors);

Changing Black-and-White Cursors

CursHandle  GetCursor(short cursorID);
void        SetCursor(const Cursor *crsr);

Changing Colour Cursors

CCrsrHandle  GetCCursor(short crsrID);
void         SetCCursor(CCrsrHandle cCrsr);
void         AllocCursor(void)
void         DisposCCursor(CCrsrHandle cCrsr);
void         DisposeCCursor(CCrsrHandle cCrsr);

Hiding, Showing , and Animating Cursors

void    HideCursor(void);
void    ShowCursor(void);
void    ObscureCursor(void);
void    ShieldCursor(const Rect *shieldRect,Point offsetPt);
void    RotateCursor(long counter);
pascal  void SpinCursor(short increment);

Appearance Manager Constants, Data Types and Functions - Cursors

Constants

KThemeArrowCursor                  = 0
KThemeCopyArrowCursor              = 1
KThemeAliasArrowCursor             = 2
KThemeContextualMenuArrowCursor    = 3
KThemeIBeamCursor                  = 4
KThemeCrossCursor                  = 5
KThemePlusCursor                   = 6
KThemeWatchCursor                  = 7  // Can animate
KThemeClosedHandCursor             = 8
KThemeOpenHandCursor               = 9
KThemePointingHandCursor           = 10
KThemeCountingUpHandCursor         = 11  // Can animate
KThemeCountingDownHandCursor       = 12  // Can animate
KThemeCountingUpAndDownHandCursor  = 13  // Can animate
KThemeSpinningCursor               = 14  // Can Animate
KThemeResizeLeftCursor             = 15
KThemeResizeRightCursor            = 16
KThemeResizeLeftRightCursor        = 17

Data Types

typedef UInt32 ThemeCursor;

Functions

OSStatus  SetThemeCursor(ThemeCursor inCursor);
OSStatus  SetAnimatedThemeCursor(ThemeCursor inCursor,UInt32 inAnimationStep);

Mac OS X Only

void      QDDisplayWaitCursor(Boolean forceWaitCursor);

Main Constants, Data Types and Functions - Icons

Constants

Types for Icon Families

kLarge1BitMask  = FOUR_CHAR_CODE('ICN#')
kLarge4BitData  = FOUR_CHAR_CODE('icl4')
kLarge8BitData  = FOUR_CHAR_CODE('icl8')
kSmall1BitMask  = FOUR_CHAR_CODE('ics#')
kSmall4BitData  = FOUR_CHAR_CODE('ics4')
kSmall8BitData  = FOUR_CHAR_CODE('ics8')
kMini1BitMask   = FOUR_CHAR_CODE('icm#')
kMini4BitData   = FOUR_CHAR_CODE('icm4')
kMini8BitData   = FOUR_CHAR_CODE('icm8')

IconAlignmentType Values

k
AlignNone              = 0x00
kAlignVerticalCenter    = 0x01
kAlignTop               = 0x02
kAlignBottom            = 0x03
kAlignHorizontalCenter  = 0x04
kAlignAbsoluteCenter    = kAlignVerticalCenter | kAlignHorizontalCenter
kAlignCenterTop         = kAlignTop            | kAlignHorizontalCenter
kAlignCenterBottom      = kAlignBottom         | kAlignHorizontalCenter
kAlignLeft              = 0x08
kAlignCenterLeft        = kAlignVerticalCenter | kAlignLeft
kAlignTopLeft           = kAlignTop            | kAlignLeft
kAlignBottomLeft        = kAlignBottom         | kAlignLeft
kAlignRight             = 0x0C
kAlignCenterRight       = kAlignVerticalCenter | kAlignRight
kAlignTopRight          = kAlignTop            | kAlignRight
kAlignBottomRight       = kAlignBottom         | kAlignRight

IconTransformType Values

kTransformNone              = 0x00
kTransformDisabled          = 0x01
kTransformOffline           = 0x02
kTransformOpen              = 0x03
kTransformLabel1            = 0x0100
kTransformLabel2            = 0x0200
kTransformLabel3            = 0x0300
kTransformLabel4            = 0x0400
kTransformLabel5            = 0x0500
kTransformLabel6            = 0x0600
kTransformLabel7            = 0x0700
kTransformSelected          = 0x4000
kTransformSelectedDisabled  = kTransformSelected | kTransformDisabled
kTransformSelectedOffline   = kTransformSelected | kTransformOffline
kTransformSelectedOpen      = kTransformSelected | kTransformOpen

IconSelectorValue Masks

kSelectorLarge1Bit         = 0x00000001
kSelectorLarge4Bit         = 0x00000002
kSelectorLarge8Bit         = 0x00000004
kSelectorSmall1Bit         = 0x00000100
kSelectorSmall4Bit         = 0x00000200
kSelectorSmall8Bit         = 0x00000400
kSelectorMini1Bit          = 0x00010000
kSelectorMini4Bit          = 0x00020000
kSelectorMini8Bit          = 0x00040000
kSelectorAllLargeData      = 0x000000FF
kSelectorAllSmallData      = 0x0000FF00
kSelectorAllMiniData       = 0x00FF0000
kSelectorAll1BitData       = kSelectorLarge1Bit | kSelectorSmall1Bit | kSelectorMini1Bit
kSelectorAll4BitData       = kSelectorLarge4Bit | kSelectorSmall4Bit | kSelectorMini4Bit
kSelectorAll8BitData       = kSelectorLarge8Bit | kSelectorSmall8Bit | kSelectorMini8Bit
kSelectorAllAvailableData  = (long)0xFFFFFFFF

Data Types

typedef short   IconAlignmentType;
typedef short   IconTransformType;
typedef UInt32  IconSelectorValue;
typedef Handle  IconSuiteRef;
typedef Handle  IconCacheRef;

CIcon

struct CIcon 
{
  PixMap  iconPMap;         // Icon's pixMap.
  BitMap  iconMask;         // Icon's mask.
  BitMap  iconBMap;         // Icon's bitMap.
  Handle  iconData;         // Icon's data.
  short   iconMaskData[1];  // Icon's mask and BitMap data.
};
typedef struct CIcon CIcon;
typedef CIcon *CIconPtr;
typedef CIconPtr *CIconHandle;

Functions

Drawing Icons From Resources

OSErr  PlotIconID(constRect *theRect,IconAlignmentType align,IconTransformType transform,
       short theResID);
void   PlotIcon(const Rect *theRect,Handle theIcon);
OSErr  PlotIconHandle(const Rect *theRect,IconAlignmentType align,
       IconTransformType transform,Handle theIcon);
void   PlotCIcon(const Rect *theRect,CIconHandle theIcon);
OSErr  PlotCIconHandle(const Rect *theRect,IconAlignmentType align,
       IconTransformType transform,CIconHandle theIcon);
OSErr  PlotSICNHandle(const Rect *theRect,IconAlignmentType align,
       IconTransformType transform,Handle theSICN);

Getting Icons From Resources Which do Not Belong to an Icon Family

Handle  GetIcon(short iconID); 
CIconHandle  GetCIcon(short iconID);

Disposing of Icons

OSErr  DisposeCIcon(CIconHandle theIcon);

Creating an Icon Suite

OSErr  GetIconSuite(Handle *theIconSuite,short theResID,IconSelectorValue selector);
OSErr  NewIconSuite(Handle *theIconSuite);
OSErr  AddIconToSuite(Handle theIconData,Handle theSuite,ResType theType);

Getting Icons From an Icon Suite

OSErr  GetIconFromSuite(Handle *theIconData,Handle theSuite,ResType theType);

Drawing Icons From an Icon Suite

OSErr  PlotIconSuite(const Rect *theRect,IconAlignmentType align,
       IconTransformType transform,Handle theIconSuite);

Performing Operations on Icons in an Icon Suite

OSErr  ForEachIconDo(handle theSuite,IconSelectorValue selector, IconActionUPP action,
       void *yourDataPtr);

Disposing of Icon Suites

OSErr  DisposeIconSuite(Handle theIconSuite,Boolean disposeData);

Converting an Icon Mask to a Region

OSErr  IconSuiteToRgn(RgnHandle theRgn,const Rect *iconRect,
       IconAlignmentType align,Handle theIconSuite);
OSErr  IconIDToRegion(RgnHandle theRgn,const Rect *iconRect,
       IconAlignmentType align,short iconID);

Determining Whether a Point or Rectangle is Within an Icon

Boolean  PtInIconSuite(Point testPt,const Rect *iconRect,IconAlignmentType align,
         Handle theIconSuite);
Boolean  PtInIconID(Point testPt,const Rect *iconRect,IconAlignmentType align,
         short iconID);
Boolean  RectInIconSuite(const Rect *testRect,const Rect *iconRect,IconAlignmentType align,
         Handle theIconSuite);
Boolean  RectInIconID(const Rect *testRect,const Rect *iconRect,IconAlignmentType align,
         short iconID);

Working With Icon Caches

OSErr  MakeIconCache(Handle *theHandle,IconGetterProcPtr makeIcon,void *yourDataPtr);
OSErr  LoadIconCache(const Rect *theRect,IconAlignmentType align,
       IconTransformType transform,Handle theIconCache);
       

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Go from lowly lizard to wicked Wyvern in...
Do you like questing, and do you like dragons? If not then boy is this not the announcement for you, as Loongcheer Game has unveiled Quest Dragon: Idle Mobile Game. Yes, it is amazing Square Enix hasn’t sued them for copyright infringement, but... | Read more »
Aether Gazer unveils Chapter 16 of its m...
After a bit of maintenance, Aether Gazer has released Chapter 16 of its main storyline, titled Night Parade of the Beasts. This big update brings a new character, a special outfit, some special limited-time events, and, of course, an engaging... | Read more »
Challenge those pesky wyverns to a dance...
After recently having you do battle against your foes by wildly flailing Hello Kitty and friends at them, GungHo Online has whipped out another surprising collaboration for Puzzle & Dragons. It is now time to beat your opponents by cha-cha... | Read more »
Pack a magnifying glass and practice you...
Somehow it has already been a year since Torchlight: Infinite launched, and XD Games is celebrating by blending in what sounds like a truly fantastic new update. Fans of Cthulhu rejoice, as Whispering Mist brings some horror elements, and tests... | Read more »
Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »
Embark into the frozen tundra of certain...
Chucklefish, developers of hit action-adventure sandbox game Starbound and owner of one of the cutest logos in gaming, has released their roguelike deck-builder Wildfrost. Created alongside developers Gaziter and Deadpan Games, Wildfrost will... | Read more »

Price Scanner via MacPrices.net

13-inch M2 MacBook Airs in stock today at App...
Apple has 13″ M2 MacBook Airs available for only $849 today in their Certified Refurbished store. These are the cheapest M2-powered MacBooks for sale at Apple. Apple’s one-year warranty is included,... Read more
New today at Apple: Series 9 Watches availabl...
Apple is now offering Certified Refurbished Apple Watch Series 9 models on their online store for up to $80 off MSRP, starting at $339. Each Watch includes Apple’s standard one-year warranty, a new... Read more
The latest Apple iPhone deals from wireless c...
We’ve updated our iPhone Price Tracker with the latest carrier deals on Apple’s iPhone 15 family of smartphones as well as previous models including the iPhone 14, 13, 12, 11, and SE. Use our price... Read more
Boost Mobile will sell you an iPhone 11 for $...
Boost Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering an iPhone 11 for $149.99 when purchased with their $40 Unlimited service plan (12GB of premium data). No trade-in is required... Read more
Free iPhone 15 plus Unlimited service for $60...
Boost Infinite, part of MVNO Boost Mobile using AT&T and T-Mobile’s networks, is offering a free 128GB iPhone 15 for $60 per month including their Unlimited service plan (30GB of premium data).... Read more
$300 off any new iPhone with service at Red P...
Red Pocket Mobile has new Apple iPhones on sale for $300 off MSRP when you switch and open up a new line of service. Red Pocket Mobile is a nationwide MVNO using all the major wireless carrier... Read more
Clearance 13-inch M1 MacBook Airs available a...
Apple has clearance 13″ M1 MacBook Airs, Certified Refurbished, available for $759 for 8-Core CPU/7-Core GPU/256GB models and $929 for 8-Core CPU/8-Core GPU/512GB models. Apple’s one-year warranty is... Read more
Updated Apple MacBook Price Trackers
Our Apple award-winning MacBook Price Trackers are continually updated with the latest information on prices, bundles, and availability for 16″ and 14″ MacBook Pros along with 13″ and 15″ MacBook... Read more
Every model of Apple’s 13-inch M3 MacBook Air...
Best Buy has Apple 13″ MacBook Airs with M3 CPUs in stock and on sale today for $100 off MSRP. Prices start at $999. Their prices are the lowest currently available for new 13″ M3 MacBook Airs among... Read more
Sunday Sale: Apple iPad Magic Keyboards for 1...
Walmart has Apple Magic Keyboards for 12.9″ iPad Pros, in Black, on sale for $150 off MSRP on their online store. Sale price for online orders only, in-store price may vary. Order online and choose... Read more

Jobs Board

Solutions Engineer - *Apple* - SHI (United...
**Job Summary** An Apple Solution Engineer's primary role is tosupport SHI customers in their efforts to select, deploy, and manage Apple operating systems and Read more
DMR Technician - *Apple* /iOS Systems - Haml...
…relevant point-of-need technology self-help aids are available as appropriate. ** Apple Systems Administration** **:** Develops solutions for supporting, deploying, Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.