summaryrefslogtreecommitdiff
path: root/src/Fl_Menu_Window.cxx
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>1998-10-06 18:21:25 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>1998-10-06 18:21:25 +0000
commitf9039b2ae21988783feae9b362818e7923e82d14 (patch)
tree6d6fe3679d73448758f9794e7d4d4f6b22a4adad /src/Fl_Menu_Window.cxx
parent67e89232f9ba067825a158734a09e0fa21aacbe3 (diff)
Initial revision
git-svn-id: file:///fltk/svn/fltk/trunk@2 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Menu_Window.cxx')
-rw-r--r--src/Fl_Menu_Window.cxx130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/Fl_Menu_Window.cxx b/src/Fl_Menu_Window.cxx
new file mode 100644
index 000000000..f74db6ea2
--- /dev/null
+++ b/src/Fl_Menu_Window.cxx
@@ -0,0 +1,130 @@
+// Fl_Menu_Window.H
+
+// This is the window type used by Fl_Menu to make the pop-ups.
+// It draws in the overlay planes if possible.
+
+// Also here is the implementation of the mouse & keyboard grab,
+// which are used so that clicks outside the program's windows
+// can be used to dismiss the menus.
+
+#include <config.h>
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Menu_Window.H>
+
+// WIN32 note: HAVE_OVERLAY is false
+#if HAVE_OVERLAY
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+static GC gc; // the GC used by all X windows
+extern uchar fl_overlay; // changes how fl_color(x) works
+#endif
+
+#include <stdio.h>
+
+void Fl_Menu_Window::show() {
+#if HAVE_OVERLAY
+ if (!shown() && overlay() && fl_find_overlay_visual()) {
+ XInstallColormap(fl_display, fl_overlay_colormap);
+ fl_background_pixel = int(fl_transparent_pixel);
+ Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+ fl_background_pixel = -1;
+ } else
+#endif
+ Fl_Single_Window::show();
+}
+
+void Fl_Menu_Window::flush() {
+#if HAVE_OVERLAY
+ if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;}
+ Fl_X *i = Fl_X::i(this);
+ fl_window = i->xid;
+ if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0);
+ fl_gc = gc;
+ fl_overlay = 1;
+ fl_clip_region(i->region); i->region = 0;
+ draw();
+ fl_overlay = 0;
+#else
+ Fl_Single_Window::flush();
+#endif
+}
+
+void Fl_Menu_Window::erase() {
+#if HAVE_OVERLAY
+ if (!gc || !shown()) return;
+//XSetForeground(fl_display, gc, 0);
+//XFillRectangle(fl_display, fl_xid(this), gc, 0, 0, w(), h());
+ XClearWindow(fl_display, fl_xid(this));
+#endif
+}
+
+// Fix the colormap flashing on Maximum Impact Graphics by erasing the
+// menu before unmapping it:
+void Fl_Menu_Window::hide() {
+ erase();
+ Fl_Single_Window::hide();
+}
+
+Fl_Menu_Window::~Fl_Menu_Window() {
+ hide();
+}
+
+////////////////////////////////////////////////////////////////
+// "Grab" is done while menu systems are up. This has several effects:
+// Events are all sent to the "grab window", which does not even
+// have to be displayed (and in the case of Fl_Menu.C it isn't).
+// Under X override_redirect and save_under is done to new windows.
+// The system is also told to "grab" events and send them to this app.
+
+extern void fl_fix_focus();
+#ifdef WIN32
+HWND fl_capture; // for some reason we must keep forcing it back on!
+#endif
+
+void Fl::grab(Fl_Window& w) {
+ grab_ = &w;
+ fl_fix_focus();
+#ifdef WIN32
+ // this seems to have no effect...
+ SetCapture(fl_capture = fl_xid(first_window()));
+#else
+ XGrabPointer(fl_display,
+ fl_xid(first_window()),
+ 1,
+ ButtonPressMask|ButtonReleaseMask|
+ ButtonMotionMask|PointerMotionMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ None,
+ 0,
+ fl_event_time);
+ XGrabKeyboard(fl_display,
+ fl_xid(first_window()),
+ 1,
+ GrabModeAsync,
+ GrabModeAsync,
+ fl_event_time);
+#endif
+}
+
+void Fl::release() {
+ grab_ = 0;
+ fl_fix_focus();
+#ifdef WIN32
+ fl_capture = 0;
+ ReleaseCapture();
+#else
+ XUngrabKeyboard(fl_display, fl_event_time);
+ XUngrabPointer(fl_display, fl_event_time);
+ // this flush is done in case the picked menu item goes into
+ // an infinite loop, so we don't leave the X server locked up:
+ XFlush(fl_display);
+#endif
+ return;
+}
+
+// end of Fl_Menu_Window.C