#include <config.h>
#include "XWorkArea.h"
+
+#include "Color.h"
#include "XFormsView.h"
+#include "XLyXKeySym.h"
#include "debug.h"
-#include "XLyXKeySym.h"
#include "funcrequest.h"
+#include "LColor.h"
#include "Timeout.h"
#include <boost/bind.hpp>
-using lyx::frontend::Box;
-using lyx::frontend::BoxList;
-using lyx::frontend::WidgetMap;
+using boost::shared_ptr;
using std::abs;
using std::dec;
using std::hex;
using std::string;
+namespace lyx {
+namespace frontend {
namespace {
fl_set_object_resize(obj, FL_RESIZE_ALL);
fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
+ unsigned int r, g, b;
+ if (getRGBColor(LColor::background, r, g, b)) {
+ fl_mapcolor(FL_FREE_COL12, r, g, b);
+ fl_set_object_color(obj, FL_FREE_COL12, FL_MCOL);
+ }
+
// The scrollbar.
scrollbar = obj = fl_add_scrollbar(FL_VERT_SCROLLBAR, 0, 0, w, h, "");
fl_set_object_boxtype(obj, FL_UP_BOX);
// Hand control of the layout of these widgets to the
// Layout Engine.
XFormsView & xview = dynamic_cast<XFormsView &>(owner);
- BoxList & boxlist = xview.getBox(XFormsView::Center).children();
+ BoxList & boxlist = xview.getBox(XFormsView::Center)->children();
- wa_box_ = &boxlist.push_back(Box(0,0));
+ wa_box_ = boxlist.push_back(Box(0,0));
wa_box_->set(Box::Horizontal);
- Box & frame_box = widgets_.add(frame, wa_box_->children(), 0, 0);
- frame_box.set(Box::Expand);
+ shared_ptr<Box> frame_box = widgets_.add(frame, wa_box_->children(), 0, 0);
+ frame_box->set(Box::Expand);
int const bw = int(abs(fl_get_border_width()));
- Box & wa_box = embed(work_area, frame_box.children(), widgets_, bw);
- wa_box.set(Box::Expand);
+ shared_ptr<Box> wa_box = embed(work_area, frame_box->children(), widgets_, bw);
+ wa_box->set(Box::Expand);
widgets_.add(scrollbar, wa_box_->children(), 17, 0);
XGCValues val;
val.function = GXcopy;
+ val.graphics_exposures = false;
copy_gc = XCreateGC(fl_get_display(), RootWindow(fl_get_display(), 0),
- GCFunction, &val);
+ GCFunction | GCGraphicsExposures, &val);
}
}
-void XWorkArea::redraw(int width, int height)
+void XWorkArea::updateGeometry(int width, int height)
{
static int cur_width = -1;
static int cur_height = -1;
- if (cur_width == width && cur_height == height && workareapixmap) {
- XCopyArea(fl_get_display(),
- getPixmap(), getWin(), copy_gc,
- 0, 0, width, height, xpos(), ypos());
+ if (cur_width == width && cur_height == height && workareapixmap)
return;
- }
cur_width = width;
cur_height = height;
}
+void XWorkArea::paint(int x, int y, int w, int h)
+{
+ lyxerr[Debug::WORKAREA]
+ << "XWorkarea::paint " << w << 'x' << h
+ << '+' << x << '+' << y << endl;
+
+ updateGeometry(workWidth(), workHeight());
+ XCopyArea(fl_get_display(),
+ getPixmap(), getWin(),
+ copy_gc, x, y, w, h,
+ work_area->x + x, work_area->y + y);
+}
+
+
void XWorkArea::setScrollbarParams(int height, int pos, int line_height)
{
// we need to cache this for scroll_cb
FL_Coord, FL_Coord,
int key, void * xev)
{
+ if (event != 11)
+ lyxerr[Debug::WORKAREA] << "Workarea event: EVENT: " << event << endl;
+
XEvent * ev = static_cast<XEvent*>(xev);
XWorkArea * area = static_cast<XWorkArea*>(ob->u_vdata);
switch (event) {
- case FL_DRAW:
+ case FL_DRAW: {
if (!area->work_area || !area->work_area->form->visible)
return 1;
- lyxerr[Debug::WORKAREA] << "Workarea event: DRAW" << endl;
- area->redraw(area->workWidth(), area->workHeight());
+
+ if (ev) {
+ lyxerr[Debug::WORKAREA]
+ << "work_area_handler, handling X11 "
+ "expose event "
+ << ev->xexpose.width << 'x'
+ << ev->xexpose.height << '+'
+ << ev->xexpose.x << '+'
+ << ev->xexpose.y << endl;
+
+ // X11 generates XEvents with x, y relative to the
+ // top left corner of the window.
+ // XScreen::expose emulates this behaviour.
+ // We therefore need to remove this offset before
+ // generating the pixmap.
+ int const x = ev->xexpose.x - ob->x;
+ int const y = ev->xexpose.y - ob->y;
+
+ area->paint(x, y,
+ ev->xexpose.width, ev->xexpose.height);
+ } else
+ area->paint(0, 0,
+ area->workWidth(), area->workHeight());
+
break;
+ }
case FL_PUSH:
if (!ev || ev->xbutton.button == 0) break;
+
+ if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+ static long last_wheel;
+
+ long cur_wheel = ev->xbutton.time;
+ if (last_wheel == cur_wheel)
+ break;
+
+ last_wheel = cur_wheel;
+
+ float l, r;
+ fl_get_scrollbar_increment(area->scrollbar, &l, &r);
+
+ if (ev->xbutton.button == 4)
+ l *= -1.0;
+
+ fl_set_scrollbar_value(
+ area->scrollbar,
+ fl_get_scrollbar_value(area->scrollbar) + l);
+
+ area->scroll_cb();
+ break;
+ }
+
// Should really have used xbutton.state
lyxerr[Debug::WORKAREA] << "Workarea event: PUSH" << endl;
area->dispatch(
case FL_RELEASE:
if (!ev || ev->xbutton.button == 0) break;
// Should really have used xbutton.state
+
+ if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+ // We ingnore wheel event here
+ break;
+ }
+
lyxerr[Debug::WORKAREA] << "Workarea event: RELEASE" << endl;
+
area->dispatch(
FuncRequest(LFUN_MOUSE_RELEASE,
ev->xbutton.x - ob->x,
break;
case FL_DRAG: {
+ lyxerr[Debug::WORKAREA] << "Workarea event: DRAG 0" << endl;
+
if (!ev || !area->scrollbar)
break;
case FL_DBLCLICK:
if (ev) {
+ if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+ // Ignore wheel events
+ break;
+ }
+
+
lyxerr[Debug::WORKAREA] << "Workarea event: DBLCLICK" << endl;
FuncRequest cmd(LFUN_MOUSE_DOUBLE,
ev->xbutton.x - ob->x,
case FL_TRPLCLICK:
if (ev) {
+ if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+ // Ignore wheel events
+ break;
+ }
+
lyxerr[Debug::WORKAREA] << "Workarea event: TRPLCLICK" << endl;
FuncRequest cmd(LFUN_MOUSE_TRIPLE,
ev->xbutton.x - ob->x,
fl_stuff_clipboard(work_area, 0, hold.data(), hold.size(), 0);
}
+
+} // namespace frontend
+} // namespace lyx