Ejemplo n.º 1
0
 public unsafe Task SetDataObjectAsync(IDataObject data)
 {
     _native.Clear();
     foreach (var fmt in data.GetDataFormats())
     {
         var o = data.Get(fmt);
         if (o is string s)
         {
             _native.SetText(fmt, s);
         }
         else if (o is byte[] bytes)
             fixed(byte *pbytes = bytes)
             _native.SetBytes(fmt, pbytes, bytes.Length);
     }
     return(Task.CompletedTask);
 }
Ejemplo n.º 2
0
 public unsafe Task SetDataObjectAsync(IDataObject data)
 {
     _native.Clear();
     foreach (var fmt in data.GetDataFormats())
     {
         var o = data.Get(fmt);
         if (o is string s)
         {
             using (var b = new Utf8Buffer(s))
                 _native.SetText(fmt, b.DangerousGetHandle());
         }
         else if (o is byte[] bytes)
             fixed(byte *pbytes = bytes)
             _native.SetBytes(fmt, new IntPtr(pbytes), bytes.Length);
     }
     return(Task.CompletedTask);
 }
Ejemplo n.º 3
0
        public async Task <DragDropEffects> DoDragDrop(IDataObject data, DragDropEffects allowedEffects)
        {
            // We need the TopLevelImpl + a mouse location so we just wait for the next event.
            var mouseEv = await _inputManager.PreProcess.OfType <RawMouseEventArgs>().FirstAsync();

            var view = ((mouseEv.Root as TopLevel)?.PlatformImpl as TopLevelImpl)?.View;

            if (view == null)
            {
                return(DragDropEffects.None);
            }

            // Prepare the source event:
            var pt = view.TranslateLocalPoint(mouseEv.Position).ToMonoMacPoint();
            var ev = NSEvent.MouseEvent(NSEventType.LeftMouseDown, pt, 0, 0, 0, null, 0, 0, 0);

            _allowedEffects = allowedEffects;
            var items = data.GetDataFormats().SelectMany(fmt => CreateDraggingItems(fmt, data.Get(fmt))).ToArray();

            view.BeginDraggingSession(items, ev, this);

            return(await _result);
        }
Ejemplo n.º 4
0
        private unsafe void OnEvent(ref XEvent ev)
        {
            if (ev.type == XEventName.SelectionRequest)
            {
                var sel  = ev.SelectionRequestEvent;
                var resp = new XEvent
                {
                    SelectionEvent =
                    {
                        type       = XEventName.SelectionNotify,
                        send_event =                          1,
                        display    = _x11.Display,
                        selection  = sel.selection,
                        target     = sel.target,
                        requestor  = sel.requestor,
                        time       = sel.time,
                        property   = IntPtr.Zero
                    }
                };
                if (sel.selection == _x11.Atoms.CLIPBOARD)
                {
                    resp.SelectionEvent.property = WriteTargetToProperty(sel.target, sel.requestor, sel.property);
                }

                XSendEvent(_x11.Display, sel.requestor, false, new IntPtr((int)EventMask.NoEventMask), ref resp);
            }

            IntPtr WriteTargetToProperty(IntPtr target, IntPtr window, IntPtr property)
            {
                Encoding textEnc;

                if (target == _x11.Atoms.TARGETS)
                {
                    var atoms = new HashSet <IntPtr> {
                        _x11.Atoms.TARGETS, _x11.Atoms.MULTIPLE
                    };
                    foreach (var fmt in _storedDataObject.GetDataFormats())
                    {
                        if (fmt == DataFormats.Text)
                        {
                            foreach (var ta in _textAtoms)
                            {
                                atoms.Add(ta);
                            }
                        }
                        else
                        {
                            atoms.Add(_x11.Atoms.GetAtom(fmt));
                        }
                    }

                    XChangeProperty(_x11.Display, window, property,
                                    _x11.Atoms.XA_ATOM, 32, PropertyMode.Replace, atoms.ToArray(), atoms.Count);
                    return(property);
                }
                else if (target == _x11.Atoms.SAVE_TARGETS && _x11.Atoms.SAVE_TARGETS != IntPtr.Zero)
                {
                    return(property);
                }
                else if ((textEnc = GetStringEncoding(target)) != null &&
                         _storedDataObject?.Contains(DataFormats.Text) == true)
                {
                    var text = _storedDataObject.GetText();
                    if (text == null)
                    {
                        return(IntPtr.Zero);
                    }
                    var data = textEnc.GetBytes(text);

                    fixed(void *pdata = data)
                    XChangeProperty(_x11.Display, window, property, target, 8,
                                    PropertyMode.Replace,
                                    pdata, data.Length);

                    return(property);
                }
                else if (target == _x11.Atoms.MULTIPLE && _x11.Atoms.MULTIPLE != IntPtr.Zero)
                {
                    XGetWindowProperty(_x11.Display, window, property, IntPtr.Zero, new IntPtr(0x7fffffff), false,
                                       _x11.Atoms.ATOM_PAIR, out _, out var actualFormat, out var nitems, out _, out var prop);
                    if (nitems == IntPtr.Zero)
                    {
                        return(IntPtr.Zero);
                    }
                    if (actualFormat == 32)
                    {
                        var data = (IntPtr *)prop.ToPointer();
                        for (var c = 0; c < nitems.ToInt32(); c += 2)
                        {
                            var subTarget = data[c];
                            var subProp   = data[c + 1];
                            var converted = WriteTargetToProperty(subTarget, window, subProp);
                            data[c + 1] = converted;
                        }

                        XChangeProperty(_x11.Display, window, property, _x11.Atoms.ATOM_PAIR, 32, PropertyMode.Replace,
                                        prop.ToPointer(), nitems.ToInt32());
                    }

                    XFree(prop);

                    return(property);
                }
                else if (_storedDataObject?.Contains(_x11.Atoms.GetAtomName(target)) == true)
                {
                    var objValue = _storedDataObject.Get(_x11.Atoms.GetAtomName(target));

                    if (!(objValue is byte[] bytes))
                    {
                        if (objValue is string s)
                        {
                            bytes = Encoding.UTF8.GetBytes(s);
                        }
                        else
                        {
                            return(IntPtr.Zero);
                        }
                    }

                    XChangeProperty(_x11.Display, window, property, target, 8,
                                    PropertyMode.Replace,
                                    bytes, bytes.Length);
                    return(property);
                }
                else
                {
                    return(IntPtr.Zero);
                }
            }

            if (ev.type == XEventName.SelectionNotify && ev.SelectionEvent.selection == _x11.Atoms.CLIPBOARD)
            {
                var sel = ev.SelectionEvent;
                if (sel.property == IntPtr.Zero)
                {
                    _requestedFormatsTcs?.TrySetResult(null);
                    _requestedDataTcs?.TrySetResult(null);
                }
                XGetWindowProperty(_x11.Display, _handle, sel.property, IntPtr.Zero, new IntPtr(0x7fffffff), true, (IntPtr)Atom.AnyPropertyType,
                                   out var actualTypeAtom, out var actualFormat, out var nitems, out var bytes_after, out var prop);
                Encoding textEnc = null;
                if (nitems == IntPtr.Zero)
                {
                    _requestedFormatsTcs?.TrySetResult(null);
                    _requestedDataTcs?.TrySetResult(null);
                }
                else
                {
                    if (sel.property == _x11.Atoms.TARGETS)
                    {
                        if (actualFormat != 32)
                        {
                            _requestedFormatsTcs?.TrySetResult(null);
                        }
                        else
                        {
                            var formats = new IntPtr[nitems.ToInt32()];
                            Marshal.Copy(prop, formats, 0, formats.Length);
                            _requestedFormatsTcs?.TrySetResult(formats);
                        }
                    }
                    else if ((textEnc = GetStringEncoding(actualTypeAtom)) != null)
                    {
                        var text = textEnc.GetString((byte *)prop.ToPointer(), nitems.ToInt32());
                        _requestedDataTcs?.TrySetResult(text);
                    }
                    else
                    {
                        if (actualTypeAtom == _x11.Atoms.INCR)
                        {
                            // TODO: Actually implement that monstrosity
                            _requestedDataTcs.TrySetResult(null);
                        }
                        else
                        {
                            var data = new byte[(int)nitems * (actualFormat / 8)];
                            Marshal.Copy(prop, data, 0, data.Length);
                            _requestedDataTcs?.TrySetResult(data);
                        }
                    }
                }

                XFree(prop);
            }
        }