TweetFollow Us on Twitter

MACINTOSH C CARBON

Demonstration Program LowEvents

Goto Contents

// *******************************************************************************************
// LowEvents.c                                                             CLASSIC EVENT MODEL
// *******************************************************************************************
// 
// This program contains a main event loop function, together with subsidiary functions which 
// perform nominal handling only of low-level and Operating System events.  It opens a window 
// in which the types of all received low-level and Operating System events are displayed.  It 
// terminates when the user clicks the window's close box.
//
// Event handling is only nominal in this program because its main purpose is to demonstrate
// the basics of an application's main event loop.  Programs in later chapters demonstrate
// the full gamut of individual event handling. 
//
// The program utilises the following resources:
//
// o  A 'plst' resource.
//
// o  A 'WIND' resource (purgeable).
//
// o  A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground,
//    doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//  
// *******************************************************************************************

// .................................................................................. includes

#include <Carbon.h>

// ................................................................................... defines

#define rWindowResource  128

#define topLeft(r)  (((Point *) &(r))[0])
#define botRight(r) (((Point *) &(r))[1])

// .......................................................................... global variables

Boolean   gDone;
RgnHandle gCursorRegionHdl;

// ....................................................................... function prototypes

void  main            (void);
void  doPreliminaries (void);
void  doNewWindow     (void);
void  eventLoop       (void);
void  doEvents        (EventRecord *);
void  doMouseDown     (EventRecord *);
void  doUpdate        (EventRecord *);
void  doOSEvent       (EventRecord *);
void  drawEventString (Str255);
void  doAdjustCursor  (WindowRef);

// ************************************************************************************** main

void  main(void)
{
  doPreliminaries();
  doNewWindow();
  eventLoop();
}

// *************************************************************************** doPreliminaries

void  doPreliminaries(void)
{
  MoreMasterPointers(48);

  InitCursor();
  FlushEvents(everyEvent,0);
}

// ******************************************************************************* doNewWindow

void  doNewWindow(void)
{
  WindowRef windowRef;

  if(!(windowRef = GetNewCWindow(rWindowResource,NULL,(WindowRef) -1)))
  {
    SysBeep(10);
    ExitToShell();
  }

  SetPortWindowPort(windowRef);
  TextSize(10);
}

// ********************************************************************************* eventLoop

void  eventLoop(void)
{
  EventRecord eventStructure;
  Boolean     gotEvent;
  
  gDone = false;
  gCursorRegionHdl = NewRgn();
  doAdjustCursor(FrontWindow());
  
  while(!gDone)
  {
    gotEvent = WaitNextEvent(everyEvent,&eventStructure,180,gCursorRegionHdl);
    if(gotEvent)
      doEvents(&eventStructure);
    else
    {
      if(eventStructure.what == nullEvent)
        drawEventString("\p   o nullEvent");
    }
  }
}

// ********************************************************************************** doEvents

void  doEvents(EventRecord *eventStrucPtr)
{
  switch(eventStrucPtr->what)
  {
    case mouseDown:
      drawEventString("\p   o mouseDown");
      doMouseDown(eventStrucPtr);
      break;

    case mouseUp:
      drawEventString("\p   o mouseUp");
      break;

    case keyDown:
      drawEventString("\p   o keyDown");
      break;

    case autoKey:
      drawEventString("\p   o autoKey");
      break;

    case updateEvt:
      drawEventString("\p   o updateEvt");
      doUpdate(eventStrucPtr);
      break;

    case activateEvt:
      drawEventString("\p   o activateEvt");
      break;

    case osEvt:
      drawEventString("\p   o osEvt - ");
      doOSEvent(eventStrucPtr);
      break;
  }
}
  
// ******************************************************************************* doMouseDown

void  doMouseDown(EventRecord *eventStrucPtr)
{
  WindowPartCode partCode;
  WindowRef      windowRef;
  
  partCode = FindWindow(eventStrucPtr->where,&windowRef);
  
  switch(partCode)
  {
    case inContent:
      if(windowRef != FrontWindow())
        SelectWindow(windowRef);
      break;

    case inDrag:
      DragWindow(windowRef,eventStrucPtr->where,NULL);
      doAdjustCursor(windowRef);
      break;

    case inGoAway:
      if(TrackGoAway(windowRef,eventStrucPtr->where))
        gDone = true;
      break;
  }
}

// ********************************************************************************** doUpdate

void  doUpdate(EventRecord *eventStrucPtr)
{
  BeginUpdate((WindowRef) eventStrucPtr->message);
  EndUpdate((WindowRef) eventStrucPtr->message);
}

// ********************************************************************************* doOSEvent

void  doOSEvent(EventRecord *eventStrucPtr)
{
  Cursor arrow;

  switch((eventStrucPtr->message >> 24) & 0x000000FF)
  {
    case suspendResumeMessage:
      if((eventStrucPtr->message & resumeFlag) == 1)
      {
        SetCursor(GetQDGlobalsArrow(&arrow));
        DrawString("\pResume");
      }
      else
        DrawString("\pSuspend");
      break;

    case mouseMovedMessage:
      doAdjustCursor(FrontWindow());
      DrawString("\pMouse-moved");
      break;
  }
}

// *************************************************************************** drawEventString

void  drawEventString(Str255 eventString)
{
  WindowRef windowRef;
  RgnHandle tempRegion;
  Rect      portRect;

  windowRef = FrontWindow();
  tempRegion = NewRgn();

  GetWindowPortBounds(windowRef,&portRect);
  ScrollRect(&portRect,0,-15,tempRegion);
  DisposeRgn(tempRegion);

  MoveTo(8,340);
  DrawString(eventString);
}

// **************************************************************************** doAdjustCursor

void  doAdjustCursor(WindowRef windowRef)
{
  RgnHandle myArrowRegion;
  RgnHandle myIBeamRegion;
  Rect      cursorRect;
  Point     mousePt;
  Cursor    arrow;
  
  myArrowRegion = NewRgn();
  myIBeamRegion = NewRgn();
  SetRectRgn(myArrowRegion,-32768,-32768,32767,32767);
  
  GetWindowPortBounds(windowRef,&cursorRect);
  SetPortWindowPort(windowRef);
  LocalToGlobal(&topLeft(cursorRect));
  LocalToGlobal(&botRight(cursorRect));  

  RectRgn(myIBeamRegion,&cursorRect);
  DiffRgn(myArrowRegion,myIBeamRegion,myArrowRegion);
  
  GetGlobalMouse(&mousePt);
  if(PtInRgn(mousePt,myIBeamRegion))
  {
    SetCursor(*(GetCursor(iBeamCursor)));
    CopyRgn(myIBeamRegion,gCursorRegionHdl);
  }
  else
  {
    SetCursor(GetQDGlobalsArrow(&arrow));
    CopyRgn(myArrowRegion,gCursorRegionHdl);
  }
  
  DisposeRgn(myArrowRegion);
  DisposeRgn(myIBeamRegion);
}

// *******************************************************************************************

Demonstration Program LowEvents Comments

When the program is run, the user should move the mouse cursor inside and outside the window,
click the mouse inside and outside the window, drag the window, and press and release keyboard
keys, noting the types of events generated by these actions as printed on the scrolling display
inside the window.

The user should also note:

o The basic window deactivation and activation that occurs when the mouse is clicked outside,
  and then inside the window.

o That when another window is positioned over part of the program's window and then dragged to
  expose more of the program's window, an update event is received on Mac OS 8/9 but not on 
  Mac OS X.

The program may be terminated by a click in the window's close box.

The general "flow" of the program is illustrated in the flow chart at Fig 4.

defines

rWindowResource establishes a constant for the ID of the 'WIND' resource.

The remaining two lines define two common macros.  The first converts the top and left fields
of a Rect to a Point.  The second converts the bottom and right field of a Rect to a Point.

Global Variables

The global variable gDone controls the termination of the main event loop and thus of the
program.  gCursorRegionHdl will be assigned the handle to a region to be passed in the mouseRgn
parameter of the WaitNextEvent function.

main

The main function calls the functions for performing certain preliminary actions common to most
applications and for creating the window.  It then calls the function containing the main event
loop.

doPreliminaries

doPreliminaries is the standard "do prelimaries" function which will be used in all subsequent
Classic event model demonstration programs.

FlushEvents empties the Operating System event queue of any low-level events left unprocessed
by another application, for example, any mouse-down or keyboard events that the user may have
entered while this program was being launched.

doNewWindow

The function doNewWindow opens the window in which the types of low-level and Operating System
events will be printed as they occur.  The 'WIND' resource passed as the first parameter
specifies that the window has a close box and a drag (title) bar.  The window's graphics port
is set as the current port for drawing and the text size is set to 10 points.

eventLoop

eventLoop is the main event loop.

The global variable gDone is set to false before the event loop is entered.  This variable will
be set to true when the user clicks on the window's close box.  The event loop (the while
loop) terminates when gDone is set to true.

The calls to NewRgn and doAdjustCursor have to do with the generation of mouse-moved events. 
The NewRgn call allocates storage for a Region object and initialises the contents of the
region to make it an empty region.  As will be seen, this first call to doAdjustCursor defines
two regions (one for the arrow cursor and one for the I-Beam cursor) and copies the handle to
one of them (depending on the current position of the mouse cursor) to the global variable
gCursorRegionHandle.

In the call to WaitNextEvent:

o The event mask everyEvent ensures that all types of low-level and Operating System events
  will be returned to the application (except keyUp events, which are masked out by the system
  event mask).

o eventStructure is the EventRecord structure which, when WaitNextEvent returns, will contain
  information about the event.

o 180 represents the number of ticks for which the application agrees to relinquish the
  processor if no events are pending for it.  180 ticks equates to about three seconds.

o If the cursor is now not within the region passed in the cursorRegion parameter, a
  mouse-moved event will be generated immediately.

WaitNextEvent returns 1 if an event was pending, otherwise it returns 0.  If an event was
pending, the program branches to doEvent to determine the type of event and handle the event
according to its type.  If 0 is returned, and if the what field of the event structure contains
nullEvent, "nullEvent" is printed in the window.  This will occur every three seconds in the
absence of other events.

doEvents

doEvents handles some events to finality and performs initial handling of others.

On return from WaitNextEvent, the what field of the event structure contains an unsigned short
integer which indicates the type of event received.  The doEvent function isolates the type of
event and switches according to that type.

In this demonstration, the action taken in every case is to print the type of event in the
window.  In addition, and in the case of mouse-down, update, and Operating System events only,
calls to individual event handling functions are made.

Note that, in the case of an Operating System event, doEvent will only print "osEvt - " in the
window.  At this stage, the program has not yet established whether the event is a suspend,
resume or mouse-moved event.

Note also that the inclusion of the key-up event handling would be pointless, since key-up
events are masked out by the Operating System.

doMouseDown

The function doMouseDown handles mouse-down events to completion.

FindWindow is called to get a reference to the window in which the event occurred and a part
code which indicates the part of that window in which the mouse-down occurred.  The function
then switches according to that part code.

The inContent case deals with a mouse-down in a window's content region.  FrontWindow returns a
reference to the frontmost window.  If this is not the same as the reference in the event
structure's message field, SelectWindow is called to generate activate events and to perform
basic window activation and deactivation.  (Actually, SelectWindow will never be called in this
demonstration because the program only opens one window, which is always the front window.)

The inDrag case deals with a mouse-down in the window's title bar (Mac OS 8/9) or title bar
(Mac OS X).  In this case, control is handed over to DragWindow, which tracks the mouse and
drags the window according to mouse movement until the mouse button is released.  A bounding
rectangle limiting the area in which the window can be dragged may be passed in DragWindow's
third parameter. In Carbon, NULL may also be passed in this parameter.  This has the effect of
setting the third parameter to the bounding box of the "desktop region" (also known as the
"gray region").  The desktop region is the region below the menu bar, including all screen real
estate in a system equipped with multiple monitors.

The regions controlling the generation of mouse-moved events are defined in global coordinates. 
The region for the I-Beam cursor is based on the window's graphics port's bounding rectangle. 
Accordingly, when the window is moved, the new location of the port rectangle, in global
coordinates, must be re-calculated so that the arrow cursor and I-Beam cursor regions may be
re-defined.  The call to doAdjustCursor re-defines these regions for the new window location
and copies the handle to one of them, depending on the current location of the mouse cursor, to
the global variable gCursorRegionHandle.  (Note that this call to doAdjustCursor will also be
required, for the same reason, when a window is re-sized or zoomed.)

The inGoAway case deals with the case of a mouse-down in the close box (Mac OS 8/9) or close
button (Mac OS X).  In this case, control is handed over to TrackGoAway, which tracks the mouse
while the mouse button remains down.  When the button is released, TrackGoAway returns true if
the cursor is still inside the close box, in which case the global variable gDone is set to
true, terminating the event loop and the program.

doUpdate

The function doUpdate handles update events to completion.

Although no window updating is performed by this program, it is nonetheless necessary to call
BeginUpdate because, amongst other things, BeginUpdate clears the update region, thus
preventing the generation of an unending stream of update events.  The call to EndUpdate always
concludes a call to BeginUpdate, undoing the results of the visible/update region manipulations
of the latter.

doOSEvent

doOSEvent first determines whether the Operating System event passed to it is a suspend/resume
event or a mouse-moved event by examining bits 24-31 of the message field.  It then switches
according to that determination.

In the case of a suspend/resume event, a further examination of the message field establishes
whether the event was a suspend event or a resume event.  In the case of a resume event, the
call to SetCursor ensures that the cursor will be set to the arrow cursor shape when the
application comes to the foreground.  (With regard to the call to GetQDGlobalsArrow, see
QuickDraw Globals and Accessor Functions, below.)

In the case of a mouse-moved event (which occurs when the mouse cursor has moved outside the
region whose handle is currently being passed in WaitNextEvent's mouseRgn parameter),
doAdjustCursor is called to change the handle passed in the mouseRgn parameter according to the
current location of the mouse.

drawEventString

drawEventString is incidental to the demonstration.  It simply prints text in the window
indicating when the various types of events are received.  ScrollRect scrolls the contents of
the current graphics port within the rectangle specified in the first parameter.  The second
parameter specifies the number of pixels to be scrolled to the right and the third parameter
specifies the number of pixels to scroll vertically, in this case 15 up.

doAdjustCursor

doAdjustCursor's primary purpose in this particular demonstration is to force the generation of
mouse-moved events.  The fact that it also changes the cursor shape simply reflects the fact
that changing the cursor shape is usually the sole reason for generating mouse-moved events in
the first place.

Basically, the function establishes two regions (the calls to NewRgn), one describing the
content area of the window (in global coordinates) and the other everything outside that.  The
location of the cursor, in global coordinates, is then ascertained by the call to
GetGlobalMouse.  If the cursor is in the content area of the window (the I-Beam region), the
cursor is set to the I-Beam shape and the handle to the I-Beam region is copied to the global
variable passed in the mouseRgn parameter in the WaitNextEvent call in the eventLoop function. 
If the cursor is in the other region (the arrow region), the cursor is set to the normal arrow
shape and the arrow region is copied to the global variable passed in the mouseRgn parameter.

GetCursor reads in the system 'CURS' resource specified by the constant iBeamCursor and returns
a handle to the 68-byte Cursor structure created by the call.  The parameter for a SetCursor
call is required to be the address of a Cursor structure.  Dereferencing the handle once
provides that address.

WaitNextEvent, of course, returns a mouse-moved event only when the cursor moves outside the
"current" region, the handle to which is passed in the mouseRgn parameter of the WaitNextEvent
call.  Only one mouse-moved event, rather than a stream of mouse-moved events, will be
generated when the cursor is moved outside the "current" region because: 

o The mouse-moved event will cause doAdjustCursor to be called.

o doAdjustCursor will thus reset the "current" region to the region in which the cursor is now
  located.

The cursor and cursor adjustment aspects, as opposed to the region-swapping aspects, of the
doAdjustCursor function are incidental to the demonstration.  These aspects are addressed in
more detail at Chapter 13.

QUICKDRAW GLOBALS AND ACCESSOR FUNCTIONS

An accessor function pertaining to application QuickDraw global variables
(GetQDGlobalsArrow) is used in this demonstration.

QuickDraw global variables are stored as part of your application's global variables.
In Carbon, accessor functions are provided, and must be used, to access the data in 
these globals.
 
The accessor functions are as follows:

CGrafPtr  GetQDGlobalsThePort(void);             // Gets pointer to current graphics port.
Cursor*   GetQDGlobalsArrow(Cursor *arrow);      // Gets standard cursor arrow shape.
void      SetQDGlobalsArrow(const Cursor *arrow);  // Sets standard cursor arrow shape.
Pattern*  GetQDGlobalsDarkGray(Pattern *dkGray);   // Gets pre-defined dark gray pattern.
Pattern*  GetQDGlobalsLightGray(Pattern *ltGray);  // Gets pre-defined light gray pattern.
Pattern*  GetQDGlobalsGray(Pattern *gray);         // Gets pre-defined gray pattern.
Pattern*  GetQDGlobalsBlack(Pattern *black);       // Gets pre-defined black pattern.
Pattern*  GetQDGlobalsWhite(Pattern *white);       // Gets pre-defined e white pattern.
long      GetQDGlobalsRandomSeed(void);            // Get random number generator seed.
void      SetQDGlobalsRandomSeed(long randomSeed); // Set random number generator seed.
BitMap*   GetQDGlobalsScreenBits(BitMap *screenBits); // screenBits.bounds contains
                                                      // rectangle enclosing main screen.
 
AAPL
$106.98
Apple Inc.
-0.36
MSFT
$46.05
Microsoft Corpora
-0.57
GOOG
$550.31
Google Inc.
+0.98

MacTech Search:
Community Search:

Software Updates via MacUpdate

Sandvox 2.9.2 - Easily build eye-catchin...
Sandvox is for Mac users who want to create a professional looking website quickly and easily. With Sandvox, you don't need to be a Web genius to build a stylish, feature-rich, standards-compliant... Read more
Cocktail 8.0.1 - General maintenance and...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
LibreOffice 4.3.3.2 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
VMware Fusion 7.0.1 - Run Windows apps a...
VMware Fusion allows you to create a Virtual Machine on your Mac and run Windows (including Windows 8.1) and Windows software on your Mac. Run your favorite Windows applications alongside Mac... Read more
OneNote 15.3.2 - Free digital notebook f...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that's too important to forget. Whether you're at... Read more
Audio Hijack Pro 2.11.4 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Iridient Developer 3.0.0 beta 3 - Powerf...
Iridient Developer (was RAW Developer) is a powerful image conversion application designed specifically for OS X. Iridient Developer gives advanced photographers total control over every aspect of... Read more
TextWrangler 4.5.11 - Free general purpo...
TextWrangler is the powerful general purpose text editor, and Unix and server administrator's tool. Oh, and also, like the best things in life, it's free. TextWrangler is the "little brother" to... Read more
NeoFinder 6.6 - Catalog your external me...
NeoFinder (formerly CDFinder) rapidly organizes your data, either on external or internal disks, or any other volumes. It catalogs all your data, so you stay in control of your data archive or disk... Read more
Chromium 38.0.2125.111 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. FreeSMUG-Free OpenSource Mac User Group build is... Read more

Latest Forum Discussions

See All

Night Sky Pro™ (Reference)
Night Sky Pro™ 3.0.1 Device: iOS Universal Category: Reference Price: $2.99, Version: 3.0.1 (iTunes) Description: Night Sky Pro™Wonder No More™ Night Sky Pro™ is the ultimate stargazing experience. From the creators of the original... | Read more »
Audio Defence : Zombie Arena (Games)
Audio Defence : Zombie Arena 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: A zombie shooter audio game. Made from gut-wrenching 3D binaural sound, for a new kind of weird immersion. You... | Read more »
RPG Asdivine Hearts (Games)
RPG Asdivine Hearts 1.1.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.1.0 (iTunes) Description: SPECIAL PRICE50% OFF (USD 7.99 -> USD 3.99)!!! Travel alongside four companions and a cat in the adventure of a... | Read more »
Haunt the House: Terrortown (Games)
Haunt the House: Terrortown 1.0.1 Device: iOS Universal Category: Games Price: $.99, Version: 1.0.1 (iTunes) Description: 66.6% OFF! SPECIAL SPOOKY HALLOWEEN LAUNCH PRICE! 66.6% OFF! ...What was that sound? Is somebody there? | Read more »
SAS: Zombie Assault 4 Review
SAS: Zombie Assault 4 Review By Jennifer Allen on October 30th, 2014 Our Rating: :: FLAWED SHOOTERUniversal App - Designed for iPhone and iPad Shoot everything that moves in this fun, if flawed, twin-stick shooter.   | Read more »
Naailde the Witch Review
Naailde the Witch Review By Amy Solomon on October 30th, 2014 Our Rating: :: PITCH-PERFECT STORYTELLINGUniversal App - Designed for iPhone and iPad Marvelous storytelling, narration, and moving illustrations make this storybook... | Read more »
1st & Goal Review
1st & Goal Review By Andrew Fisher on October 30th, 2014 Our Rating: :: FOR THE D&D LOVING QBUniversal App - Designed for iPhone and iPad 1st & Goal is a board gamer’s football game, a football fan’s board game, and... | Read more »
French Developer Pated Unveils Seashine
French Developer Pated Unveils Seashine Posted by Ellis Spice on October 30th, 2014 [ permalink ] French one-man studio Pated has unveiled Seashine, “a poetic journey into the abyss.” Players take on the role of a jellyfish strugglin | Read more »
Agents of Storm: Tips, Tricks, and Strat...
Calling all agents: Would you like to see what we thought of this rather pretty base builder? Check out our Agents of Storm review! Have you downloaded Agents of Storm, been bowled over by the graphics, and aren’t quite sure what to do next? Never... | Read more »
Any.DO 2.0 Hopes to Help Manage Producti...
Any.DO 2.0 Hopes to Help Manage Productivity Posted by Ellis Spice on October 30th, 2014 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »

Price Scanner via MacPrices.net

Apple Regains Momentum As Windows Stutters An...
The latest smartphone sales data from Kantar Worldpanel ComTech, for the three months to March 2014, shows Apple performing strongly in the first quarter of the year, with sales bouncing back in... Read more
Worldwide Smartphone Shipments Increase 25.2%...
New smartphone releases and an increased emphasis on emerging markets drove global smartphone shipments above 300 million units for the second consecutive quarter, according to preliminary data from... Read more
Apple now offering refurbished 2014 15-inch M...
The Apple Store is now offering Apple Certified Refurbished 2014 15″ Retina MacBook Pros for up to $400 off the cost of new models. An Apple one-year warranty is included with each model, and... Read more
Apple drops prices on refurbished 2013 Retina...
The Apple Store has dropped prices on 2013 Apple Certified Refurbished 13″ and 15″ Retina MacBook Pros, with Retina models now available starting at $999. Apple’s one-year warranty is standard, and... Read more
New 2.8GHz Mac mini on sale for $949, save $5...
Abt Electronics has the new 2.8GHz Mac mini in stock and on sale for $949.05 including free shipping. Their price is $50 off MSRP, and it’s the lowest price available for this model from any reseller... Read more
Sale! 3.7GHz Quad Core Mac Pro available for...
 B&H Photo has the 3.7GHz Quad Core Mac Pro on sale for $2649 including free shipping plus NY sales tax only. Their price is $350 off MSRP, and it’s the lowest price for this model from any... Read more
Mujjo Steps Up The Game With Refined Touchscr...
Netherlands based Mujjo have just launched their Refined Touchscreen Gloves, stepping up their game. The gloves feature a updated elegant design that takes these knitted gloves to the next level. A... Read more
Sale! Preorder the new 27-inch 5K iMac for $2...
 Abt Electronics has the new 27″ 3.5GHz 5K iMac on sale and available for preorder for $2374.05 including free shipping. Their price is $125 off MSRP, and it’s the lowest price available for this... Read more
Simplex Solutions Inc. Brings Secure Web Surf...
New York based Simplex Solutions Inc. has announced the release and immediate availability of Private Browser 1.0, its revolutionary new secure web browser developed for iPhone, iPad and iPod touch... Read more
Save up to $180 off MSRP with an Apple refurb...
The Apple Store has Apple Certified Refurbished 2014 MacBook Airs available for up to $180 off the cost of new models. An Apple one-year warranty is included with each MacBook, and shipping is free.... Read more

Jobs Board

Position Opening at *Apple* - Apple (United...
**Job Summary** Every day, business customers come to the Apple Store to discover what powerful, easy-to-use Apple products can do for them. As a Business Leader, Read more
Sr. Manager, *Apple* Deployment Programs fo...
**Job Summary** Apple is seeking candidates for a new position on the Education Content and Technology team. iPad and Mac is in the hands of millions of teachers and Read more
*Apple* Solutions Consultant (ASC) - Apple I...
…important role that the ASC serves is that of providing an excellent Apple Customer Experience. Responsibilities include: * Promoting Apple products and solutions Read more
*Apple* Solutions Consultant (ASC) - Apple I...
…important role that the ASC serves is that of providing an excellent Apple Customer Experience. Responsibilities include: * Promoting Apple products and solutions Read more
*Apple* Solutions Consultant (ASC) - Apple I...
…important role that the ASC serves is that of providing an excellent Apple Customer Experience. Responsibilities include: * Promoting Apple products and solutions Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.