You've already forked linux-packaging-mono
Imported Upstream version 4.2.0.179
Former-commit-id: 4610231f55806d2a05ed69e5ff3faa7336cc1479
This commit is contained in:
committed by
Jo Shields
parent
aa7da660d6
commit
c042cd0c52
@@ -0,0 +1,371 @@
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Copyright (c) 2007 Novell, Inc.
|
||||
//
|
||||
// Authors:
|
||||
// Geoff Norton (gnorton@novell.com)
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace System.Windows.Forms.CarbonInternal {
|
||||
internal delegate void DragTrackingDelegate (short message, IntPtr window, IntPtr data, IntPtr dragref);
|
||||
|
||||
internal class Dnd {
|
||||
internal const uint kEventParamDragRef = 1685217639;
|
||||
internal const uint typeDragRef = 1685217639;
|
||||
|
||||
internal const uint typeMono = 1836019311;
|
||||
internal const uint typeMonoSerializedObject = 1836279154;
|
||||
|
||||
private static DragDropEffects effects = DragDropEffects.None;
|
||||
private static DragTrackingDelegate DragTrackingHandler = new DragTrackingDelegate (TrackingCallback);
|
||||
|
||||
static Dnd () {
|
||||
try {
|
||||
InstallTrackingHandler (DragTrackingHandler, IntPtr.Zero, IntPtr.Zero);
|
||||
} catch (EntryPointNotFoundException) {
|
||||
// it is deprecated in 10.6 and does not exist anymore.
|
||||
}
|
||||
}
|
||||
|
||||
internal Dnd () {
|
||||
}
|
||||
|
||||
internal static void TrackingCallback (short message, IntPtr window, IntPtr data, IntPtr dragref) {
|
||||
XplatUICarbon.GetInstance ().FlushQueue ();
|
||||
}
|
||||
|
||||
internal static DragDropEffects DragActionsToEffects (UInt32 actions) {
|
||||
DragDropEffects effects = DragDropEffects.None;
|
||||
if ((actions & 1) != 0)
|
||||
effects |= DragDropEffects.Copy;
|
||||
if ((actions & (1 << 4)) != 0)
|
||||
effects |= DragDropEffects.Move;
|
||||
if ((actions & 0xFFFFFFFF) != 0)
|
||||
effects |= DragDropEffects.All;
|
||||
|
||||
return effects;
|
||||
}
|
||||
|
||||
internal static DataObject DragToDataObject (IntPtr dragref) {
|
||||
UInt32 items = 0;
|
||||
ArrayList flavorlist = new ArrayList ();
|
||||
|
||||
CountDragItems (dragref, ref items);
|
||||
|
||||
for (uint item_counter = 1; item_counter <= items; item_counter++) {
|
||||
IntPtr itemref = IntPtr.Zero;
|
||||
UInt32 flavors = 0;
|
||||
|
||||
GetDragItemReferenceNumber (dragref, item_counter, ref itemref);
|
||||
CountDragItemFlavors (dragref, itemref, ref flavors);
|
||||
for (uint flavor_counter = 1; flavor_counter <= flavors; flavor_counter++) {
|
||||
FlavorHandler flavor = new FlavorHandler (dragref, itemref, flavor_counter);
|
||||
if (flavor.Supported)
|
||||
flavorlist.Add (flavor);
|
||||
}
|
||||
}
|
||||
|
||||
if (flavorlist.Count > 0) {
|
||||
return ((FlavorHandler) flavorlist [0]).Convert (flavorlist);
|
||||
}
|
||||
|
||||
return new DataObject ();
|
||||
}
|
||||
|
||||
internal static bool HandleEvent (IntPtr callref, IntPtr eventref, IntPtr handle, uint kind, ref MSG msg) {
|
||||
Control control;
|
||||
DataObject data;
|
||||
DragEventArgs drag_event;
|
||||
DragDropEffects allowed;
|
||||
QDPoint point = new QDPoint ();
|
||||
UInt32 actions = 0;
|
||||
IntPtr dragref = IntPtr.Zero;
|
||||
Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
|
||||
|
||||
if (hwnd == null || hwnd.Handle != handle)
|
||||
return false;
|
||||
|
||||
GetEventParameter (eventref, kEventParamDragRef, typeDragRef, IntPtr.Zero, (uint) Marshal.SizeOf (typeof (IntPtr)), IntPtr.Zero, ref dragref);
|
||||
XplatUICarbon.GetGlobalMouse (ref point);
|
||||
GetDragAllowableActions (dragref, ref actions);
|
||||
control = Control.FromHandle (hwnd.Handle);
|
||||
allowed = DragActionsToEffects (actions);
|
||||
data = DragToDataObject (dragref);
|
||||
drag_event = new DragEventArgs (data, 0, point.x, point.y, allowed, DragDropEffects.None);
|
||||
|
||||
switch (kind) {
|
||||
case ControlHandler.kEventControlDragEnter: {
|
||||
bool accept = control.AllowDrop;
|
||||
SetEventParameter (eventref, ControlHandler.kEventParamControlLikesDrag, ControlHandler.typeBoolean, (uint)Marshal.SizeOf (typeof (bool)), ref accept);
|
||||
|
||||
control.DndEnter (drag_event);
|
||||
effects = drag_event.Effect;
|
||||
return false;
|
||||
}
|
||||
case ControlHandler.kEventControlDragWithin:
|
||||
control.DndOver (drag_event);
|
||||
effects = drag_event.Effect;
|
||||
break;
|
||||
case ControlHandler.kEventControlDragLeave:
|
||||
control.DndLeave (drag_event);
|
||||
break;
|
||||
case ControlHandler.kEventControlDragReceive:
|
||||
control.DndDrop (drag_event);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetAllowDrop (Hwnd hwnd, bool allow) {
|
||||
if (hwnd.allow_drop == allow)
|
||||
return;
|
||||
|
||||
hwnd.allow_drop = allow;
|
||||
SetControlDragTrackingEnabled (hwnd.whole_window, true);
|
||||
SetControlDragTrackingEnabled (hwnd.client_window, true);
|
||||
}
|
||||
|
||||
public void SendDrop (IntPtr handle, IntPtr from, IntPtr time) {
|
||||
}
|
||||
|
||||
public DragDropEffects StartDrag (IntPtr handle, object data, DragDropEffects allowed_effects) {
|
||||
IntPtr dragref = IntPtr.Zero;
|
||||
EventRecord eventrecord = new EventRecord ();
|
||||
|
||||
effects = DragDropEffects.None;
|
||||
|
||||
NewDrag (ref dragref);
|
||||
XplatUICarbon.GetGlobalMouse (ref eventrecord.mouse);
|
||||
StoreObjectInDrag (handle, dragref, data);
|
||||
|
||||
TrackDrag (dragref, ref eventrecord, IntPtr.Zero);
|
||||
|
||||
DisposeDrag (dragref);
|
||||
|
||||
return effects;
|
||||
}
|
||||
|
||||
public void StoreObjectInDrag (IntPtr handle, IntPtr dragref, object data) {
|
||||
IntPtr type = IntPtr.Zero;
|
||||
IntPtr dataptr = IntPtr.Zero;
|
||||
Int32 size = 0;
|
||||
|
||||
if (data is string) {
|
||||
// implement me
|
||||
throw new NotSupportedException ("Implement me.");
|
||||
} else if (data is ISerializable) {
|
||||
MemoryStream stream = new MemoryStream ();
|
||||
BinaryFormatter bf = new BinaryFormatter ();
|
||||
|
||||
bf.Serialize (stream, data);
|
||||
|
||||
dataptr = Marshal.AllocHGlobal ((int) stream.Length);
|
||||
stream.Seek (0, 0);
|
||||
|
||||
for (int i = 0; i < stream.Length; i++) {
|
||||
Marshal.WriteByte (dataptr, i, (byte) stream.ReadByte ());
|
||||
}
|
||||
|
||||
type = (IntPtr) typeMonoSerializedObject;
|
||||
size = (int) stream.Length;
|
||||
} else {
|
||||
dataptr = (IntPtr) GCHandle.Alloc (data);
|
||||
|
||||
type = (IntPtr) typeMono;
|
||||
size = Marshal.SizeOf (typeof (IntPtr));
|
||||
}
|
||||
|
||||
AddDragItemFlavor (dragref, handle, type, ref dataptr, size, 1 << 0);
|
||||
}
|
||||
|
||||
[DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
static extern int InstallTrackingHandler (DragTrackingDelegate callback, IntPtr window, IntPtr data);
|
||||
|
||||
[DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
static extern int GetEventParameter (IntPtr eventref, uint name, uint type, IntPtr outtype, uint size, IntPtr outsize, ref IntPtr data);
|
||||
[DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
static extern int SetEventParameter (IntPtr eventref, uint name, uint type, uint size, ref bool data);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int SetControlDragTrackingEnabled (IntPtr view, bool enabled);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int AddDragItemFlavor (IntPtr dragref, IntPtr itemref, IntPtr flavortype, ref IntPtr data, Int32 size, UInt32 flags);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int CountDragItems (IntPtr dragref, ref UInt32 count);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int CountDragItemFlavors (IntPtr dragref, IntPtr itemref, ref UInt32 count);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int GetDragItemReferenceNumber (IntPtr dragref, UInt32 index, ref IntPtr itemref);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int NewDrag (ref IntPtr dragref);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int TrackDrag (IntPtr dragref, ref EventRecord eventrecord, IntPtr region);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int DisposeDrag (IntPtr dragref);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int GetDragAllowableActions (IntPtr dragref, ref UInt32 actions);
|
||||
}
|
||||
|
||||
internal struct EventRecord {
|
||||
internal UInt16 what;
|
||||
internal UInt32 message;
|
||||
internal UInt32 when;
|
||||
internal QDPoint mouse;
|
||||
internal UInt16 modifiers;
|
||||
}
|
||||
|
||||
internal class FlavorHandler {
|
||||
internal IntPtr flavorref;
|
||||
internal IntPtr dragref;
|
||||
internal IntPtr itemref;
|
||||
internal Int32 size;
|
||||
internal UInt32 flags;
|
||||
internal byte [] data;
|
||||
internal string fourcc;
|
||||
|
||||
internal FlavorHandler (IntPtr dragref, IntPtr itemref, uint counter) {
|
||||
GetFlavorType (dragref, itemref, counter, ref flavorref);
|
||||
GetFlavorFlags (dragref, itemref, flavorref, ref flags);
|
||||
byte [] fourcc_b = BitConverter.GetBytes ((Int32)flavorref);
|
||||
this.fourcc = String.Format ("{0}{1}{2}{3}", (char)fourcc_b [3], (char)fourcc_b [2], (char)fourcc_b [1], (char)fourcc_b [0]);
|
||||
this.dragref = dragref;
|
||||
this.itemref = itemref;
|
||||
|
||||
this.GetData ();
|
||||
}
|
||||
|
||||
internal void GetData () {
|
||||
GetFlavorDataSize (dragref, itemref, flavorref, ref size);
|
||||
data = new byte [size];
|
||||
GetFlavorData (dragref, itemref, flavorref, data, ref size, 0);
|
||||
}
|
||||
|
||||
internal string DataString {
|
||||
get { return Encoding.Default.GetString (this.data); }
|
||||
}
|
||||
|
||||
internal byte[] DataArray {
|
||||
get { return this.data; }
|
||||
}
|
||||
|
||||
internal IntPtr DataPtr {
|
||||
get { return (IntPtr) BitConverter.ToInt32 (this.data, 0); }
|
||||
}
|
||||
|
||||
internal bool Supported {
|
||||
get {
|
||||
switch (fourcc) {
|
||||
case "furl":
|
||||
return true;
|
||||
case "mono":
|
||||
return true;
|
||||
case "mser":
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal DataObject Convert (ArrayList flavorlist) {
|
||||
switch (fourcc) {
|
||||
case "furl":
|
||||
return ConvertToFileDrop (flavorlist);
|
||||
case "mono":
|
||||
return ConvertToObject (flavorlist);
|
||||
case "mser":
|
||||
return DeserializeObject (flavorlist);
|
||||
}
|
||||
|
||||
return new DataObject ();
|
||||
}
|
||||
|
||||
internal DataObject DeserializeObject (ArrayList flavorlist) {
|
||||
DataObject data = new DataObject ();
|
||||
MemoryStream stream = new MemoryStream (this.DataArray);
|
||||
BinaryFormatter bf = new BinaryFormatter ();
|
||||
|
||||
if (stream.Length == 0)
|
||||
return data;
|
||||
|
||||
stream.Seek (0, 0);
|
||||
data.SetData (bf.Deserialize (stream));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
internal DataObject ConvertToObject (ArrayList flavorlist) {
|
||||
DataObject data = new DataObject ();
|
||||
|
||||
foreach (FlavorHandler flavor in flavorlist) {
|
||||
GCHandle handle = (GCHandle) flavor.DataPtr;
|
||||
|
||||
data.SetData (handle.Target);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
internal DataObject ConvertToFileDrop (ArrayList flavorlist) {
|
||||
DataObject data = new DataObject ();
|
||||
ArrayList uri_list = new ArrayList ();
|
||||
|
||||
foreach (FlavorHandler flavor in flavorlist) {
|
||||
try {
|
||||
uri_list.Add (new Uri (flavor.DataString).LocalPath);
|
||||
} catch { }
|
||||
}
|
||||
|
||||
string [] l = (string []) uri_list.ToArray (typeof (string));
|
||||
if (l.Length < 1)
|
||||
return data;
|
||||
data.SetData (DataFormats.FileDrop, l);
|
||||
data.SetData ("FileName", l [0]);
|
||||
data.SetData ("FileNameW", l [0]);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public override string ToString () {
|
||||
return fourcc;
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int GetFlavorDataSize (IntPtr dragref, IntPtr itemref, IntPtr flavorref, ref Int32 size);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int GetFlavorData (IntPtr dragref, IntPtr itemref, IntPtr flavorref, [In, Out] byte[] data, ref Int32 size, UInt32 offset);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int GetFlavorFlags (IntPtr dragref, IntPtr itemref, IntPtr flavorref, ref UInt32 flags);
|
||||
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
|
||||
extern static int GetFlavorType (IntPtr dragref, IntPtr itemref, UInt32 index, ref IntPtr flavor);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user