X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;ds=sidebyside;f=cinelerra-5.1%2Fguicast%2Fbcwindowbase.C;h=e861238e388e177a041b093407513421cb1ea8c9;hb=e854f4eeda320c2626780afdac9546f482de54b1;hp=0d9f95d4eede1a54100c45376e4b53a00fae282f;hpb=6ff8b339d215bb1c2cef589fd7959aa2e1834105;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 0d9f95d4..e861238e 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -624,7 +624,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title } if(!hidden) show_window(); - + init_glyphs(); } draw_background(0, 0, this->w, this->h); @@ -1261,35 +1261,8 @@ if( debug && event->type != ClientMessage ) { case XK_F10: key_pressed = KEY_F10; break; case XK_F11: key_pressed = KEY_F11; break; case XK_F12: key_pressed = KEY_F12; break; - +// activates remote case XK_Menu: key_pressed = KPMENU; break; /* menu */ -// remote control -// above case XK_KP_Enter: key_pressed = KPENTER; break; /* check */ - case XF86XK_MenuKB: key_pressed = KPMENU; break; /* menu */ -// intercepted case XF86XK_PowerDown: key_pressed = KPPOWER; break; /* Power */ - case XF86XK_Launch1: key_pressed = KPTV; break; /* TV */ - case XF86XK_Launch2: key_pressed = KPDVD; break; /* DVD */ -// intercepted case XF86XK_WWW: key_pressed = KPWWEB; break; /* WEB */ - case XF86XK_Launch3: key_pressed = KPBOOK; break; /* book */ - case XF86XK_Launch4: key_pressed = KPHAND; break; /* hand */ - case XF86XK_Reply: key_pressed = KPTMR; break; /* timer */ - case SunXK_Front: key_pressed = KPMAXW; break; /* max */ -// above case XK_Left: key_pressed = LEFT; break; /* left */ -// above case XK_Right: key_pressed = RIGHT; break; /* right */ -// above case XK_Down: key_pressed = DOWN; break; /* down */ -// above case XK_Up: key_pressed = UP; break; /* up */ -// above case XK_SPACE: key_pressed = KPSPACE; break; /* ok */ -// intercepted case XF86XK_AudioRaiseVolume: key_pressed = KPVOLU; break; /* VOL + */ -// intercepted case XF86XK_AudioMute: key_pressed = KPMUTE; break; /* MUTE */ -// intercepted case XF86XK_AudioLowerVolume: key_pressed = KPVOLD; break; /* VOL - */ - case XF86XK_ScrollUp: key_pressed = KPCHUP; break; /* CH + */ - case XF86XK_ScrollDown: key_pressed = KPCHDN; break; /* CH - */ - case XF86XK_AudioRecord: key_pressed = KPRECD; break; /* ( o) red */ - case XF86XK_Forward: key_pressed = KPPLAY; break; /* ( >) */ - case XK_Redo: key_pressed = KPFWRD; break; /* (>>) */ - case XF86XK_Back: key_pressed = KPBACK; break; /* (<<) */ - case XK_Cancel: key_pressed = KPSTOP; break; /* ([]) */ - case XK_Pause: key_pressed = KPAUSE; break; /* ('') */ default: key_pressed = keysym & 0xff; @@ -2427,6 +2400,33 @@ xft_init_lock.unlock(); #endif // HAVE_XFT } +void BC_WindowBase::init_glyphs() +{ +// draw all ascii char glyphs +// There are problems with some/my graphics boards/drivers +// which cause some glyphs to be munged if draws occur while +// the font is being loaded. This code fills the font caches +// by drawing all the ascii glyphs before the system starts. +// Not a fix, but much better than nothing. + static int inited = 0; + if( inited ) return; + XGrabServer(display); + XSync(display, 0); + inited = 1; + int cur_font = current_font; +// locale encodings, needed glyphs to be preloaded + const char *text = _( // ascii 0x20...0x7e + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~"); + for( int font=SMALLFONT; font<=LARGEFONT; ++font ) { + set_font(font); + draw_text(5,5, text, 0); + } + set_font(cur_font); + XUngrabServer(display); +} + void BC_WindowBase::init_im() { XIMStyles *xim_styles; @@ -3036,6 +3036,39 @@ int BC_WindowBase::get_text_height(int font, const char *text) return h * rowh; } +// truncate the text with ... & return a new string +char *BC_WindowBase::get_truncated_text(int font, const char *text, int max_w) +{ + char *result = cstrdup(text); + int text_w = get_text_width(font, text); + int ci = -1, len = strlen(text); + if( text_w > max_w ) { +// get center of string + int cx = text_w/2, best = INT_MAX; + for( int i=1; i<=len; ++i ) { + int cw = get_text_width(font, text, i); + if( abs(cw-cx) < abs(best-cx) ) { + best = cw; ci = i; + } + } + } + if( ci > 0 && ci < len-1 ) { +// insert ... in the center + result[ci-1] = result[ci] = result[ci+1] = '.'; + + while( ci-2>=0 && ci+2<(int)strlen(result) && + get_text_width(font, result) > max_w ) { +// take away a character from the longer side + int left_w = get_text_width(font, result, ci-2); + int right_w = get_text_width(font, result + ci+3); + int i = left_w > right_w ? --ci-1 : ci+2; + while( (result[i]=result[i+1])!=0 ) ++i; + } + } + + return result; +} + BC_Bitmap* BC_WindowBase::new_bitmap(int w, int h, int color_model) { if(color_model < 0) color_model = top_level->get_color_model(); @@ -4181,6 +4214,8 @@ void BC_WindowBase::set_force_tooltip(int v) int BC_WindowBase::raise_window(int do_flush) { + if( hidden ) return 1; + if( wait_viewable(500) ) return 1; XRaiseWindow(top_level->display, win); if(do_flush) XFlush(top_level->display); return 0; @@ -4237,6 +4272,26 @@ void BC_WindowBase::set_title(const char *text, int utf8) flush(); } +// must be RGBA8888 +void BC_WindowBase::set_net_icon(VFrame *data) +{ + int width = data->get_w(), height = data->get_h(); + int size = 2 + width * height; + unsigned long *icon_data = new unsigned long[size]; + unsigned long *lp = icon_data; + *lp++ = width; *lp++ = height; + uint8_t **rows = data->get_rows(); + for( int y=0; ydisplay, top_level->win, NetWMIcon, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)icon_data, size); + delete [] icon_data; +} + const char *BC_WindowBase::get_title() { return title; @@ -4258,27 +4313,28 @@ int BC_WindowBase::set_icon(VFrame *data) icon_pixmap = new BC_Pixmap(top_level, data, PIXMAP_ALPHA, 1); if(icon_window) delete icon_window; - icon_window = new BC_Popup(this, - (int)BC_INFINITY, - (int)BC_INFINITY, - icon_pixmap->get_w(), - icon_pixmap->get_h(), - -1, - 1, // All windows are hidden initially + icon_window = new BC_Popup(this, 0, 0, + icon_pixmap->get_w(), icon_pixmap->get_h(), + -1, 1, // All windows are hidden initially icon_pixmap); - XWMHints wm_hints; - wm_hints.flags = WindowGroupHint | IconPixmapHint | IconMaskHint | IconWindowHint; + XWMHints wm_hints; memset(&wm_hints, 0, sizeof(wm_hints)); + wm_hints.flags = IconPixmapHint; // | IconMaskHint | IconWindowHint; wm_hints.icon_pixmap = icon_pixmap->get_pixmap(); wm_hints.icon_mask = icon_pixmap->get_alpha(); wm_hints.icon_window = icon_window->win; - wm_hints.window_group = XGroupLeader; + if( XGroupLeader ) { + wm_hints.flags |= WindowGroupHint; + wm_hints.window_group = XGroupLeader; + } // for(int i = 0; i < 1000; i++) // printf("02x ", icon_pixmap->get_alpha()->get_row_pointers()[0][i]); // printf("\n"); XSetWMHints(top_level->display, top_level->win, &wm_hints); + + set_net_icon(data); XSync(top_level->display, 0); return 0; } @@ -4576,3 +4632,15 @@ void BC_WindowBase::focus() XSetInputFocus(top_level->display, top_level->win, RevertToParent, CurrentTime); } +int BC_WindowBase::wait_viewable(int ms) +{ + Timer timer; + XWindowAttributes xwa; + do { + XGetWindowAttributes(top_level->display, top_level->win, &xwa); + if( xwa.map_state == IsViewable ) return 1; + usleep(10000); + } while( timer.get_difference() < ms ); + return 0; +} +