📄 bcwindow.c
字号:
#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <math.h>#include "bccolors.h"#include "bckeys.h"#include "bcmenubar.h"#include "bcpopupmenu.h"#include "bcwindow.h"BC_Window::BC_Window(char *display_name, int color, char *title, int w, int h, int minw, int minh, int private_color, int hide) : BC_WindowBase(0, 0, w, h, color){// initialize flags ctrl_mask = shift_mask = button_pressed = key_pressed = key_sym = resized = 0; done = 0; button_down = double_click = cursorleft = button_just_released = 0; button_time1 = button_time2 = 0; motion_buffer = 0; repeat_buffer = 0; last_deleted_window = motion_buffer_win = 0; active_menubar = 0; active_tool = 0; active_popup_menu = 0; last_w = w; last_h = h; repeat = 0; this->hidden = hide;// This function must be the first Xlib// function a multi-threaded program calls XInitThreads(); this->private_color = private_color; if(display_name && display_name[0] == 0) display_name = NULL; if ( (display=XOpenDisplay(display_name)) == NULL ) { printf("cannot connect to X server\n"); if (getenv("DISPLAY") == NULL) printf("'DISPLAY' environment variable not set.\n"); exit ( -1 ); } screen = DefaultScreen(display); rootwin = RootWindow(display, screen); vis = DefaultVisual(display, screen); init_colors(); init_fonts();// ==================================== build the window unsigned long gcmask; gcmask = GCFont | GCGraphicsExposures; XGCValues gcvalues; gcvalues.font = largefont->fid; // set the font gcvalues.graphics_exposures = 0; // prevent expose events for every redraw gc = XCreateGC(display, rootwin, gcmask, &gcvalues); XSetWindowAttributes attr; unsigned long mask; Cursor arrow; XSizeHints size_hints; arrow = XCreateFontCursor(display, XC_top_left_arrow); mask = CWBackingStore | CWEventMask | CWBackPixel | CWBorderPixel | CWColormap | CWCursor | CWOverrideRedirect | CWSaveUnder; attr.event_mask = LeaveWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | KeyPressMask | PointerMotionMask | FocusChangeMask; attr.background_pixel = get_color(color); attr.border_pixel = get_color(color); attr.colormap = cmap; attr.cursor = arrow; attr.override_redirect = False; attr.save_under = False; attr.backing_store = Always; win = XCreateWindow(display, rootwin, 0, 0, w, h, 0, depth, InputOutput, vis, mask, &attr); size_hints.flags = PSize | PMinSize | PMaxSize; size_hints.width = w; size_hints.height = h; size_hints.min_width = minw; if(minw == w) size_hints.max_width = w; else size_hints.max_width = 32767; size_hints.min_height = minh; if(minh == h) size_hints.max_height = h; else size_hints.max_height = 32767; XSetStandardProperties(display, win, title, title, None, 0, 0, &size_hints);// =============================== fix close button DelWinXAtom = XInternAtom(display, "WM_DELETE_WINDOW", False); if(ProtoXAtom = XInternAtom(display, "WM_PROTOCOLS", False)) XChangeProperty(display, win, ProtoXAtom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&DelWinXAtom, True );// show the window if(!hide) show_window(); XFlush(display);// ======================== fix threading//unlock_window();}BC_Window::~BC_Window(){ // base class deletes everything since it's the last destructor called}// ================================== color tableBC_Window::init_fonts(){ if ((titlefont = XLoadQueryFont(display, "-*-helvetica-bold-r-normal--24-240-75-75-p-124-iso8859-1")) == NULL) { printf("Sorry, can't find helvetica font. Using fixed instead.\n"); titlefont = XLoadQueryFont(display, "fixed"); } if ((largefont = XLoadQueryFont(display, "-*-helvetica-bold-o-normal-*-14-*")) == NULL) { printf("Sorry, can't find helvetica font. Using fixed instead.\n"); largefont = XLoadQueryFont(display, "fixed"); } if ((smallfont = XLoadQueryFont(display, "-*-helvetica-medium-r-normal-*-10-*")) == NULL) { printf("Sorry, can't find helvetica font. Using fixed instead.\n"); smallfont = XLoadQueryFont(display, "fixed"); }}BC_Window::init_colors(){ total_colors = 0; current_color_value = current_color_pixel = 0; depth = DefaultDepth(display, screen); switch(depth) { case 8: if(private_color) { cmap = XCreateColormap(display, rootwin, vis, AllocNone); create_private_colors(); } else { cmap = DefaultColormap(display, screen); create_shared_colors(); } allocate_color_table(); break; default: cmap = DefaultColormap(display, screen); break; }}BC_Window::create_private_colors(){ int color; total_colors = 256; for(int i = 0; i < 255; i++) { color = (i & 0xc0) << 16; color += (i & 0x38) << 10; color += (i & 0x7) << 5; color_table[i][0] = color; } create_shared_colors(); // overwrite the necessary colors on the table}BC_Window::create_color(int color){ if(total_colors == 256) {// replace the closest match with an exact match color_table[get_color_8(color)][0] = color; } else {// add the color to the table color_table[total_colors][0] = color; total_colors++; }}BC_Window::create_shared_colors(){ create_color(BLACK); create_color(WHITE); create_color(LTGREY); create_color(MEGREY); create_color(MDGREY); create_color(DKGREY); create_color(LTCYAN); create_color(MECYAN); create_color(MDCYAN); create_color(DKCYAN); create_color(LTGREEN); create_color(GREEN); create_color(DKGREEN); create_color(LTPINK); create_color(PINK); create_color(RED); create_color(LTBLUE); create_color(BLUE); create_color(DKBLUE); create_color(LTYELLOW); create_color(MEYELLOW); create_color(MDYELLOW); create_color(DKYELLOW); create_color(LTPURPLE); create_color(MEPURPLE); create_color(MDPURPLE); create_color(DKPURPLE); }BC_Window::allocate_color_table(){ int red, green, blue, color; int result; XColor col; for(int i = 0; i < total_colors; i++) { color = color_table[i][0]; red = (color & 0xFF0000) >> 16; green = (color & 0x00FF00) >> 8; blue = color & 0xFF; col.flags = DoRed | DoGreen | DoBlue; col.red = red<<8 | red; col.green = green<<8 | green; col.blue = blue<<8 | blue; XAllocColor(display, cmap, &col); color_table[i][1] = col.pixel;//printf("BC_Window::allocate_color_table %x %x %x %d\n", col.red, col.green, col.blue, color_table[i][1]); //if(!) //{ // cmap = XCopyColormapAndFree(display, cmap); // XAllocColor(display, cmap, &Col); //} } XInstallColormap(display, cmap);}BC_Window::get_color(long color) {// return pixel of color// use this only for drawing tools not for bitmaps int i, test, difference, result; if(depth <= 8) { if(private_color) { return get_color_8(color); } else {// test last color looked up if(current_color_value == color) return current_color_pixel;// look up in table current_color_value = color; for(i = 0; i < total_colors; i++) { if(color_table[i][0] == color) { current_color_pixel = color_table[i][1];//printf("BC_Window::get_color %x %d\n", color, current_color_pixel); return current_color_pixel; } }// find nearest match difference = 0xFFFFFF; for(i = 0, result = 0; i < total_colors; i++) { test = abs((int)(color_table[i][0] - color)); if(test < difference) { current_color_pixel = color_table[i][1]; difference = test; } } return current_color_pixel; } } else switch(depth){ case 16: return get_color_16(color); break; case 24: return color; break; default: return color; break; } return color;}BC_Window::get_color_8(int color){ int pixel; pixel = (color & 0xc00000) >> 16; pixel += (color & 0xe000) >> 10; pixel += (color & 0xe0) >> 5; return pixel;}long BC_Window::get_color_16(int color){ long result; result = (color & 0xf80000) >> 8; result += (color & 0xfc00) >> 5; result += (color & 0xf8) >> 3; return result;}// =========================== initializationBC_Tool* BC_Window::add_tool(BC_Tool *tool){ if(!top_level) top_level = this; BC_WindowBase::add_tool(tool);}BC_Window::add_border(int light, int medium, int dark){ if(!top_level) top_level = this; BC_WindowBase::add_border(light, medium, dark);}BC_SubWindow* BC_Window::add_subwindow(BC_SubWindow* subwindow){ if(!top_level) top_level = this; BC_WindowBase::add_subwindow(subwindow);}// =========================== event dispatchingBC_Window::run_window(){// initialize final flags done = 0; // reset done flag return_value = 0; // default return value top_level = this; parent_window = this; while(!done) { dispatch_event(); } unlock_window(); return return_value;}BC_Window::dispatch_event(){ static XEvent report, report2; static Window tempwin; static int repeat_next_event; // for clearing motion notifies static int button_x, button_y; static result, i; // result from a dispatch determines if event has been trapped// delay next repeat and execute repeat if// there is no active menubar// there are no waiting events// there is no motion history if(repeat && !active_menubar && !active_popup_menu && !XPending(display) && !motion_buffer) {// wait only if no repeats were skipped for events
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -