#include "bcwindowbase.h"
#include "bcwindowevents.h"
#include "bccmodels.h"
-#include "colors.h"
+#include "bccolors.h"
#include "condition.h"
#include "cursors.h"
#include "bchash.h"
#include "mutex.h"
#include "sizes.h"
#include "vframe.h"
+#include "workarounds.h"
#ifdef HAVE_GL
#include <GL/gl.h>
Mutex BC_KeyboardHandlerLock::keyboard_listener_mutex("keyboard_listener",0);
ArrayList<BC_KeyboardHandler*> BC_KeyboardHandler::listeners;
-BC_WindowBase::BC_WindowBase(int opts)
+BC_WindowBase::BC_WindowBase()
{
- this->options = opts;
//printf("BC_WindowBase::BC_WindowBase 1\n");
BC_WindowBase::initialize();
}
delete pixmap;
+//printf("delete glx=%08x, win=%08x %s\n", (unsigned)glx_win, (unsigned)win, title);
#ifdef HAVE_GL
- if( get_resources()->get_synchronous() &&
- (top_level->options & GLX_WINDOW) && glx_win != 0 )
+ if( get_resources()->get_synchronous() && glx_win != 0 ) {
get_resources()->get_synchronous()->delete_window(this);
- else
+ }
#endif
- XDestroyWindow(top_level->display, win);
+ XDestroyWindow(top_level->display, win);
if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap;
if(icon_pixmap) delete icon_pixmap;
&BC_WindowBase::mediumfont,
&BC_WindowBase::largefont,
&BC_WindowBase::bigfont,
+ &BC_WindowBase::clockfont,
};
for( int i=sizeof(xfont)/sizeof(xfont[0]); --i>=0; )
XFreeFont(display, this->*xfont[i]);
-// bug in X causes XRenderExtensionInfo to be damaged if this is done here
-// left to be done in XCloseDisplay by Xlib.
-#if defined(HAVE_XFT) && 0
+#ifdef HAVE_XFT
+// prevents a bug when Xft closes with unrefd fonts
+ FcPattern *defaults = FcPatternCreate();
+ FcPatternAddInteger(defaults, "maxunreffonts", 0);
+ XftDefaultSet(display, defaults);
+
static void *BC_WindowBase::*xft_font[] = {
&BC_WindowBase::smallfont_xft,
&BC_WindowBase::mediumfont_xft,
&BC_WindowBase::bold_smallfont_xft,
&BC_WindowBase::bold_mediumfont_xft,
&BC_WindowBase::bold_largefont_xft,
+ &BC_WindowBase::clockfont_xft,
};
for( int i=sizeof(xft_font)/sizeof(xft_font[0]); --i>=0; ) {
XftFont *xft = (XftFont *)(this->*xft_font[i]);
- if( xft ) XftFontClose (display, xft);
+ if( xft ) xftFontClose (display, xft);
}
#endif
finit_im();
XvUngrabPort(display, xvideo_port_id, CurrentTime);
unlock_window();
-// Can't close display if another thread is waiting for events.
-// Synchronous thread must delete display it owns a GLX_WINDOW
// Must be last reference to display.
-#ifndef SINGLE_THREAD
-#ifdef HAVE_GL
- if( (options & GLX_DISPLAY) != 0 && get_resources()->get_synchronous() ) {
- printf(_("BC_WindowBase::~BC_WindowBase window deleted but opengl deletion is not\n"
- "implemented for BC_Pixmap.\n"));
- get_resources()->get_synchronous()->delete_display(this);
- }
- else
-#endif
- XCloseDisplay(display);
+// _XftDisplayInfo needs a lock.
+ get_resources()->create_window_lock->lock("BC_WindowBase::~BC_WindowBase");
+ XCloseDisplay(display);
+ get_resources()->create_window_lock->unlock();
+
// clipboard uses a different display connection
clipboard->stop_clipboard();
delete clipboard;
-#endif // SINGLE_THREAD
}
resize_history.remove_all_objects();
keys_return[0] = 0;
is_deleting = 0;
window_lock = 0;
+ resend_event_window = 0;
x = 0;
y = 0;
w = 0;
active_menubar = 0;
active_popup_menu = 0;
active_subwindow = 0;
+ cursor_entered = 0;
pixmap = 0;
bg_pixmap = 0;
_7segment_pixmaps = 0;
#ifdef HAVE_LIBXXF86VM
vm_switched = 0;
#endif
- smallfont_xft = 0;
- bold_largefont_xft = 0;
- bold_mediumfont_xft = 0;
- bold_smallfont_xft = 0;
input_method = 0;
input_context = 0;
+ smallfont = 0;
+ mediumfont = 0;
+ largefont = 0;
+ bigfont = 0;
+ clockfont = 0;
+
+ smallfont_xft = 0;
mediumfont_xft = 0;
largefont_xft = 0;
bigfont_xft = 0;
+ clockfont_xft = 0;
+
+ bold_smallfont_xft = 0;
+ bold_mediumfont_xft = 0;
+ bold_largefont_xft = 0;
#ifdef SINGLE_THREAD
completion_lock = new Condition(0, "BC_WindowBase::completion_lock");
#else
FocusChangeMask
-int BC_WindowBase::create_window(BC_WindowBase *parent_window,
- const char *title,
- int x,
- int y,
- int w,
- int h,
- int minw,
- int minh,
- int allow_resize,
- int private_color,
- int hide,
- int bg_color,
- const char *display_name,
- int window_type,
- BC_Pixmap *bg_pixmap,
- int group_it)
+int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title,
+ int x, int y, int w, int h, int minw, int minh, int allow_resize,
+ int private_color, int hide, int bg_color, const char *display_name,
+ int window_type, BC_Pixmap *bg_pixmap, int group_it)
{
XSetWindowAttributes attr;
unsigned long mask;
#endif
id = get_resources()->get_id();
- int need_lock = 0;
if(parent_window) top_level = parent_window->top_level;
- if( top_level ) { // need this to avoid deadlock with Xlib's locks
- need_lock = 1;
- lock_window("BC_WindowBase::create_window");
- }
+ if( top_level ) lock_window("BC_WindowBase::create_window");
get_resources()->create_window_lock->lock("BC_WindowBase::create_window");
#ifdef HAVE_LIBXXF86VM
else
this->display_name[0] = 0;
- put_title(_(title));
+ put_title(title);
if(bg_pixmap) shared_bg_pixmap = 1;
subwindows = new BC_SubWindowList;
if( shm_completion_event < 0 ) shm_completion_event =
ShmCompletion + XShmGetEventBase(display);
#endif
+ lock_window("BC_WindowBase::create_window 1");
screen = DefaultScreen(display);
rootwin = RootWindow(display, screen);
size_hints.x = this->x;
size_hints.y = this->y;
}
-
- char *txlist[2];
- txlist[0] = this->title;
- txlist[1] = 0;
- XTextProperty titleprop;
- if(options & WINDOW_UTF8)
- Xutf8TextListToTextProperty(display, txlist, 1,
- XUTF8StringStyle, &titleprop);
- else
- XmbTextListToTextProperty(display, txlist, 1,
- XStdICCTextStyle, &titleprop);
- XSetWMProperties(display, win, &titleprop, &titleprop,
- 0, 0, &size_hints, 0, 0);
- XFree(titleprop.value);
+ XSetWMProperties(display, win, 0, 0, 0, 0, &size_hints, 0, 0);
get_atoms();
-
+ set_title(title);
#ifndef SINGLE_THREAD
- clipboard = new BC_Clipboard(display_name);
+ clipboard = new BC_Clipboard(this);
clipboard->start_clipboard();
#endif
if(!hidden) show_window();
}
get_resources()->create_window_lock->unlock();
- if(need_lock) unlock_window();
+ unlock_window();
return 0;
}
}
}
}
+
+ static int xsynch = -1;
+ if( xsynch < 0 ) {
+ const char *cp = getenv("CIN_XSYNCH");
+ xsynch = !cp ? 0 : atoi(cp);
+ }
+ if( xsynch > 0 )
+ XSynchronize(display, True);
+
return display;
}
// event_names[event->type] : "Unknown");
//}
- if( active_grab && active_grab->grab_event(event) ) {
+ if( active_grab ) {
unlock_window();
- return 0;
+ active_grab->lock_window("BC_WindowBase::dispatch_event 3");
+ result = active_grab->grab_event(event);
+ active_grab->unlock_window();
+ if( result ) return result;
+ lock_window("BC_WindowBase::dispatch_event 4");
}
-
switch(event->type) {
case ClientMessage:
// Clear the resize buffer
done = 1;
} else
{ // We currently use X marshalling for xatom events, we can switch to something else later
- recieve_custom_xatoms((xatom_event *)ptr);
+ receive_custom_xatoms((xatom_event *)ptr);
}
break;
break;
case ButtonPress:
+ if(motion_events)
+ {
+ dispatch_motion_event();
+ }
get_key_masks(event->xbutton.state);
cursor_x = event->xbutton.x;
cursor_y = event->xbutton.y;
break;
case ButtonRelease:
+ if(motion_events)
+ {
+ dispatch_motion_event();
+ }
get_key_masks(event->xbutton.state);
button_number = event->xbutton.button;
event_win = event->xany.window;
case XK_KP_Insert: key_pressed = KPINS; break;
case XK_KP_Decimal:
case XK_KP_Delete: key_pressed = KPDEL; break;
+
+ case XK_F1: key_pressed = KEY_F1; break;
+ case XK_F2: key_pressed = KEY_F2; break;
+ case XK_F3: key_pressed = KEY_F3; break;
+ case XK_F4: key_pressed = KEY_F4; break;
+ case XK_F5: key_pressed = KEY_F5; break;
+ case XK_F6: key_pressed = KEY_F6; break;
+ case XK_F7: key_pressed = KEY_F7; break;
+ case XK_F8: key_pressed = KEY_F8; break;
+ case XK_F9: key_pressed = KEY_F9; break;
+ case XK_F10: key_pressed = KEY_F10; break;
+ case XK_F11: key_pressed = KEY_F11; break;
+ case XK_F12: key_pressed = KEY_F12; break;
+
case XK_Menu: key_pressed = KPMENU; break; /* menu */
// remote control
// above case XK_KP_Enter: key_pressed = KPENTER; break; /* check */
break;
case LeaveNotify:
+ if( event->xcrossing.mode != NotifyNormal ) break;
+ if( cursor_entered && event->xcrossing.window == win ) {
+ cursor_entered = 0;
+ }
event_win = event->xany.window;
dispatch_cursor_leave();
break;
case EnterNotify:
+ if( event->xcrossing.mode != NotifyNormal ) break;
+ if( !cursor_entered && event->xcrossing.window == win ) {
+ if( !event->xcrossing.focus && get_resources()->grab_input_focus ) {
+ XSetInputFocus(display, win, RevertToParent, CurrentTime);
+ }
+ cursor_entered = 1;
+ }
event_win = event->xany.window;
cursor_x = event->xcrossing.x;
cursor_y = event->xcrossing.y;
dispatch_cursor_enter();
break;
+
default:
break;
}
#ifndef SINGLE_THREAD
unlock_window();
- if(event) delete event;
+ if(event) {
+ if( resend_event_window ) {
+ resend_event_window->put_event(event);
+ resend_event_window = 0;
+ }
+ else
+ delete event;
+ }
#else
// if(done) completion_lock->unlock();
#endif
if( wy >= (y1-=h) ) wy = y1;
// avoid tip under cursor (flickers)
int abs_x, abs_y;
- get_abs_cursor_xy(abs_x,abs_y, 0);
+ get_abs_cursor(abs_x,abs_y, 0);
if( wx < abs_x && abs_x < wx+w && wy < abs_y && abs_y < wy+h ) {
if( wx-abs_x < wy-abs_y )
wx = abs_x+1;
}
#endif
-int BC_WindowBase::recieve_custom_xatoms(xatom_event *event)
+int BC_WindowBase::receive_custom_xatoms(xatom_event *event)
{
return 0;
}
downleft_resize_cursor = XCreateFontCursor(display, XC_bottom_left_corner);
downright_resize_cursor = XCreateFontCursor(display, XC_bottom_right_corner);
hourglass_cursor = XCreateFontCursor(display, XC_watch);
-
+ grabbed_cursor = create_grab_cursor();
static char cursor_data[] = { 0,0,0,0, 0,0,0,0 };
Colormap colormap = DefaultColormap(display, screen);
pixmap_bottom, pixmap_bottom, &black, &black, 0, 0);
// XDefineCursor(display, win, transparent_cursor);
XFreePixmap(display, pixmap_bottom);
-
- int iw = 23, iw1 = iw-1, iw2 = iw/2;
- int ih = 23, ih1 = ih-1, ih2 = ih/2;
- VFrame grab(iw,ih,BC_RGB888);
- grab.clear_frame();
- grab.set_pixel_color(RED); // fg
- grab.draw_smooth(iw2,0, iw1,0, iw1,ih2);
- grab.draw_smooth(iw1,ih2, iw1,ih1, iw2,ih1);
- grab.draw_smooth(iw2,ih1, 0,ih1, 0,ih2);
- grab.draw_smooth(0,ih2, 0,0, iw2,0);
- grab.set_pixel_color(WHITE); // bg
- grab.draw_line(0,ih2, iw2-2,ih2);
- grab.draw_line(iw2+2,ih2, iw1,ih2);
- grab.draw_line(iw2,0, iw2,ih2-2);
- grab.draw_line(iw2,ih2+2, iw2,ih1);
-
- int bpl = (iw+7)/8, isz = bpl * ih;
- char img[isz]; memset(img, 0, isz);
- char msk[isz]; memset(msk, 0, isz);
- unsigned char **rows = grab.get_rows();
- for( int iy=0; iy<ih; ++iy ) {
- char *op = img + iy*bpl;
- char *mp = msk + iy*bpl;
- unsigned char *ip = rows[iy];
- for( int ix=0; ix<iw; ++ix,ip+=3 ) {
- if( ip[0] ) mp[ix>>3] |= (1<<(ix&7));
- if( !ip[1] ) op[ix>>3] |= (1<<(ix&7));
- }
- }
- unsigned long white_pix = WhitePixel(display, screen);
- unsigned long black_pix = BlackPixel(display, screen);
- Pixmap img_xpm = XCreatePixmapFromBitmapData(display, rootwin,
- img, iw,ih, white_pix,black_pix, 1);
- Pixmap msk_xpm = XCreatePixmapFromBitmapData(display, rootwin,
- msk, iw,ih, white_pix,black_pix, 1);
-
- XColor fc, bc;
- fc.flags = bc.flags = DoRed | DoGreen | DoBlue;
- fc.red = 0xffff; fc.green = fc.blue = 0; // fg
- bc.red = bc.green = bc.blue = 0x0000; // bg
- grabbed_cursor = XCreatePixmapCursor(display, img_xpm,msk_xpm, &fc,&bc, iw2,ih2);
- XFreePixmap(display, img_xpm);
- XFreePixmap(display, msk_xpm);
}
int BC_WindowBase::evaluate_color_model(int client_byte_order, int server_byte_order, int depth)
return 0;
}
+Cursor BC_WindowBase::create_grab_cursor()
+{
+ int iw = 23, iw1 = iw-1, iw2 = iw/2;
+ int ih = 23, ih1 = ih-1, ih2 = ih/2;
+ VFrame grab(iw,ih,BC_RGB888);
+ grab.clear_frame();
+ grab.set_pixel_color(RED); // fg
+ grab.draw_smooth(iw2,0, iw1,0, iw1,ih2);
+ grab.draw_smooth(iw1,ih2, iw1,ih1, iw2,ih1);
+ grab.draw_smooth(iw2,ih1, 0,ih1, 0,ih2);
+ grab.draw_smooth(0,ih2, 0,0, iw2,0);
+ grab.set_pixel_color(WHITE); // bg
+ grab.draw_line(0,ih2, iw2-2,ih2);
+ grab.draw_line(iw2+2,ih2, iw1,ih2);
+ grab.draw_line(iw2,0, iw2,ih2-2);
+ grab.draw_line(iw2,ih2+2, iw2,ih1);
+
+ int bpl = (iw+7)/8, isz = bpl * ih;
+ char img[isz]; memset(img, 0, isz);
+ char msk[isz]; memset(msk, 0, isz);
+ unsigned char **rows = grab.get_rows();
+ for( int iy=0; iy<ih; ++iy ) {
+ char *op = img + iy*bpl;
+ char *mp = msk + iy*bpl;
+ unsigned char *ip = rows[iy];
+ for( int ix=0; ix<iw; ++ix,ip+=3 ) {
+ if( ip[0] ) mp[ix>>3] |= (1<<(ix&7));
+ if( !ip[1] ) op[ix>>3] |= (1<<(ix&7));
+ }
+ }
+ unsigned long white_pix = WhitePixel(display, screen);
+ unsigned long black_pix = BlackPixel(display, screen);
+ Pixmap img_xpm = XCreatePixmapFromBitmapData(display, rootwin,
+ img, iw,ih, white_pix,black_pix, 1);
+ Pixmap msk_xpm = XCreatePixmapFromBitmapData(display, rootwin,
+ msk, iw,ih, white_pix,black_pix, 1);
+
+ XColor fc, bc;
+ fc.flags = bc.flags = DoRed | DoGreen | DoBlue;
+ fc.red = 0xffff; fc.green = fc.blue = 0; // fg
+ bc.red = bc.green = bc.blue = 0x0000; // bg
+ Cursor cursor = XCreatePixmapCursor(display, img_xpm,msk_xpm, &fc,&bc, iw2,ih2);
+ XFreePixmap(display, img_xpm);
+ XFreePixmap(display, msk_xpm);
+ return cursor;
+}
+
int BC_WindowBase::allocate_color_table()
{
int red, green, blue, color;
if( !(bigfont = XLoadQueryFont(display, _(resources.big_font2))) )
bigfont = XLoadQueryFont(display, "fixed");
+ if((clockfont = XLoadQueryFont(display, _(resources.clock_font))) == NULL)
+ if((clockfont = XLoadQueryFont(display, _(resources.clock_font2))) == NULL)
+ clockfont = XLoadQueryFont(display, "fixed");
+
init_xft();
if(get_resources()->use_fontset)
{
largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
bigfontset = XCreateFontSet(display, resources.big_fontset, &m, &n, &d);
if( !bigfontset )
- largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
- if(bigfontset && largefontset && mediumfontset && smallfontset) {
+ bigfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
+ clockfontset = XCreateFontSet(display, resources.clock_fontset, &m, &n, &d);
+ if( !clockfontset )
+ clockfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d);
+ if(clockfontset && bigfontset && largefontset && mediumfontset && smallfontset) {
curr_fontset = mediumfontset;
get_resources()->use_fontset = 1;
}
{
#ifdef HAVE_XFT
if( !get_resources()->use_xft ) return;
+// apparently, xft is not reentrant, more than this is needed
+static Mutex xft_init_lock("BC_WindowBase::xft_init_lock", 0);
+xft_init_lock.lock("BC_WindowBase::init_xft");
if(!(smallfont_xft =
(resources.small_font_xft[0] == '-' ?
- XftFontOpenXlfd(display, screen, resources.small_font_xft) :
- XftFontOpenName(display, screen, resources.small_font_xft))) )
+ xftFontOpenXlfd(display, screen, resources.small_font_xft) :
+ xftFontOpenName(display, screen, resources.small_font_xft))) )
if(!(smallfont_xft =
- XftFontOpenXlfd(display, screen, resources.small_font_xft2)))
- smallfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+ xftFontOpenXlfd(display, screen, resources.small_font_xft2)))
+ smallfont_xft = xftFontOpenXlfd(display, screen, "fixed");
if(!(mediumfont_xft =
(resources.medium_font_xft[0] == '-' ?
- XftFontOpenXlfd(display, screen, resources.medium_font_xft) :
- XftFontOpenName(display, screen, resources.medium_font_xft))) )
+ xftFontOpenXlfd(display, screen, resources.medium_font_xft) :
+ xftFontOpenName(display, screen, resources.medium_font_xft))) )
if(!(mediumfont_xft =
- XftFontOpenXlfd(display, screen, resources.medium_font_xft2)))
- mediumfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+ xftFontOpenXlfd(display, screen, resources.medium_font_xft2)))
+ mediumfont_xft = xftFontOpenXlfd(display, screen, "fixed");
if(!(largefont_xft =
(resources.large_font_xft[0] == '-' ?
- XftFontOpenXlfd(display, screen, resources.large_font_xft) :
- XftFontOpenName(display, screen, resources.large_font_xft))) )
+ xftFontOpenXlfd(display, screen, resources.large_font_xft) :
+ xftFontOpenName(display, screen, resources.large_font_xft))) )
if(!(largefont_xft =
- XftFontOpenXlfd(display, screen, resources.large_font_xft2)))
- largefont_xft = XftFontOpenXlfd(display, screen, "fixed");
+ xftFontOpenXlfd(display, screen, resources.large_font_xft2)))
+ largefont_xft = xftFontOpenXlfd(display, screen, "fixed");
if(!(bigfont_xft =
(resources.big_font_xft[0] == '-' ?
- XftFontOpenXlfd(display, screen, resources.big_font_xft) :
- XftFontOpenName(display, screen, resources.big_font_xft))) )
+ xftFontOpenXlfd(display, screen, resources.big_font_xft) :
+ xftFontOpenName(display, screen, resources.big_font_xft))) )
if(!(bigfont_xft =
- XftFontOpenXlfd(display, screen, resources.big_font_xft2)))
- bigfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+ xftFontOpenXlfd(display, screen, resources.big_font_xft2)))
+ bigfont_xft = xftFontOpenXlfd(display, screen, "fixed");
+ if(!(clockfont_xft =
+ (resources.clock_font_xft[0] == '-' ?
+ xftFontOpenXlfd(display, screen, resources.clock_font_xft) :
+ xftFontOpenName(display, screen, resources.clock_font_xft))) )
+ clockfont_xft = xftFontOpenXlfd(display, screen, "fixed");
+
if(!(bold_smallfont_xft =
(resources.small_b_font_xft[0] == '-' ?
- XftFontOpenXlfd(display, screen, resources.small_b_font_xft) :
- XftFontOpenName(display, screen, resources.small_b_font_xft))) )
- bold_smallfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+ xftFontOpenXlfd(display, screen, resources.small_b_font_xft) :
+ xftFontOpenName(display, screen, resources.small_b_font_xft))) )
+ bold_smallfont_xft = xftFontOpenXlfd(display, screen, "fixed");
if(!(bold_mediumfont_xft =
(resources.medium_b_font_xft[0] == '-' ?
- XftFontOpenXlfd(display, screen, resources.medium_b_font_xft) :
- XftFontOpenName(display, screen, resources.medium_b_font_xft))) )
- bold_mediumfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+ xftFontOpenXlfd(display, screen, resources.medium_b_font_xft) :
+ xftFontOpenName(display, screen, resources.medium_b_font_xft))) )
+ bold_mediumfont_xft = xftFontOpenXlfd(display, screen, "fixed");
if(!(bold_largefont_xft =
(resources.large_b_font_xft[0] == '-' ?
- XftFontOpenXlfd(display, screen, resources.large_b_font_xft) :
- XftFontOpenName(display, screen, resources.large_b_font_xft))) )
- bold_largefont_xft = XftFontOpenXlfd(display, screen, "fixed");
+ xftFontOpenXlfd(display, screen, resources.large_b_font_xft) :
+ xftFontOpenName(display, screen, resources.large_b_font_xft))) )
+ bold_largefont_xft = xftFontOpenXlfd(display, screen, "fixed");
-// Extension failed to locate fonts
if( !smallfont_xft || !mediumfont_xft || !largefont_xft || !bigfont_xft ||
- !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ) {
+ !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ||
+ !clockfont_xft ) {
printf("BC_WindowBase::init_fonts: no xft fonts found:"
- " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n",
+ " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n",
resources.small_font_xft, smallfont_xft,
resources.medium_font_xft, mediumfont_xft,
resources.large_font_xft, largefont_xft,
resources.big_font_xft, bigfont_xft,
+ resources.clock_font_xft, clockfont_xft,
resources.small_b_font_xft, bold_smallfont_xft,
resources.medium_b_font_xft, bold_mediumfont_xft,
resources.large_b_font_xft, bold_largefont_xft);
get_resources()->use_xft = 0;
exit(1);
}
+// _XftDisplayInfo needs a lock.
+ xftDefaultHasRender(display);
+xft_init_lock.unlock();
#endif // HAVE_XFT
}
{
switch(cursor)
{
- case ARROW_CURSOR: return top_level->arrow_cursor; break;
+ case ARROW_CURSOR: return top_level->arrow_cursor;
case CROSS_CURSOR: return top_level->cross_cursor;
- case IBEAM_CURSOR: return top_level->ibeam_cursor; break;
- case VSEPARATE_CURSOR: return top_level->vseparate_cursor; break;
- case HSEPARATE_CURSOR: return top_level->hseparate_cursor; break;
- case MOVE_CURSOR: return top_level->move_cursor; break;
- case LEFT_CURSOR: return top_level->left_cursor; break;
- case RIGHT_CURSOR: return top_level->right_cursor; break;
- case UPRIGHT_ARROW_CURSOR: return top_level->upright_arrow_cursor; break;
- case UPLEFT_RESIZE: return top_level->upleft_resize_cursor; break;
- case UPRIGHT_RESIZE: return top_level->upright_resize_cursor; break;
- case DOWNLEFT_RESIZE: return top_level->downleft_resize_cursor; break;
- case DOWNRIGHT_RESIZE: return top_level->downright_resize_cursor; break;
- case HOURGLASS_CURSOR: return top_level->hourglass_cursor; break;
- case TRANSPARENT_CURSOR: return top_level->transparent_cursor; break;
+ case IBEAM_CURSOR: return top_level->ibeam_cursor;
+ case VSEPARATE_CURSOR: return top_level->vseparate_cursor;
+ case HSEPARATE_CURSOR: return top_level->hseparate_cursor;
+ case MOVE_CURSOR: return top_level->move_cursor;
+ case LEFT_CURSOR: return top_level->left_cursor;
+ case RIGHT_CURSOR: return top_level->right_cursor;
+ case UPRIGHT_ARROW_CURSOR: return top_level->upright_arrow_cursor;
+ case UPLEFT_RESIZE: return top_level->upleft_resize_cursor;
+ case UPRIGHT_RESIZE: return top_level->upright_resize_cursor;
+ case DOWNLEFT_RESIZE: return top_level->downleft_resize_cursor;
+ case DOWNRIGHT_RESIZE: return top_level->downright_resize_cursor;
+ case HOURGLASS_CURSOR: return top_level->hourglass_cursor;
+ case TRANSPARENT_CURSOR: return top_level->transparent_cursor;
+ case GRABBED_CURSOR: return top_level->grabbed_cursor;
}
return 0;
}
case MEDIUMFONT: return top_level->mediumfont; break;
case LARGEFONT: return top_level->largefont; break;
case BIGFONT: return top_level->bigfont; break;
+ case CLOCKFONT: return top_level->clockfont; break;
}
return 0;
}
case MEDIUMFONT: fs = top_level->mediumfontset; break;
case LARGEFONT: fs = top_level->largefontset; break;
case BIGFONT: fs = top_level->bigfontset; break;
+ case CLOCKFONT: fs = top_level->clockfontset; break;
}
}
case MEDIUMFONT: return (XftFont*)top_level->mediumfont_xft;
case LARGEFONT: return (XftFont*)top_level->largefont_xft;
case BIGFONT: return (XftFont*)top_level->bigfont_xft;
+ case CLOCKFONT: return (XftFont*)top_level->clockfont_xft;
case MEDIUMFONT_3D: return (XftFont*)top_level->bold_mediumfont_xft;
case SMALLFONT_3D: return (XftFont*)top_level->bold_smallfont_xft;
case LARGEFONT_3D: return (XftFont*)top_level->bold_largefont_xft;
#endif
-
-
-
-
-
-
-
int BC_WindowBase::get_current_font()
{
return top_level->current_font;
case MEDIUMFONT: fs = top_level->mediumfontset; break;
case LARGEFONT: fs = top_level->largefontset; break;
case BIGFONT: fs = top_level->bigfontset; break;
+ case CLOCKFONT: fs = top_level->clockfontset; break;
}
}
#ifdef X_HAVE_UTF8_STRING
if(get_resources()->locale_utf8)
{
- XftTextExtentsUtf8(top_level->display,
+ xftTextExtentsUtf8(top_level->display,
get_xft_struct(font),
(const XftChar8 *)text,
length,
else
#endif
{
- XftTextExtents8(top_level->display,
+ xftTextExtents8(top_level->display,
get_xft_struct(font),
(const XftChar8 *)text,
length,
}
}
-int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length)
-{
-#ifdef HAVE_XFT
- if(get_resources()->use_xft && get_xft_struct(font)) {
- XGlyphInfo extents;
-
- XftTextExtents32(top_level->display, get_xft_struct(font),
- (const FcChar32*)text, length, &extents);
- return extents.xOff;
- }
-#endif
- if(!get_font_struct(font)) return 0;
- XChar2b xtext[length], *xp = xtext;
- for( int i=0; i<length; ++i,++xp ) {
- xp->byte1 = (unsigned char) (text[i] >> 8);
- xp->byte2 = (unsigned char) (text[i] & 0xff);
- }
- return XTextWidth16(get_font_struct(font), xtext, length);
-}
-
int BC_WindowBase::get_text_width(int font, const char *text, int length)
{
int i, j, w = 0, line_w = 0;
this->grab_active = 0;
return 1;
}
+int BC_WindowBase::grab_event_count()
+{
+ int result = 0;
+#ifndef SINGLE_THREAD
+ result = grab_active->get_event_count();
+#endif
+ return result;
+}
int BC_WindowBase::grab_buttons()
{
XSync(top_level->display, False);
if( XGrabButton(top_level->display, AnyButton, AnyModifier,
top_level->rootwin, True, ButtonPressMask | ButtonReleaseMask,
- GrabModeAsync, GrabModeSync, None, grabbed_cursor) == GrabSuccess ) {
+ GrabModeAsync, GrabModeSync, None, None) == GrabSuccess ) {
set_active_subwindow(this);
return 0;
}
}
void BC_WindowBase::grab_cursor()
{
- XDefineCursor(top_level->display, top_level->rootwin, grabbed_cursor);
+ Cursor cursor_grab = get_cursor_struct(GRABBED_CURSOR);
+ XGrabPointer(top_level->display, top_level->rootwin, True,
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync, None, cursor_grab, CurrentTime);
}
void BC_WindowBase::ungrab_cursor()
{
- XUndefineCursor(top_level->display, top_level->rootwin);
+ XUngrabPointer(top_level->display, CurrentTime);
}
// for get_root_w/h
return 0;
}
int top_x = get_x(), top_y = get_y();
+ if( BC_DisplayInfo::left_border >= 0 ) top_x += BC_DisplayInfo::left_border;
+ if( BC_DisplayInfo::top_border >= 0 ) top_y += BC_DisplayInfo::top_border;
for( int i=0; i<xinerama_screens; ++i ) {
int scr_y = top_y - xinerama_info[i].y_org;
if( scr_y < 0 || scr_y >= xinerama_info[i].height ) continue;
return 0;
}
+void BC_WindowBase::get_fullscreen_geometry(int &wx, int &wy, int &ww, int &wh)
+{
+ XineramaScreenInfo *info = top_level->get_xinerama_info(-1);
+ if( info ) {
+ wx = info->x_org; wy = info->y_org;
+ ww = info->width; wh = info->height;
+ }
+ else {
+ wx = get_screen_x(0, -1);
+ wy = get_screen_y(0, -1);
+ int scr_w0 = get_screen_w(0, 0);
+ int root_w = get_root_w(0);
+ int root_h = get_root_h(0);
+ if( root_w > scr_w0 ) { // multi-headed
+ if( wx >= scr_w0 ) {
+ // assumes right side is the big one
+ ww = root_w - scr_w0;
+ wh = root_h;
+ }
+ else {
+ // use same aspect ratio to compute left height
+ ww = scr_w0;
+ wh = (w*root_h) / (root_w-scr_w0);
+ }
+ }
+ else {
+ ww = root_w;
+ wh = root_h;
+ }
+ }
+}
+
int BC_WindowBase::get_screen_x(int lock_display, int screen)
{
int result = -1;
#endif
}
-void BC_WindowBase::get_relative_cursor_xy(int &x, int &y, int lock_window)
+Atom BC_WindowBase::to_clipboard(const char *data, long len, int clipboard_num)
+{
+ return get_clipboard()->to_clipboard(this, data, len, clipboard_num);
+}
+
+long BC_WindowBase::from_clipboard(char *data, long maxlen, int clipboard_num)
+{
+ return get_clipboard()->from_clipboard(data, maxlen, clipboard_num);
+}
+
+long BC_WindowBase::clipboard_len(int clipboard_num)
+{
+ return get_clipboard()->clipboard_len(clipboard_num);
+}
+
+int BC_WindowBase::do_selection_clear(Window win)
+{
+ top_level->event_win = win;
+ return dispatch_selection_clear();
+}
+
+int BC_WindowBase::dispatch_selection_clear()
+{
+ int result = 0;
+ for( int i=0; i<subwindows->total && !result; ++i )
+ result = subwindows->values[i]->dispatch_selection_clear();
+ if( !result )
+ result = selection_clear_event();
+ return result;
+}
+
+
+void BC_WindowBase::get_relative_cursor(int &x, int &y, int lock_window)
{
int abs_x, abs_y, win_x, win_y;
unsigned int temp_mask;
Window temp_win;
- if(lock_window) this->lock_window("BC_WindowBase::get_relative_cursor_xy");
+ if(lock_window) this->lock_window("BC_WindowBase::get_relative_cursor");
XQueryPointer(top_level->display, top_level->win,
&temp_win, &temp_win, &abs_x, &abs_y, &win_x, &win_y,
&temp_mask);
int BC_WindowBase::get_relative_cursor_x(int lock_window)
{
int x, y;
- get_relative_cursor_xy(x, y, lock_window);
+ get_relative_cursor(x, y, lock_window);
return x;
}
int BC_WindowBase::get_relative_cursor_y(int lock_window)
{
int x, y;
- get_relative_cursor_xy(x, y, lock_window);
+ get_relative_cursor(x, y, lock_window);
return y;
}
-void BC_WindowBase::get_abs_cursor_xy(int &abs_x, int &abs_y, int lock_window)
+void BC_WindowBase::get_abs_cursor(int &abs_x, int &abs_y, int lock_window)
{
int win_x, win_y;
unsigned int temp_mask;
Window temp_win;
- if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor_xy");
+ if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor");
XQueryPointer(top_level->display, top_level->win,
&temp_win, &temp_win, &abs_x, &abs_y, &win_x, &win_y,
&temp_mask);
int BC_WindowBase::get_abs_cursor_x(int lock_window)
{
int abs_x, abs_y;
- get_abs_cursor_xy(abs_x, abs_y, lock_window);
+ get_abs_cursor(abs_x, abs_y, lock_window);
return abs_x;
}
int BC_WindowBase::get_abs_cursor_y(int lock_window)
{
int abs_x, abs_y;
- get_abs_cursor_xy(abs_x, abs_y, lock_window);
+ get_abs_cursor(abs_x, abs_y, lock_window);
return abs_y;
}
-void BC_WindowBase::get_pop_cursor_xy(int &px, int &py, int lock_window)
+void BC_WindowBase::get_pop_cursor(int &px, int &py, int lock_window)
{
int margin = 100;
- get_abs_cursor_xy(px, py, lock_window);
+ get_abs_cursor(px, py, lock_window);
if( px < margin ) px = margin;
if( py < margin ) py = margin;
int wd = get_screen_w(lock_window,-1) - margin;
int BC_WindowBase::get_pop_cursor_x(int lock_window)
{
int px, py;
- get_pop_cursor_xy(px, py, lock_window);
+ get_pop_cursor(px, py, lock_window);
return px;
}
int BC_WindowBase::get_pop_cursor_y(int lock_window)
{
int px, py;
- get_pop_cursor_xy(px, py, lock_window);
+ get_pop_cursor(px, py, lock_window);
return py;
}
int BC_WindowBase::get_cursor_over_window()
{
- if(top_level != this) return top_level->get_cursor_over_window();
-
int abs_x, abs_y, win_x, win_y;
- unsigned int temp_mask;
+ unsigned int mask_return;
Window root_return, child_return;
- int ret = XQueryPointer(display, win,
+ int ret = XQueryPointer(top_level->display, top_level->rootwin,
&root_return, &child_return, &abs_x, &abs_y,
- &win_x, &win_y, &temp_mask);
-//printf("BC_WindowBase::get_cursor_over_window %d %s 0x%x %d 0x%x\n",
-// __LINE__, title, win, ret, child_return);
-
- int result = !ret || child_return == None ? 0 :
- match_window(child_return);
- return result;
+ &win_x, &win_y, &mask_return);
+ if( ret && child_return == None ) ret = 0;
+ if( ret && win != child_return )
+ ret = top_level->match_window(child_return);
+// query pointer can return a window manager window with this top_level as a child
+// for kde this can be two levels deep
+ unsigned int nchildren_return = 0;
+ Window parent_return, *children_return = 0;
+ Window top_win = top_level->win;
+ while( !ret && top_win != top_level->rootwin && top_win != root_return &&
+ XQueryTree(top_level->display, top_win, &root_return,
+ &parent_return, &children_return, &nchildren_return) ) {
+ if( children_return ) XFree(children_return);
+ if( (top_win=parent_return) == child_return ) ret = 1;
+ }
+ return ret;
}
int BC_WindowBase::cursor_above()
{
int rx, ry;
- get_relative_cursor_xy(rx, ry);
+ get_relative_cursor(rx, ry);
return rx < 0 || rx >= get_w() ||
ry < 0 || ry >= get_h() ? 0 : 1;
}
*cp = 0;
}
-void BC_WindowBase::set_title(const char *text)
-{
- put_title(_(text));
-
- char *txlist[2];
- txlist[0] = this->title;
- txlist[1] = 0;
-
- XTextProperty titleprop;
- XmbTextListToTextProperty(top_level->display, txlist, 1,
- XStdICCTextStyle, &titleprop);
- XSetWMName(top_level->display, top_level->win, &titleprop);
- XSetWMIconName(top_level->display, top_level->win, &titleprop);
- XFree(titleprop.value);
-
- flush();
-}
-
-void BC_WindowBase::set_utf8title(const char *text)
-{
- XTextProperty titleprop;
- char *txlist[2];
-
- strcpy(this->title, text);
- txlist[0] = this->title;
- txlist[1] = 0;
-
- Xutf8TextListToTextProperty(top_level->display, txlist, 1,
- XUTF8StringStyle, &titleprop);
- XSetWMName(top_level->display, top_level->win, &titleprop);
- XSetWMIconName(top_level->display, top_level->win, &titleprop);
- XFree(titleprop.value);
-
+void BC_WindowBase::set_title(const char *text, int utf8)
+{
+// utf8>0: wm + net_wm, utf8=0: wm only, utf<0: net_wm only
+ put_title(text);
+ const unsigned char *wm_title = (const unsigned char *)title;
+ int title_len = strlen((const char *)title);
+ if( utf8 >= 0 ) {
+ Atom xa_wm_name = XA_WM_NAME;
+ Atom xa_icon_name = XA_WM_ICON_NAME;
+ Atom xa_string = XA_STRING;
+ XChangeProperty(display, win, xa_wm_name, xa_string, 8,
+ PropModeReplace, wm_title, title_len);
+ XChangeProperty(display, win, xa_icon_name, xa_string, 8,
+ PropModeReplace, wm_title, title_len);
+ }
+ if( utf8 != 0 ) {
+ Atom xa_net_wm_name = XInternAtom(display, "_NET_WM_NAME", True);
+ Atom xa_net_icon_name = XInternAtom(display, "_NET_WM_ICON_NAME", True);
+ Atom xa_utf8_string = XInternAtom(display, "UTF8_STRING", True);
+ XChangeProperty(display, win, xa_net_wm_name, xa_utf8_string, 8,
+ PropModeReplace, wm_title, title_len);
+ XChangeProperty(display, win, xa_net_icon_name, xa_utf8_string, 8,
+ PropModeReplace, wm_title, title_len);
+ }
flush();
}
resources->filebox_columnwidth[1] = defaults->get("FILEBOX_WIDTH1", resources->filebox_columnwidth[1]);
resources->filebox_columnwidth[2] = defaults->get("FILEBOX_WIDTH2", resources->filebox_columnwidth[2]);
resources->filebox_columnwidth[3] = defaults->get("FILEBOX_WIDTH3", resources->filebox_columnwidth[3]);
+ resources->filebox_size_format = defaults->get("FILEBOX_SIZE_FORMAT", get_resources()->filebox_size_format);
defaults->get("FILEBOX_FILTER", resources->filebox_filter);
return 0;
}
defaults->update("FILEBOX_WIDTH2", resources->filebox_columnwidth[2]);
defaults->update("FILEBOX_WIDTH3", resources->filebox_columnwidth[3]);
defaults->update("FILEBOX_FILTER", resources->filebox_filter);
+ defaults->update("FILEBOX_SIZE_FORMAT", get_resources()->filebox_size_format);
return 0;
}
event_lock->unlock();
}
+int BC_WindowBase::resend_event(BC_WindowBase *window)
+{
+ if( resend_event_window ) return 1;
+ resend_event_window = window;
+ return 0;
+}
+
+#else
+
+int BC_WindowBase::resend_event(BC_WindowBase *window)
+{
+ return 1;
+}
+
#endif // SINGLE_THREAD
int BC_WindowBase::get_id()