mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
299 lines
10 KiB
C++
299 lines
10 KiB
C++
|
/*
|
||
|
* $Id: Cursor.cpp 1700 2006-07-22 18:51:10Z karijes $
|
||
|
*
|
||
|
* Edewm, window manager
|
||
|
* Part of Equinox Desktop Environment (EDE).
|
||
|
* Copyright (c) 2000-2006 EDE Authors.
|
||
|
*
|
||
|
* This program is licenced under terms of the
|
||
|
* GNU General Public Licence version 2 or newer.
|
||
|
* See COPYING for details.
|
||
|
*/
|
||
|
|
||
|
#include "Cursor.h"
|
||
|
#include "Frame.h"
|
||
|
#include "Tracers.h"
|
||
|
|
||
|
#include <efltk/x.h>
|
||
|
#include <X11/cursorfont.h>
|
||
|
|
||
|
#include <assert.h>
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#include <map>
|
||
|
std::map<CursorType, const char*> cursors_map;
|
||
|
#endif
|
||
|
|
||
|
/* Windows like cursors (copied from FLTK).
|
||
|
* These are cursors for some shapes (given in comments). For others, default X are used.
|
||
|
*/
|
||
|
#define CURSORSIZE 16
|
||
|
#define HOTXY 8
|
||
|
static struct TableEntry {
|
||
|
uchar bits[CURSORSIZE*CURSORSIZE/8];
|
||
|
uchar mask[CURSORSIZE*CURSORSIZE/8];
|
||
|
Cursor cursor;
|
||
|
} table[] = {
|
||
|
{{ // FL_CURSOR_NS
|
||
|
0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
|
||
|
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||
|
0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00},
|
||
|
{
|
||
|
0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
|
||
|
0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
|
||
|
0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}},
|
||
|
{{ // FL_CURSOR_EW
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
|
||
|
0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||
|
{
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
|
||
|
0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||
|
{{ // FL_CURSOR_NWSE
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
|
||
|
0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
|
||
|
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||
|
{
|
||
|
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
|
||
|
0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
|
||
|
0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}},
|
||
|
{{ // FL_CURSOR_NESW
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e,
|
||
|
0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00,
|
||
|
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||
|
{
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f,
|
||
|
0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00,
|
||
|
0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||
|
{{0}, {0}} // FL_CURSOR_NONE & unknown
|
||
|
};
|
||
|
|
||
|
// Mozilla-like busy cursor
|
||
|
#define LAWATCH_WIDTH 32
|
||
|
#define LAWATCH_HEIGHT 32
|
||
|
#define LAWATCH_HOTXY 2
|
||
|
const char left_arrow_watch_bits [] =
|
||
|
{
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||
|
0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
|
||
|
0x7c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00,
|
||
|
0xfc, 0x3b, 0x00, 0x00, 0x7c, 0x38, 0x00, 0x00, 0x6c, 0x54, 0x00, 0x00,
|
||
|
0xc4, 0xdc, 0x00, 0x00, 0xc0, 0x44, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00,
|
||
|
0x80, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||
|
};
|
||
|
|
||
|
const char left_arrow_watch_mask [] =
|
||
|
{
|
||
|
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
||
|
0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
|
||
|
0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x3b, 0x00, 0x00,
|
||
|
0xfe, 0x7f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00,
|
||
|
0xee, 0xff, 0x01, 0x00, 0xe4, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00,
|
||
|
0xc0, 0x7f, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||
|
};
|
||
|
|
||
|
Cursor CreateLeftArrowWatch(void)
|
||
|
{
|
||
|
XColor dummy;
|
||
|
Pixmap p = XCreateBitmapFromData(fl_display, RootWindow(fl_display, fl_screen),
|
||
|
left_arrow_watch_bits, LAWATCH_WIDTH, LAWATCH_HEIGHT);
|
||
|
Pixmap m = XCreateBitmapFromData(fl_display, RootWindow(fl_display, fl_screen),
|
||
|
left_arrow_watch_mask, LAWATCH_WIDTH, LAWATCH_HEIGHT);
|
||
|
|
||
|
Cursor cursor = XCreatePixmapCursor(fl_display, p, m, &dummy, &dummy, LAWATCH_HOTXY, LAWATCH_HOTXY);
|
||
|
|
||
|
// recolor created cursor to usefull colors
|
||
|
XColor fgc;
|
||
|
Fl_Color fg = fl_get_color(FL_BLACK);
|
||
|
fgc.red = (fg>>16)&0xFF00;
|
||
|
fgc.green = (fg>>8)&0xFF00;
|
||
|
fgc.blue = fg & 0xFF00;
|
||
|
|
||
|
XColor bgc;
|
||
|
Fl_Color bg = fl_get_color(FL_WHITE);
|
||
|
bgc.red = (bg>>16)&0xFF00;
|
||
|
bgc.green = (bg>>8)&0xFF00;
|
||
|
bgc.blue = bg & 0xFF00;
|
||
|
XRecolorCursor(fl_display, cursor, &fgc, &bgc);
|
||
|
|
||
|
return cursor;
|
||
|
}
|
||
|
|
||
|
Cursor CreateFltkCursor(Fl_Cursor c)
|
||
|
{
|
||
|
Cursor cursor;
|
||
|
if(!c)
|
||
|
return None;
|
||
|
|
||
|
if(c >= FL_CURSOR_NS)
|
||
|
{
|
||
|
TableEntry* q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS);
|
||
|
if(!(q->cursor))
|
||
|
{
|
||
|
XColor dummy;
|
||
|
Pixmap p = XCreateBitmapFromData(fl_display, RootWindow(fl_display, fl_screen), (const char*)q->bits,
|
||
|
CURSORSIZE, CURSORSIZE);
|
||
|
Pixmap m = XCreateBitmapFromData(fl_display, RootWindow(fl_display, fl_screen), (const char*)q->mask,
|
||
|
CURSORSIZE, CURSORSIZE);
|
||
|
q->cursor = XCreatePixmapCursor(fl_display, p, m, &dummy, &dummy, HOTXY, HOTXY);
|
||
|
|
||
|
XFreePixmap(fl_display, m);
|
||
|
XFreePixmap(fl_display, p);
|
||
|
}
|
||
|
cursor = q->cursor;
|
||
|
}
|
||
|
else
|
||
|
cursor = XCreateFontCursor(fl_display, (c-1)*2);
|
||
|
|
||
|
// recolor created cursor to usefull colors
|
||
|
XColor fgc;
|
||
|
Fl_Color fg = fl_get_color(FL_BLACK);
|
||
|
fgc.red = (fg>>16)&0xFF00;
|
||
|
fgc.green = (fg>>8)&0xFF00;
|
||
|
fgc.blue = fg & 0xFF00;
|
||
|
|
||
|
XColor bgc;
|
||
|
Fl_Color bg = fl_get_color(FL_WHITE);
|
||
|
bgc.red = (bg>>16)&0xFF00;
|
||
|
bgc.green = (bg>>8)&0xFF00;
|
||
|
bgc.blue = bg & 0xFF00;
|
||
|
XRecolorCursor(fl_display, cursor, &fgc, &bgc);
|
||
|
|
||
|
return cursor;
|
||
|
}
|
||
|
|
||
|
CursorHandler::CursorHandler()
|
||
|
{
|
||
|
cursors_loaded = false;
|
||
|
|
||
|
/* In some cases curr_cursor_type can't be set
|
||
|
* fast enough (mostly for Frame::grab_cursor()) which
|
||
|
* will crash whole wm. This will prevent that.
|
||
|
*/
|
||
|
curr_cursor_type = CURSOR_DEFAULT;
|
||
|
}
|
||
|
|
||
|
CursorHandler::~CursorHandler()
|
||
|
{
|
||
|
if(st != X_CURSORS)
|
||
|
return;
|
||
|
|
||
|
for(int i = 0; i < CURSOR_LIST_SIZE; i++)
|
||
|
XFreeCursor(fl_display, cursors[i]);
|
||
|
}
|
||
|
|
||
|
void CursorHandler::load(CursorShapeType s)
|
||
|
{
|
||
|
TRACE_FUNCTION("void CursorHandler::load(CursorShapeType s)");
|
||
|
|
||
|
st = s;
|
||
|
if(st == FLTK_CURSORS)
|
||
|
{
|
||
|
cursors[CURSOR_DEFAULT] = CreateFltkCursor(FL_CURSOR_ARROW);
|
||
|
cursors[CURSOR_MOVE] = CreateFltkCursor(FL_CURSOR_MOVE);
|
||
|
|
||
|
//cursors[CURSOR_WAIT] = CreateFltkCursor(FL_CURSOR_WAIT);
|
||
|
cursors[CURSOR_WAIT] = CreateLeftArrowWatch();
|
||
|
|
||
|
cursors[CURSOR_HELP] = CreateFltkCursor(FL_CURSOR_HELP);
|
||
|
cursors[CURSOR_N] = CreateFltkCursor(FL_CURSOR_NS);
|
||
|
cursors[CURSOR_NE] = CreateFltkCursor(FL_CURSOR_NESW);
|
||
|
cursors[CURSOR_E] = CreateFltkCursor(FL_CURSOR_WE);
|
||
|
cursors[CURSOR_SE] = CreateFltkCursor(FL_CURSOR_NWSE);
|
||
|
cursors[CURSOR_S] = CreateFltkCursor(FL_CURSOR_NS);
|
||
|
cursors[CURSOR_SW] = CreateFltkCursor(FL_CURSOR_NESW);
|
||
|
cursors[CURSOR_W] = CreateFltkCursor(FL_CURSOR_WE);
|
||
|
cursors[CURSOR_NW] = CreateFltkCursor(FL_CURSOR_NWSE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cursors[CURSOR_DEFAULT] = XCreateFontCursor(fl_display, XC_left_ptr);
|
||
|
cursors[CURSOR_MOVE] = XCreateFontCursor(fl_display, XC_fleur);
|
||
|
|
||
|
//cursors[CURSOR_WAIT] = XCreateFontCursor(fl_display, XC_watch);
|
||
|
cursors[CURSOR_WAIT] = CreateLeftArrowWatch();
|
||
|
|
||
|
cursors[CURSOR_HELP] = XCreateFontCursor(fl_display, XC_question_arrow);
|
||
|
cursors[CURSOR_N] = XCreateFontCursor(fl_display, XC_top_side);
|
||
|
cursors[CURSOR_NE] = XCreateFontCursor(fl_display, XC_top_right_corner);
|
||
|
cursors[CURSOR_E] = XCreateFontCursor(fl_display, XC_right_side);
|
||
|
cursors[CURSOR_SE] = XCreateFontCursor(fl_display, XC_bottom_right_corner);
|
||
|
cursors[CURSOR_S] = XCreateFontCursor(fl_display, XC_bottom_side);
|
||
|
cursors[CURSOR_SW] = XCreateFontCursor(fl_display, XC_bottom_left_corner);
|
||
|
cursors[CURSOR_W] = XCreateFontCursor(fl_display, XC_left_side);
|
||
|
cursors[CURSOR_NW] = XCreateFontCursor(fl_display, XC_top_left_corner);
|
||
|
}
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
cursors_map[CURSOR_DEFAULT] = "CURSOR_DEFAULT";
|
||
|
cursors_map[CURSOR_MOVE] = "CURSOR_MOVE";
|
||
|
cursors_map[CURSOR_WAIT] = "CURSOR_WAIT";
|
||
|
cursors_map[CURSOR_HELP] = "CURSOR_HELP";
|
||
|
cursors_map[CURSOR_N] = "CURSOR_N";
|
||
|
cursors_map[CURSOR_NE] = "CURSOR_NE";
|
||
|
cursors_map[CURSOR_E] = "CURSOR_E";
|
||
|
cursors_map[CURSOR_SE] = "CURSOR_SE";
|
||
|
cursors_map[CURSOR_S] = "CURSOR_S";
|
||
|
cursors_map[CURSOR_SW] = "CURSOR_SW";
|
||
|
cursors_map[CURSOR_W] = "CURSOR_W";
|
||
|
cursors_map[CURSOR_NW] = "CURSOR_NW";
|
||
|
#endif
|
||
|
|
||
|
cursors_loaded = true;
|
||
|
}
|
||
|
|
||
|
void CursorHandler::set_cursor(Frame* f, CursorType t)
|
||
|
{
|
||
|
TRACE_FUNCTION("void CursorHandler::set_cursor(Frame* f, CursorType t)");
|
||
|
#ifdef _DEBUG
|
||
|
ELOG("Cursor set to %s", cursors_map[t]);
|
||
|
#endif
|
||
|
assert(cursors_loaded != false);
|
||
|
assert(f != NULL);
|
||
|
|
||
|
// do not set cursor to same type again
|
||
|
if(t == curr_cursor_type)
|
||
|
return;
|
||
|
|
||
|
curr_cursor_type = t;
|
||
|
|
||
|
XDefineCursor(fl_display, fl_xid(f), cursors[curr_cursor_type]);
|
||
|
}
|
||
|
|
||
|
// only for root window
|
||
|
void CursorHandler::set_root_cursor(void)
|
||
|
{
|
||
|
TRACE_FUNCTION("void CursorHandler::set_root_cursor(void)");
|
||
|
assert(cursors_loaded != false);
|
||
|
|
||
|
root_window_cursor = cursors[CURSOR_DEFAULT];
|
||
|
XDefineCursor(fl_display, RootWindow(fl_display, fl_screen), root_window_cursor);
|
||
|
}
|
||
|
|
||
|
void CursorHandler::set_root_cursor(CursorType t)
|
||
|
{
|
||
|
TRACE_FUNCTION("void CursorHandler::set_root_cursor(CursorType t)");
|
||
|
assert(cursors_loaded != false);
|
||
|
|
||
|
root_window_cursor = cursors[t];
|
||
|
XDefineCursor(fl_display, RootWindow(fl_display, fl_screen), root_window_cursor);
|
||
|
}
|
||
|
|
||
|
Cursor CursorHandler::current_cursor(void) const
|
||
|
{
|
||
|
TRACE_FUNCTION("Cursor CursorHandler::current_cursor(void) const");
|
||
|
//assert(current_cursor > 0 && current_cursor < CURSOR_LIST_SIZE);
|
||
|
return cursors[curr_cursor_type];
|
||
|
}
|