TweetFollow Us on Twitter

FKEY for FKEYs
Volume Number:4
Issue Number:6
Column Tag:Assembly Language Lab

FKEY that runs other FKEYs!

By John Holder, Contributing Editor

[John Holder is a previous contributor to MacTutor and is well known for his numerous FKEY shareware products. In this article, John shows us how to create an FKEY that runs other FKEYS without installing them in the system folder! Hence this FKEY has an event loop, menu bar and all the other goodies normally found in a regular application. The source code disk for this month also includes two of his more popular FKEYS to use as launch samples, along with a shareware application so you can contact John about other goodies he might have for you. -Ed]

What’s an FKEY?

FKEY’s (Function Keys) are resources containing executable code that are called upon by hitting the keys Command-Shift-# (any number 0-9) at the same time. In the standard System file there are two FKEY’s; with an ID#3 and #4 that are used to dump the current screen or window onto disk or printer.

There are also many other FKEY’s out in the Mac world, some Public Domain or Shareware, and others are sold commercially. They can be installed into the System file by using “ResEdit” or “Fkey Installer” (this application was created by “Dreams of the Phoenix, Inc™” and released into the public domain to encourage people to make Fkeys). The Fkey presented in this article can be used to access other Fkey’s which are not in the System file!

What’s this all about?

This article will show you how to create an FKEY with an interface similar to a standard applications (menus with command key equivalents, windows, and an event loop). It does not support DA’s nor does it have an EDIT menu, but if you need to add this function to your own Fkey it would be very simple.

This Fkey was created with the Macintosh 68000 Development System. All applications are on a disk titled ‘MDS1’ and all .D files are on a disk titled ‘MDS2’. First assemble the file ‘FkeyTemp.Asm’, then run the linker on the file ‘FkeyTemp.Link’, and finally run RMaker on the file ‘FkeyTemp.R’. You will now have an FKEY ready to put into your System file!

Fig. 1 Our FKEY launches other fkeys!

Fkey Sampler, How it Works

First, we create an offset table that is used to store the FKEY’s many “global” variables. This is done by naming the offsets that it will need such as sfReply, WindPtr, etc., and calculating how many bytes each will take (explained under “How to set up the offset Table”).

When the Fkey starts, there is a short jump over its header, then the applications current port and all registers are saved, next it brings up the standard arrow cursor with _InitCursor. We now check the global variable MenuList to see if the application which is currently running has a menu, if it doesn’t have one (like the MiniFinder) then we can’t let the Fkey run! If it does have a menu, we try to allocate enough space for the Fkey’s global variables by making a non-relocatable block with _NewPtr. If there is not enough memory for the globals (there has been an error if _NewPtr returns a zero in register A0) it beeps the speaker and returns to the Application. Otherwise, a pointer to the storage area is put into register A4.

If the storage was allocated, we go on and get a handle to a copy of the applications menu bar with _GetMenuBar, and clear the menu so that we may replace it with our own. After the Fkey’s menus are created with _NewMenu, _AppendMenu, and _InsertMenu, we create a window that will simulate the standard desktop. Creating a new window generates an update event, so when it gets to the main event loop, the window will be filled with the current desktop pattern.

The Main Event

Now its off to the main loop to look for events. This Fkey uses only keydown, mousedown & update events. Upon a useable event we jump to the appropriate routine to handle it, if it’s an update event the background window is filled with the current desktop pattern (found in the system global variable “DeskPattern”). Other events are handled just like a standard application by using a jump table to jump to the appropriate routines.

Doing the About...

When the mouse is clicked in the “About Fkey Sampler...” menu item under the Apple menu, a window is created and set as the current port. Then the windows text font and size is set to 9 point Monaco with _TextFont and _TextSize. Now the stack is set up for _TextBox (a very handy routine that displays text in a given rectangle with left, right or center justification!) Then we jump to a routine that uses _GetOSEvent to watch for a mousedown or key down event. When a key or the mouse button has been clicked we dispose of the window, unhighlight the menu and return to the main loop to get the next event!

Fig. 2 A useful FKEY running under our FKEY

Opening the Fkey

The purpose of this particular Fkey is to open and use other FKEY’s (of Type ‘FKEY’) that are not in the System file. When this routine is called, the standard get file dialog is displayed with _Pack3. If a name is chosen, the volume the file is on is set as the current volume with _SetVol. Now we try to open the resource fork of the file (_OpenResFile will return a #-1 if it can’t open a files resource fork). If the resource file opened with no problems we want to get the Fkey resource which is inside this file and execute it (run it, not kill it!).

Now we want to get the first Fkey resource in memory by using _GetIndResource (the newly opened res file is searched first). We check to make sure the returned Fkey is from the newly opened resource file by using _HomeResFile (when given a handle to a resource, this routine returns its resource files reference number). If it is from the Fkey file just opened, the Fkey resource is locked in memory (we don’t want the Fkey moving!), the handle is made into a pointer and the Fkey is executed by jumping to it (with JSR). When that Fkey is done, we close the resource file and return for the next event.

Doing the Quit!

When an Fkey quits it must dispose of any memory it created. The first thing dumped is the window used as the desktop, then the menus it made are released from memory with _DisposMenu and the menu bar is cleared. Now the applications menu bar is restored, the memory we allocated for the globals is released, all events are flushed, the applications current port and registers are restored, and a return from subroutine RTS returns command to the application!

Fig. 3 Map for how the FKEY is constructed Use ResEdit to copy the FKEY into the system file

Making your own FKEY

All Fkey’s must start with the FKEY header shown in the code listing. The only thing you will need to change in the header for your own Fkey is the ID number. You can use this Fkey to test all of your own Fkeys without installing them into the System file!

To make your own Fkey using this one as a template should be very simple. Just make your own offset table, or use this one and add your own needed offsets (explained below), then add your own menus and the appropriate routines to handle them. Also, change the contents of the text between MyTextBegin and MyTextEnd to whatever you want for your Fkeys ‘About..’ window.

A complete jump table for events and a jump table for where the mouse was clicked (returned by _FindWindow) is included to help in making your own Fkeys. Just remember to always check if there is enough memory before loading a resource or creating storage and to dispose of any storage that the Fkey created before returning control to the application!

How to set up the Offset Table

Lets say you need room for one handle (4 bytes) and two separate words (2 bytes each) of storage.

For the this storage you would need to put #8 into register D0 before calling _NewPtr (8 bytes are needed)

;Your Offset table (example)

AHandle equ  0 ;4 bytes
AWord equ 4 ;2 bytes
NextWordequ 6  ;2 bytes

Register A4 points to your global storage area . To store a word into the global “AWord” just use:

move  #99, AWord(A4)

To put the value contained in AWord(A4) into Register D2 , use:

move  AWord(A4), D2

That’s all folks...

Well, that’s it, I hope you’ve learned something, and I hope to see lots of new Fkeys around!

;File:   FkeyTemp.Asm
;------------------------------------------------
;An Fkey sampler Fkey
;By John Holder    2/8/87
;Revised          3/29/88
;------------------------------------------------
 IncludeTraps.D
 IncludeToolequ.D
 IncludeSysequ.D

;------------------------------------------------
;Macros to save & restore the registers
;------------------------------------------------
MACRO SaveRegs =
 movem.lA0-A4/D0-D7,-(SP)
 |

MACRO RestoreRegs =
 movem.l(SP)+,A0-A4/D0-D7
 |

;------------------------------------------------
;All equates go here
;------------------------------------------------
;these are offsets into the global storage.
;(a non-relocatable block we created pointed to by A4)
;------------------------------------------------
sfReply equ 0  ;sfreply record
GetVRef equ 6
GetVers equ 8
GFileName equ  10
IOParamBlkequ  76;IOparamblock (80 bytes)
WindPtr equ 156  ;for our background ;window
EventBlkequ 160  ;Event Block
what    equ 160  ;Event number
message equ 162  ;Additional information
when    equ 166  ;Time event was posted 
where   equ 170  ;Mouse coordinates
modify  equ 174  ;State of keys and button
wWindow equ 176  ;Window pointer
Menu1Hndl equ  180 ;handle to our Apple menu
Menu2Hndl equ  184 ;handle to our File menu
oldMenuBarequ  188 ;handle to applications   ;menu
TheWindow equ  192 ;for _FindWindow

;event masks for _GetOSEvent
mDownMask equ  2
keyDownMask equ  8

;Menu equates
AppleMenu equ  1 ;Apple Menu
AboutItem equ  1 
FileMenuequ 2  ;File Menu
OpenFkeyItemequ  1
QuitItemequ 3

;------------------------------------------------
;All FKEY’s must have this FKEY resource header!
;------------------------------------------------
 bra.s  StartIt  ;branch over header
 dc0    ;flags (not used)
 dc.b   ‘FKEY’   ;resource type
 dc9    ;Resource ID #
 dc0    ;version # (not used)
;------------------------------------------------
StartIt
 SaveRegs ;save regs MACRO
 subq   #4,SP
 move.l SP,-(SP)
 _GetPort ;save Port for later
 _InitCursor;standard arrow cursor

 ;does application have a menu???  if not, then quit!
 move.l MenuList,D0
 beq    NoMenuJump ;no menu, beep & quit!

 move.l #200,D0  ;200 bytes of storage
 _NewPtr,CLEAR   ;for our globals
 move.l A0,A4    ;pointer in A4
 cmp.l  #0,A4
 bne.s  StorageOk;if not zero, ptr is ok!

NoMenuJump
 bsr    Mem_Error;otherwise beep
 bra    No_Mem   ;and quit
 
StorageOk
 bsr    SetUpMenus ;set up our menus
 bsr    SetUpWindow;set up background  ;window
;------------------------------------------------
MainLoop;standard event loop
 _SystemTask
      clr    -(SP)
 move   #$0FFF,-(SP) ;event mask
 pea    EventBlk(A4) ;Place to return results
 _GetNextEvent   ;Look for an event
 move   (SP)+,D2 
 beq    MainLoop ;zero if we shouldn’t
 move   What(A4),D0;respond
 add    D0,D0
 move   EventTable(D0),D0
 jmp    EventTable(D0)  ;jump to appropriate       ;routine

EventTable
 dcMainLoop-EventTable  ;null event
 dcMouseDown-EventTable   ;mouse down
 dcMainLoop-EventTable  ;mouse up
 dcKeyDown-EventTable;key down
 dcMainLoop-EventTable  ;key up
 dcKeyDown-EventTable;auto key
 dcUpDateJump-EventTable  ;update event
 dcMainLoop-EventTable  ;disk event
 dcMainLoop-EventTable  ;activate event
 dcMainLoop-EventTable  ;abort
 dcMainLoop-EventTable  ;network event
 dcMainLoop-EventTable  ;I/O driver event

;------------------------------------------------
SetUpWindow
 clr.l  -(SP)    ;for returned pointer
 clr.l  -(SP)    ;let Mac make storage
 pea    WindowRect ;windows rectangle
 clr.l  -(SP)    ;no title
 move.b #1,-(SP) ;it is visible
 move   #plainDBox,-(SP)  ;Type of window
 move.l #-1,-(SP);in front
 move.b #0,-(SP) ;no close box
 clr.l  -(SP)    ;refcon zero
 _NewWindow ;make window!
 move.l (SP),WindPtr(a4)  ;pointer into global
 _SetPort ;set as the port
 rts

;------------------------------------------------
SetUpMenus
 clr.l  -(SP)    ;get applications menu
 _GetMenuBar;bar handle for later
 move.l (SP)+,oldMenuBar(A4)  ;restoration!
 _ClearMenuBar   ;clear Apps menu bar

;make all of our menus
;the apple menu  
 clr.l  -(SP)    
 move   #1,-(SP)
 pea    AppleSymbol
 _NewMenu
 move.l (SP)+,Menu1Hndl(A4)
 move.l Menu1Hndl(A4),-(sp)
 pea    ‘About Fkey Sampler...’
 _AppendMenu
 move.l Menu1Hndl(A4),-(sp) 
 move   #2,-(SP) 
 _InsertMenu
;the File menu
 clr.l  -(SP)
 move   #2,-(SP)
 pea    ‘File’
 _NewMenu
 move.l (SP)+,Menu2Hndl(A4)
 move.l Menu2Hndl(A4),-(sp)
 pea    ‘Open FKEY/F’
 _AppendMenu
 move.l Menu2Hndl(A4),-(sp)
 pea    ‘(-’
 _AppendMenu
 move.l Menu2Hndl(A4),-(sp)
 pea    ‘Quit/Q’
 _AppendMenu
 move.l Menu2Hndl(A4),-(sp) 
 clr    -(SP)
 _InsertMenu
 _DrawMenuBar    ;draw the new menu bar
 rts

UpDateJump
 bsr    UpDateWindow
 bra    MainLoop

;------------------------------------------------
;This routine keeps our background window (The DeskTop!) 
;the same pattern as the current standard desktop!
;------------------------------------------------
UpDateWindow
 move.l WindPtr(A4),-(SP)  ;our background
 ;window
 _BeginUpdate    ;is kept in WindPtr(A4)
 move.l WindPtr(A4),-(SP)
 _SetPort
 pea    PaintRect;the rectangle to paint
 pea    DeskPattern;global var, contains
 _FillRect;pattern used for desktop
 move.l WindPtr(A4),-(SP)
 _EndUpdate
 rts

;------------------------------------------------
;A key down event occured, check if the command key was 
;down, if not, get the next event!
;------------------------------------------------
KeyDown
 move   Modify(A4),D1
 btst   #8,D1    ;check command key bit
 beq    MainLoop ;zero if command key
 ;is not down!
 clr.l  -(sp)
 move   message+2(A4),-(sp)   ;put char onto stack
 _MenuKey ; for _MenuKey
 move.l (sp)+,D4 ;put result in D4
 beq    MainLoop ;if zero, no menu equivalent
 bra    WhatMenu

;------------------------------------------------
;A mousedown event occured, we only check if its in a menu, if 
;not then get the next event!
;------------------------------------------------
MouseDown
 clr    -(SP)    ;word result
 move.l where(A4),-(SP)   ;where field of    ;event record
 pea    TheWindow(A4);returns the window     ;pntr the
 _FindWindow;mouse was clicked in, 
 move   (SP)+,D0 ;if it was in one.

 add    D0,D0
 move   WindowTable(D0),D0
 jmp    WindowTable(D0) ;jump to appropriate       ;routine

;We only use InMenu event!
WindowTable
 dcMainLoop-WindowTable   ;In Desk
 dcInMenu-WindowTable     ;In Menu Bar
 dcMainLoop-WindowTable   ;In System Window
 dcMainLoop-WindowTable   ;in Content
 dcMainLoop-WindowTable   ;in drag
 dcMainLoop-WindowTable   ;in grow
 dcMainLoop-WindowTable   ;in go away

;------------------------------------------------
;The mouse was clicked in the menu bar.
;------------------------------------------------
InMenu
 clr.l  -(SP)
 move.l where(A4),-(SP)
 _MenuSelect
 move.l (SP)+,D4
 beq  MainLoop   ;zero if no item selected

;jump to here after command key down event
WhatMenu
 move.l D4,D6    ;D6 will now have the
 swap   D4; item # D4 will have menu #
WhichMenuWasIt
 cmp    #AppleMenu,D4;is it in the apple menu?
 beq    InAppleMenu;if so, go see which item!
 cmp    #FileMenu,D4 ;is it in the File menu?
 beq    InFileMenu
 bra    MainLoop ;where else could it be!

InAppleMenu ;in the “Apple” menu
 cmp    #AboutItem,D6
 beq    DoAbout  ;its in the About... Item!
 bra    MainLoop

InFileMenu;in the “File” menu
 cmp    #OpenFkeyItem,D6  ;in the OpenFkey Item?
 beq    Open_Fkey;if so go open it!
 cmp    #QuitItem,D6 ;Quit item?
 beq    QuitRoutine;if so go quit
 bra    MainLoop

;------------------------------------------------
;Show the “About Fkey Sampler...” window
;------------------------------------------------
DoAbout
 saveregs ;save the registers
 
 clr.l  -(SP)
 clr.l  -(SP)    
 pea    AboutRect
 move.l #0,-(SP) 
 move.b #1,-(SP)
 move   #1,-(SP)
 move.l #-1,-(SP)
 move.b #0,-(SP)
 clr.l  -(SP)
 _NewWindow ;make a window
 move.l (SP),A2  ;put pointer into A2
 _SetPort ;make it the port

 move   #Monaco,-(SP);Use the Monaco Font
 _TextFont
 move   #9,-(SP) ;make it 9 point (size)
 _TextSize

 pea    MyTextBegin;address of “About” Text

;calculate how many chars in text for TextBox
 move.l #MyTextEnd-MyTextBegin,-(SP)
 pea    TextRect ;rectangle for text
 move   #1,-(SP) ;center justification
 _TextBox
 bsr    Wait_For_Event  ;wait for button/key down
 move.l A2,-(SP)
 _DisposWindow   ;get rid of the window
 bsr    UnHiliteIt ;go unhilight the menu!
 move.l WindPtr(A4),-(sp)
 _SetPort ;reset our old port
 restoreregs;restore registers
 bra    MainLoop ;go get another event

;------------------------------------------------
;Wait for mouse or key down event
;------------------------------------------------
Wait_For_Event
 link   A6,#-evtBlkSize   ;link, event block size
WaitLoop
 lea    -evtBlkSize(A6),A0  ;ptr to event block in A0
 moveq  #mDownMask!KeyDownMask,D0 ;Event masks in D0
 _GetOSEvent
 beq    Clicked  ;if zero, time to leave!
 bra    WaitLoop ;loop until event
Clicked ;mouse or key clicked!
 unlk   A6;unlink A6
 rts
 
;------------------------------------------------
;Quitting, dispose of all our storage and menus and return to 
;the application that the Fkey was called from!
;------------------------------------------------
QuitRoutine
 move.l WindPtr(A4),-(SP) ;dump background 
 _DisposWindow   ;window
 move.l Menu1Hndl(A4),-(SP)   ;dump our #1 
 _DisposMenu                ;menu
 move.l Menu2Hndl(A4),-(SP) ;dump our #2
 _DisposMenu              ;menu
 _ClearMenuBar   ;clear the menu
 move.l oldMenuBar(A4),-(SP)
 _SetMenuBar;restore apps menu bar!
 move.l oldMenuBar(A4),A0   ;dump copy of    
 _DisposHandle   ;apps menu handle!
 _DrawMenuBar    ;draw it
 move.l A4,A0
 _DisposPtr ;dump our global  ;storage

No_Mem
 move.l #$0000FFFF,D0     ;flush all events
 _FlushEvents
 _SetPort ;set original port!
 restoreregs;restore the registers
 rts    ;return to the application!

;------------------------------------------------
;Couldn’t allocate space for our global storage area
;just beep & quit!
;------------------------------------------------
Mem_Error
 move   #10,-(SP)
 _SysBeep
 rts

;------------------------------------------------
;Unhilight menu bar after mouse down in a menu item
;------------------------------------------------
UnHiliteIt
 move   #0,-(SP)
 _HiliteMenu
 rts

;------------------------------------------------
;Get a file of type “FKEY”, open its resource fork, and
;execute the Fkey (if there is one) contained in it!
;------------------------------------------------
Open_Fkey
 saveregs ;save registers
 move   #82,-(SP);coordinates for GetFile
 move   #100,-(SP) ;dialog box
 clr.l  -(SP)    ;prompt
 clr.l  -(SP)    ;File Filter Proc Pointer
 move   #1,-(SP) ;number of file types
 pea    TypeList ;our type list
 clr.l  -(SP)    ;Dialog Hook Proc Pointer
 pea    sfReply(A4);sfreply record
 move   #2,-(SP) ;#2 for SFGetFile
 _Pack3 ;Call the Get File Pack
 cmp.b  #0,sfReply(A4)
 beq    Cancel   ;if user hit cancel, quit!

 bsr    UpDateWindow ;update window before
 ;opening the Fkey
 lea    IOParamBlk(A4),A2 ;the IO param block
 clr.l  12(A2)   ;zero “ioCompletion”
 lea    GFileName(A4),A0  ;put a pointer to the files
 move.l A0,18(A2);name into “ioNamePtr”
 move   GetVRef(A4),22(A2)  ;”ioVRefNum”
 move.l A2,A0    ;put param block ptr in A0
 _SetVol;set as current volume

 clr    -(SP)    ;space for refnum
 pea    GFileName(A4);name of res file to open
 _OpenResFile    ;Open that resource file
 move   (SP)+,D7 ;put result in D7
 cmp    #-1,D7   ;will be -1 if any
 ;errors!
 beq  Cancel;if error go to cancel

;this stops resources from being loaded with GetIndResource,
;GetResource or GetNamedResource
 move.w #0,-(sp)
 _SetResLoad

 clr.l  -(sp)
 move.l #’FKEY’,-(sp)
 move   #1,-(sp)
 _GetIndResource ;get first FKEY resource
 move.l (sp)+,A3 ;handle into A3

;Turns Automatic resource loading back on!
 move.b #1,-(sp)
 _SetResLoad

 clr.l  -(sp)
 move.l A3,-(sp)
 _SizeRsrc
 move.l (sp)+,D2 ;how big is the resource?
 cmp.l  #-1,D2   ;-1 = no resource
 beq    NotEnoughMem ;no resource error so quit

;do we have enough memory to load the FKEY   
 move.l D2,D0
 _NewHandle
 move.l A0,A1
 cmp.l  #0,A1    ;was zero returned?
 beq    NotEnoughMem ;not enough room, so quit!
 _DisposHandle   ;otherwise dispose the new
 ;handle, and go on..
 move.l A3,-(sp)
 _LoadResource   ;Load resource into memory!
 clr    -(sp)
 move.l A3,-(SP)
 _HomeResFile    ;what resource file
 move   (sp)+,D2 ;is this resource from?

 cmp    D2,D7    ;is it from new file?
 beq    YepItsFromNewFile ;yep!
 bra    NotEnoughMem ;if not, close the res
 ;file and quit!
YepItsFromNewFile
 move.l A3,A0
 _Hlock ;Lock it before jumping to it
 move.l (A3),A2      ;put pointer to FKEY in A2
 SaveRegs ;save the regs
 jsr    (A2);Run the Fkey!!
 RestoreRegs;restore the regs
 move.l A3,A0
 _HUnlock ;UnLock FKEY handle
 bsr    CloseIt  ;go close res file

Cancel
 restoreregs;restore the regs
 bsr    UnHiliteIt ;unhilight the menu
 bra    MainLoop ;get the next event


NotEnoughMem
 bsr    CloseIt
 bra    Cancel

CloseIt
 move   D7,-(SP)
 _CloseResFile   ;Close the res file
 rts

;------------------------------------------------
;All constants go here
;------------------------------------------------
;rect of background (desktop) window
;make it giant to cover entire background!

WindowRectdc0,0,4000,4000
PaintRect dc0,0,4000,4000
TypeListdc.b‘FKEY’

 .ALIGN 2

;rect of “About...” window
AboutRect dc130,100,190,412

;rect text will be displayed in for _TextBox
TextRectdc10,10,90,302

AppleSymbol dc.b 1,$14  ;apple symbol for menu #1
 .ALIGN 2

MyTextBegin dc.b ‘Fkey Sampler 1.0’,$0D,$0D
 dc.b ‘Written by John Holder’
 .ALIGN 2
MyTextEnd

 END


;The Linker file     (file name FkeyTemp.Link)

]

FKEYTemp
/Output FkeyTemp.Code
/Type ‘TEMP’
$


*The RMaker file   (file name FkeyTemp.R)

Fkey Sampler.Fkey
FKEYQD15

TYPE FKEY = PROC
Fkey Sampler,9
FkeyTemp.Code
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Dragon Dictate 6.0 - Premium voice-recog...
With Dragon Dictate speech recognition software, you can use your voice to create and edit text or interact with your favorite Mac applications. Far more than just speech-to-text, Dragon Dictate lets... Read more
OmniFocus 3.11.7 - GTD task manager with...
OmniFocus is an organizer app. It uses projects to organize tasks naturally, and then add tags to organize across projects. Easily enter tasks when you’re on the go, and process them when you have... Read more
rekordbox 6.5.1.0009 - Professional DJ m...
rekordbox is the best way of preparing and managing your tracks, be it at home, in the studio, or even on the plane! It allows you to import music from other music-management software using the... Read more
1Password 7.8.1 - Powerful password mana...
1Password is a password manager that uniquely brings you both security and convenience. It is the only program that provides anti-phishing protection and goes beyond password management by adding Web... Read more
Ableton Live 10.1.35 - Record music usin...
Ableton Live lets you create and record music on your Mac. Use digital instruments, pre-recorded sounds, and sampled loops to arrange, produce, and perform your music like never before. Ableton Live... Read more
Microsoft Office 365, 2019 16.48 - Popul...
Microsoft Office 365. The essentials to get it all done. Unmistakably Office, designed for Mac Get started quickly with new, modern versions of Word, Excel, PowerPoint, Outlook and OneNote-... Read more
Adobe After Effects 18.1 - Create profes...
After Effects is available as part of Adobe Creative Cloud for $52.99/month (or $20.99/month for a single app license). The new, more connected After Effects can make the impossible possible. Get... Read more
Adobe Audition 14.1 - Professional post-...
Audition is available as part of Adobe Creative Cloud for as little as $20.99/month (or $9.99/month if you're a previous Audition customer). Adobe Audition empowers you to create and deliver... Read more
Adobe Animate 21.0.5 - Animation authori...
Animate is available as part of Adobe Creative Cloud for as little as $20.99/month (or $9.99/month if you're a previous Flash Professional customer). Animate (was Flash CC) lets you share work... Read more
Adobe Photoshop 22.3.1 - Professional im...
You can download Photoshop for Mac as a part of Creative Cloud for only $20.99/month (or $9.99/month if you have purchased an earlier software version). Adobe Photoshop is a recognized classic of... Read more

Latest Forum Discussions

See All

Moonlight Sculptor is an upcoming MMORPG...
Kakao Games and XL Games – who you might be familiar with from their previous game ArcheAge – have announced that their MMORPG Moonlight Sculptor is now available to pre-order for iOS and Android devices. Moonlight Sculptor has previously launched... | Read more »
MU Archangel is now open for pre-registr...
MU Archangel is now open for pre-registration in Southeast Asia following its massive success in other territories. Players from Singapore, Thailand, Malaysia, Indonesia, and the Philippines (except Vietnam) can now join in on the fun by applying... | Read more »
Compete, a new social media app you can...
Whoever told you you can’t get rich making videos has obviously never heard of Compete, Competitive Media Technologies Limited’s hot new social media app where you can rake in all the dough just by doing what you love. Video monetization that... | Read more »
Bethesda has released a new DOOM mobile...
Bethesda Softworks has released a new DOOM game out of the blue exclusively for mobile devices. It’s called Mighty DOOM and is currently only available as an early access title on Android but will be expanding to more users in the future. [Read... | Read more »
Anagraphs is a word puzzle game with a t...
Cinq-Mars Media has released its word puzzle game Anagraphs for iOS and Android devices. The game released last week after a short delay in getting it onto the appropriate platforms. [Read more] | Read more »
These are the top 5 best iPhone games li...
Fortnite has been the big hitter in mobile gaming this year, and it's not hard to see why. Thanks to some excellent marketing, and a polished experience that almost anyone can enjoy, it's really taken the App Store by storm. But there are other... | Read more »
The top 5 best iPhone games like Pokemon...
Pokemon GO is still the, if you'll excuse the pun, go-to game if you want some AR action on your phone. But it's not the only choice out there, and if you've got a hankering for something a bit different, then your eyes might already have started... | Read more »
The top 5 best iPhone games like Starcra...
Starcraft sits at the top of the RTS tree for a number of very good reasons. It also isn't on mobile, again, for a number of very good reasons. But that doesn't mean you can't find a way to indulge your sci-fi, competitive, massive, or engaging RTS... | Read more »
Apple Arcade: Ranked - Top 25 [Updated 4...
In case you missed it, I am on a quest to rank every Apple Arcade game there is. [Read more] | Read more »
The top 5 best iPhone games like The Roo...
The Room has had a massive impact on the world of mobile gaming. Not only is it a brilliant adventure, it also shows how the touchscreen controls on your iPhone can be turned into something far more elegant and tactile than just a bunch of buttons... | Read more »

Price Scanner via MacPrices.net

B&H is offering clearance prices on lefto...
Apple reseller B&H Photo has clearance 2020 13″ 1.4GHz Intel-based MacBook Pros on sale today for $200-$300 off Apple’s original MSRP with prices starting at only $1099. Expedited shipping is... Read more
Roundup of Today’s Best MacBook Deals: M1 Mac...
Apple resellers are offering sale prices on Apple’s M1-powered 13″ MacBook Airs ranging up to $190 off MSRP. Here’s where to pick one up today, and as always, keep an eye on our 13″ MacBook Air Price... Read more
Apple AirPods Pro drop to new low price of on...
Amazon has Apple’s AirPods Pro on sale today for a new low price of only $197 shipped. That’s $52 off MSRP and the lowest price currently available for a set of AirPods Pro from any Apple reseller.... Read more
Apple restocks clearance 13″ Intel-based MacB...
Apple has clearance, Certified Refurbished, 2020 13″ Intel-based MacBook Airs available starting at only $809 and up to $280 off original MSRP. Each MacBook features a new outer case, comes with a... Read more
OWC drops prices on 2020 Intel multi-core Mac...
Other World Computing has clearance 2020 Intel-based Mac minis on sale starting at only $499. Both 4-core and 6-core models are in stock today. These are new, unopened, factory-sealed minis: – 3.6GHz... Read more
Save $50 off Apple’s 10.9″ iPad Air today at...
B&H Photo has new 10.9″ Apple iPad Airs in stock and on sale today for up to $50 off MSRP. Expedited shipping is free to most addresses in the US. Note that some sale prices may be restricted to... Read more
Rare Apple sale: Get a HomePod mini for $10 o...
Apple reseller Expercom has the Space Gray HomePod mini on sale today for $89 shipped. Their price is $10 off Apple’s MSRP, and it’s currently the only sale price available for a HomePod mini among... Read more
Apple has M1 Mac minis available starting at...
Apple has a full line of standard configuration M1 Mac minis available in their Certified Refurbished section starting at only $589 and up to $140 off MSRP. Each mini comes with Apple’s one-year... Read more
New sale at Amazon: $55-$70 discounts on Appl...
Amazon has 7.9″ iPad minis on sale today for up to $70 off Apple’s MSRP, each including free shipping. Prices start at $344. These are the same iPad minis sold by Apple in their retail and online... Read more
Apple offering 13″ M1 MacBook Airs for as lit...
Apple has a full line of 2020 13″ M1 MacBook Airs available, Certified Refurbished, starting at only $849 and up to $190 off original MSRP. These are the cheapest M1 MacBook Airs for sale today at... Read more

Jobs Board

*Apple* Valley 20hr Teller - Wells Fargo (Un...
…or scheduled + Ability to stand for extended periods of time **Street Address** **MN- Apple Valley:** 14325 Cedar Ave - Apple Valley, MN **Disclaimer** All offers Read more
*Apple* Valley 20hr Teller - Wells Fargo (Un...
…or scheduled + Ability to stand for extended periods of time **Street Address** **MN- Apple Valley:** 14325 Cedar Ave - Apple Valley, MN **Disclaimer** All offers Read more
Desktop Support Technician - *Apple* / Mac...
…infrastructure and internal desktop systems. Must have an IT background that includes Apple / Mac support. **Overview:** + Responds to routine technical questions or Read more
Geek Squad *Apple* Consultation Professiona...
**801042BR** **Job Title:** Geek Squad Apple Consultation Professional **Job Category:** Store Associates **Store Number or Department:** 000214-Willowbrook-Store Read more
*Apple* Mobility Specialist - Best Buy (Unit...
**800879BR** **Job Title:** Apple Mobility Specialist **Job Category:** Store Associates **Store Number or Department:** 000803-Lansing-Store **Job Description:** Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.