bugGNU Octave - Bugs: bug #66819, Use Cocoa framework on Apple

 
 

bug #66819: Use Cocoa framework on Apple

Submitter:  Dmitri A. Sergatskov <dasergatskov>
Submitted:  Wed 19 Feb 2025 03:20:39 PM UTC
   
 
Category:  Configuration and Build System Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Other
Status:  Confirmed Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Release: 
Operating System:  * Mac OS Fixed Release:  None
Planned Release:  11.1.0 (current default)
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 12 Mar 2025 11:58:01 PM UTC, comment #6: 

Existing configure.ac has


OCTAVE_HAVE_FRAMEWORK([Carbon],
  [[#include <Carbon/Carbon.h>]], [[CGMainDisplayID ()]],
  [have_framework_carbon=yes], [have_framework_carbon=no])
if test $have_framework_carbon = yes; then
  AC_DEFINE(HAVE_FRAMEWORK_CARBON, 1,
    [Define to 1 if framework CARBON is available.])
  CARBON_LIBS="-framework Carbon"
  AC_MSG_NOTICE([adding -framework Carbon to CARBON_LIBS])
  AC_SUBST(CARBON_LIBS)
fi


The definition HAVE_FRAMEWORK_CARBON is then used 4 times in the Octave code base.


libinterp/corefcn/cdisplay.c:34:#elif defined (HAVE_FRAMEWORK_CARBON)
libinterp/corefcn/cdisplay.c:85:#elif defined (HAVE_FRAMEWORK_CARBON)
src/display-available.c:34:#elif defined (HAVE_FRAMEWORK_CARBON)
src/display-available.c:63:#elif defined (HAVE_FRAMEWORK_CARBON)


To support Cocoa the code block in configure.ac can be duplicated and then appropriate changes made.  There should probably be additional code to make sure only one Framework is selected.

And then presumably the 4 instances in the code base each need a branch with


#elif defined (HAVE_FRAMEWORK_COCOA)


Rik <rik5>
Group administrator
Fri 28 Feb 2025 07:59:39 AM UTC, comment #5: 

No. It still works as it is.
(I think getting wayland working would be a higher priority and that is being pushed to dev...)

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Fri 28 Feb 2025 05:49:21 AM UTC, comment #4: 

@Dmitri: Is this bug one that must be resolved for 10.1?

Rik <rik5>
Group administrator
Wed 19 Feb 2025 11:17:23 PM UTC, comment #3: 

The following code uses CoreGraphics framework (lowere level?)
and it works:

% cat cdisplay_macos4.m
#include <stdio.h>
#include <CoreGraphics/CoreGraphics.h>

const char *
octave_get_display_info(int *ht, int *wd, int *dp, double *rx, double *ry, int *dpy_avail);

int main() {
    int height = 0, width = 0, depth = 0, dpy_avail = 0;
    double rx = 0.0, ry = 0.0;

    const char *msg = octave_get_display_info(&height, &width, &depth, &rx, &ry, &dpy_avail);

    if (msg) {
        printf("Error: %s\n", msg);
        return 1;
    }

    if (dpy_avail) {
        printf("Display Information:\n");
        printf("  Height: %d pixels\n", height);
        printf("  Width: %d pixels\n", width);
        printf("  Depth: %d bits per pixel\n", depth);
        printf("  Horizontal DPI: %.2f\n", rx);
        printf("  Vertical DPI: %.2f\n", ry);
    } else {
        printf("No display information available.\n");
    }

    return 0;
}

const char *
octave_get_display_info(int *ht, int *wd, int *dp, double *rx, double *ry, int *dpy_avail)
{
    const char *msg = NULL;

    *dpy_avail = 0;

    double ht_mm = 0.0;
    double wd_mm = 0.0;

    // Get the main display ID
    CGDirectDisplayID displayID = CGMainDisplayID();

    if (displayID) {
        // Get the screen size in pixels
        *ht = (int)CGDisplayPixelsHigh(displayID);
        *wd = (int)CGDisplayPixelsWide(displayID);

        printf("Size Height = %i\n", *ht);
        printf("Size Width = %i\n", *wd);

        // Get the screen's physical size in millimeters
        CGSize sizeInMillimeters = CGDisplayScreenSize(displayID);
        ht_mm = sizeInMillimeters.height;
        wd_mm = sizeInMillimeters.width;

        printf("ht_mm = %f\n", ht_mm);
        printf("wd_mm = %f\n", wd_mm);

        // Get the current display mode
        CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayID);
        if (mode) {
            // Get the bits per pixel from the display mode
            CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
            if (pixelEncoding) {
                if (CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), 0) == kCFCompareEqualTo) {
                    *dp = 32;
                } else if (CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), 0) == kCFCompareEqualTo) {
                    *dp = 16;
                } else if (CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), 0) == kCFCompareEqualTo) {
                    *dp = 8;
                } else {
                    *dp = 0; // Unknown pixel format
                }
                CFRelease(pixelEncoding);
            }
            CFRelease(mode);
        }

        // Check if the physical dimensions are valid
        if (wd_mm <= 0 || ht_mm <= 0) {
            // Use default DPI if physical dimensions are invalid
            *rx = 96.0;
            *ry = 96.0;
            printf("Warning: Invalid physical dimensions. Using default DPI (96).\n");
        } else {
            // Calculate DPI from physical dimensions
            *rx = *wd * 25.4 / wd_mm;
            *ry = *ht * 25.4 / ht_mm;
        }

        *dpy_avail = 1;
    } else {
        msg = "no graphical display found";
    }

    return msg;
}


But it complains:

 % clang -Wall -framework CoreGraphics  -framework CoreFoundation cdisplay_macos4.m -o cdisplay_macos4
cdisplay_macos4.m:65:41: warning: 'CGDisplayModeCopyPixelEncoding' is deprecated: first deprecated in macOS 10.11 - No longer supported [-Wdeprecated-declarations]
   65 |             CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
      |                                         ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:177:34: note: 'CGDisplayModeCopyPixelEncoding' has been explicitly marked deprecated here
  177 | CG_EXTERN CFStringRef __nullable CGDisplayModeCopyPixelEncoding(
      |                                  ^
1 warning generated.

It runs:

 % ./cdisplay_macos4
Size Height = 1440
Size Width = 2560
ht_mm = 329.513509
wd_mm = 599.299530
Display Information:
  Height: 1440 pixels
  Width: 2560 pixels
  Depth: 32 bits per pixel
  Horizontal DPI: 108.50
  Vertical DPI: 111.00

but because of those deprecation warnings I am not sure if we wins anything with that replacement.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Wed 19 Feb 2025 11:01:28 PM UTC, comment #2: 

Apparently it not trivial to get physical dimensions.
I tried the following code (Note this is Obj-C):

% cat cdisplay_macos.m
#include <stdio.h>

#include <Cocoa/Cocoa.h>
/* LDFLAGS += -framework Cocoa */

const char *
octave_get_display_info (const char *dpy_name, int *ht, int *wd, int *dp,
                         double *rx, double *ry, int *dpy_avail);

int main() {
    int height = 0, width = 0, depth = 0, dpy_avail = 0;
    double rx = 0.0, ry = 0.0;
    const char *dpy_name = NULL; // Use default display

    const char *msg = octave_get_display_info(dpy_name, &height, &width, &depth, &rx, &ry, &dpy_avail);

    if (msg) {
        printf("Error: %s\n", msg);
        return 1;
    }

    if (dpy_avail) {
        printf("Display Information:\n");
        printf("  Height: %d pixels\n", height);
        printf("  Width: %d pixels\n", width);
        printf("  Depth: %d bits per pixel\n", depth);
        printf("  Horizontal DPI: %.2f\n", rx);
        printf("  Vertical DPI: %.2f\n", ry);
    } else {
        printf("No display information available.\n");
    }

    return 0;
}



const char *
octave_get_display_info (const char *dpy_name, int *ht, int *wd, int *dp,
                         double *rx, double *ry, int *dpy_avail)
{
    const char *msg = NULL;

    *dpy_avail = 0;

    double ht_mm = 0.0;
    double wd_mm = 0.0;

    // Get the main screen
    NSScreen *mainScreen = [NSScreen mainScreen];
    if (mainScreen)
    {
        NSRect screenRect = [mainScreen frame];
        *ht = (int)screenRect.size.height;
        *wd = (int)screenRect.size.width;

        printf ("Size Height = %i\n", *ht);
        printf ("Size Width = %i\n", *wd);

        // Get the screen's depth
        NSWindowDepth depth = [mainScreen depth];
        *dp = NSBitsPerPixelFromDepth(depth);

        // Get the screen's physical size in millimeters
        NSDictionary *description = [mainScreen deviceDescription];
        NSSize sizeInMillimeters = [[description objectForKey:NSDeviceSize] sizeValue];
        ht_mm = sizeInMillimeters.height;
        wd_mm = sizeInMillimeters.width;
        printf ("ht_mm = %f\n", ht_mm);
        printf ("wd_mm = %f\n", wd_mm);
        *dpy_avail = 1;
    }
    else
    {
        msg = "no graphical display found";
    }

    if (*dpy_avail)
    {
        if (wd_mm == 0 || ht_mm == 0)
        {
            msg = "screen width or height reported to be zero";

            // Guess a DPI.
            *rx = 96.0;
            *ry = 96.0;
        }
        else
        {
            *rx = *wd * 25.4 / wd_mm;
            *ry = *ht * 25.4 / ht_mm;
        }
    }

    return msg;
}


But it returns:

% ./cdisplay_macos
Size Height = 1440
Size Width = 2560
ht_mm = 1440.000000
wd_mm = 2560.000000
Display Information:
  Height: 1440 pixels
  Width: 2560 pixels
  Depth: 24 bits per pixel
  Horizontal DPI: 25.40
  Vertical DPI: 25.40

I.e. pixels instead of mm. Perhaps I am doing something wrong.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Wed 19 Feb 2025 05:47:03 PM UTC, comment #1: 

This sounds reasonable.  It seems that the last release of Carbon was 2019.  Should the default be Cocoa, but still allow for use of Carbon?  Or should we just get rid of Carbon in configure.ac entirely?  Supporting two things is harder than one, but maybe it is still the right thing to do.

It seems that there is one macro in configure.ac and one macro in m4/acinclude.m4 that will need to be updated.

I don't have a Mac so I don't know which files to check for and can't verify any patch.

And should this be a part of 10.1 release?

Rik <rik5>
Group administrator
Wed 19 Feb 2025 03:20:39 PM UTC, original submission:  

On Apple, Octave still uses Carbon framework. It should switch
to Cocoa.

The affected file(s) are essentially libinterp/corefcn/cdisplay.c
(and the files related to build system).

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by dasergatskov (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-03-12 rik5 Planned ReleaseNone 11.1.0 (current default)
    2025-02-19 rik5 CategoryOctave Function Configuration and Build System
        StatusNone Confirmed

    Back to the top

    Powered by Savane 3.14-7003.
    Corresponding source code