add `Tools->Grab screen area` function (unix only)
This commit is contained in:
parent
6405ac4c09
commit
61b1c0b368
|
|
@ -122,6 +122,7 @@ LeftButton Double click Terminate Polygon placement
|
|||
- BackSpace Back to parent schematic
|
||||
- Delete Delete selected objects
|
||||
- Insert Insert element from library
|
||||
- Print Scrn Grab screen area
|
||||
- Escape Abort, redraw, unselect
|
||||
ctrl Enter Confirm closing dialog boxes
|
||||
- Down Move down
|
||||
|
|
|
|||
|
|
@ -840,6 +840,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
Return various global variables used in the program </pre>
|
||||
<li><kbd> go_back</kbd></li><pre>
|
||||
Go up one level (pop) in hierarchy </pre>
|
||||
<li><kbd> grabscreen</kbd></li><pre>
|
||||
grab root window </pre>
|
||||
<li><kbd> hash_file file [skip_path_lines]</kbd></li><pre>
|
||||
Do a simple hash of 'file'
|
||||
'skip_path_lines' is an integer (default: 0) passed to hash_file() </pre>
|
||||
|
|
@ -860,13 +862,17 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
'inst' can be an instance name or number </pre>
|
||||
<li><kbd> hilight_netname net</kbd></li><pre>
|
||||
Highlight net name 'net' </pre>
|
||||
<li><kbd> image [invert|white_transp|black_transp|transp_white|transp_black|write_back]</kbd></li><pre>
|
||||
<li><kbd> image [invert|white_transp|black_transp|transp_white|transp_black|write_back|</kbd></li><pre>
|
||||
blend_white|blend_black]
|
||||
Apply required changes to selected images
|
||||
invert: invert colors
|
||||
white_transp: transform white to transparent color (alpha=0) after invert.
|
||||
black_transp: transform black to transparent color (alpha=0) after invert.
|
||||
transp_white: transform white to transparent color (alpha=0) after invert.
|
||||
transp_black: transform black to transparent color (alpha=0) after invert.</pre>
|
||||
transp_black: transform black to transparent color (alpha=0) after invert.
|
||||
blend_white: blend with white background and remove alpha
|
||||
blend_black: blend with black background and remove alpha
|
||||
write_back: write resulting image back into `image_data` attribute</pre>
|
||||
<li><kbd> instance sym_name x y rot flip [prop] [n]</kbd></li><pre>
|
||||
Place a new instance of symbol 'sym_name' at position x,y,
|
||||
rotation and flip set to 'rot', 'flip'
|
||||
|
|
|
|||
137
src/callback.c
137
src/callback.c
|
|
@ -1736,6 +1736,130 @@ static void end_shape_point_edit()
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__unix__) && HAS_CAIRO==1
|
||||
static int grabscreen(const char *winpath, int event, int mx, int my, KeySym key,
|
||||
int button, int aux, int state)
|
||||
{
|
||||
static int grab_state = 0;
|
||||
static int x1, y1, x2, y2;
|
||||
int rmx, rmy, wmx, wmy;
|
||||
unsigned int msq;
|
||||
Window rw, cw;
|
||||
XSetWindowAttributes winattr;
|
||||
XGCValues gcv;
|
||||
static GC gc = NULL;
|
||||
static Window clientwin = 0;
|
||||
static int first_motion = 1;
|
||||
static int displayh = 0, displayw = 0;
|
||||
static unsigned long white = 0;
|
||||
|
||||
if(grab_state == 0 && event == ButtonPress && button == Button1) {
|
||||
unsigned long gcvm = GCFunction | GCForeground;
|
||||
|
||||
white = WhitePixel(display, screen_number);
|
||||
displayh = DisplayHeight(display, screen_number);
|
||||
displayw = DisplayWidth(display, screen_number);
|
||||
|
||||
XQueryPointer(display, xctx->window, &rw, &cw , &rmx, &rmy, &wmx, &wmy, &msq);
|
||||
gcv.function = GXxor;
|
||||
gcv.foreground = white;
|
||||
gc = XCreateGC(display, rw, gcvm, &gcv);
|
||||
|
||||
winattr.override_redirect = True;
|
||||
clientwin = XCreateWindow(display, rw, 0, 0, displayw, displayh, 0, screendepth,
|
||||
InputOutput, visual, CWOverrideRedirect, &winattr);
|
||||
XMapRaised(display,clientwin);
|
||||
|
||||
x1 = rmx;
|
||||
y1 = rmy;
|
||||
dbg(1, "grabscreen(): got point1: %d %d\n", x1, y1);
|
||||
grab_state = 1;
|
||||
}
|
||||
|
||||
if(grab_state == 1 && event == MotionNotify) {
|
||||
static int xx1, xx2, yy1, yy2;
|
||||
xx1 = x1; yy1 = y1; xx2 = x2; yy2 = y2;
|
||||
INT_RECTORDER(xx1, yy1, xx2, yy2);
|
||||
dbg(1, "Motion: %d %d %d %d\n", xx1, yy1, xx2, yy2);
|
||||
if(!first_motion) {
|
||||
XDrawRectangle(display, clientwin, gc, xx1 - 1, yy1 - 1, xx2 - xx1 + 2, yy2 - yy1 + 2);
|
||||
}
|
||||
first_motion = 0;
|
||||
XQueryPointer(display, xctx->window, &rw, &cw , &rmx, &rmy, &wmx, &wmy, &msq);
|
||||
x2 = xx2 = rmx;
|
||||
y2 = yy2 = rmy;
|
||||
xx1 = x1; yy1 = y1;
|
||||
INT_RECTORDER(xx1, yy1, xx2, yy2);
|
||||
XDrawRectangle(display, clientwin, gc, xx1 - 1, yy1 - 1, xx2 - xx1 + 2, yy2 - yy1 + 2);
|
||||
}
|
||||
|
||||
if(grab_state == 1 && event == ButtonRelease) {
|
||||
int grab_w = 0, grab_h = 0;
|
||||
cairo_surface_t *sfc = NULL, *subsfc = NULL;
|
||||
png_to_byte_closure_t closure;
|
||||
char *encoded_data = NULL;
|
||||
size_t olength;
|
||||
char *prop = NULL;
|
||||
grab_state = 0;
|
||||
first_motion = 1;
|
||||
xctx->ui_state &= ~GRABSCREEN;
|
||||
XQueryPointer(display, xctx->window, &rw, &cw , &rmx, &rmy, &wmx, &wmy, &msq);
|
||||
x2 = rmx;
|
||||
y2 = rmy;
|
||||
INT_RECTORDER(x1, y1, x2, y2);
|
||||
tcleval("grab release [xschem get current_win_path]");
|
||||
if(x2 - x1 > 10 && y2 -y1 > 10) {
|
||||
grab_w = (x2 - x1 + 1);
|
||||
grab_h = (y2 - y1 + 1);
|
||||
dbg(1, "grabscreen(): grab area: %d %d - %d %d\n", x1, y1, x2, y2);
|
||||
dbg(1, "grabscreen(): root w=%d, h=%d\n", displayw, displayh);
|
||||
sfc = cairo_xlib_surface_create(display, rw, visual, displayw, displayh);
|
||||
if(!sfc || cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS) {
|
||||
dbg(0, "grabscreen(): failure creating sfc\n");
|
||||
XFreeGC(display, gc);
|
||||
XDestroyWindow(display, clientwin);
|
||||
return 0;
|
||||
}
|
||||
dbg(1, "sfc: w=%d, h=%d\n",
|
||||
cairo_xlib_surface_get_width(sfc),
|
||||
cairo_xlib_surface_get_height(sfc));
|
||||
subsfc = cairo_surface_create_for_rectangle(sfc, x1, y1, grab_w, grab_h);
|
||||
if(!subsfc || cairo_surface_status(subsfc) != CAIRO_STATUS_SUCCESS) {
|
||||
dbg(0, "grabscreen(): failure creating subsfc\n");
|
||||
cairo_surface_destroy(sfc);
|
||||
XFreeGC(display, gc);
|
||||
XDestroyWindow(display, clientwin);
|
||||
return 0;
|
||||
}
|
||||
closure.buffer = NULL;
|
||||
closure.size = 0;
|
||||
closure.pos = 0;
|
||||
cairo_surface_write_to_png_stream(subsfc, png_writer, &closure);
|
||||
cairo_surface_destroy(subsfc);
|
||||
cairo_surface_destroy(sfc);
|
||||
closure.size = closure.pos;
|
||||
dbg(1, "closure.size = %ld\n", closure.size);
|
||||
encoded_data = base64_encode((unsigned char *)closure.buffer, closure.size, &olength, 0);
|
||||
dbg(1, "olength = %ld\n", olength);
|
||||
my_free(_ALLOC_ID_, &closure.buffer);
|
||||
my_mstrcat(_ALLOC_ID_, &prop, "flags=image,unscaled\nalpha=0.8\nimage_data=", encoded_data, NULL);
|
||||
my_free(_ALLOC_ID_, &encoded_data);
|
||||
storeobject(-1, xctx->mousex_snap, xctx->mousey_snap, xctx->mousex_snap + grab_w, xctx->mousey_snap + grab_h,
|
||||
xRECT, GRIDLAYER, SELECTED, prop);
|
||||
my_free(_ALLOC_ID_, &prop);
|
||||
xctx->need_reb_sel_arr=1;
|
||||
rebuild_selected_array();
|
||||
move_objects(START,0,0,0);
|
||||
xctx->ui_state |= START_SYMPIN;
|
||||
}
|
||||
XFreeGC(display, gc);
|
||||
XDestroyWindow(display, clientwin);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* main window callback */
|
||||
/* mx and my are set to the mouse coord. relative to window */
|
||||
/* winpath: set to .drw or sub windows .x1.drw, .x2.drw, ... */
|
||||
|
|
@ -1854,6 +1978,12 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
}
|
||||
|
||||
dbg(1, "key=%d EQUAL_MODMASK=%d, SET_MODMASK=%d\n", key, SET_MODMASK, EQUAL_MODMASK);
|
||||
|
||||
#if defined(__unix__) && HAS_CAIRO==1
|
||||
if(xctx->ui_state & GRABSCREEN) {
|
||||
grabscreen(winpath, event, mx, my, key, button, aux, state);
|
||||
} else
|
||||
#endif
|
||||
switch(event)
|
||||
{
|
||||
|
||||
|
|
@ -2708,6 +2838,13 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
}
|
||||
break;
|
||||
}
|
||||
#if defined(__unix__) && HAS_CAIRO==1
|
||||
if(key == XK_Print) {
|
||||
xctx->ui_state |= GRABSCREEN;
|
||||
tcleval("grab set -global [xschem get current_win_path]");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if(key=='Q' && rstate == 0) /* edit attributes in editor */
|
||||
{
|
||||
if(xctx->semaphore >= 2) break;
|
||||
|
|
|
|||
|
|
@ -4049,7 +4049,7 @@ static cairo_surface_t *get_surface_from_file(const char *filename, const char *
|
|||
}
|
||||
filesize = (size_t)buf.st_size;
|
||||
if(filesize > 0) {
|
||||
fd = fopen(filename, "r");
|
||||
fd = fopen(filename, fopen_read_mode);
|
||||
if(fd) {
|
||||
size_t bytes_read;
|
||||
filedata = my_malloc(_ALLOC_ID_, filesize);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ LeftButton Double click Terminate Polygon placement
|
|||
- BackSpace Back to parent schematic
|
||||
- Delete Delete selected objects
|
||||
- Insert Insert element from library
|
||||
- Print Scrn Grab screen area
|
||||
- Escape Abort, redraw, unselect
|
||||
ctrl Enter Confirm closing dialog boxes
|
||||
- Down Move down
|
||||
|
|
|
|||
|
|
@ -1907,6 +1907,18 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
if((xctx->semaphore == 0)) go_back(1);
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
/* grabscreen
|
||||
* grab root window */
|
||||
else if(!strcmp(argv[1], "grabscreen"))
|
||||
{
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
#if defined(__unix__) && HAS_CAIRO==1
|
||||
xctx->ui_state |= GRABSCREEN;
|
||||
tcleval("grab set -global [xschem get current_win_path]");
|
||||
#endif
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
else { cmd_found = 0;}
|
||||
break;
|
||||
case 'h': /*----------------------------------------------*/
|
||||
|
|
@ -5397,7 +5409,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else if(argc > 2 && atoi(argv[2]) == 2) {
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
else if(argc > 3 && atoi(argv[2]) == 3) {
|
||||
else if(argc > 2 && atoi(argv[2]) == 3) {
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2551,6 +2551,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
|
|||
tcleval(name);
|
||||
}
|
||||
}
|
||||
if(debug_var==-10) debug_var=0;
|
||||
/* */
|
||||
/* EXECUTE xschem.tcl */
|
||||
/* */
|
||||
|
|
@ -2594,7 +2595,6 @@ int Tcl_AppInit(Tcl_Interp *inter)
|
|||
cadlayers=tclgetintvar("cadlayers");
|
||||
fix_broken_tiled_fill = tclgetboolvar("fix_broken_tiled_fill");
|
||||
fix_mouse_coord = tclgetboolvar("fix_mouse_coord");
|
||||
if(debug_var==-10) debug_var=0;
|
||||
my_snprintf(tmp, S(tmp), "%.16g",CADGRID);
|
||||
tclvareval("set_ne cadgrid ", tmp, NULL);
|
||||
my_snprintf(tmp, S(tmp), "%.16g",CADSNAP);
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ extern char win_temp_dir[PATH_MAX];
|
|||
#define START_SYMPIN 16384U
|
||||
#define GRAPHPAN 32768U /* bit 15 */
|
||||
#define MENUSTART 65536U /* bit 16 */
|
||||
#define GRABSCREEN 131072 /* bit 17 */
|
||||
|
||||
#define SELECTED 1U /* used in the .sel field for selected objs. */
|
||||
#define SELECTED1 2U /* first point selected... */
|
||||
|
|
@ -349,6 +350,13 @@ extern char win_temp_dir[PATH_MAX];
|
|||
if(y2 < y1) {xxtmp = y1; y1 = y2; y2 = xxtmp;} \
|
||||
}
|
||||
|
||||
#define INT_RECTORDER(x1,y1,x2,y2) { \
|
||||
int xxtmp; \
|
||||
if(x2 < x1) {xxtmp = x1; x1 = x2; x2 = xxtmp;} \
|
||||
if(y2 < y1) {xxtmp = y1; y1 = y2; y2 = xxtmp;} \
|
||||
}
|
||||
|
||||
|
||||
#define LINE_OUTSIDE(xa,ya,xb,yb,x1,y1,x2,y2) \
|
||||
(xa>=x2 || xb<=x1 || ( (ya<yb)? (ya>=y2 || yb<=y1) : (yb>=y2 || ya<=y1) ) )
|
||||
|
||||
|
|
|
|||
|
|
@ -7736,6 +7736,8 @@ proc build_widgets { {topwin {} } } {
|
|||
$topwin.menubar.tools.menu add command -label "Insert circle" -command "xschem circle" -accelerator Ctrl+Shift+C
|
||||
toolbar_add ToolInsertCircle "xschem circle" "Insert Circle" $topwin
|
||||
$topwin.menubar.tools.menu add command -label "Insert JPG/PNG image" -command "xschem add_image"
|
||||
$topwin.menubar.tools.menu add command -label "Grab screen area" -command "xschem grabscreen" \
|
||||
-accelerator {Print Scrn}
|
||||
$topwin.menubar.tools.menu add command -label "Search" -accelerator Ctrl+F -command property_search
|
||||
toolbar_add ToolSearch property_search "Search" $topwin
|
||||
$topwin.menubar.tools.menu add command -label "Align to Grid" -accelerator Alt+U -command "xschem align"
|
||||
|
|
|
|||
Loading…
Reference in New Issue