#ifndef lint static char sccsid[] = "@(#)M% 9.5 88/02/10 Copyright 1985 Sun Micro"; #endif /* * Copyright (c) 1986 by Sun Microsystems, Inc. */ /* * Cursor manipulation * * cursor.c, Wed Mar 20 10:11:53 1985 * * James Gosling, Sun Microsystems */ #include #ifdef REF #include #include #endif #include "shape.h" #include "canvas.h" #include "font.h" #include "cursor.h" #include #include struct cursor_state cv_cursor; static void cs_newcursor(); static int cursor_disable; cv_cursor_up() { if (cursor_disable) return; OVERLAYUP(); cv_cursor.up = 1; if (cv_cursor.canvas) { register struct pixrect *display = cv_cursor.canvas->scene->display; register struct cursor_shape *c = &cv_cursor.canvas->cdata.cursor; cv_cursor.ul.x = cfloorfr(cv_cursor.ri.pos.x) - c->hotspot.x; cv_cursor.ul.y = cfloorfr(cv_cursor.ri.pos.y) - c->hotspot.y; cv_cursor.lr.x = cv_cursor.ul.x + c->size.x; cv_cursor.lr.y = cv_cursor.ul.y + c->size.y; pr_rop(cv_cursor.old, 0, 0, c->size.x, c->size.y, PIX_SRC, display, cv_cursor.ul.x, cv_cursor.ul.y); if (cv_cursor.ri.g = c->glyph[CURSOR_MASK]) { cv_cursor.ri.bits = ((struct generic_glyph *) c->glyph[CURSOR_MASK])->bits; pr_shapetext(display, c->ropcode[CURSOR_MASK], c->font, &InfiniteShape, &cv_cursor.ri, 1); } if (cv_cursor.ri.g = c->glyph[CURSOR_SHAPE]) { cv_cursor.ri.bits = ((struct generic_glyph *) c->glyph[CURSOR_SHAPE])->bits; pr_shapetext(display, c->ropcode[CURSOR_SHAPE], c->font, &InfiniteShape, &cv_cursor.ri, 1); } } } cv_cursor_down() { if (cursor_disable) return; cv_cursor.up = 0; if (cv_cursor.canvas) pr_rop(cv_cursor.canvas->scene->display, cv_cursor.ul.x, cv_cursor.ul.y, cv_cursor.lr.x - cv_cursor.ul.x, cv_cursor.lr.y - cv_cursor.ul.y, PIX_SRC, cv_cursor.old, 0, 0); OVERLAYDOWN(); } void cs_initcursor(gc, str, len, c) register struct graphics_context *gc; register char *str; register struct cursor_shape *c; { if (len != 0) { extern struct font *cs_concretefont(); register op; extern char textopmap[]; struct font *f = cs_concretefont(gc); register struct glyph *g; c->font = f; (*f->u.ops->get_rendering_info) (f, str, len, gc->currentpoint.x, gc->currentpoint.y, 0, 0); if (rendering_info_length > 0) { g = rendering_info[CURSOR_SHAPE].g; c->glyph[CURSOR_SHAPE] = g; c->hotspot = g->origin; c->size = g->size; } else { c->hotspot.x = c->hotspot.y = 0; c->size.x = c->size.y = 0; c->glyph[CURSOR_SHAPE] = 0; } if (rendering_info_length > 1) { register t; g = rendering_info[CURSOR_MASK].g; c->glyph[CURSOR_MASK] = g; if ((t = c->hotspot.x - g->origin.x) < 0) c->hotspot.x = g->origin.x, c->size.x -= t; if ((t = c->hotspot.y - g->origin.y) < 0) c->hotspot.y = g->origin.y, c->size.y -= t; if ((t = (c->size.x - c->hotspot.x) - (g->size.x - g->origin.x)) < 0) c->size.x -= t; if ((t = (c->size.y - c->hotspot.y) - (g->size.y - g->origin.y)) < 0) c->size.y -= t; } else c->glyph[CURSOR_MASK] = 0; c->color[CURSOR_SHAPE] = black_color; c->color[CURSOR_MASK] = white_color; op = pixrectopcode(gc->canvas, &c->color[CURSOR_SHAPE]); c->ropcode[CURSOR_SHAPE] = (op & ~0x1F) | textopmap[op & 0x1F]; op = pixrectopcode(gc->canvas, &c->color[CURSOR_MASK]); c->ropcode[CURSOR_MASK] = (op & ~0x1F) | textopmap[op & 0x1F]; c->index[CURSOR_SHAPE] = str[CURSOR_SHAPE]; c->index[CURSOR_MASK] = str[CURSOR_MASK]; } } void cs_setcursor(canvas, cursor) register struct canvas *canvas; register struct cursor_shape *cursor; { short was_up; if (canvas == cv_cursor.canvas) { was_up = cv_cursor.up; cs_cursordown(); canvas->cdata.cursor = *cursor; cs_newcursor(canvas); if (was_up) cs_cursorup(); } else canvas->cdata.cursor = *cursor; } void cs_setcursorcanvas(canvas) register struct canvas *canvas; { if (canvas == cv_cursor.canvas) return; cs_newcursor(canvas); } static void cs_newcursor(canvas) register struct canvas *canvas; { register struct cursor_shape *cursor; register struct pixrect *pr; short was_up = cv_cursor.up; int depth; cs_cursordown(); cv_cursor.canvas = canvas; if (canvas == 0) /* Just return if setting canvas to null */ return; /* Adjust old so that it is able to hold all of cursor image */ cursor = &canvas->cdata.cursor; pr = cv_cursor.old; depth = cv_cursor.canvas->scene->display->pr_depth; if (pr == 0 || pr->pr_width < cursor->size.x || pr->pr_height < cursor->size.y || depth != pr->pr_depth) { if (pr) pr_destroy(pr); cv_cursor.old = mem_create(cursor->size.x, cursor->size.y, depth); } if (was_up) cs_cursorup(); } cs_checkcursor(cv, left, top, width, height) struct canvas *cv; short left, top, width, height; { static cv_cursor_always; /* Debugging aid */ /* cv_cursor.up check has been done in macros */ left += cv->scr_pos.x; top += cv->scr_pos.y; if (cv_cursor_always || /* Debugging aid */ (ovl_state > 0) || /* Always take down cursor when overlay */ /* Check graphics intersection with cursor */ (left < cv_cursor.lr.x && top < cv_cursor.lr.y && cv_cursor.ul.x < (left + width) && cv_cursor.ul.y < (top + height) && cv->mapped)) cs_cursordown(); } void cs_cursorenable() { cursor_disable = 0; } void cs_cursordisable() { cursor_disable = 1; }