[compiz] [PATCH] Annotate shapes, text and dbus support

Mike Dransfield mike at blueroot.co.uk
Sun Nov 12 22:15:19 PST 2006


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    = &reg.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, &reg);
+
+    }
+}
+
+
+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    = &reg.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, &reg);
+
+    }
+}
+
+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    = &reg.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, &reg);
+
+    }
+}
+
+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    = &reg.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, &reg);
+
+    }
+}
+
+
+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    = &reg.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, &reg);
     }
 }
 
@@ -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;
     }


More information about the compiz mailing list