diff options
author | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2008-02-14 13:55:01 +0000 |
---|---|---|
committer | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2008-02-14 13:55:01 +0000 |
commit | 4e07a9235c9ff59556fd11ef4b17dfa8082a7b41 (patch) | |
tree | 98d0622532d0078e5ca6d738bc61bf0d8e0aac12 /src/corelib/x11/gfx_x11.pas | |
parent | f13f399a8a6076b09d3e7d0262bc34787343ebc3 (diff) | |
download | fpGUI-4e07a9235c9ff59556fd11ef4b17dfa8082a7b41.tar.xz |
* X11: fpGUI will now raise an exception if it can't open the X Display.
* X11: clipboard support has now been implemented to work across applications. It still needs more testing. eg: unicode copy and paste doesn't always work.
Diffstat (limited to 'src/corelib/x11/gfx_x11.pas')
-rw-r--r-- | src/corelib/x11/gfx_x11.pas | 126 |
1 files changed, 121 insertions, 5 deletions
diff --git a/src/corelib/x11/gfx_x11.pas b/src/corelib/x11/gfx_x11.pas index c6ccf16a..de987f0b 100644 --- a/src/corelib/x11/gfx_x11.pas +++ b/src/corelib/x11/gfx_x11.pas @@ -165,7 +165,7 @@ type DefaultScreen: integer; DefaultVisual: PVisual; DefaultColorMap: TColorMap; - RootWindow: TfpgWinHandle; + FRootWindow: TfpgWinHandle; xia_clipboard: TAtom; xia_motif_wm_hints: TAtom; xia_wm_protocols: TAtom; @@ -186,9 +186,21 @@ type function GetScreenWidth: TfpgCoord; function GetScreenHeight: TfpgCoord; property Display: PXDisplay read FDisplay; + property RootWindow: TfpgWinHandle read FRootWindow; end; + TfpgClipboardImpl = class(TfpgClipboardBase) + private + FWaitingForSelection: Boolean; + protected + FClipboardText: string; + function DoGetText: string; override; + procedure DoSetText(const AValue: string); override; + procedure InitClipboard; override; + end; + + implementation uses @@ -395,6 +407,65 @@ begin Result := '#' + IntToStr(Event); end; +// clipboard event +procedure ProcessSelection(var ev: TXEvent); +var + s: string; + actual: TAtom; + format: integer; + count, remaining: longword; + data: PChar; +begin + if ev.xselection._property > 0 then + begin + XGetWindowProperty(xapplication.Display, ev.xselection.requestor, + ev.xselection._property, 0, 16000, + false, // delete + 0, // type + @actual, @format, @count, @remaining, + @data); + s := data; + + fpgClipboard.FClipboardText := s; + XFree(data); + end + else + begin + fpgClipboard.FClipboardText := ''; + end; + + fpgClipboard.FWaitingForSelection := false; +end; + +// clipboard event +procedure ProcessSelectionRequest(var ev: TXEvent); +var + e: TXSelectionEvent; + a: TAtom; +begin + e._type := SelectionNotify; + e.requestor := ev.xselectionrequest.requestor; + e.selection := ev.xselectionrequest.selection; + e.selection := xapplication.xia_clipboard; + e.target := ev.xselectionrequest.target; + e.time := ev.xselectionrequest.time; + e._property := ev.xselectionrequest._property; + + if e.target = xapplication.xia_targets then + begin + a := XA_STRING; + XChangeProperty(xapplication.Display, e.requestor, e._property, + XA_ATOM, sizeof(TAtom)*8, 0, PByte(@a), sizeof(TAtom)); + end + else + begin + XChangeProperty(xapplication.Display, e.requestor, e._property, e.target, + 8, 0, PByte(@fpgClipboard.FClipboardText[1]), Length(fpgClipboard.FClipboardText)); + end; + + XSendEvent(xapplication.Display, e.requestor, false, 0, @e ); +end; + { TfpgApplicationImpl } function TfpgApplicationImpl.ConvertShiftState(AState: Cardinal): TShiftState; @@ -537,11 +608,14 @@ begin FDisplay := XOpenDisplay(PChar(aparams)); if FDisplay = nil then - Exit; //==> +// begin + raise Exception.Create('fpGUI-X11: Could not open the display. Is your X11 server running?'); +// halt(1); +// end; Terminated := False; DefaultScreen := XDefaultScreen(Display); - RootWindow := XRootWindow(FDisplay, DefaultScreen); + FRootWindow := XRootWindow(FDisplay, DefaultScreen); DefaultBackground := XBlackPixel(FDisplay, DefaultScreen); DefaultForeground := XWhitePixel(FDisplay, DefaultScreen); @@ -989,7 +1063,6 @@ begin end; end; -{ X.SelectionNotify: begin ProcessSelection(ev); @@ -999,7 +1072,16 @@ begin begin ProcessSelectionRequest(ev); end; -} + + X.SelectionClear: + begin + { TODO : Not sure if I am handling this correctly? } + if ev.xselectionclear.selection = xia_clipboard then + begin + fpgClipboard.FClipboardText := ''; + Exit; + end; + end; X.FocusIn: fpgPostMessage(nil, FindWindowByHandle(ev.xfocus.window), FPGM_ACTIVATE); @@ -1908,6 +1990,40 @@ begin Result := @FXimgMask; end; +{ TfpgClipboardImpl } + +function TfpgClipboardImpl.DoGetText: string; +begin + XConvertSelection(xapplication.Display, xapplication.xia_clipboard, + XA_STRING, xapplication.xia_clipboard, FClipboardWndHandle, 0); + + FWaitingForSelection := True; + fpgDeliverMessages; // delivering the remaining messages + + repeat + fpgWaitWindowMessage; + fpgDeliverMessages; + until not FWaitingForSelection; + + Result := FClipboardText; +end; + +procedure TfpgClipboardImpl.DoSetText(const AValue: string); +begin + FClipboardText := AValue; + XSetSelectionOwner(xapplication.Display, xapplication.xia_clipboard, + FClipboardWndHandle, 0); +end; + +procedure TfpgClipboardImpl.InitClipboard; +begin + FWaitingForSelection := False; + FClipboardWndHandle := XCreateSimpleWindow(xapplication.Display, + xapplication.RootWindow, 10, 10, 10, 10, 0, 0, 0); +end; + + + initialization xapplication := nil; |