From 12f9af62b82bbb86fdfbfe73d92e8b3e2fb7dd56 Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Tue, 18 Jan 2022 02:49:28 +0100 Subject: [PATCH] reverted xcb since text quality is slightly better --- config.h.in | 3 ++ scconfig/hooks.c | 38 +++++++++++++++++++- src/globals.c | 7 ++++ src/scheduler.c | 3 ++ src/xinit.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ src/xschem.h | 17 +++++++++ 6 files changed, 157 insertions(+), 1 deletion(-) diff --git a/config.h.in b/config.h.in index 1a5105dc..10f2be67 100644 --- a/config.h.in +++ b/config.h.in @@ -23,6 +23,9 @@ print [@/*************************************************************/ print {\n\n/* Define this var if cairo is available and is to be used */\n} print_ternary ?libs/gui/cairo/presents {#define HAS_CAIRO 1} {/*#undef HAS_CAIRO */} +print {\n\n/* Define this var if Xlib's xcb is available */\n} +print_ternary ?libs/gui/xcb/presents {#define HAS_XCB 1} {/*#undef HAS_XCB */} + print {\n\n/* Define this var if Xlib's xrender is available */\n} print_ternary ?libs/gui/xrender/presents {#define HAS_XRENDER 1} {/*#undef HAS_RENDER */} diff --git a/scconfig/hooks.c b/scconfig/hooks.c index 335ee32f..3e9643ae 100644 --- a/scconfig/hooks.c +++ b/scconfig/hooks.c @@ -164,6 +164,21 @@ int hook_detect_host() return 0; } +static void disable_xcb(void) +{ + put("libs/gui/xcb/presents", ""); + put("libs/gui/xcb/includes", ""); + put("libs/gui/xcb/cflags", ""); + put("libs/gui/xcb/ldflags", ""); + put("libs/gui/xcb_render/presents", ""); + put("libs/gui/xcb_render/includes", ""); + put("libs/gui/xcb_render/cflags", ""); + put("libs/gui/xcb_render/ldflags", ""); + put("libs/gui/xgetxcbconnection/presents", ""); + put("libs/gui/xgetxcbconnection/includes", ""); + put("libs/gui/xgetxcbconnection/cflags", ""); + put("libs/gui/xgetxcbconnection/ldflags", ""); +} /* Runs when things should be detected for the host->target system (commands that will be executed on host but will produce files to be used on target) */ @@ -227,11 +242,31 @@ int hook_detect_target() require("libs/io/dup2/*", 0, 0); /* Stefan: query dup2() availability */ require("parsgen/flex/presents", 0, 1); require("parsgen/bison/presents", 0, 1); - require("libs/script/tk/*", 0, 1); /* this will also bring libs/script/tcl */ + require("libs/script/tk/*", 0, 1); /* this will also bring libs/script/tcl/* */ require("fstools/awk", 0, 1); require("libs/gui/xpm/*", 0, 1); require("libs/gui/cairo/*", 0, 0); require("libs/gui/xrender/*", 0, 0); + + if (require("libs/gui/cairo-xcb/*", 0, 0) != 0) { + put("libs/gui/xcb/presents", sfalse); + } + else if (require("libs/gui/xcb/*", 0, 0) == 0) { + /* if xcb is used, the code requires these: */ + require("libs/gui/xgetxcbconnection/*", 0, 0); + if (!istrue(get("libs/gui/xgetxcbconnection/presents"))) { + report("Disabling xcb because xgetxcbconnection is not found...\n"); + disable_xcb(); + } + else { + require("libs/gui/xcb_render/*", 0, 0); + if (!istrue(get("libs/gui/xcb_render/presents"))) { + report("Disabling xcb because xcb_render is not found...\n"); + disable_xcb(); + } + } + } + return 0; } @@ -281,6 +316,7 @@ int hook_generate() printf(" tk: %s\n", get("/target/libs/script/tk/ldflags")); printf(" cairo: %s\n", istrue(get("/target/libs/gui/cairo/presents")) ? "yes" : "no"); printf(" xrender: %s\n", istrue(get("/target/libs/gui/xrender/presents")) ? "yes" : "no"); + printf(" xcb: %s\n", istrue(get("/target/libs/gui/xcb/presents")) ? "yes" : "no"); printf("\nConfiguration complete, ready to compile.\n\n"); } diff --git a/src/globals.c b/src/globals.c index 1c0e892f..55d41189 100644 --- a/src/globals.c +++ b/src/globals.c @@ -130,6 +130,13 @@ Visual *visual; XRenderPictFormat *render_format; #endif +#if HAS_XCB==1 +xcb_connection_t *xcbconn; +xcb_render_pictforminfo_t format_rgb, format_rgba; +xcb_screen_t *screen_xcb; +xcb_visualtype_t *visual_xcb; +#endif /*HAS_XCB */ + /* ---------------------------------------------- */ /* These variables are mirrored in tcl code */ /* ---------------------------------------------- */ diff --git a/src/scheduler.c b/src/scheduler.c index 8b23229a..f6b85870 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1152,6 +1152,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg #ifdef HAS_CAIRO my_snprintf(res, S(res), "HAS_CAIRO=%d\n", HAS_CAIRO); Tcl_AppendResult(interp, res, NULL); #endif + #ifdef HAS_XCB + my_snprintf(res, S(res), "HAS_XCB=%d\n", HAS_XCB); Tcl_AppendResult(interp, res, NULL); + #endif #ifdef XSCHEM_SHAREDIR my_snprintf(res, S(res), "XSCHEM_SHAREDIR=%s\n", XSCHEM_SHAREDIR); Tcl_AppendResult(interp, res, NULL); #endif diff --git a/src/xinit.c b/src/xinit.c index 5533e640..a859a18e 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -871,6 +871,28 @@ void tclexit(ClientData s) if(init_done) xwin_exit(); } +#if HAS_XCB==1 +/* from xcb.freedesktop.org -- don't ask me what it does... 20171125 */ +static xcb_visualtype_t *find_visual(xcb_connection_t *xcbconn, xcb_visualid_t visual) +{ + xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(xcbconn)); + + for (; screen_iter.rem; xcb_screen_next(&screen_iter)) { + xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen_iter.data); + for (; depth_iter.rem; xcb_depth_next(&depth_iter)) { + xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data); + for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) { + if (visual == visual_iter.data->visual_id) { + return visual_iter.data; + } + } + } + } + + return NULL; +} +#endif /*HAS_XCB */ + int source_tcl_file(char *s) { char tmp[1024]; @@ -1488,8 +1510,13 @@ void resetcairo(int create, int clear, int force_or_resize) if(create && force_or_resize) { /***** Create Cairo save buffer drawing area *****/ #if HAS_XRENDER==1 + #if HAS_XCB==1 + xctx->cairo_save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap, + &format_rgb, xctx->xrect[0].width, xctx->xrect[0].height); + #else xctx->cairo_save_sfc = cairo_xlib_surface_create_with_xrender_format(display, xctx->save_pixmap, DefaultScreenOfDisplay(display), render_format, xctx->xrect[0].width, xctx->xrect[0].height); + #endif /* HAS_XCB */ #else xctx->cairo_save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, xctx->xrect[0].width, xctx->xrect[0].height); @@ -1506,9 +1533,15 @@ void resetcairo(int create, int clear, int force_or_resize) cairo_set_line_cap(xctx->cairo_save_ctx, CAIRO_LINE_CAP_ROUND); /***** Create Cairo main drawing window structures *****/ #if HAS_XRENDER==1 + #if HAS_XCB==1 + dbg(1, "create_cairo_surface: w=%d, h=%d\n", xctx->xrect[0].width, xctx->xrect[0].height); + xctx->cairo_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, + screen_xcb, xctx->window, &format_rgb, xctx->xrect[0].width, xctx->xrect[0].height); + #else xctx->cairo_sfc = cairo_xlib_surface_create_with_xrender_format (display, xctx->window, DefaultScreenOfDisplay(display), render_format, xctx->xrect[0].width, xctx->xrect[0].height); + #endif /* HAS_XCB */ #else xctx->cairo_sfc = cairo_xlib_surface_create(display, xctx->window, visual, xctx->xrect[0].width, xctx->xrect[0].height); @@ -1523,6 +1556,13 @@ void resetcairo(int create, int clear, int force_or_resize) cairo_set_line_width(xctx->cairo_ctx, 1); cairo_set_line_join(xctx->cairo_ctx, CAIRO_LINE_JOIN_ROUND); cairo_set_line_cap(xctx->cairo_ctx, CAIRO_LINE_CAP_ROUND); + #if 0 + * #if HAS_XCB==1 && HAS_XRENDER==1 + * cairo_xcb_surface_set_size(xctx->cairo_sfc, xctx->xrect[0].width, xctx->xrect[0].height); + * #else + * cairo_xlib_surface_set_size(xctx->cairo_sfc, xctx->xrect[0].width, xctx->xrect[0].height); + * #endif /* HAS_XCB && HAS_XRENDER */ + #endif } #endif /* HAS_CAIRO */ } @@ -1624,6 +1664,15 @@ int Tcl_AppInit(Tcl_Interp *inter) int running_in_src_dir; int fs; + /* XVisualInfo vinfo; */ + #if HAS_XCB==1 + #if HAS_XRENDER==1 + xcb_render_query_pict_formats_reply_t *formats_reply; + xcb_render_pictforminfo_t *formats; + xcb_render_query_pict_formats_cookie_t formats_cookie; + #endif + #endif + /* get PWD and HOME */ if(!getcwd(pwd_dir, PATH_MAX)) { fprintf(errfp, "Tcl_AppInit(): getcwd() failed\n"); @@ -2026,6 +2075,47 @@ int Tcl_AppInit(Tcl_Interp *inter) dbg(1, "Tcl_AppInit(): top window ID=0x%lx\n",topwindow); dbg(1, "Tcl_AppInit(): done tkinit()\n"); + #if HAS_XCB==1 + /* grab an existing xlib connection 20171125 */ + xcbconn = XGetXCBConnection(display); + if(xcb_connection_has_error(xcbconn)) { + fprintf(errfp, "Could not connect to X11 server"); + return 1; + } + screen_xcb = xcb_setup_roots_iterator(xcb_get_setup(xcbconn)).data; + visual_xcb = find_visual(xcbconn, screen_xcb->root_visual); + if(!visual_xcb) { + fprintf(errfp, "got NULL (xcb_visualtype_t)visual"); + return 1; + } + #if HAS_XRENDER==1 + /*/--------------------------Xrender xcb stuff------- */ + formats_cookie = xcb_render_query_pict_formats(xcbconn); + formats_reply = xcb_render_query_pict_formats_reply(xcbconn, formats_cookie, 0); + + formats = xcb_render_query_pict_formats_formats(formats_reply); + for (i = 0; i < formats_reply->num_formats; i++) { + /* fprintf(errfp, "i=%d depth=%d type=%d red_shift=%d\n", i, + formats[i].depth, formats[i].type, formats[i].direct.red_shift); */ + if (formats[i].direct.red_mask != 0xff && + formats[i].direct.red_shift != 16) + continue; + if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT && + formats[i].depth == 24 && formats[i].direct.red_shift == 16) + format_rgb = formats[i]; + if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT && + formats[i].depth == 32 && + formats[i].direct.alpha_mask == 0xff && + formats[i].direct.alpha_shift == 24) + format_rgba = formats[i]; + } + free(formats_reply); /* can not use my_free() since not allocated by my_* allocator wrappers */ + formats_reply = NULL; + #endif /* HAS_XRENDER */ + /*/---------------------------------------------------- */ + /* /20171125 */ + #endif /*HAS_XCB */ + screen_number = Tk_ScreenNumber(mainwindow); colormap = Tk_Colormap(mainwindow); screendepth = Tk_Depth(mainwindow); diff --git a/src/xschem.h b/src/xschem.h index 071e84e0..c34fb90a 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -104,11 +104,19 @@ extern char win_temp_dir[PATH_MAX]; #define xftell _ftelli64 #endif +#if HAS_XCB==1 +#include +#include +#endif #if HAS_CAIRO==1 #include #include #include "cairo-xlib-xrender.h" + +#if HAS_XCB==1 +#include +#endif #endif #include @@ -938,6 +946,15 @@ extern Visual *visual; #if HAS_XRENDER==1 extern XRenderPictFormat *render_format; #endif +#if HAS_XCB==1 +extern xcb_connection_t *xcbconn; +extern xcb_screen_t *screen_xcb; +#if HAS_XRENDER==1 +extern xcb_render_pictforminfo_t format_rgb, format_rgba; +#endif +extern xcb_visualtype_t *visual_xcb; +#endif /* HAS_XCB */ + /*********** These variables are mirrored in tcl code ***********/ extern int cadlayers; extern int has_x;