Mike Dransfield
2006-Nov-12 21:58 UTC
[compiz] [PATCH] Annotate shapes, text and dbus support
Here are my patches to add extra shapes to the annotate plugin. I have also added dbus support and made a few things configurable. The new tools available are Line, Rectangle and Circle, the original is called Brush. There is no selection line at the moment because I do not understand OpenGL yet. Hopefully these patches can be added and something added later. There is an extra action called initiate_remote. This is only used by dbus and should probably be hidden in gconf. I had a problem getting colors from dbus, it appears that they are not supported yet. I commented the code that should work but doesn't. I added text support but only via dbus. There are certain problems with typing directly to the screen. You can write to the screen with a dbus command like this. dbus-send --type=method_call --dest=org.freedesktop.compiz \ /org/freedesktop/compiz/annotate/allscreens/remote_initiate \ org.freedesktop.compiz.activate string:'root' \ int32:`xwininfo -root | grep id: | awk '{ print $4 }'` \ string:tool string:text string:x double:1000 string:y double:200 \ string:text string:"Hello World" string:family string:Sans \ string:size double:92.0 string:stroke_width double:1.0 \ string:slant string:italic All of the tools are available this way too. I also allowed colours to have transparency (not sure why it wasnt there before, it works well here). -------------- next part -------------- --- ../../clean/plugins/annotate.c 2006-11-10 00:13:43.830444008 +0000 +++ ./annotate.c 2006-11-13 06:00:57.902332048 +0000 @@ -24,6 +24,8 @@ */ #include <stdlib.h> +#include <math.h> +#include <string.h> #include <cairo-xlib-xrender.h> #include <compiz.h> @@ -41,16 +43,38 @@ #define ANNO_COLOR_GREEN_DEFAULT 0x0000 #define ANNO_COLOR_BLUE_DEFAULT 0x0000 +#define ANNO_LINE_WIDTH_MIN 0.1f +#define ANNO_LINE_WIDTH_MAX 100.0f +#define ANNO_LINE_WIDTH_DEFAULT 3.0f +#define ANNO_LINE_WIDTH_PRECISION 0.1f + +#define ANNO_STROKE_WIDTH_MIN 0.1f +#define ANNO_STROKE_WIDTH_MAX 20.0f +#define ANNO_STROKE_WIDTH_DEFAULT 1.0f +#define ANNO_STROKE_WIDTH_PRECISION 0.1f + + static int displayPrivateIndex; static int annoLastPointerX = 0; static int annoLastPointerY = 0; -#define ANNO_DISPLAY_OPTION_INITIATE 0 -#define ANNO_DISPLAY_OPTION_ERASE 1 -#define ANNO_DISPLAY_OPTION_CLEAR 2 -#define ANNO_DISPLAY_OPTION_COLOR 3 -#define ANNO_DISPLAY_OPTION_NUM 4 +static char *tools[] = { N_("Brush"), + N_("Rectangle"), + N_("Circle"), + N_("Line") }; +char *defaultTool = "Brush"; + +#define ANNO_DISPLAY_OPTION_INITIATE 0 +#define ANNO_DISPLAY_OPTION_REMOTE_INITIATE 1 +#define ANNO_DISPLAY_OPTION_ERASE 2 +#define ANNO_DISPLAY_OPTION_CLEAR 3 +#define ANNO_DISPLAY_OPTION_FILL_COLOR 4 +#define ANNO_DISPLAY_OPTION_STROKE_COLOR 5 +#define ANNO_DISPLAY_OPTION_LINE_WIDTH 6 +#define ANNO_DISPLAY_OPTION_STROKE_WIDTH 7 +#define ANNO_DISPLAY_OPTION_TOOL 8 +#define ANNO_DISPLAY_OPTION_NUM 9 typedef struct _AnnoDisplay { int screenPrivateIndex; @@ -68,6 +92,12 @@ cairo_surface_t *surface; cairo_t *cairo; Bool content; + + double startX; + double startY; + + Bool eraseMode; + } AnnoScreen; #define GET_ANNO_DISPLAY(d) \ @@ -85,6 +115,8 @@ #define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption)) +#define NUM_TOOLS (sizeof (tools) / sizeof (tools[0])) + static void annoCairoClear (CompScreen *s, cairo_t *cr) @@ -143,6 +175,335 @@ return as->cairo; } + +static void +annoDrawCircle (CompScreen *s, double xc, double yc, double radius, + unsigned short *fillColor, unsigned short *strokeColor, + double strokeWidth) +{ + REGION reg; + cairo_t *cr; + + ANNO_SCREEN (s); + + cr = annoCairoContext (s); + + if (cr) + { + + double ex1, ey1, ex2, ey2; + cairo_set_source_rgba (cr, + (double) fillColor[0] / 0xffff, + (double) fillColor[1] / 0xffff, + (double) fillColor[2] / 0xffff, + (double) fillColor[3] / 0xffff); + cairo_arc (cr, xc, yc, radius, 0, 2*M_PI); + cairo_fill_preserve (cr); + cairo_set_line_width (cr, strokeWidth); + cairo_stroke_extents (cr, &ex1, &ey1, &ex2, &ey2); + cairo_set_source_rgba (cr, + (double) strokeColor[0] / 0xffff, + (double) strokeColor[1] / 0xffff, + (double) strokeColor[2] / 0xffff, + (double) strokeColor[3] / 0xffff); + cairo_stroke (cr); + + reg.rects = ®.extents; + reg.numRects = 1; + + reg.extents.x1 = ex1; + reg.extents.y1 = ey1; + reg.extents.x2 = ex2; + reg.extents.y2 = ey2; + + as->content = TRUE; + damageScreenRegion (s, ®); + + } +} + + +static void +annoDrawRectangle (CompScreen *s, double x, double y, double w, double h, + unsigned short *fillColor, unsigned short *strokeColor, + double strokeWidth) +{ + REGION reg; + cairo_t *cr; + + ANNO_SCREEN (s); + + cr = annoCairoContext (s); + + if (cr) + { + + double ex1, ey1, ex2, ey2; + + cairo_set_source_rgba (cr, + (double) fillColor[0] / 0xffff, + (double) fillColor[1] / 0xffff, + (double) fillColor[2] / 0xffff, + (double) fillColor[3] / 0xffff); + cairo_rectangle (cr, x, y, w, h); + cairo_fill_preserve (cr); + cairo_set_line_width (cr, strokeWidth); + cairo_stroke_extents (cr, &ex1, &ey1, &ex2, &ey2); + cairo_set_source_rgba (cr, + (double) strokeColor[0] / 0xffff, + (double) strokeColor[1] / 0xffff, + (double) strokeColor[2] / 0xffff, + (double) strokeColor[3] / 0xffff); + cairo_stroke (cr); + + reg.rects = ®.extents; + reg.numRects = 1; + + reg.extents.x1 = ex1; + reg.extents.y1 = ey1; + reg.extents.x2 = ex2 + 2.0; + reg.extents.y2 = ey2 + 2.0; + + as->content = TRUE; + damageScreenRegion (s, ®); + + } +} + +static void +annoDrawLine (CompScreen *s, double x1, double y1, + double x2, double y2, + double width, unsigned short *color) +{ + REGION reg; + cairo_t *cr; + + ANNO_SCREEN (s); + + cr = annoCairoContext (s); + + if (cr) + { + + double ex1, ey1, ex2, ey2; + + cairo_set_line_width (cr, width); + cairo_move_to (cr, x1, y1); + cairo_line_to (cr, x2, y2); + cairo_stroke_extents (cr, &ex1, &ey1, &ex2, &ey2); + + if (as->eraseMode) + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0); + else + cairo_set_source_rgba (cr, + (double) color[0] / 0xffff, + (double) color[1] / 0xffff, + (double) color[2] / 0xffff, + (double) color[3] / 0xffff); + cairo_stroke (cr); + + reg.rects = ®.extents; + reg.numRects = 1; + + reg.extents.x1 = ex1; + reg.extents.y1 = ey1; + reg.extents.x2 = ex2; + reg.extents.y2 = ey2; + + as->content = TRUE; + damageScreenRegion (s, ®); + + } +} + +static void +annoDrawText (CompScreen *s, double x, double y, + char *text, + char *fontFamily, double fontSize, + int fontSlant, int fontWeight, + unsigned short *fillColor, unsigned short *strokeColor, + double strokeWidth) +{ + REGION reg; + cairo_t *cr; + cairo_text_extents_t extents; + + ANNO_SCREEN (s); + + cr = annoCairoContext (s); + + if (cr) + { + + cairo_set_line_width (cr, strokeWidth); + cairo_set_source_rgba (cr, + (double) fillColor[0] / 0xffff, + (double) fillColor[1] / 0xffff, + (double) fillColor[2] / 0xffff, + (double) fillColor[3] / 0xffff); + cairo_select_font_face (cr, fontFamily, fontSlant, + fontWeight); + cairo_set_font_size (cr, fontSize); + + cairo_text_extents (cr, text, &extents); + + cairo_save (cr); + cairo_move_to (cr, x, y); + cairo_text_path (cr, text); + cairo_fill_preserve (cr); + cairo_set_source_rgba (cr, + (double) strokeColor[0] / 0xffff, + (double) strokeColor[1] / 0xffff, + (double) strokeColor[2] / 0xffff, + (double) strokeColor[3] / 0xffff); + cairo_stroke (cr); + cairo_restore (cr); + + reg.rects = ®.extents; + reg.numRects = 1; + + reg.extents.x1 = x; + reg.extents.y1 = y + extents.y_bearing - 2.0; + reg.extents.x2 = x + extents.width + 20.0; + reg.extents.y2 = y + extents.height; + + + as->content = TRUE; + damageScreenRegion (s, ®); + + } +} + + +static Bool +annoRemoteInitiate (CompDisplay *d, + CompAction *action, + CompActionState state, + CompOption *option, + int nOption) +{ + CompScreen *s; + Window xid; + char *tool; + cairo_t *cr; + + xid = getIntOptionNamed (option, nOption, "root", 0); + + tool = getStringOptionNamed (option, nOption, "tool", "Brush"); + + s = findScreenAtDisplay (d, xid); + + if (s) + { + + cr = annoCairoContext (s); + + if (cr) + { + unsigned short *fillColor, *strokeColor; + double lineWidth, strokeWidth; + + ANNO_DISPLAY (d); + + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + + /*fillColor = getColorOptionNamed (option, nOption, "fill_color", + ad->opt[ANNO_DISPLAY_OPTION_FILL_COLOR].value.c); + strokeColor = getColorOptionNamed (option, nOption, "stroke_color", + ad->opt[ANNO_DISPLAY_OPTION_STROKE_COLOR].value.c);*/ + fillColor = ad->opt[ANNO_DISPLAY_OPTION_FILL_COLOR].value.c; + strokeColor = ad->opt[ANNO_DISPLAY_OPTION_STROKE_COLOR].value.c; + + strokeWidth = getFloatOptionNamed (option, nOption, "stroke_width", + ad->opt[ANNO_DISPLAY_OPTION_STROKE_WIDTH].value.f); + lineWidth = getFloatOptionNamed (option, nOption, "line_width", + ad->opt[ANNO_DISPLAY_OPTION_LINE_WIDTH].value.f); + + + if (strcasecmp (tool, "brush")==0) + { + double x, y; + + x = getFloatOptionNamed (option, nOption, "x", 0); + y = getFloatOptionNamed (option, nOption, "y", 0); + + annoDrawLine (s, x, y, x+1.0, y+1.0, lineWidth, fillColor); + } + if (strcasecmp (tool, "rectangle")==0) + { + double x, y, w, h; + + x = getFloatOptionNamed (option, nOption, "x", 0); + y = getFloatOptionNamed (option, nOption, "y", 0); + w = getFloatOptionNamed (option, nOption, "w", 100); + h = getFloatOptionNamed (option, nOption, "h", 100); + + annoDrawRectangle (s, x, y, w, h, fillColor, strokeColor, + strokeWidth); + } + if (strcasecmp (tool, "circle")==0) + { + double xc, yc, r; + + xc = getFloatOptionNamed (option, nOption, "xc", 0); + yc = getFloatOptionNamed (option, nOption, "yc", 0); + r = getFloatOptionNamed (option, nOption, "radius", 100); + + annoDrawCircle (s, xc, yc, r, fillColor, strokeColor, + strokeWidth); + } + if (strcasecmp (tool, "line")==0) + { + double x1, y1, x2, y2; + + x1 = getFloatOptionNamed (option, nOption, "x1", 0); + y1 = getFloatOptionNamed (option, nOption, "y1", 0); + x2 = getFloatOptionNamed (option, nOption, "x2", 100); + y2 = getFloatOptionNamed (option, nOption, "y2", 100); + + annoDrawLine (s, x1, y1, x2, y2, lineWidth, fillColor); + } + if (strcasecmp (tool, "text")==0) + { + double x, y, size; + char *text, *family; + unsigned int slant, weight; + + char *slantStr = getStringOptionNamed (option, nOption, + "slant", ""); + if (strcasecmp(slantStr, "oblique")==0) + slant = CAIRO_FONT_SLANT_OBLIQUE; + if (strcasecmp(slantStr, "italic")==0) + slant = CAIRO_FONT_SLANT_ITALIC; + else + slant = CAIRO_FONT_SLANT_NORMAL; + + char *weightStr = getStringOptionNamed (option, nOption, + "weight", ""); + if (strcasecmp(weightStr, "bold")==0) + weight = CAIRO_FONT_WEIGHT_BOLD; + else + weight = CAIRO_FONT_WEIGHT_NORMAL; + + x = getFloatOptionNamed (option, nOption, "x", 0); + y = getFloatOptionNamed (option, nOption, "y", 0); + text = getStringOptionNamed (option, nOption, "text", + ""); + family = getStringOptionNamed (option, nOption, "family", + "Sans"); + size = getFloatOptionNamed (option, nOption, "size", 36.0); + + annoDrawText (s, x, y, text, family, size, slant, weight, + fillColor, strokeColor, strokeWidth); + } + } + } + + return FALSE; + +} + static Bool annoInitiate (CompDisplay *d, CompAction *action, @@ -174,24 +535,28 @@ if (state & CompActionStateInitKey) action->state |= CompActionStateTermKey; - annoLastPointerX = pointerX; - annoLastPointerY = pointerY; + as->startX = annoLastPointerX = pointerX; + as->startY = annoLastPointerY = pointerY; cr = annoCairoContext (s); if (cr) { + as->eraseMode = FALSE; unsigned short *color; ANNO_DISPLAY (s->display); - color = ad->opt[ANNO_DISPLAY_OPTION_COLOR].value.c; + color = ad->opt[ANNO_DISPLAY_OPTION_FILL_COLOR].value.c; cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgb (cr, - (double) color[0] / 0xffff, - (double) color[1] / 0xffff, - (double) color[2] / 0xffff); - cairo_set_line_width (cr, 4.0); + + cairo_set_source_rgba (cr, + (double) color[0] / 0xffff, + (double) color[1] / 0xffff, + (double) color[2] / 0xffff, + (double) color[3] / 0xffff); + cairo_set_line_width (cr, + ad->opt[ANNO_DISPLAY_OPTION_LINE_WIDTH].value.f); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); } } @@ -206,6 +571,94 @@ CompOption *option, int nOption) { + CompScreen *s; + Window xid; + cairo_t *cr; + char *tool; + unsigned short *fillColor, *strokeColor; + double lineWidth, strokeWidth; + + xid = getIntOptionNamed (option, nOption, "root", 0); + + + ANNO_DISPLAY(d); + + tool = ad->opt[ANNO_DISPLAY_OPTION_TOOL].value.s; + + for (s = d->screens; s; s = s->next) + { + ANNO_SCREEN (s); + + fillColor = ad->opt[ANNO_DISPLAY_OPTION_FILL_COLOR].value.c; + strokeColor = ad->opt[ANNO_DISPLAY_OPTION_STROKE_COLOR].value.c; + lineWidth = ad->opt[ANNO_DISPLAY_OPTION_LINE_WIDTH].value.f; + strokeWidth = ad->opt[ANNO_DISPLAY_OPTION_STROKE_WIDTH].value.f; + + if (xid && s->root != xid) + continue; + + if (as->grabIndex) + { + if (strcmp(tool, "Brush")!=0) + { + cr = annoCairoContext (s); + + if (cr) + { + double width = pointerX - as->startX; + double height = pointerY - as->startY; + + if (strcmp(tool, "Rectangle")==0) + { + + annoDrawRectangle (s, as->startX, as->startY, width, + height, fillColor, + strokeColor, strokeWidth); + + } + else if (strcmp(tool, "Circle")==0) + { + if (height < 0) + height *= -1; + if (width < 0) + width *= -1; + + double xc = as->startX; + double yc = as->startY; + double radius = MAX (width, height); + + annoDrawCircle (s, xc, yc, radius, fillColor, + strokeColor, strokeWidth); + + } + else if (strcmp(tool, "Line")==0) + { + + annoDrawLine (s, as->startX, as->startY, + pointerX, pointerY, + lineWidth, fillColor); + + } + } + } + + removeScreenGrab (s, as->grabIndex, NULL); + as->grabIndex = 0; + } + } + + action->state &= ~(CompActionStateTermKey | CompActionStateTermButton); + + return FALSE; +} + +static Bool +annoEraseTerminate (CompDisplay *d, + CompAction *action, + CompActionState state, + CompOption *option, + int nOption) +{ CompScreen *s; Window xid; @@ -267,6 +720,7 @@ cr = annoCairoContext (s); if (cr) { + as->eraseMode = TRUE; cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0); cairo_set_line_width (cr, 20.0); @@ -277,6 +731,7 @@ return FALSE; } + static Bool annoClear (CompDisplay *d, CompAction *action, @@ -381,37 +836,28 @@ int xRoot, int yRoot) { + ANNO_DISPLAY(s->display); ANNO_SCREEN (s); if (as->grabIndex) { cairo_t *cr; - double x1, y1, x2, y2; - REGION reg; cr = annoCairoContext (s); if (!cr) return; - cairo_move_to (cr, annoLastPointerX, annoLastPointerY); - cairo_line_to (cr, xRoot, yRoot); - cairo_stroke_extents (cr, &x1, &y1, &x2, &y2); - cairo_stroke (cr); - - as->content = TRUE; + if ((strcmp(ad->opt[ANNO_DISPLAY_OPTION_TOOL].value.s, "Brush")==0) || + as->eraseMode) + { + annoDrawLine (s, annoLastPointerX, annoLastPointerY, + xRoot, yRoot, + ad->opt[ANNO_DISPLAY_OPTION_LINE_WIDTH].value.f, + ad->opt[ANNO_DISPLAY_OPTION_FILL_COLOR].value.c); + } annoLastPointerX = xRoot; annoLastPointerY = yRoot; - - reg.rects = ®.extents; - reg.numRects = 1; - - reg.extents.x1 = x1; - reg.extents.y1 = y1; - reg.extents.x2 = (x2 + 0.5); - reg.extents.y2 = (y2 + 0.5); - - damageScreenRegion (s, ®); } } @@ -464,13 +910,26 @@ o->value.action.button.modifiers = ANNO_INITIATE_BUTTON_MODIFIERS_DEFAULT; o->value.action.button.button = ANNO_INITIATE_BUTTON_DEFAULT; + o = &ad->opt[ANNO_DISPLAY_OPTION_REMOTE_INITIATE]; + o->name = "remote_initiate"; + o->shortDesc = N_("Initiate Remotely"); + o->longDesc = N_("Initiate annotate drawing with dbus"); + o->type = CompOptionTypeAction; + o->value.action.initiate = annoRemoteInitiate; + o->value.action.terminate = 0; + o->value.action.bell = FALSE; + o->value.action.edgeMask = 0; + o->value.action.type = CompBindingTypeButton; + o->value.action.button.modifiers = 0; + o->value.action.button.button = 0; + o = &ad->opt[ANNO_DISPLAY_OPTION_ERASE]; o->name = "erase"; o->shortDesc = N_("Initiate erase"); o->longDesc = N_("Initiate annotate erasing"); o->type = CompOptionTypeAction; o->value.action.initiate = annoEraseInitiate; - o->value.action.terminate = annoTerminate; + o->value.action.terminate = annoEraseTerminate; o->value.action.bell = FALSE; o->value.action.edgeMask = 0; o->value.action.type = CompBindingTypeButton; @@ -497,15 +956,55 @@ XKeysymToKeycode (display, XStringToKeysym (ANNO_CLEAR_KEY_DEFAULT)); - o = &ad->opt[ANNO_DISPLAY_OPTION_COLOR]; - o->name = "color"; - o->shortDesc = N_("Annotate Color"); - o->longDesc = N_("Line color for annotations"); + o = &ad->opt[ANNO_DISPLAY_OPTION_FILL_COLOR]; + o->name = "fill_color"; + o->shortDesc = N_("Annotate Fill Color"); + o->longDesc = N_("Fill color for annotations"); o->type = CompOptionTypeColor; o->value.c[0] = ANNO_COLOR_RED_DEFAULT; o->value.c[1] = ANNO_COLOR_GREEN_DEFAULT; o->value.c[2] = ANNO_COLOR_BLUE_DEFAULT; o->value.c[3] = 0xffff; + + o = &ad->opt[ANNO_DISPLAY_OPTION_STROKE_COLOR]; + o->name = "stroke_color"; + o->shortDesc = N_("Annotate Stroke Color"); + o->longDesc = N_("Stroke color for annotations"); + o->type = CompOptionTypeColor; + o->value.c[0] = 0; + o->value.c[1] = 0; + o->value.c[2] = 0; + o->value.c[3] = 0xaaaa; + + o = &ad->opt[ANNO_DISPLAY_OPTION_LINE_WIDTH]; + o->name = "line_width"; + o->shortDesc = N_("Line width"); + o->longDesc = N_("Line width for annotations"); + o->type = CompOptionTypeFloat; + o->value.f = ANNO_LINE_WIDTH_DEFAULT; + o->rest.f.min = ANNO_LINE_WIDTH_MIN; + o->rest.f.max = ANNO_LINE_WIDTH_MAX; + o->rest.f.precision = ANNO_LINE_WIDTH_PRECISION; + + o = &ad->opt[ANNO_DISPLAY_OPTION_STROKE_WIDTH]; + o->name = "stroke_width"; + o->shortDesc = N_("Stroke width"); + o->longDesc = N_("Stroke width for annotations"); + o->type = CompOptionTypeFloat; + o->value.f = ANNO_STROKE_WIDTH_DEFAULT; + o->rest.f.min = ANNO_STROKE_WIDTH_MIN; + o->rest.f.max = ANNO_STROKE_WIDTH_MAX; + o->rest.f.precision = ANNO_STROKE_WIDTH_PRECISION; + + o = &ad->opt[ANNO_DISPLAY_OPTION_TOOL]; + o->name = "tool"; + o->shortDesc = N_("Tool"); + o->longDesc = N_("Currnet tool for annotations " \ + "(Brush, Rectangle, Circle, Line)"); + o->type = CompOptionTypeString; + o->value.s = strdup (defaultTool); + o->rest.s.string = tools; + o->rest.s.nString = NUM_TOOLS; } static CompOption * @@ -539,9 +1038,20 @@ if (setDisplayAction (display, o, value)) return TRUE; break; - case ANNO_DISPLAY_OPTION_COLOR: + case ANNO_DISPLAY_OPTION_FILL_COLOR: + case ANNO_DISPLAY_OPTION_STROKE_COLOR: if (compSetColorOption (o, value)) return TRUE; + break; + case ANNO_DISPLAY_OPTION_LINE_WIDTH: + case ANNO_DISPLAY_OPTION_STROKE_WIDTH: + if (compSetFloatOption (o, value)) + return TRUE; + break; + case ANNO_DISPLAY_OPTION_TOOL: + if (compSetStringOption (o, value)) + return TRUE; + break; default: break; }
David Reveman
2006-Nov-15 09:42 UTC
[compiz] [PATCH] Annotate shapes, text and dbus support
On Mon, 2006-11-13 at 06:15 +0000, Mike Dransfield wrote:> Here are my patches to add extra shapes to the annotate > plugin. I have also added dbus support and made a few things > configurable. > > The new tools available are Line, Rectangle and Circle, the > original is called Brush. There is no selection line at the > moment because I do not understand OpenGL yet. Hopefully > these patches can be added and something added later.I'm not sure what you mean by selection line but interactive drawing with these tools will require us to draw into an intermediate buffer that we blend on top of the previous content. We can add that later though.> > There is an extra action called initiate_remote. This is only > used by dbus and should probably be hidden in gconf.I didn't like the initiate_remote name. I change the name to 'draw'.> > I had a problem getting colors from dbus, it appears that they > are not supported yet. I commented the code that should work > but doesn't.I fixed that.> > I added text support but only via dbus. There are certain problems > with typing directly to the screen. You can write to the screen with > a dbus command like this. > > dbus-send --type=method_call --dest=org.freedesktop.compiz \ > /org/freedesktop/compiz/annotate/allscreens/remote_initiate \ > org.freedesktop.compiz.activate string:'root' \ > int32:`xwininfo -root | grep id: | awk '{ print $4 }'` \ > string:tool string:text string:x double:1000 string:y double:200 \ > string:text string:"Hello World" string:family string:Sans \ > string:size double:92.0 string:stroke_width double:1.0 \ > string:slant string:italic > > All of the tools are available this way too.I changes so all these tools are available only through the 'draw' option. We need do drawing to an intermediate buffer as I mentioned above before it makes sense to allow interactive use of these tools. I've pushed this out, but I haven't verified that it actually works. Let me know if I broke something while doing these changes. Thanks, -David