From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Joe Matarazzo Newsgroups: gmane.emacs.devel Subject: [PATCH] Feedback request for x_set_mouse_color on NextSTEP/MacOS Date: Tue, 12 Aug 2014 11:32:50 -0700 Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=e89a8ffbae41209a96050072e6f9 X-Trace: ger.gmane.org 1407868391 1163 80.91.229.3 (12 Aug 2014 18:33:11 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 12 Aug 2014 18:33:11 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Aug 12 20:33:03 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1XHGsV-0004l1-4c for ged-emacs-devel@m.gmane.org; Tue, 12 Aug 2014 20:32:59 +0200 Original-Received: from localhost ([::1]:43520 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XHGsU-0005H1-1B for ged-emacs-devel@m.gmane.org; Tue, 12 Aug 2014 14:32:58 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52019) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XHGsP-0005Gv-PL for emacs-devel@gnu.org; Tue, 12 Aug 2014 14:32:55 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XHGsO-0008RB-5l for emacs-devel@gnu.org; Tue, 12 Aug 2014 14:32:53 -0400 Original-Received: from mail-ig0-x233.google.com ([2607:f8b0:4001:c05::233]:47534) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XHGsN-0008QH-Te for emacs-devel@gnu.org; Tue, 12 Aug 2014 14:32:52 -0400 Original-Received: by mail-ig0-f179.google.com with SMTP id h18so7605560igc.12 for ; Tue, 12 Aug 2014 11:32:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=J7p5ynArO/PmUf6WsM/HsjfMS10gJzcV0lIOoWT8B0w=; b=JdlHUlhlqTwJEjC0Yf+xwd6c/KuAmE3HunRie7xwjN4JlO35nUCOP4WLStXN5+IS4T mman6K4yxu23O9YeW3Y5sh4D/4JxGr2s9i7uRib4s76oyUrg5vJSAhWknPIrVU4lwq94 59S+YflE9o9Qhwl7HwBuaZ3vjDzPb5xuIavFwtqMGIFHf+rFA4qESDy+sbh/i8IphgUw QNryqF1MUKsXtJ3auK7N0nCJhUKJfMr91zXpR1GrKQu0MFjXzh5reJVNsqjIXH1iRchs FCF8lrcXEPRSBp6tkscgp8lAJkqcvBpLgwiGwzw1/vYtHhpxTI8Zpkax+WQ35gKt7u0E hDww== X-Received: by 10.50.107.7 with SMTP id gy7mr589231igb.15.1407868370718; Tue, 12 Aug 2014 11:32:50 -0700 (PDT) Original-Received: by 10.107.157.200 with HTTP; Tue, 12 Aug 2014 11:32:50 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c05::233 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:173604 Archived-At: --e89a8ffbae41209a96050072e6f9 Content-Type: text/plain; charset=UTF-8 Hi, I would like feedback on a patch to enable changing the text and non-text mouse pointer colors on MacOS, via "set-mouse-color". I'm new to Emacs development and objective-C, so I expect I have a sub-optimal and potentially leaky implementation. I chose to only modify those pointers, as my implementation is a bit heavy handed and changes the entire cursor image to the requested color. On the I-beam (text) cursor this is ok, but the (nontext) arrow pointer loses its thin white outline. The other cursors (the modeline and resize pointers) don't suffer the visibility problems the text/nontext pointers do when using a dark frame background, and are left alone. Thanks, Joe -------------- diff --git a/src/nsfns.m b/src/nsfns.m index ca8f492..266ae5b 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -61,11 +61,15 @@ int fns_trace_num = 1; #ifdef HAVE_NS +// Required for set-mouse-color +#import + extern NSArray *ns_send_types, *ns_return_types, *ns_drag_types; extern Lisp_Object Qforeground_color; extern Lisp_Object Qbackground_color; extern Lisp_Object Qcursor_color; +extern Lisp_Object Qmouse_color; extern Lisp_Object Qinternal_border_width; extern Lisp_Object Qvisibility; extern Lisp_Object Qcursor_type; @@ -878,15 +882,90 @@ x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) set_frame_cursor_types (f, arg); } + +#undef Z +static void +changeMouseColor(NSCursor **crs, NSColor *col) +{ + + NSPoint hs = [*crs hotSpot]; + NSImage *img = [*crs image]; + + CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort]; + CIContext *context = [CIContext contextWithCGContext:myContext options:nil]; + + // Convert to CIImage input + NSRect rect; + rect.origin = NSMakePoint(0.0, 0.0); + rect.size = [img size]; + + CGImageRef cgImage = [img CGImageForProposedRect:&rect + context:[NSGraphicsContext currentContext] + hints:nil]; + CIImage *inputImage = [CIImage imageWithCGImage:cgImage]; + + + // Set up the filter path + CIFilter *constColor = [CIFilter filterWithName:@ "CIConstantColorGenerator"]; + CIColor *newColor = [CIColor colorWithCGColor:[col CGColor]]; + [constColor setValue:newColor forKey: kCIInputColorKey]; + + // Needs crop to be usable + constColor = [CIFilter filterWithName:@"CICrop" keysAndValues: + kCIInputImageKey, [constColor valueForKey: kCIOutputImageKey], + @"inputRectangle", [CIVector vectorWithX:0.0f Y:0.0f Z:2.0f W:2.0f], + nil]; + + // Apply a constant color map to change all colors in the image + CIFilter *colorMap = [CIFilter filterWithName:@"CIColorMap"]; + [colorMap setValue:inputImage forKey:kCIInputImageKey]; + [colorMap setValue:[constColor valueForKey: kCIOutputImageKey] + forKey:kCIInputGradientImageKey]; + + + // Render the output image + CIImage *render = [colorMap valueForKey: kCIOutputImageKey]; + CGRect extent = [render extent]; + CGImageRef finalImg = [context createCGImage:render fromRect:extent]; + + NSImage *resultImage = [[NSImage alloc] initWithCGImage:finalImg size:extent.size]; + + if (resultImage) + { + *crs = [[NSCursor alloc] initWithImage:resultImage hotSpot:hs]; + [resultImage release]; + } + else { + error("Could not change cursor"); + } +} + + + /* called to set mouse pointer color, but all other terms use it to initialize pointer types (and don't set the color ;) */ static void x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { - /* don't think we can do this on Nextstep */ + NSColor *col; + if (ns_lisp_to_color (arg, &col)) + { + store_frame_param (f, Qmouse_color, oldval); + error ("Unknown color"); + } + + // Only change text and non-text cursor colors. The pointy hand and resize + // cursors should be okay (ie. easily visible) in their appropriate window + // locations. + if (FRAME_CURSOR(f, text)) changeMouseColor(&FRAME_CURSOR(f, text), col); + if (FRAME_CURSOR(f, nontext)) changeMouseColor(&FRAME_CURSOR(f, nontext), col); + + store_frame_param(f, Qmouse_color, arg); } + + #define Str(x) #x #define Xstr(x) Str(x) diff --git a/src/nsterm.h b/src/nsterm.h index 00a0b54..7c26259 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -736,9 +736,10 @@ struct x_output #define FRAME_DEFAULT_FACE(f) FACE_FROM_ID (f, DEFAULT_FACE_ID) -#define FRAME_NS_VIEW(f) ((f)->output_data.ns->view) +#define FRAME_NS_VIEW(f) ((f)->output_data.ns->view) #define FRAME_CURSOR_COLOR(f) ((f)->output_data.ns->cursor_color) #define FRAME_POINTER_TYPE(f) ((f)->output_data.ns->current_pointer) +#define FRAME_CURSOR(f, t) ((f)->output_data.ns->t##_cursor) #define FRAME_FONT(f) ((f)->output_data.ns->font) --e89a8ffbae41209a96050072e6f9 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi, I would like feedback on a patch to enable changi= ng the text and
non-text mouse pointer colors on MacOS, via "= ;set-mouse-color". I'm new
to Emacs development and obje= ctive-C, so I expect I have a sub-optimal
and potentially leaky implementation.

I chose= to only modify those pointers, as my implementation is a bit
hea= vy handed and changes the entire cursor image to the requested
color. On the I-beam (text) cursor this is ok, but the (nontext) arrow
pointer loses its thin white outline. The other cursors (the modeline=
and resize pointers) don't suffer the visibility problems th= e
text/nontext pointers do when using a dark frame background, and are
left alone.

Thanks,
Joe

--------------

diff --git a/src/= nsfns.m b/src/nsfns.m
index ca8f492..266ae5b 100644
--- a/src/nsfns.m
++= + b/src/nsfns.m
@@ -61,11 +61,15 @@ int fns_trace_num =3D 1;
=C2=A0
=C2=A0#ifdef HAVE_NS
=C2=A0
+// = Required for set-mouse-color
+#import <QuartzCore/CoreImage.h>
+
=C2=A0ex= tern NSArray *ns_send_types, *ns_return_types, *ns_drag_types;
= =C2=A0
=C2=A0extern Lisp_Object Qforeground_color;
=C2= =A0extern Lisp_Object Qbackground_color;
=C2=A0extern Lisp_Object Qcursor_color;
+extern Lisp_Object = Qmouse_color;
=C2=A0extern Lisp_Object Qinternal_border_width;
=C2=A0extern Lisp_Object Qvisibility;
=C2=A0extern Lisp_O= bject Qcursor_type;
@@ -878,15 +882,90 @@ x_set_cursor_type (struct frame *f, Lisp_Object = arg, Lisp_Object oldval)
=C2=A0 =C2=A0set_frame_cursor_types (f, = arg);
=C2=A0}
=C2=A0
+
+#undef Z
+static void
+changeMouseColor(NSCursor **crs, NSColor *col)
+{
+
+ =C2=A0NSPoint hs =C2=A0 =C2=A0=3D [*crs hotSpot];
= + =C2=A0NSImage *img =C2=A0=3D [*crs image];
+
+ =C2=A0= CGContextRef myContext =3D [[NSGraphicsContext currentContext] graphicsPort= ];
+ =C2=A0CIContext *context =C2=A0 =C2=A0 =3D [CIContext contextWithCGC= ontext:myContext options:nil];
+
+ =C2=A0// Convert to = CIImage input
+ =C2=A0NSRect =C2=A0rect;
+ =C2=A0rect.o= rigin =3D NSMakePoint(0.0, 0.0);
+ =C2=A0rect.size =C2=A0 =3D [img size];
+
+ =C2= =A0CGImageRef cgImage =3D [img CGImageForProposedRect:&rect
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 c= ontext:[NSGraphicsContext currentContext]
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 hints:nil];
+ =C2=A0CIImage *inputImage =3D [CIImage image= WithCGImage:cgImage];
+
+
+ =C2=A0// Set up t= he filter path
+ =C2=A0CIFilter *constColor =3D [CIFilter filterW= ithName:@"CIConstantColorGenerator"];
+ =C2=A0CIColor =C2=A0*newColor =C2=A0 =3D [CIColor colorWithCGColor:[= col CGColor]];
+ =C2=A0[constColor setValue:newColor forKey: kCII= nputColorKey];
+
+ =C2=A0// Needs crop to be usable
+ =C2=A0constColor =3D [CIFilter filterWithName:@"CICrop" = keysAndValues:
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 kCIInputImageKey, [constColor valueForKey: kCIOutp= utImageKey],
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 @"inputRectangle", [CIVector v= ectorWithX:0.0f Y:0.0f Z:2.0f W:2.0f],
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 nil];
+
+ =C2=A0// Apply a constant color ma= p to change all colors in the image
+ =C2=A0CIFilter *colorMap = =C2=A0 =3D [CIFilter filterWithName:@"CIColorMap"];
+ = =C2=A0[colorMap setValue:inputImage forKey:kCIInputImageKey];
+ =C2=A0[colorMap setValue:[constColor valueForKey: kCIOutputImageKey]=
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0forKey:kCIInpu= tGradientImageKey];
+
+
+ =C2=A0// Render the= output image
+ =C2=A0CIImage =C2=A0 =C2=A0 =C2=A0*render =3D [co= lorMap valueForKey: kCIOutputImageKey];
+ =C2=A0CGRect =C2=A0 =C2=A0 =C2=A0 =C2=A0extent =3D [render extent];<= /div>
+ =C2=A0CGImageRef =C2=A0finalImg =3D [context createCGImage:rend= er fromRect:extent];
+
+ =C2=A0NSImage *resultImage =3D= [[NSImage alloc] initWithCGImage:finalImg size:extent.size];
+
+ =C2=A0if (resultImage)
+ =C2=A0 =C2=A0{
<= div>+ =C2=A0 =C2=A0 =C2=A0*crs =3D [[NSCursor alloc] initWithImage:resultIm= age hotSpot:hs];
+ =C2=A0 =C2=A0 =C2=A0[resultImage release];
+ =C2=A0 =C2=A0}
+ =C2=A0else {
+ =C2=A0 =C2=A0error("Could not change cursor");
+ =C2= =A0}
+}
+
+
+
=C2=A0/* ca= lled to set mouse pointer color, but all other terms use it to
= =C2=A0 =C2=A0 initialize pointer types (and don't set the color ;) */
=C2=A0static void
=C2=A0x_set_mouse_color (struct frame *f, = Lisp_Object arg, Lisp_Object oldval)
=C2=A0{
- =C2=A0/*= don't think we can do this on Nextstep */
+ =C2=A0NSColor *c= ol;
+ =C2=A0if (ns_lisp_to_color (arg, &col))
+ =C2=A0 =C2=A0{
+ =C2=A0 =C2=A0 =C2=A0store_frame_param (f,= Qmouse_color, oldval);
+ =C2=A0 =C2=A0 =C2=A0error ("Unknow= n color");
+ =C2=A0 =C2=A0}
+
+ =C2=A0//= Only change text and non-text cursor colors. The pointy hand and resize
+ =C2=A0// cursors should be okay (ie. easily visible) in their approp= riate window
+ =C2=A0// locations.
+ =C2=A0if (FRAME_CU= RSOR(f, text)) =C2=A0 =C2=A0changeMouseColor(&FRAME_CURSOR(f, text), co= l);
+ =C2=A0if (FRAME_CURSOR(f, nontext)) changeMouseColor(&F= RAME_CURSOR(f, nontext), col);
+
+ =C2=A0store_frame_param(f, Qmouse_color, arg);
=C2=A0}
=C2=A0
=C2=A0
+
+
=C2=A0#define Str(x) #x
=C2=A0#define Xstr(x) Str(x)
= =C2=A0
diff --git a/src/nsterm.h b/src/nsterm.h
index 00a0b54..7c26259 100644
--- a/src/nsterm.h
+= ++ b/src/nsterm.h
@@ -736,9 +736,10 @@ struct x_output
= =C2=A0
=C2=A0#define FRAME_DEFAULT_FACE(f) FACE_FROM_ID (f, DEFAU= LT_FACE_ID)
=C2=A0
-#define FRAME_NS_VIEW(f) ((f)->output_data.ns->= ;view)
+#define FRAME_NS_VIEW(f) =C2=A0 =C2=A0 =C2=A0((f)->out= put_data.ns->view)
=C2=A0#define FRAME_CURSOR_COLOR(f) ((f)-&g= t;output_data.ns->cursor_color)
=C2=A0#define FRAME_POINTER_TYPE(f) ((f)->output_data.ns->curren= t_pointer)
+#define FRAME_CURSOR(f, t) =C2=A0 =C2=A0((f)->outp= ut_data.ns->t##_cursor)
=C2=A0
=C2=A0#define FRAME_F= ONT(f) ((f)->output_data.ns->font)
=C2=A0
--e89a8ffbae41209a96050072e6f9--