Implement display-monitor-attributes-list for NS.
* lisp/frame.el (display-monitor-attributes-list): Add NS case. (ns-display-monitor-attributes-list): Declare. * src/nsfns.m: Include IOGraphicsLib.h if Cocoa. (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare. (MonitorInfo): New struct. (free_monitors, ns_screen_name, ns_make_monitor_attribute_list) (Fns_display_monitor_attributes_list): New functions. (display-usable-bounds): Remove. (syms_of_nsfns): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes and Qsource.
This commit is contained in:
parent
7583e2a0e2
commit
4465bfb465
5 changed files with 244 additions and 24 deletions
|
@ -4247,6 +4247,9 @@ case "$opsys" in
|
|||
## each); under Cocoa 31 commands are required.
|
||||
if test "$HAVE_NS" = "yes"; then
|
||||
libs_nsgui="-framework AppKit"
|
||||
if test "$NS_IMPL_COCOA" = "yes"; then
|
||||
libs_nsgui="$libs_nsgui -framework IOKit"
|
||||
fi
|
||||
headerpad_extra=6C8
|
||||
else
|
||||
libs_nsgui=
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-05-09 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* frame.el (display-monitor-attributes-list): Add NS case.
|
||||
(ns-display-monitor-attributes-list): Declare.
|
||||
|
||||
2013-05-09 Ulrich Mueller <ulm@gentoo.org>
|
||||
|
||||
* descr-text.el (describe-char): Fix %d/%x typo. (Bug#14360)
|
||||
|
|
|
@ -1495,6 +1495,8 @@ The value is one of the symbols `static-gray', `gray-scale',
|
|||
|
||||
(declare-function x-display-monitor-attributes-list "xfns.c"
|
||||
(&optional terminal))
|
||||
(declare-function ns-display-monitor-attributes-list "nsfns.c"
|
||||
(&optional terminal))
|
||||
|
||||
(defun display-monitor-attributes-list (&optional display)
|
||||
"Return a list of physical monitor attributes on DISPLAY.
|
||||
|
@ -1528,6 +1530,8 @@ monitors."
|
|||
(cond
|
||||
((eq frame-type 'x)
|
||||
(x-display-monitor-attributes-list display))
|
||||
((eq frame-type 'ns)
|
||||
(ns-display-monitor-attributes-list display))
|
||||
(t
|
||||
(let ((geometry (list 0 0 (display-pixel-width display)
|
||||
(display-pixel-height display))))
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2013-05-09 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* nsfns.m: Include IOGraphicsLib.h if Cocoa.
|
||||
(Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare.
|
||||
(MonitorInfo): New struct.
|
||||
(free_monitors, ns_screen_name, ns_make_monitor_attribute_list)
|
||||
(Fns_display_monitor_attributes_list): New functions.
|
||||
(display-usable-bounds): Remove.
|
||||
(syms_of_nsfns): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes and
|
||||
Qsource.
|
||||
|
||||
2013-05-09 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* xterm.h (GTK_PREREQ): Remove, replacing with GTK_CHECK_VERSION.
|
||||
|
|
245
src/nsfns.m
245
src/nsfns.m
|
@ -44,6 +44,10 @@ Updated by Christian Limpach (chris@nice.ch)
|
|||
#include "fontset.h"
|
||||
#include "font.h"
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int fns_trace_num = 1;
|
||||
#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
|
||||
|
@ -101,6 +105,8 @@ Updated by Christian Limpach (chris@nice.ch)
|
|||
static ptrdiff_t image_cache_refcount;
|
||||
#endif
|
||||
|
||||
static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
|
||||
|
||||
/* ==========================================================================
|
||||
|
||||
Internal utility functions
|
||||
|
@ -2321,35 +2327,221 @@ and GNUstep implementations ("distributor-specific release
|
|||
return make_number ((int) [ns_get_screen (display) frame].size.height);
|
||||
}
|
||||
|
||||
struct MonitorInfo {
|
||||
XRectangle geom, work;
|
||||
int mm_width, mm_height;
|
||||
char *name;
|
||||
};
|
||||
|
||||
DEFUN ("display-usable-bounds", Fns_display_usable_bounds,
|
||||
Sns_display_usable_bounds, 0, 1, 0,
|
||||
doc: /* Return the bounds of the usable part of the screen.
|
||||
The return value is a list of integers (LEFT TOP WIDTH HEIGHT), which
|
||||
are the boundaries of the usable part of the screen, excluding areas
|
||||
reserved for the Mac menu, dock, and so forth.
|
||||
|
||||
The screen queried corresponds to DISPLAY, which should be either a
|
||||
frame, a display name (a string), or terminal ID. If omitted or nil,
|
||||
that stands for the selected frame's display. */)
|
||||
(Lisp_Object display)
|
||||
static void
|
||||
free_monitors (struct MonitorInfo *monitors, int n_monitors)
|
||||
{
|
||||
NSScreen *screen;
|
||||
NSRect vScreen;
|
||||
int i;
|
||||
for (i = 0; i < n_monitors; ++i)
|
||||
xfree (monitors[i].name);
|
||||
xfree (monitors);
|
||||
}
|
||||
|
||||
check_ns_display_info (display);
|
||||
screen = ns_get_screen (display);
|
||||
if (!screen)
|
||||
#ifdef NS_IMPL_COCOA
|
||||
/* Returns the name for the screen that DICT came from, or NULL.
|
||||
Caller must free return value.
|
||||
*/
|
||||
|
||||
char *
|
||||
ns_screen_name (CGDirectDisplayID did)
|
||||
{
|
||||
char *name = NULL;
|
||||
NSDictionary *info = (NSDictionary *)
|
||||
IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did),
|
||||
kIODisplayOnlyPreferredName);
|
||||
NSDictionary *names
|
||||
= [info objectForKey:
|
||||
[NSString stringWithUTF8String:kDisplayProductName]];
|
||||
|
||||
if ([names count] > 0) {
|
||||
NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]];
|
||||
if (n != nil)
|
||||
name = xstrdup ([n UTF8String]);
|
||||
}
|
||||
|
||||
[info release];
|
||||
return name;
|
||||
}
|
||||
#endif
|
||||
|
||||
static Lisp_Object
|
||||
ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
|
||||
int n_monitors,
|
||||
int primary_monitor,
|
||||
const char *source)
|
||||
{
|
||||
Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
|
||||
Lisp_Object frame, rest, attributes_list = Qnil;
|
||||
Lisp_Object primary_monitor_attributes = Qnil;
|
||||
NSArray *screens = [NSScreen screens];
|
||||
int i;
|
||||
|
||||
FOR_EACH_FRAME (rest, frame)
|
||||
{
|
||||
struct frame *f = XFRAME (frame);
|
||||
|
||||
if (FRAME_NS_P (f))
|
||||
{
|
||||
NSView *view = FRAME_NS_VIEW (f);
|
||||
NSScreen *screen = [[view window] screen];
|
||||
NSUInteger k;
|
||||
|
||||
i = -1;
|
||||
for (k = 0; i == -1 && k < [screens count]; ++k)
|
||||
{
|
||||
if ([screens objectAtIndex: k] == screen)
|
||||
i = (int)k;
|
||||
}
|
||||
|
||||
if (i > -1)
|
||||
ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n_monitors; ++i)
|
||||
{
|
||||
Lisp_Object geometry, workarea, attributes = Qnil;
|
||||
struct MonitorInfo *mi = &monitors[i];
|
||||
|
||||
if (mi->geom.width == 0) continue;
|
||||
|
||||
workarea = list4i (mi->work.x, mi->work.y,
|
||||
mi->work.width, mi->work.height);
|
||||
geometry = list4i (mi->geom.x, mi->geom.y,
|
||||
mi->geom.width, mi->geom.height);
|
||||
attributes = Fcons (Fcons (Qsource,
|
||||
make_string (source, strlen (source))),
|
||||
attributes);
|
||||
attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
|
||||
attributes);
|
||||
attributes = Fcons (Fcons (Qmm_size,
|
||||
list2i (mi->mm_width, mi->mm_height)),
|
||||
attributes);
|
||||
attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
|
||||
attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
|
||||
if (mi->name)
|
||||
attributes = Fcons (Fcons (Qname, make_string (mi->name,
|
||||
strlen (mi->name))),
|
||||
attributes);
|
||||
|
||||
if (i == primary_monitor)
|
||||
primary_monitor_attributes = attributes;
|
||||
else
|
||||
attributes_list = Fcons (attributes, attributes_list);
|
||||
}
|
||||
|
||||
if (!NILP (primary_monitor_attributes))
|
||||
attributes_list = Fcons (primary_monitor_attributes, attributes_list);
|
||||
return attributes_list;
|
||||
}
|
||||
|
||||
DEFUN ("ns-display-monitor-attributes-list",
|
||||
Fns_display_monitor_attributes_list,
|
||||
Sns_display_monitor_attributes_list,
|
||||
0, 1, 0,
|
||||
doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
|
||||
|
||||
The optional argument TERMINAL specifies which display to ask about.
|
||||
TERMINAL should be a terminal object, a frame or a display name (a string).
|
||||
If omitted or nil, that stands for the selected frame's display.
|
||||
|
||||
In addition to the standard attribute keys listed in
|
||||
`display-monitor-attributes-list', the following keys are contained in
|
||||
the attributes:
|
||||
|
||||
source -- String describing the source from which multi-monitor
|
||||
information is obtained, \"NS\" is always the source."
|
||||
|
||||
Internal use only, use `display-monitor-attributes-list' instead. */)
|
||||
(Lisp_Object terminal)
|
||||
{
|
||||
struct terminal *term = get_terminal (terminal, 1);
|
||||
NSArray *screens;
|
||||
NSUInteger i, n_monitors;
|
||||
struct MonitorInfo *monitors;
|
||||
Lisp_Object attributes_list = Qnil;
|
||||
CGFloat primary_display_height = 0;
|
||||
|
||||
if (term->type != output_ns)
|
||||
return Qnil;
|
||||
|
||||
vScreen = [screen visibleFrame];
|
||||
screens = [NSScreen screens];
|
||||
n_monitors = [screens count];
|
||||
if (n_monitors == 0)
|
||||
return Qnil;
|
||||
|
||||
/* NS coordinate system is upside-down.
|
||||
Transform to screen-specific coordinates. */
|
||||
return list4i (vScreen.origin.x,
|
||||
[screen frame].size.height
|
||||
- vScreen.size.height - vScreen.origin.y,
|
||||
vScreen.size.width, vScreen.size.height);
|
||||
monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
|
||||
|
||||
for (i = 0; i < [screens count]; ++i)
|
||||
{
|
||||
NSScreen *s = [screens objectAtIndex:i];
|
||||
struct MonitorInfo *m = &monitors[i];
|
||||
NSRect fr = [s frame];
|
||||
NSRect vfr = [s visibleFrame];
|
||||
NSDictionary *dict = [s deviceDescription];
|
||||
NSValue *resval = [dict valueForKey:NSDeviceResolution];
|
||||
short y, vy;
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
|
||||
CGDirectDisplayID did = [nid unsignedIntValue];
|
||||
#endif
|
||||
if (i == 0)
|
||||
{
|
||||
primary_display_height = fr.size.height;
|
||||
y = (short) fr.origin.y;
|
||||
vy = (short) vfr.origin.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flip y coordinate as NS has y starting from the bottom.
|
||||
y = (short) (primary_display_height - fr.size.height - fr.origin.y);
|
||||
vy = (short) (primary_display_height -
|
||||
vfr.size.height - vfr.origin.y);
|
||||
}
|
||||
|
||||
m->geom.x = (short) fr.origin.x;
|
||||
m->geom.y = y;
|
||||
m->geom.width = (unsigned short) fr.size.width;
|
||||
m->geom.height = (unsigned short) fr.size.height;
|
||||
|
||||
m->work.x = (short) vfr.origin.x;
|
||||
// y is flipped on NS, so vy - y are pixels missing at the bottom,
|
||||
// and fr.size.height - vfr.size.height are pixels missing in total.
|
||||
// Pixels missing at top are
|
||||
// fr.size.height - vfr.size.height - vy + y.
|
||||
// work.y is then pixels missing at top + y.
|
||||
m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
|
||||
m->work.width = (unsigned short) vfr.size.width;
|
||||
m->work.height = (unsigned short) vfr.size.height;
|
||||
|
||||
#ifdef NS_IMPL_COCOA
|
||||
m->name = ns_screen_name (did);
|
||||
|
||||
{
|
||||
CGSize mms = CGDisplayScreenSize (did);
|
||||
m->mm_width = (int) mms.width;
|
||||
m->mm_height = (int) mms.height;
|
||||
}
|
||||
|
||||
#else
|
||||
// Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
|
||||
m->mm_width = (int) (25.4 * fr.size.width / 92.0);
|
||||
m->mm_height = (int) (25.4 * fr.size.height / 92.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Primary monitor is always first for NS.
|
||||
attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
|
||||
0, "NS");
|
||||
|
||||
free_monitors (monitors, n_monitors);
|
||||
return attributes_list;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2729,6 +2921,11 @@ - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
|
|||
void
|
||||
syms_of_nsfns (void)
|
||||
{
|
||||
DEFSYM (Qgeometry, "geometry");
|
||||
DEFSYM (Qworkarea, "workarea");
|
||||
DEFSYM (Qmm_size, "mm-size");
|
||||
DEFSYM (Qframes, "frames");
|
||||
DEFSYM (Qsource, "source");
|
||||
Qfontsize = intern_c_string ("fontsize");
|
||||
staticpro (&Qfontsize);
|
||||
|
||||
|
@ -2774,7 +2971,7 @@ - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename
|
|||
defsubr (&Sx_server_version);
|
||||
defsubr (&Sx_display_pixel_width);
|
||||
defsubr (&Sx_display_pixel_height);
|
||||
defsubr (&Sns_display_usable_bounds);
|
||||
defsubr (&Sns_display_monitor_attributes_list);
|
||||
defsubr (&Sx_display_mm_width);
|
||||
defsubr (&Sx_display_mm_height);
|
||||
defsubr (&Sx_display_screens);
|
||||
|
|
Loading…
Add table
Reference in a new issue