diff options
| author | Jan Djärv | 2013-05-09 17:17:38 +0200 |
|---|---|---|
| committer | Jan Djärv | 2013-05-09 17:17:38 +0200 |
| commit | 4465bfb465ffdecc9422bd2f3cd34440c7710dfa (patch) | |
| tree | 8ddad534e448b0cd115f7747f7e7e59b8ce755b5 | |
| parent | 7583e2a0e23b20ecd29fa0e308e710bde4873ea4 (diff) | |
| download | emacs-4465bfb465ffdecc9422bd2f3cd34440c7710dfa.tar.gz emacs-4465bfb465ffdecc9422bd2f3cd34440c7710dfa.zip | |
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.
| -rw-r--r-- | configure.ac | 3 | ||||
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/frame.el | 4 | ||||
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/nsfns.m | 243 |
5 files changed, 243 insertions, 23 deletions
diff --git a/configure.ac b/configure.ac index fe70676f752..de3bf9d50d8 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -4247,6 +4247,9 @@ case "$opsys" in | |||
| 4247 | ## each); under Cocoa 31 commands are required. | 4247 | ## each); under Cocoa 31 commands are required. |
| 4248 | if test "$HAVE_NS" = "yes"; then | 4248 | if test "$HAVE_NS" = "yes"; then |
| 4249 | libs_nsgui="-framework AppKit" | 4249 | libs_nsgui="-framework AppKit" |
| 4250 | if test "$NS_IMPL_COCOA" = "yes"; then | ||
| 4251 | libs_nsgui="$libs_nsgui -framework IOKit" | ||
| 4252 | fi | ||
| 4250 | headerpad_extra=6C8 | 4253 | headerpad_extra=6C8 |
| 4251 | else | 4254 | else |
| 4252 | libs_nsgui= | 4255 | libs_nsgui= |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5bbfe1a6ff7..3839375c6dc 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2013-05-09 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * frame.el (display-monitor-attributes-list): Add NS case. | ||
| 4 | (ns-display-monitor-attributes-list): Declare. | ||
| 5 | |||
| 1 | 2013-05-09 Ulrich Mueller <ulm@gentoo.org> | 6 | 2013-05-09 Ulrich Mueller <ulm@gentoo.org> |
| 2 | 7 | ||
| 3 | * descr-text.el (describe-char): Fix %d/%x typo. (Bug#14360) | 8 | * descr-text.el (describe-char): Fix %d/%x typo. (Bug#14360) |
diff --git a/lisp/frame.el b/lisp/frame.el index 94a4842fc4e..e1a55bdffc4 100644 --- a/lisp/frame.el +++ b/lisp/frame.el | |||
| @@ -1495,6 +1495,8 @@ The value is one of the symbols `static-gray', `gray-scale', | |||
| 1495 | 1495 | ||
| 1496 | (declare-function x-display-monitor-attributes-list "xfns.c" | 1496 | (declare-function x-display-monitor-attributes-list "xfns.c" |
| 1497 | (&optional terminal)) | 1497 | (&optional terminal)) |
| 1498 | (declare-function ns-display-monitor-attributes-list "nsfns.c" | ||
| 1499 | (&optional terminal)) | ||
| 1498 | 1500 | ||
| 1499 | (defun display-monitor-attributes-list (&optional display) | 1501 | (defun display-monitor-attributes-list (&optional display) |
| 1500 | "Return a list of physical monitor attributes on DISPLAY. | 1502 | "Return a list of physical monitor attributes on DISPLAY. |
| @@ -1528,6 +1530,8 @@ monitors." | |||
| 1528 | (cond | 1530 | (cond |
| 1529 | ((eq frame-type 'x) | 1531 | ((eq frame-type 'x) |
| 1530 | (x-display-monitor-attributes-list display)) | 1532 | (x-display-monitor-attributes-list display)) |
| 1533 | ((eq frame-type 'ns) | ||
| 1534 | (ns-display-monitor-attributes-list display)) | ||
| 1531 | (t | 1535 | (t |
| 1532 | (let ((geometry (list 0 0 (display-pixel-width display) | 1536 | (let ((geometry (list 0 0 (display-pixel-width display) |
| 1533 | (display-pixel-height display)))) | 1537 | (display-pixel-height display)))) |
diff --git a/src/ChangeLog b/src/ChangeLog index e152d8de951..95b15a0f5a0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2013-05-09 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * nsfns.m: Include IOGraphicsLib.h if Cocoa. | ||
| 4 | (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare. | ||
| 5 | (MonitorInfo): New struct. | ||
| 6 | (free_monitors, ns_screen_name, ns_make_monitor_attribute_list) | ||
| 7 | (Fns_display_monitor_attributes_list): New functions. | ||
| 8 | (display-usable-bounds): Remove. | ||
| 9 | (syms_of_nsfns): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes and | ||
| 10 | Qsource. | ||
| 11 | |||
| 1 | 2013-05-09 Paul Eggert <eggert@cs.ucla.edu> | 12 | 2013-05-09 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 13 | ||
| 3 | * xterm.h (GTK_PREREQ): Remove, replacing with GTK_CHECK_VERSION. | 14 | * xterm.h (GTK_PREREQ): Remove, replacing with GTK_CHECK_VERSION. |
diff --git a/src/nsfns.m b/src/nsfns.m index 95fdd516b99..497a856aa10 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -44,6 +44,10 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) | |||
| 44 | #include "fontset.h" | 44 | #include "fontset.h" |
| 45 | #include "font.h" | 45 | #include "font.h" |
| 46 | 46 | ||
| 47 | #ifdef NS_IMPL_COCOA | ||
| 48 | #include <IOKit/graphics/IOGraphicsLib.h> | ||
| 49 | #endif | ||
| 50 | |||
| 47 | #if 0 | 51 | #if 0 |
| 48 | int fns_trace_num = 1; | 52 | int fns_trace_num = 1; |
| 49 | #define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \ | 53 | #define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \ |
| @@ -101,6 +105,8 @@ static int as_status; | |||
| 101 | static ptrdiff_t image_cache_refcount; | 105 | static ptrdiff_t image_cache_refcount; |
| 102 | #endif | 106 | #endif |
| 103 | 107 | ||
| 108 | static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource; | ||
| 109 | |||
| 104 | /* ========================================================================== | 110 | /* ========================================================================== |
| 105 | 111 | ||
| 106 | Internal utility functions | 112 | Internal utility functions |
| @@ -2321,35 +2327,221 @@ If omitted or nil, that stands for the selected frame's display. */) | |||
| 2321 | return make_number ((int) [ns_get_screen (display) frame].size.height); | 2327 | return make_number ((int) [ns_get_screen (display) frame].size.height); |
| 2322 | } | 2328 | } |
| 2323 | 2329 | ||
| 2330 | struct MonitorInfo { | ||
| 2331 | XRectangle geom, work; | ||
| 2332 | int mm_width, mm_height; | ||
| 2333 | char *name; | ||
| 2334 | }; | ||
| 2335 | |||
| 2336 | static void | ||
| 2337 | free_monitors (struct MonitorInfo *monitors, int n_monitors) | ||
| 2338 | { | ||
| 2339 | int i; | ||
| 2340 | for (i = 0; i < n_monitors; ++i) | ||
| 2341 | xfree (monitors[i].name); | ||
| 2342 | xfree (monitors); | ||
| 2343 | } | ||
| 2344 | |||
| 2345 | #ifdef NS_IMPL_COCOA | ||
| 2346 | /* Returns the name for the screen that DICT came from, or NULL. | ||
| 2347 | Caller must free return value. | ||
| 2348 | */ | ||
| 2324 | 2349 | ||
| 2325 | DEFUN ("display-usable-bounds", Fns_display_usable_bounds, | 2350 | char * |
| 2326 | Sns_display_usable_bounds, 0, 1, 0, | 2351 | ns_screen_name (CGDirectDisplayID did) |
| 2327 | doc: /* Return the bounds of the usable part of the screen. | 2352 | { |
| 2328 | The return value is a list of integers (LEFT TOP WIDTH HEIGHT), which | 2353 | char *name = NULL; |
| 2329 | are the boundaries of the usable part of the screen, excluding areas | 2354 | NSDictionary *info = (NSDictionary *) |
| 2330 | reserved for the Mac menu, dock, and so forth. | 2355 | IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did), |
| 2356 | kIODisplayOnlyPreferredName); | ||
| 2357 | NSDictionary *names | ||
| 2358 | = [info objectForKey: | ||
| 2359 | [NSString stringWithUTF8String:kDisplayProductName]]; | ||
| 2360 | |||
| 2361 | if ([names count] > 0) { | ||
| 2362 | NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]]; | ||
| 2363 | if (n != nil) | ||
| 2364 | name = xstrdup ([n UTF8String]); | ||
| 2365 | } | ||
| 2331 | 2366 | ||
| 2332 | The screen queried corresponds to DISPLAY, which should be either a | 2367 | [info release]; |
| 2333 | frame, a display name (a string), or terminal ID. If omitted or nil, | 2368 | return name; |
| 2334 | that stands for the selected frame's display. */) | 2369 | } |
| 2335 | (Lisp_Object display) | 2370 | #endif |
| 2371 | |||
| 2372 | static Lisp_Object | ||
| 2373 | ns_make_monitor_attribute_list (struct MonitorInfo *monitors, | ||
| 2374 | int n_monitors, | ||
| 2375 | int primary_monitor, | ||
| 2376 | const char *source) | ||
| 2377 | { | ||
| 2378 | Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil); | ||
| 2379 | Lisp_Object frame, rest, attributes_list = Qnil; | ||
| 2380 | Lisp_Object primary_monitor_attributes = Qnil; | ||
| 2381 | NSArray *screens = [NSScreen screens]; | ||
| 2382 | int i; | ||
| 2383 | |||
| 2384 | FOR_EACH_FRAME (rest, frame) | ||
| 2385 | { | ||
| 2386 | struct frame *f = XFRAME (frame); | ||
| 2387 | |||
| 2388 | if (FRAME_NS_P (f)) | ||
| 2389 | { | ||
| 2390 | NSView *view = FRAME_NS_VIEW (f); | ||
| 2391 | NSScreen *screen = [[view window] screen]; | ||
| 2392 | NSUInteger k; | ||
| 2393 | |||
| 2394 | i = -1; | ||
| 2395 | for (k = 0; i == -1 && k < [screens count]; ++k) | ||
| 2396 | { | ||
| 2397 | if ([screens objectAtIndex: k] == screen) | ||
| 2398 | i = (int)k; | ||
| 2399 | } | ||
| 2400 | |||
| 2401 | if (i > -1) | ||
| 2402 | ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i))); | ||
| 2403 | } | ||
| 2404 | } | ||
| 2405 | |||
| 2406 | for (i = 0; i < n_monitors; ++i) | ||
| 2407 | { | ||
| 2408 | Lisp_Object geometry, workarea, attributes = Qnil; | ||
| 2409 | struct MonitorInfo *mi = &monitors[i]; | ||
| 2410 | |||
| 2411 | if (mi->geom.width == 0) continue; | ||
| 2412 | |||
| 2413 | workarea = list4i (mi->work.x, mi->work.y, | ||
| 2414 | mi->work.width, mi->work.height); | ||
| 2415 | geometry = list4i (mi->geom.x, mi->geom.y, | ||
| 2416 | mi->geom.width, mi->geom.height); | ||
| 2417 | attributes = Fcons (Fcons (Qsource, | ||
| 2418 | make_string (source, strlen (source))), | ||
| 2419 | attributes); | ||
| 2420 | attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), | ||
| 2421 | attributes); | ||
| 2422 | attributes = Fcons (Fcons (Qmm_size, | ||
| 2423 | list2i (mi->mm_width, mi->mm_height)), | ||
| 2424 | attributes); | ||
| 2425 | attributes = Fcons (Fcons (Qworkarea, workarea), attributes); | ||
| 2426 | attributes = Fcons (Fcons (Qgeometry, geometry), attributes); | ||
| 2427 | if (mi->name) | ||
| 2428 | attributes = Fcons (Fcons (Qname, make_string (mi->name, | ||
| 2429 | strlen (mi->name))), | ||
| 2430 | attributes); | ||
| 2431 | |||
| 2432 | if (i == primary_monitor) | ||
| 2433 | primary_monitor_attributes = attributes; | ||
| 2434 | else | ||
| 2435 | attributes_list = Fcons (attributes, attributes_list); | ||
| 2436 | } | ||
| 2437 | |||
| 2438 | if (!NILP (primary_monitor_attributes)) | ||
| 2439 | attributes_list = Fcons (primary_monitor_attributes, attributes_list); | ||
| 2440 | return attributes_list; | ||
| 2441 | } | ||
| 2442 | |||
| 2443 | DEFUN ("ns-display-monitor-attributes-list", | ||
| 2444 | Fns_display_monitor_attributes_list, | ||
| 2445 | Sns_display_monitor_attributes_list, | ||
| 2446 | 0, 1, 0, | ||
| 2447 | doc: /* Return a list of physical monitor attributes on the X display TERMINAL. | ||
| 2448 | |||
| 2449 | The optional argument TERMINAL specifies which display to ask about. | ||
| 2450 | TERMINAL should be a terminal object, a frame or a display name (a string). | ||
| 2451 | If omitted or nil, that stands for the selected frame's display. | ||
| 2452 | |||
| 2453 | In addition to the standard attribute keys listed in | ||
| 2454 | `display-monitor-attributes-list', the following keys are contained in | ||
| 2455 | the attributes: | ||
| 2456 | |||
| 2457 | source -- String describing the source from which multi-monitor | ||
| 2458 | information is obtained, \"NS\" is always the source." | ||
| 2459 | |||
| 2460 | Internal use only, use `display-monitor-attributes-list' instead. */) | ||
| 2461 | (Lisp_Object terminal) | ||
| 2336 | { | 2462 | { |
| 2337 | NSScreen *screen; | 2463 | struct terminal *term = get_terminal (terminal, 1); |
| 2338 | NSRect vScreen; | 2464 | NSArray *screens; |
| 2465 | NSUInteger i, n_monitors; | ||
| 2466 | struct MonitorInfo *monitors; | ||
| 2467 | Lisp_Object attributes_list = Qnil; | ||
| 2468 | CGFloat primary_display_height = 0; | ||
| 2339 | 2469 | ||
| 2340 | check_ns_display_info (display); | 2470 | if (term->type != output_ns) |
| 2341 | screen = ns_get_screen (display); | 2471 | return Qnil; |
| 2342 | if (!screen) | 2472 | |
| 2473 | screens = [NSScreen screens]; | ||
| 2474 | n_monitors = [screens count]; | ||
| 2475 | if (n_monitors == 0) | ||
| 2343 | return Qnil; | 2476 | return Qnil; |
| 2344 | 2477 | ||
| 2345 | vScreen = [screen visibleFrame]; | 2478 | monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); |
| 2479 | |||
| 2480 | for (i = 0; i < [screens count]; ++i) | ||
| 2481 | { | ||
| 2482 | NSScreen *s = [screens objectAtIndex:i]; | ||
| 2483 | struct MonitorInfo *m = &monitors[i]; | ||
| 2484 | NSRect fr = [s frame]; | ||
| 2485 | NSRect vfr = [s visibleFrame]; | ||
| 2486 | NSDictionary *dict = [s deviceDescription]; | ||
| 2487 | NSValue *resval = [dict valueForKey:NSDeviceResolution]; | ||
| 2488 | short y, vy; | ||
| 2489 | |||
| 2490 | #ifdef NS_IMPL_COCOA | ||
| 2491 | NSNumber *nid = [dict objectForKey:@"NSScreenNumber"]; | ||
| 2492 | CGDirectDisplayID did = [nid unsignedIntValue]; | ||
| 2493 | #endif | ||
| 2494 | if (i == 0) | ||
| 2495 | { | ||
| 2496 | primary_display_height = fr.size.height; | ||
| 2497 | y = (short) fr.origin.y; | ||
| 2498 | vy = (short) vfr.origin.y; | ||
| 2499 | } | ||
| 2500 | else | ||
| 2501 | { | ||
| 2502 | // Flip y coordinate as NS has y starting from the bottom. | ||
| 2503 | y = (short) (primary_display_height - fr.size.height - fr.origin.y); | ||
| 2504 | vy = (short) (primary_display_height - | ||
| 2505 | vfr.size.height - vfr.origin.y); | ||
| 2506 | } | ||
| 2507 | |||
| 2508 | m->geom.x = (short) fr.origin.x; | ||
| 2509 | m->geom.y = y; | ||
| 2510 | m->geom.width = (unsigned short) fr.size.width; | ||
| 2511 | m->geom.height = (unsigned short) fr.size.height; | ||
| 2512 | |||
| 2513 | m->work.x = (short) vfr.origin.x; | ||
| 2514 | // y is flipped on NS, so vy - y are pixels missing at the bottom, | ||
| 2515 | // and fr.size.height - vfr.size.height are pixels missing in total. | ||
| 2516 | // Pixels missing at top are | ||
| 2517 | // fr.size.height - vfr.size.height - vy + y. | ||
| 2518 | // work.y is then pixels missing at top + y. | ||
| 2519 | m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y; | ||
| 2520 | m->work.width = (unsigned short) vfr.size.width; | ||
| 2521 | m->work.height = (unsigned short) vfr.size.height; | ||
| 2522 | |||
| 2523 | #ifdef NS_IMPL_COCOA | ||
| 2524 | m->name = ns_screen_name (did); | ||
| 2525 | |||
| 2526 | { | ||
| 2527 | CGSize mms = CGDisplayScreenSize (did); | ||
| 2528 | m->mm_width = (int) mms.width; | ||
| 2529 | m->mm_height = (int) mms.height; | ||
| 2530 | } | ||
| 2531 | |||
| 2532 | #else | ||
| 2533 | // Assume 92 dpi as x-display-mm-height/x-display-mm-width does. | ||
| 2534 | m->mm_width = (int) (25.4 * fr.size.width / 92.0); | ||
| 2535 | m->mm_height = (int) (25.4 * fr.size.height / 92.0); | ||
| 2536 | #endif | ||
| 2537 | } | ||
| 2538 | |||
| 2539 | // Primary monitor is always first for NS. | ||
| 2540 | attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors, | ||
| 2541 | 0, "NS"); | ||
| 2346 | 2542 | ||
| 2347 | /* NS coordinate system is upside-down. | 2543 | free_monitors (monitors, n_monitors); |
| 2348 | Transform to screen-specific coordinates. */ | 2544 | return attributes_list; |
| 2349 | return list4i (vScreen.origin.x, | ||
| 2350 | [screen frame].size.height | ||
| 2351 | - vScreen.size.height - vScreen.origin.y, | ||
| 2352 | vScreen.size.width, vScreen.size.height); | ||
| 2353 | } | 2545 | } |
| 2354 | 2546 | ||
| 2355 | 2547 | ||
| @@ -2729,6 +2921,11 @@ handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent) | |||
| 2729 | void | 2921 | void |
| 2730 | syms_of_nsfns (void) | 2922 | syms_of_nsfns (void) |
| 2731 | { | 2923 | { |
| 2924 | DEFSYM (Qgeometry, "geometry"); | ||
| 2925 | DEFSYM (Qworkarea, "workarea"); | ||
| 2926 | DEFSYM (Qmm_size, "mm-size"); | ||
| 2927 | DEFSYM (Qframes, "frames"); | ||
| 2928 | DEFSYM (Qsource, "source"); | ||
| 2732 | Qfontsize = intern_c_string ("fontsize"); | 2929 | Qfontsize = intern_c_string ("fontsize"); |
| 2733 | staticpro (&Qfontsize); | 2930 | staticpro (&Qfontsize); |
| 2734 | 2931 | ||
| @@ -2774,7 +2971,7 @@ be used as the image of the icon representing the frame. */); | |||
| 2774 | defsubr (&Sx_server_version); | 2971 | defsubr (&Sx_server_version); |
| 2775 | defsubr (&Sx_display_pixel_width); | 2972 | defsubr (&Sx_display_pixel_width); |
| 2776 | defsubr (&Sx_display_pixel_height); | 2973 | defsubr (&Sx_display_pixel_height); |
| 2777 | defsubr (&Sns_display_usable_bounds); | 2974 | defsubr (&Sns_display_monitor_attributes_list); |
| 2778 | defsubr (&Sx_display_mm_width); | 2975 | defsubr (&Sx_display_mm_width); |
| 2779 | defsubr (&Sx_display_mm_height); | 2976 | defsubr (&Sx_display_mm_height); |
| 2780 | defsubr (&Sx_display_screens); | 2977 | defsubr (&Sx_display_screens); |