Skip to content

Commit

Permalink
Add functionality to draw lines via command
Browse files Browse the repository at this point in the history
* action: add a --line command line option for drawing lines

* targets: add GA_LINE and GA_LINEDATA targets to allow cli to send
parameters to the main app

* chore: remove debug logs

* chore: formatting fixes

* callbacks: free line_ctx, might prevent potential memory leak

* README: add docs for --line command

* callbacks: fix memory leak

* main: indentation fixes

* cmdline: failsafe checks

* cmdline: fix minor failsafe check bug

* README: add line example

* README: indentation error

* README: add quotes around color argument
  • Loading branch information
VanillaViking authored Sep 11, 2023
1 parent e47c6c8 commit d30f9b8
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ Usage:
will undo the last drawing stroke (or "-z")
gromit-mpx --redo
will redo the last undone drawing stroke (or "-y")
gromit-mpx --line <startX> <startY> <endX> <endY> <color> <thickness>
will draw a straight line with characteristics specified by the arguments (or "-l")
eg: gromit-mpx -l 200 200 400 400 '#C4A7E7' 6

If activated Gromit-MPX prevents you from using other programs with the
mouse. You can press the button and paint on the screen. Key presses
Expand Down
63 changes: 62 additions & 1 deletion src/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ void on_clientapp_selection_get (GtkWidget *widget,
if(data->debug)
g_printerr("DEBUG: clientapp received request.\n");

if (gtk_selection_data_get_target(selection_data) == GA_TOGGLEDATA)

if (gtk_selection_data_get_target(selection_data) == GA_TOGGLEDATA || gtk_selection_data_get_target(selection_data) == GA_LINEDATA)
{
ans = data->clientdata;
}
Expand Down Expand Up @@ -435,6 +436,13 @@ void on_mainapp_selection_get (GtkWidget *widget,
GA_TOGGLEDATA, time);
gtk_main(); /* Wait for the response */
}
else if(action == GA_LINE)
{
/* ask back client for device id */
gtk_selection_convert (data->win, GA_DATA,
GA_LINEDATA, time);
gtk_main(); /* Wait for the response */
}
else if (action == GA_VISIBILITY)
toggle_visibility (data);
else if (action == GA_CLEAR)
Expand Down Expand Up @@ -502,6 +510,59 @@ void on_mainapp_selection_received (GtkWidget *widget,
g_printerr("ERROR: No device at index %ld.\n", (long)dev_nr);
}
}
else if (gtk_selection_data_get_target(selection_data) == GA_LINEDATA)
{

gchar** line_args = g_strsplit((gchar*)gtk_selection_data_get_data(selection_data), " ", 6);
int startX = atoi(line_args[0]);
int startY = atoi(line_args[1]);
int endX = atoi(line_args[2]);
int endY = atoi(line_args[3]);
gchar* hex_code = line_args[4];
int thickness = atoi(line_args[5]);

if(data->debug)
{
g_printerr("DEBUG: mainapp got line data back from client:\n");
g_printerr("startX startY endX endY: %d %d %d %d\n", startX, startY, endX, endY);
g_printerr("color: %s\n", hex_code);
g_printerr("thickness: %d\n", thickness);
}

GdkRGBA* color = g_malloc (sizeof (GdkRGBA));
GdkRGBA *fg_color=data->red;
if (gdk_rgba_parse (color, hex_code))
{
fg_color = color;
}
else
{
g_printerr ("Unable to parse color. "
"Keeping default.\n");
}
GromitPaintContext* line_ctx = paint_context_new(data, GROMIT_PEN, fg_color, thickness, 0, thickness, thickness);

GdkRectangle rect;
rect.x = MIN (startX,endX) - thickness / 2;
rect.y = MIN (startY,endY) - thickness / 2;
rect.width = ABS (startX-endX) + thickness;
rect.height = ABS (startY-endY) + thickness;

if(data->debug)
g_printerr("DEBUG: draw line from %d %d to %d %d\n", startX, startY, endX, endY);

cairo_set_line_width(line_ctx->paint_ctx, thickness);
cairo_move_to(line_ctx->paint_ctx, startX, startY);
cairo_line_to(line_ctx->paint_ctx, endX, endY);
cairo_stroke(line_ctx->paint_ctx);

data->modified = 1;
gdk_window_invalidate_rect(gtk_widget_get_window(data->win), &rect, 0);
data->painted = 1;

g_free(line_ctx);
g_free (color);
}
}

gtk_main_quit ();
Expand Down
36 changes: 36 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ void setup_main_app (GromitData *data, int argc, char ** argv)
gtk_selection_add_target (data->win, GA_CONTROL, GA_RELOAD, 7);
gtk_selection_add_target (data->win, GA_CONTROL, GA_UNDO, 8);
gtk_selection_add_target (data->win, GA_CONTROL, GA_REDO, 9);
gtk_selection_add_target (data->win, GA_CONTROL, GA_LINE, 10);



Expand Down Expand Up @@ -982,6 +983,40 @@ int main_client (int argc, char **argv, GromitData *data)
else
data->clientdata = "-1"; /* default to grab all */
}
else if (strcmp (arg, "-l") == 0 ||
strcmp (arg, "--line") == 0)
{
if (argc - (i+1) == 6) /* this command must have exactly 6 params */
{

// check if provided values are valid coords on the screen
if (atoi(argv[i+1]) < 0 || atoi(argv[i+1]) > (int)data->width ||
atoi(argv[i+2]) < 0 || atoi(argv[i+2]) > (int)data->height ||
atoi(argv[i+3]) < 0 || atoi(argv[i+3]) > (int)data->width ||
atoi(argv[i+4]) < 0 || atoi(argv[i+4]) > (int)data->height)
{
g_printerr ("Invalid coordinates\n");
wrong_arg = TRUE;
}
else if (atoi(argv[i+6]) < 1)
{
g_printerr ("Thickness must be atleast 1\n");
wrong_arg = TRUE;
}
else
{
data->clientdata = g_strjoin(" ", argv[i+1], argv[i+2], argv[i+3], argv[i+4], argv[i+5], argv[i+6], NULL);
}

action = GA_LINE;
i += 6;
}
else
{
g_printerr ("-l requires 6 parameters: startX, startY, endX, endY, color, thickness\n");
wrong_arg = TRUE;
}
}
else if (strcmp (arg, "-v") == 0 ||
strcmp (arg, "--visibility") == 0)
{
Expand Down Expand Up @@ -1093,6 +1128,7 @@ int main (int argc, char **argv)

gtk_selection_owner_set (data->win, GA_DATA, GDK_CURRENT_TIME);
gtk_selection_add_target (data->win, GA_DATA, GA_TOGGLEDATA, 1007);
gtk_selection_add_target (data->win, GA_DATA, GA_LINEDATA, 1008);



Expand Down
2 changes: 2 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define GA_ACTIVATE gdk_atom_intern ("Gromit/activate", FALSE)
#define GA_DEACTIVATE gdk_atom_intern ("Gromit/deactivate", FALSE)
#define GA_TOGGLE gdk_atom_intern ("Gromit/toggle", FALSE)
#define GA_LINE gdk_atom_intern ("Gromit/line", FALSE)
#define GA_VISIBILITY gdk_atom_intern ("Gromit/visibility", FALSE)
#define GA_CLEAR gdk_atom_intern ("Gromit/clear", FALSE)
#define GA_RELOAD gdk_atom_intern ("Gromit/reload", FALSE)
Expand All @@ -56,6 +57,7 @@

#define GA_DATA gdk_atom_intern ("Gromit/data", FALSE)
#define GA_TOGGLEDATA gdk_atom_intern ("Gromit/toggledata", FALSE)
#define GA_LINEDATA gdk_atom_intern ("Gromit/linedata", FALSE)

#define GROMIT_MAX_UNDO 4

Expand Down

0 comments on commit d30f9b8

Please sign in to comment.