diff -r da012f5acb6f -r fd8185a1ecc8 intern/ghost/GHOST_Types.h
--- a/intern/ghost/GHOST_Types.h	Wed Nov 04 20:50:09 2009 +0000
+++ b/intern/ghost/GHOST_Types.h	Tue Nov 03 22:46:51 2009 +0000
@@ -151,6 +151,7 @@
 	GHOST_kEventButtonDown,		/// Mouse button event
 	GHOST_kEventButtonUp,		/// Mouse button event
 	GHOST_kEventWheel,			/// Mouse wheel event
+	GHOST_kEventPan,			/// Mouse pan event
 
 	GHOST_kEventNDOFMotion,		/// N degree of freedom device motion event
 	GHOST_kEventNDOFButton,		/// N degree of freedom device button event
@@ -367,6 +368,17 @@
 	GHOST_TInt32 z;	
 } GHOST_TEventWheelData;
 
+typedef struct {
+	/** The x-location of the pan event */
+	GHOST_TInt32 x;
+	/** The y-location of the pan event */
+	GHOST_TInt32 y;
+	/** The x-delta of the pan */
+	GHOST_TInt32 deltaX;
+	/** The y-delta of the pan */
+	GHOST_TInt32 deltaY;
+} GHOST_TEventPanData;
+
 
 /* original patch used floats, but the driver return ints and uns. We will calibrate in view, no sense on doing conversions twice */
 /* as all USB device controls are likely to use ints, this is also more future proof */
diff -r da012f5acb6f -r fd8185a1ecc8 intern/ghost/intern/GHOST_EventPan.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/intern/ghost/intern/GHOST_EventPan.h	Tue Nov 03 22:46:51 2009 +0000
@@ -0,0 +1,70 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/**
+ * @file	GHOST_EventPan.h
+ * Declaration of GHOST_EventPan class.
+ */
+
+#ifndef _GHOST_EVENT_PAN_H_
+#define _GHOST_EVENT_PAN_H_
+
+#include "GHOST_Event.h"
+
+/**
+ * Mouse pan event.
+ * @author	James Deery
+ * @date	October 31, 2009
+ */
+class GHOST_EventPan : public GHOST_Event
+{
+public:
+	/**
+	 * Constructor.
+	 * @param msec		The time this event was generated.
+	 * @param type		The type of this event.
+	 * @param x			The x-delta of the pan event.
+	 * @param y			The y-delta of the pan event.
+	 */
+	GHOST_EventPan(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY)
+		: GHOST_Event(msec, GHOST_kEventPan, window)
+	{
+		m_panEventData.x = x;
+		m_panEventData.y = y;
+		m_panEventData.deltaX = deltaX;
+		m_panEventData.deltaY = deltaY;
+		m_data = &m_panEventData;
+	}
+
+protected:
+	/** The mouse pan data */
+	GHOST_TEventPanData m_panEventData;
+};
+
+
+#endif // _GHOST_EVENT_PAN_H_
+
diff -r da012f5acb6f -r fd8185a1ecc8 intern/ghost/intern/GHOST_SystemCocoa.h
--- a/intern/ghost/intern/GHOST_SystemCocoa.h	Wed Nov 04 20:50:09 2009 +0000
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h	Tue Nov 03 22:46:51 2009 +0000
@@ -245,6 +245,9 @@
 	 * Needed because cocoa event delta cursor move takes setCursorPosition changes too.
 	 */
 	GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y;
+	
+	/** Keep track of the sub-pixel position of the scroll events */
+	double m_panMicroPos_x, m_panMicroPos_y;
 };
 
 #endif // _GHOST_SYSTEM_COCOA_H_
diff -r da012f5acb6f -r fd8185a1ecc8 intern/ghost/intern/GHOST_SystemCocoa.mm
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm	Wed Nov 04 20:50:09 2009 +0000
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm	Tue Nov 03 22:46:51 2009 +0000
@@ -41,6 +41,7 @@
 #include "GHOST_EventCursor.h"
 #include "GHOST_EventWheel.h"
 #include "GHOST_EventNDOF.h"
+#include "GHOST_EventPan.h"
 
 #include "GHOST_TimerManager.h"
 #include "GHOST_TimerTask.h"
@@ -465,6 +466,9 @@
 	m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
 	
 	m_ignoreWindowSizedMessages = false;
+	
+	m_panMicroPos_x = 0;
+	m_panMicroPos_y = 0;
 }
 
 GHOST_SystemCocoa::~GHOST_SystemCocoa()
@@ -1103,13 +1107,21 @@
 			
 		case NSScrollWheel:
 			{
-				GHOST_TInt32 delta;
+				if ([event deltaX] == 0 && [event deltaY] == 0) break;
 				
-				double deltaF = [event deltaY];
-				if (deltaF == 0.0) break; //discard trackpad delta=0 events
+				m_panMicroPos_x -= [event deltaX] * 5;
+				m_panMicroPos_y += [event deltaY] * 5;
 				
-				delta = deltaF > 0.0 ? 1 : -1;
-				pushEvent(new GHOST_EventWheel([event timestamp], window, delta));
+				GHOST_TInt32 deltaX = m_panMicroPos_x;
+				GHOST_TInt32 deltaY = m_panMicroPos_y;
+				
+				m_panMicroPos_x -= deltaX;
+				m_panMicroPos_y -= deltaY;
+				
+				if (deltaX != 0 || deltaY != 0) {
+					NSPoint mousePos = [event locationInWindow];
+					pushEvent(new GHOST_EventPan([event timestamp], window, mousePos.x, mousePos.y, deltaX, deltaY));
+				}
 			}
 			break;
 			
diff -r da012f5acb6f -r fd8185a1ecc8 source/blender/editors/interface/view2d_ops.c
--- a/source/blender/editors/interface/view2d_ops.c	Wed Nov 04 20:50:09 2009 +0000
+++ b/source/blender/editors/interface/view2d_ops.c	Tue Nov 03 22:46:51 2009 +0000
@@ -196,6 +196,15 @@
 	vpd= op->customdata;
 	v2d= vpd->v2d;
 	
+	if (event->type == MOUSEPAN) {
+		RNA_int_set(op->ptr, "deltax", event->prevx - event->x);
+		RNA_int_set(op->ptr, "deltay", event->prevy - event->y);
+		
+		view_pan_apply(C, op);
+		view_pan_exit(C, op);
+		return OPERATOR_FINISHED;
+	}
+	
 	/* set initial settings */
 	vpd->startx= vpd->lastx= event->x;
 	vpd->starty= vpd->lasty= event->y;
@@ -750,6 +759,15 @@
 	vzd= op->customdata;
 	v2d= vzd->v2d;
 	
+	if (event->type == MOUSEPAN) {
+		RNA_float_set(op->ptr, "deltax", event->prevx - event->x);
+		RNA_float_set(op->ptr, "deltay", event->prevy - event->y);
+		
+		view_zoomdrag_apply(C, op);
+		view_zoomdrag_exec(C, op);
+		return OPERATOR_FINISHED;
+	}	
+	
 	/* set initial settings */
 	vzd->lastx= event->x;
 	vzd->lasty= event->y;
@@ -1415,6 +1433,8 @@
 	WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
 	
+	WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MOUSEPAN, 0, 0, 0);
+	
 	WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_right", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
 	WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_left", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
 	
@@ -1437,6 +1457,7 @@
 	
 	/* zoom - drag */
 	WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
+	WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEPAN, 0, KM_OSKEY, 0);
 	
 	/* borderzoom - drag */
 	WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0);
diff -r da012f5acb6f -r fd8185a1ecc8 source/blender/editors/space_view3d/view3d_edit.c
--- a/source/blender/editors/space_view3d/view3d_edit.c	Wed Nov 04 20:50:09 2009 +0000
+++ b/source/blender/editors/space_view3d/view3d_edit.c	Tue Nov 03 22:46:51 2009 +0000
@@ -609,6 +609,16 @@
 			vod->rv3d->persp= RV3D_PERSP;
 		ED_region_tag_redraw(vod->ar);
 	}
+	
+	if (event->type == MOUSEPAN) {
+		viewrotate_apply(vod, event->prevx, event->prevy);
+		request_depth_update(CTX_wm_region_view3d(C));
+		
+		MEM_freeN(vod);
+		op->customdata = NULL;
+		
+		return OPERATOR_FINISHED;
+	}
 
 	/* add temp handler */
 	WM_event_add_modal_handler(C, op);
@@ -732,6 +742,17 @@
 	/* makes op->customdata */
 	viewops_data(C, op, event);
 
+	if (event->type == MOUSEPAN) {
+		ViewOpsData *vod= op->customdata;
+		viewmove_apply(vod, event->prevx, event->prevy);
+		request_depth_update(CTX_wm_region_view3d(C));
+		
+		MEM_freeN(vod);
+		op->customdata= NULL;
+		
+		return OPERATOR_FINISHED;
+	}
+	
 	/* add temp handler */
 	WM_event_add_modal_handler(C, op);
 
@@ -975,6 +996,17 @@
 	else {
 		/* makes op->customdata */
 		viewops_data(C, op, event);
+		
+		if (event->type == MOUSEPAN) {
+			ViewOpsData *vod= op->customdata;
+			viewzoom_apply(vod, event->prevx, event->prevy);
+			request_depth_update(CTX_wm_region_view3d(C));
+			
+			MEM_freeN(vod);
+			op->customdata= NULL;
+			
+			return OPERATOR_FINISHED;
+		}
 
 		/* add temp handler */
 		WM_event_add_modal_handler(C, op);
diff -r da012f5acb6f -r fd8185a1ecc8 source/blender/editors/space_view3d/view3d_ops.c
--- a/source/blender/editors/space_view3d/view3d_ops.c	Wed Nov 04 20:50:09 2009 +0000
+++ b/source/blender/editors/space_view3d/view3d_ops.c	Tue Nov 03 22:46:51 2009 +0000
@@ -128,6 +128,10 @@
 
 	WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
 	
+	WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, KM_SHIFT, 0);
+	WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, 0, 0);
+	WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEPAN, 0, KM_OSKEY, 0);
+	
 	RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
 	RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1);
 	RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELINMOUSE, KM_PRESS, 0, 0)->ptr, "delta", 1);
diff -r da012f5acb6f -r fd8185a1ecc8 source/blender/windowmanager/intern/wm_event_system.c
--- a/source/blender/windowmanager/intern/wm_event_system.c	Wed Nov 04 20:50:09 2009 +0000
+++ b/source/blender/windowmanager/intern/wm_event_system.c	Tue Nov 03 22:46:51 2009 +0000
@@ -1622,6 +1622,21 @@
 			}
 			break;
 		}
+		case GHOST_kEventPan: {
+			if (win->active) {
+				GHOST_TEventPanData * pd = customdata;
+				event.type= MOUSEPAN;
+				event.x= pd->x;
+				event.y= pd->y;
+				// Use prevx/prevy so we can calculate the delta later
+				event.prevx= pd->x - pd->deltaX;
+				event.prevy= pd->y - pd->deltaY;
+				
+				update_tablet_data(win, &event);
+				wm_event_add(win, &event);
+			}			
+			break;
+		}
 		/* mouse button */
 		case GHOST_kEventButtonDown:
 		case GHOST_kEventButtonUp: {
diff -r da012f5acb6f -r fd8185a1ecc8 source/blender/windowmanager/wm_event_types.h
--- a/source/blender/windowmanager/wm_event_types.h	Wed Nov 04 20:50:09 2009 +0000
+++ b/source/blender/windowmanager/wm_event_types.h	Tue Nov 03 22:46:51 2009 +0000
@@ -62,6 +62,7 @@
 		/* defaults from ghost */
 #define WHEELUPMOUSE	0x00a	
 #define WHEELDOWNMOUSE	0x00b
+#define MOUSEPAN		0x00e
 		/* mapped with userdef */
 #define WHEELINMOUSE	0x00c
 #define WHEELOUTMOUSE	0x00d
