return 1;
}
-DEF_CMD(xcb_close_display)
+DEF_CMD_CLOSED(xcb_close_display)
{
/* If this is only display, then refuse to close this one */
struct call_return cr;
static void kbd_free(struct xcb_data *xd safe);
-DEF_CMD(xcb_close)
+DEF_CMD_CLOSED(xcb_close)
{
struct xcb_data *xd = ci->home->data;
curs.width = log.width;
}
- /* Add half to x,y as stroke is either side of the line */
- cx = x * PANGO_SCALE + curs.x + PANGO_SCALE/2;
- cy = (y - baseline) * PANGO_SCALE + curs.y + PANGO_SCALE/2;
- ch = curs.height - PANGO_SCALE;
- cw = curs.width - PANGO_SCALE;
- cairo_rectangle(ctx, cx/PANGO_SCALE, cy/PANGO_SCALE,
- cw/PANGO_SCALE, ch/PANGO_SCALE);
- cairo_set_line_width(ctx, 1.0);
- cairo_stroke(ctx);
-
while (in_focus && f->parent->parent != f &&
f->parent != ci->home) {
if (f->parent->focus != f && f->z >= 0)
in_focus = False;
f = f->parent;
}
- if (in_focus) {
- if (fg.g >= 0)
- cairo_set_source_rgb(ctx, fg.r, fg.g, fg.b);
- cairo_rectangle(ctx, x+curs.x/PANGO_SCALE,
+ if (!in_focus) {
+ /* Just an fg:rectangle around the fg:text */
+ /* Add half to x,y as stroke is either side of the line */
+ cx = x * PANGO_SCALE + curs.x + PANGO_SCALE/2;
+ cy = (y - baseline) * PANGO_SCALE + curs.y + PANGO_SCALE/2;
+ ch = curs.height - PANGO_SCALE;
+ cw = curs.width - PANGO_SCALE;
+ cairo_rectangle(ctx, cx/PANGO_SCALE, cy/PANGO_SCALE,
+ cw/PANGO_SCALE, ch/PANGO_SCALE);
+ cairo_set_line_width(ctx, 1.0);
+ cairo_stroke(ctx);
+ } else {
+ /* solid fd:block with txt in bg color */
+ cairo_rectangle(ctx,
+ x+curs.x/PANGO_SCALE,
y-baseline+curs.y/PANGO_SCALE,
curs.width / PANGO_SCALE,
curs.height / PANGO_SCALE);
return 1;
}
+struct di_info {
+ struct command c;
+ MagickWand *wd safe;
+ int x,y,w,h;
+ int xo, yo;
+ struct panes *ps safe;
+};
+
+DEF_CB(xcb_draw_image_cb)
+{
+ struct di_info *dii = container_of(ci->comm, struct di_info, c);
+ int stride;
+ int fmt[2];
+ unsigned char *buf;
+ cairo_surface_t *surface;
+
+ switch (ci->key[0]) {
+ case 'w': /* width */
+ return MagickGetImageWidth(dii->wd);
+ case 'h': /* height */
+ return MagickGetImageHeight(dii->wd);
+ case 's': /* scale */
+ MagickResizeImage(dii->wd, ci->num, ci->num2, BoxFilter, 1.0);
+ return 1;
+ case 'c': /* crop or cursor */
+ if (ci->key[1] != 'u') {
+ /* crop */
+ dii->x = ci->x;
+ dii->y = ci->y;
+ dii->w = ci->num;
+ dii->h = ci->num2;
+ return 1;
+ } else {
+ /* cursor */
+ cairo_rectangle(dii->ps->ctx,
+ ci->x + dii->xo, ci->y + dii->yo,
+ ci->num, ci->num2);
+ cairo_set_line_width(dii->ps->ctx, 1.0);
+ cairo_set_source_rgb(dii->ps->ctx, 1.0, 0.0, 0.0);
+ cairo_stroke(dii->ps->ctx);
+ return 1;
+ }
+ case 'd': /* draw */
+ if (dii->w <= 0 || dii->h <= 0)
+ return Efail;
+ stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24,
+ dii->w);
+ buf = malloc(dii->h * stride);
+ // Cairo expects 32bit values with A in the high byte, then RGB.
+ // Magick provides 8bit values in the order requests.
+ // So depending on byte order, a different string is needed
+
+ fmt[0] = ('A'<<24) | ('R' << 16) | ('G' << 8) | ('B' << 0);
+ fmt[1] = 0;
+ MagickExportImagePixels(dii->wd, dii->x, dii->y,
+ dii->w, dii->h,
+ (char*)fmt, CharPixel, buf);
+ surface = cairo_image_surface_create_for_data(
+ buf, CAIRO_FORMAT_ARGB32, dii->w, dii->h, stride);
+ cairo_set_source_surface(dii->ps->ctx, surface,
+ ci->num + dii->xo, ci->num2 + dii->yo);
+ cairo_paint(dii->ps->ctx);
+ cairo_surface_destroy(surface);
+ free(buf);
+ return 1;
+ default:
+ return Efail;
+ }
+}
+
DEF_CMD(xcb_draw_image)
{
/* 'str' identifies the image. Options are:
* file:filename - load file from fs
* comm:command - run command collecting bytes
- * 'num' is '16' if image should be stretched to fill pane
- * Otherwise it is the 'or' of
- * 0,1,2 for left/middle/right in x direction
- * 0,4,8 for top/middle/bottom in y direction
- * only one of these can be used as image will fill pane
- * in other direction.
- * If 'x' and 'y' are both positive, draw cursor box at
- * p->cx, p->cy of a size so that 'x' will fit across and
- * 'y' will fit down.
+ * 'str2' and numbers are handled by Draw:scale-image.
*/
struct xcb_data *xd = ci->home->data;
- bool stretch = ci->num & 16;
- int pos = ci->num;
- int w = ci->focus->w, h = ci->focus->h;
- int x = 0, y = 0;
- int xo, yo;
- int stride;
+ struct di_info dii;
+ MagickWand *wd = NULL;
struct panes *ps;
- MagickBooleanType status;
- MagickWand *wd;
- int fmt[2];
- unsigned char *buf;
- cairo_surface_t *surface;
if (!ci->str)
return Enoarg;
- ps = find_pixmap(xd, ci->focus, &xo, &yo);
+ ps = find_pixmap(xd, ci->focus, &dii.xo, &dii.yo);
if (!ps)
return Einval;
- if (!ps->ctx)
- instantiate_pixmap(xd, ps);
- ps->bg.g = -1;
- if (!ps->ctx)
+ dii.ps = ps;
+ if (!dii.ps->ctx)
+ instantiate_pixmap(xd, dii.ps);
+ dii.ps->bg.g = -1;
+ if (!dii.ps->ctx)
return Efail;
if (strstarts(ci->str, "file:")) {
+ MagickBooleanType status;
+
wd = NewMagickWand();
status = MagickReadImage(wd, ci->str + 5);
if (status == MagickFalse) {
return Efail;
}
} else if (strstarts(ci->str, "comm:")) {
+ MagickBooleanType status;
struct call_return cr;
+
wd = NewMagickWand();
- cr = call_ret(bytes, ci->str+5, ci->focus, 0, NULL, ci->str2);
+ cr = call_ret(bytes, ci->str+5, ci->focus);
if (!cr.s) {
DestroyMagickWand(wd);
return Efail;
DestroyMagickWand(wd);
return Efail;
}
- } else
+ }
+
+ if (!wd)
return Einval;
MagickAutoOrientImage(wd);
- if (!stretch) {
- int ih = MagickGetImageHeight(wd);
- int iw = MagickGetImageWidth(wd);
+ dii.c = xcb_draw_image_cb;
+ dii.wd = wd;
+ dii.w = dii.h = dii.x = dii.y = dii.xo = dii.yo = 0;
+ call("Draw:scale-image", ci->focus,
+ ci->num, NULL, NULL, ci->num2, NULL, ci->str2,
+ ci->x, ci->y, &dii.c);
- if (iw <= 0 || iw <= 0) {
- DestroyMagickWand(wd);
- return Efail;
- }
- if (iw * h > ih * w) {
- /* Image is wider than space, use less height */
- ih = ih * w / iw;
- switch(pos & (8+4)) {
- case 4: /* center */
- y = (h - ih) / 2; break;
- case 8: /* bottom */
- y = h - ih; break;
- }
- h = ih;
- } else {
- /* image is too tall, use less width */
- iw = iw * h / ih;
- switch (pos & (1+2)) {
- case 1: /* center */
- x = (w - iw) / 2; break;
- case 2: /* right */
- x = w - iw ; break;
- }
- w = iw;
- }
- }
- MagickAdaptiveResizeImage(wd, w, h);
- stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
- buf = malloc(h * stride);
- // Cairo expects 32bit values with A in the high byte, then RGB.
- // Magick provides 8bit values in the order requests.
- // So depending on byte order, a different string is needed
-
- fmt[0] = ('A'<<24) | ('R' << 16) | ('G' << 8) | ('B' << 0);
- fmt[1] = 0;
- MagickExportImagePixels(wd, 0, 0, w, h, (char*)fmt, CharPixel, buf);
- surface = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32,
- w, h, stride);
- cairo_set_source_surface(ps->ctx, surface, x + xo, y + yo);
- cairo_paint(ps->ctx);
- cairo_surface_destroy(surface);
- free(buf);
-
- if (ci->x > 0 && ci->y > 0 && ci->focus->cx >= 0) {
- struct pane *p = ci->focus;
- cairo_rectangle(ps->ctx, p->cx + xo, p->cy + yo,
- w/ci->x, h/ci->y);
- cairo_set_line_width(ps->ctx, 1.0);
- cairo_set_source_rgb(ps->ctx, 1.0, 0.0, 0.0);
- cairo_stroke(ps->ctx);
- }
DestroyMagickWand(wd);
pane_damaged(ci->home, DAMAGED_POSTORDER);
} else if (strstarts(ci->str, "comm:")) {
struct call_return cr;
wd = NewMagickWand();
- cr = call_ret(bytes, ci->str+5, ci->focus, 0, NULL, ci->str2);
+ cr = call_ret(bytes, ci->str+5, ci->focus);
if (!cr.s) {
DestroyMagickWand(wd);
return Efail;
cme->format == 32 &&
cme->window == xd->win &&
cme->data.data32[0] == xd->atoms[a_WM_DELETE_WINDOW]) {
- call("window:close", pane_focus(home));
+ call("Window:close", pane_focus(home));
return;
}
xcb_flush(xd->conn);
}
if (xcb_connection_has_error(xd->conn)) {
- call("window:close", ci->home->parent);
+ call("Window:close", ci->home->parent);
pane_close(ci->home);
}
return ret;
if (xcb_connection_has_error(conn))
return NULL;
- p = pane_register(pane_root(focus), 1, &xcb_handle.c);
+ p = call_ret(pane, "attach-window-core", focus);
+ if (!p)
+ return NULL;
+ p = pane_register(p, 1, &xcb_handle.c);
if (!p)
return NULL;
xd = p->data;
attr_set_str(&p->attrs, "scale:M", scale);
xd->last_event = time(NULL);
call("editor:request:all-displays", p);
- p = call_ret(pane, "editor:activate-display", p);
return p;
abort:
kbd_free(xd);
if (!d)
return Enoarg;
p = xcb_display_init(d, disp_auth, ci->focus);
- if (p)
- home_call_ret(pane, ci->focus, "doc:attach-view", p, 1);
+ if (strcmp(ci->key, "interactive-cmd-x11window") == 0)
+ p = home_call_ret(pane, p,
+ "Window:activate-display", ci->focus);
if (p)
comm_call(ci->comm2, "cb", p);
return 1;
xcb_map = key_alloc();
- key_add(xcb_map, "window:close", &xcb_close_display);
- key_add(xcb_map, "window:external-viewer", &xcb_external_viewer);
- key_add(xcb_map, "window:fullscreen", &xcb_fullscreen);
- key_add(xcb_map, "window:new", &xcb_new_display);
+ key_add(xcb_map, "Window:close", &xcb_close_display);
+ key_add(xcb_map, "Window:external-viewer", &xcb_external_viewer);
+ key_add(xcb_map, "Window:fullscreen", &xcb_fullscreen);
+ key_add(xcb_map, "Window:new", &xcb_new_display);
key_add(xcb_map, "Close", &xcb_close);
key_add(xcb_map, "Draw:clear", &xcb_clear);