[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[mgp-users-jp 00925] Forward: Bug#129516: rakugaki mode enhancements (fix included)



こういうパッチがおくられてきたんですが、これはどうでしょうか?

-- 
鵜飼文敏

--- Begin Message ---
Package: mgp
Version: 1.06a.19991206-2

Rakugaki (jot) mode is a great thing for courses, but it's suboptimal given
that mice can't be moved with high precision, usually. Also, using uppercase-X
to change pen color is not practical during presentations.

The following patch adds the following features:
	- use a different lowercase letter for each color
		(so one finger is enough to go to the desired color)
	- change pen width using the keyboard
	- the default width of three pixels is much more perfomant now
	- added modes to draw straight lines, rectangles and ovals
	- capround and jonround is used, to have better result with wide lines

What follow is the detailed description of the implementation:

* the keys in the upper keyboard raw are used to select the color: r,
t, y, u, i, o do red, green, blue, yellow, black white (rationale: R
like red, then colors in order; I for black is like 1 (mark on white
paper), O for white is like 0 (no mark on white paper). X retains the
previous role, so there's no changein default behaviour.

* F1-F8 to select pen width, in increasing order from one pixel (default
is three pixels, like it used to be

* at startup a width of three is selected, as well as capround and joinround

* F9-F12 select the four modes of operation: F9 is the default and
selects "drawing follows mouse" mode, then there are straight line
(F10), rectangle (F11) and oval (F12). Those modes only use the press
location and the release location to draw the item. Line and rect mode
put a dot in the original press location, oval does not as the press
location is not part of the final oval.  Rationale: on most keyboards
the four keys are a separate group, and the modes are from lowest to
highest abstraction from the actual gesture.



returns True. draw.c::draw_one() loops every two seconds internally
and only returns True when it gets an X event to process.

Solution: make draw_one() return False, and fille the (otherwise empty)
while loop in main_loop() to refresh the app, using the same code used
elsewhere. I see no drawbacks in this change as draw_one() is only called
from the condition in while, so the change can't affect anything else.

Thanks for your attention, and for your great work with Debian GNU/Linux
/alessandro

--- ./mgp.c.orig	Tue Dec 18 18:00:41 2001
+++ ./mgp.c	Wed Jan 16 14:59:24 2002
@@ -57,6 +57,7 @@
 static int rakugaki_x = -1;
 static int rakugaki_y = -1;
 static int rakugaki_color = 0;
+static int rakugaki_mode = 0; /* draw, line, rectangle, oval */
 static XColor rakugaki_fore;
 static XColor rakugaki_back;
 static char *rakugaki_forecolors[] = {
@@ -897,7 +898,7 @@
 
 			case XK_b:
 			case XK_k:
-			case XK_p:
+			    /* case XK_p: */
 			case XK_Up:
 			case XK_Prior:
 			case XK_BackSpace:
@@ -936,6 +937,7 @@
 				break;
 
 			case XK_t:
+			    if (shift) {
 				if (tbar_mode)
 					tbar_mode = 0;
 				else {
@@ -943,20 +945,8 @@
 						tbar_mode = 1;
 				}
 				break;
-
-			case XK_Control_L:
-			case XK_Control_R:
-				pl_on(&state);
-				control = 1;
-				number = 0;
-				break;
-
-			case XK_Shift_L:
-			case XK_Shift_R:
-				shift = 1;
-				number = 0;
-				break;
-
+			    }
+			    /* fall through */
 			case XK_r:
 				if (control) {
 reload:
@@ -970,9 +960,64 @@
 						state.page = 1;
 					state_goto(&state, state.page, 1);
 					goto repaint;
+					break;
 				}
+				/* fall through */
+			case XK_y:
+			case XK_u:
+			case XK_i:
+			case XK_o:
+			    rakugaki_color =
+				key == XK_r ? 0 :
+				    key == XK_t ? 1 :
+					key == XK_y ? 2 :
+					    key == XK_u ? 3 :
+						key == XK_i ? 4 : 5;
+			    rakugaki_updatecolor(pen_curs);
+			    XUndefineCursor(display, window);
+			    XDefineCursor(display, window,
+					  pen_curs);
+			    XFlush(display);
+			    break;
+
+			case XK_F1:
+			case XK_F2:
+			case XK_F3:
+			case XK_F4:
+			case XK_F5:
+			case XK_F6:
+			case XK_F7:
+			case XK_F8: {
+			    XGCValues values;
+			    values.line_width = 1+2*(key-XK_F1);
+			    XChangeGC(display, gcpen,
+				      GCLineWidth, &values);
+			}
+			break;
+
+			case XK_F9:
+				rakugaki_mode = 0; break;
+			case XK_F10:
+				rakugaki_mode = 1; break;
+			case XK_F11:
+				rakugaki_mode = 2; break;
+			case XK_F12:
+				rakugaki_mode = 3; break;
+
+			case XK_Control_L:
+			case XK_Control_R:
+				pl_on(&state);
+				control = 1;
+				number = 0;
+				break;
+
+			case XK_Shift_L:
+			case XK_Shift_R:
+				shift = 1;
+				number = 0;
 				break;
 
+
 			case XK_l:	/* used to be control-L */
 repaint:;
 			    {
@@ -1136,40 +1181,52 @@
 	struct render_state *state;
 	XEvent *e;
 {
-	int x, y;
+    int x, y, x1, y1, x2, y2;
+	XButtonReleasedEvent *er = (XButtonReleasedEvent *)e;
 
-	if (e->type == MotionNotify) {
-		XMotionEvent *em;
-		em = (XMotionEvent *)e;
-		x = em->x; y = em->y;
-	} else if (e->type == ButtonPress) {
-		XButtonPressedEvent *eb;
-		eb = (XButtonPressedEvent *)e;
+	if (e->type == ButtonPress) {
+		XButtonPressedEvent *eb = (XButtonPressedEvent *)e;
+		if (eb->button != 1) return;
 		x = eb->x; y = eb->y;
-		if (e->xbutton.button != 1) return;
-	} else {
-		rakugaki_x = rakugaki_y = -1;
+		/* This is, actually, a round dot */
+		if (rakugaki_mode != 3)
+			XDrawLine(display, state->target, gcpen, x, y, x, y);
+		rakugaki_x = x;
+		rakugaki_y = y;
 		return;
 	}
-
-	if (rakugaki_x < 0 || rakugaki_y < 0)
-		XDrawRectangle(display, state->target, gcpen, x, y, 1, 1);
-	else {
-		XDrawLine(display, state->target, gcpen,
-			x, y,
-			rakugaki_x, rakugaki_y);
-		XDrawLine(display, state->target, gcpen,
-			x + 1, y,
-			rakugaki_x + 1, rakugaki_y);
-		XDrawLine(display, state->target, gcpen,
-			x, y + 1,
-			rakugaki_x, rakugaki_y + 1);
+	if (e->type == MotionNotify) {
+		XMotionEvent *em = (XMotionEvent *)e;
+		if (rakugaki_mode != 0) return;
+		x = em->x; y = em->y;
 		XDrawLine(display, state->target, gcpen,
-			x + 1, y + 1,
-			rakugaki_x + 1, rakugaki_y + 1);
+			x, y, rakugaki_x, rakugaki_y);
+		rakugaki_x = x;
+		rakugaki_y = y;
+		return;
+	}
+	/* button release */
+	if (er->button != 1) return;
+	x1 = rakugaki_x; x2 = er->x;
+	y1 = rakugaki_y; y2 = er->y;
+	if (x1>x2) { x2 = x1; x1 = er->x; }
+	if (y1>y2) { y2 = y1; y1 = er->y; }
+	switch (rakugaki_mode) {
+		case 0:
+			return;
+		case 1: 
+			XDrawLine(display, state->target, gcpen, er->x, er->y,
+				rakugaki_x, rakugaki_y);
+			return;
+		case 2:
+			XDrawRectangle(display, state->target, gcpen,
+				x1, y1, x2-x1, y2-y1);
+			return;
+		case 3:
+			XDrawArc(display, state->target, gcpen,
+				x1, y1, x2-x1, y2-y1, 0, 360*64);
+			return;
 	}
-	rakugaki_x = x;
-	rakugaki_y = y;
 }
 
 static void
--- ./x11.c.orig	Sat Jul  3 17:52:47 1999
+++ ./x11.c	Wed Jan 16 14:59:24 2002
@@ -210,6 +210,7 @@
 {
 	XSetWindowAttributes xsa;
 	XSizeHints hints;
+	XGCValues values;
 	u_long mask;
 	struct gcconf *pc;
 	u_long color;
@@ -255,7 +256,13 @@
 			XSetForeground(display, *pc->gc, color);
 		}
 	}
-
+	/* additionally, set line_width, cap style and join style for pen */
+	values.line_width = 3;
+	values.cap_style = CapRound;
+	values.join_style = JoinRound;
+	XChangeGC(display, gcpen, GCLineWidth | GCCapStyle | GCJoinStyle,
+		  &values);
+	   
  	if (mgp_flag & FL_OVER){
 		if (0 <= window_x && 0 <= window_y) {
 			hints.x = window_x;




--- End Message ---