2002-06-18 15:44:30 +00:00
|
|
|
/**
|
|
|
|
* \file xscreen.C
|
2002-09-05 15:14:23 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-06-18 15:44:30 +00:00
|
|
|
*
|
|
|
|
* \author unknown
|
2002-11-24 15:20:31 +00:00
|
|
|
* \author John Levon
|
2002-09-05 14:10:50 +00:00
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS
|
2002-06-18 15:44:30 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
|
|
|
|
#include "frontends/screen.h"
|
|
|
|
#include "frontends/font_metrics.h"
|
|
|
|
#include "XWorkArea.h"
|
|
|
|
#include "xscreen.h"
|
|
|
|
#include "lyxtext.h"
|
|
|
|
#include "lyxrow.h"
|
|
|
|
#include "Painter.h"
|
|
|
|
#include "WorkArea.h"
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "BufferView.h"
|
|
|
|
#include "insets/insettext.h"
|
|
|
|
#include "ColorHandler.h"
|
|
|
|
#include "language.h"
|
2002-06-21 02:22:13 +00:00
|
|
|
#include "debug.h"
|
2002-06-18 15:44:30 +00:00
|
|
|
|
2002-06-21 16:33:12 +00:00
|
|
|
using std::endl;
|
2002-06-18 15:44:30 +00:00
|
|
|
using std::max;
|
|
|
|
using std::min;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
GC createGC()
|
|
|
|
{
|
|
|
|
XGCValues val;
|
2002-06-24 20:28:12 +00:00
|
|
|
val.foreground = BlackPixel(fl_get_display(),
|
2002-06-18 15:44:30 +00:00
|
|
|
DefaultScreen(fl_get_display()));
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2002-06-18 15:44:30 +00:00
|
|
|
val.function = GXcopy;
|
|
|
|
val.graphics_exposures = false;
|
|
|
|
val.line_style = LineSolid;
|
|
|
|
val.line_width = 0;
|
2002-06-24 20:28:12 +00:00
|
|
|
return XCreateGC(fl_get_display(), RootWindow(fl_get_display(), 0),
|
2002-06-18 15:44:30 +00:00
|
|
|
GCForeground | GCFunction | GCGraphicsExposures
|
2002-08-15 16:02:22 +00:00
|
|
|
| GCLineWidth | GCLineStyle, &val);
|
2002-06-18 15:44:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace anon
|
|
|
|
|
|
|
|
|
|
|
|
XScreen::XScreen(XWorkArea & o)
|
|
|
|
: LyXScreen(), owner_(o)
|
|
|
|
{
|
|
|
|
// the cursor isnt yet visible
|
|
|
|
cursor_pixmap = 0;
|
|
|
|
cursor_pixmap_x = 0;
|
|
|
|
cursor_pixmap_y = 0;
|
|
|
|
cursor_pixmap_w = 0;
|
|
|
|
cursor_pixmap_h = 0;
|
|
|
|
|
|
|
|
// We need this GC
|
|
|
|
gc_copy = createGC();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XScreen::~XScreen()
|
|
|
|
{
|
|
|
|
XFreeGC(fl_get_display(), gc_copy);
|
|
|
|
}
|
|
|
|
|
2002-06-24 20:28:12 +00:00
|
|
|
|
|
|
|
void XScreen::setCursorColor()
|
2002-06-18 15:44:30 +00:00
|
|
|
{
|
2002-11-08 11:14:49 +00:00
|
|
|
if (!lyxColorHandler.get())
|
|
|
|
return;
|
2002-06-18 15:44:30 +00:00
|
|
|
|
|
|
|
GC gc = lyxColorHandler->getGCForeground(LColor::cursor);
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2002-06-18 15:44:30 +00:00
|
|
|
XGCValues val;
|
|
|
|
XGetGCValues(fl_get_display(),
|
|
|
|
gc, GCForeground, &val);
|
|
|
|
XChangeGC(fl_get_display(), gc_copy, GCForeground, &val);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void XScreen::showManualCursor(LyXText const * text, int x, int y,
|
|
|
|
int asc, int desc, Cursor_Shape shape)
|
|
|
|
{
|
|
|
|
// Update the cursor color.
|
|
|
|
setCursorColor();
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2003-03-06 20:21:21 +00:00
|
|
|
int const y1 = max(y - text->top_y() - asc, 0);
|
|
|
|
int const y_tmp = min(y - text->top_y() + desc,
|
2002-06-18 15:44:30 +00:00
|
|
|
static_cast<int>(owner_.workHeight()));
|
|
|
|
|
|
|
|
// Secure against very strange situations
|
|
|
|
int const y2 = max(y_tmp, y1);
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2002-06-18 15:44:30 +00:00
|
|
|
if (cursor_pixmap) {
|
|
|
|
XFreePixmap(fl_get_display(), cursor_pixmap);
|
|
|
|
cursor_pixmap = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y2 > 0 && y1 < int(owner_.workHeight())) {
|
|
|
|
cursor_pixmap_h = y2 - y1 + 1;
|
|
|
|
cursor_pixmap_y = y1;
|
|
|
|
|
|
|
|
switch (shape) {
|
|
|
|
case BAR_SHAPE:
|
|
|
|
cursor_pixmap_w = 1;
|
|
|
|
cursor_pixmap_x = x;
|
|
|
|
break;
|
|
|
|
case L_SHAPE:
|
|
|
|
cursor_pixmap_w = cursor_pixmap_h/3;
|
|
|
|
cursor_pixmap_x = x;
|
|
|
|
break;
|
|
|
|
case REVERSED_L_SHAPE:
|
|
|
|
cursor_pixmap_w = cursor_pixmap_h/3;
|
|
|
|
cursor_pixmap_x = x - cursor_pixmap_w + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2002-06-24 20:28:12 +00:00
|
|
|
cursor_pixmap =
|
2002-06-18 15:44:30 +00:00
|
|
|
XCreatePixmap (fl_get_display(),
|
|
|
|
fl_root,
|
|
|
|
cursor_pixmap_w,
|
|
|
|
cursor_pixmap_h,
|
|
|
|
fl_get_visual_depth());
|
|
|
|
XCopyArea (fl_get_display(),
|
|
|
|
owner_.getWin(),
|
|
|
|
cursor_pixmap,
|
|
|
|
gc_copy,
|
|
|
|
owner_.xpos() + cursor_pixmap_x,
|
|
|
|
owner_.ypos() + cursor_pixmap_y,
|
|
|
|
cursor_pixmap_w,
|
|
|
|
cursor_pixmap_h,
|
|
|
|
0, 0);
|
|
|
|
XDrawLine(fl_get_display(),
|
|
|
|
owner_.getWin(),
|
|
|
|
gc_copy,
|
|
|
|
x + owner_.xpos(),
|
|
|
|
y1 + owner_.ypos(),
|
|
|
|
x + owner_.xpos(),
|
|
|
|
y2 + owner_.ypos());
|
|
|
|
switch (shape) {
|
|
|
|
case BAR_SHAPE:
|
|
|
|
break;
|
|
|
|
case L_SHAPE:
|
|
|
|
case REVERSED_L_SHAPE:
|
|
|
|
int const rectangle_h = (cursor_pixmap_h + 10) / 20;
|
|
|
|
XFillRectangle(fl_get_display(),
|
|
|
|
owner_.getWin(),
|
|
|
|
gc_copy,
|
|
|
|
cursor_pixmap_x + owner_.xpos(),
|
|
|
|
y2 - rectangle_h + 1 + owner_.ypos(),
|
|
|
|
cursor_pixmap_w - 1, rectangle_h);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
cursor_visible_ = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void XScreen::hideCursor()
|
|
|
|
{
|
|
|
|
if (!cursor_visible_) return;
|
|
|
|
|
|
|
|
if (cursor_pixmap) {
|
2002-06-24 20:28:12 +00:00
|
|
|
XCopyArea (fl_get_display(),
|
2002-06-18 15:44:30 +00:00
|
|
|
cursor_pixmap,
|
|
|
|
owner_.getWin(),
|
|
|
|
gc_copy,
|
2002-06-24 20:28:12 +00:00
|
|
|
0, 0,
|
2002-06-18 15:44:30 +00:00
|
|
|
cursor_pixmap_w, cursor_pixmap_h,
|
|
|
|
cursor_pixmap_x + owner_.xpos(),
|
|
|
|
cursor_pixmap_y + owner_.ypos());
|
|
|
|
}
|
|
|
|
cursor_visible_ = false;
|
|
|
|
}
|
|
|
|
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2002-06-21 02:22:13 +00:00
|
|
|
void XScreen::expose(int x, int y, int w, int h)
|
2002-06-18 15:44:30 +00:00
|
|
|
{
|
2002-11-27 10:30:28 +00:00
|
|
|
lyxerr[Debug::GUI] << "expose " << w << 'x' << h
|
|
|
|
<< '+' << x << '+' << y << endl;
|
2002-06-18 15:44:30 +00:00
|
|
|
XCopyArea(fl_get_display(),
|
|
|
|
owner_.getPixmap(),
|
|
|
|
owner_.getWin(),
|
|
|
|
gc_copy,
|
2002-06-21 02:22:13 +00:00
|
|
|
x, y, w, h,
|
2002-06-18 15:44:30 +00:00
|
|
|
x + owner_.xpos(),
|
|
|
|
y + owner_.ypos());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void XScreen::draw(LyXText * text, BufferView * bv, unsigned int y)
|
|
|
|
{
|
2002-11-08 11:14:49 +00:00
|
|
|
if (cursor_visible_)
|
|
|
|
hideCursor();
|
2002-06-18 15:44:30 +00:00
|
|
|
|
2003-03-06 20:21:21 +00:00
|
|
|
int const old_first = text->top_y();
|
|
|
|
text->top_y(y);
|
2002-06-18 15:44:30 +00:00
|
|
|
|
|
|
|
// is any optimization possible?
|
|
|
|
if ((y - old_first) < owner_.workHeight()
|
|
|
|
&& (old_first - y) < owner_.workHeight())
|
|
|
|
{
|
2003-03-06 20:21:21 +00:00
|
|
|
if (text->top_y() < old_first) {
|
2003-03-22 17:26:03 +00:00
|
|
|
drawFromTo(text, bv, 0, old_first - text->top_y(), 0, 0);
|
|
|
|
XCopyArea(fl_get_display(),
|
|
|
|
owner_.getWin(),
|
|
|
|
owner_.getWin(),
|
|
|
|
gc_copy,
|
|
|
|
owner_.xpos(),
|
|
|
|
owner_.ypos(),
|
|
|
|
owner_.workWidth(),
|
|
|
|
owner_.workHeight() - old_first + text->top_y(),
|
|
|
|
owner_.xpos(),
|
|
|
|
owner_.ypos() + old_first - text->top_y()
|
2002-06-18 15:44:30 +00:00
|
|
|
);
|
|
|
|
// expose the area drawn
|
|
|
|
expose(0, 0,
|
|
|
|
owner_.workWidth(),
|
2003-03-06 20:21:21 +00:00
|
|
|
old_first - text->top_y());
|
2002-06-18 15:44:30 +00:00
|
|
|
} else {
|
|
|
|
drawFromTo(text, bv,
|
2003-03-06 20:21:21 +00:00
|
|
|
owner_.workHeight() + old_first - text->top_y(),
|
2003-03-22 17:26:03 +00:00
|
|
|
owner_.workHeight(), 0, 0);
|
|
|
|
XCopyArea(fl_get_display(),
|
|
|
|
owner_.getWin(),
|
|
|
|
owner_.getWin(),
|
|
|
|
gc_copy,
|
|
|
|
owner_.xpos(),
|
|
|
|
owner_.ypos() + text->top_y() - old_first,
|
|
|
|
owner_.workWidth(),
|
|
|
|
owner_.workHeight() + old_first - text->top_y(),
|
|
|
|
owner_.xpos(),
|
|
|
|
owner_.ypos());
|
2002-06-18 15:44:30 +00:00
|
|
|
// expose the area drawn
|
2003-03-06 20:21:21 +00:00
|
|
|
expose(0, owner_.workHeight() + old_first - text->top_y(),
|
|
|
|
owner_.workWidth(), text->top_y() - old_first);
|
2002-06-18 15:44:30 +00:00
|
|
|
}
|
|
|
|
} else {
|
2002-06-24 20:28:12 +00:00
|
|
|
// make a dumb new-draw
|
2003-03-22 17:26:03 +00:00
|
|
|
drawFromTo(text, bv, 0, owner_.workHeight(), 0, 0);
|
2002-06-18 15:44:30 +00:00
|
|
|
expose(0, 0, owner_.workWidth(), owner_.workHeight());
|
|
|
|
}
|
|
|
|
|
|
|
|
XSync(fl_get_display(), 0);
|
2002-11-24 15:20:31 +00:00
|
|
|
}
|