2 * This file is part of the libCEC(R) library.
4 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
9 * This program is dual-licensed; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
35 #include "lib/platform/os.h"
36 #include "randr-edid.h"
39 #include <X11/Xatom.h>
40 #include <X11/extensions/Xrandr.h>
44 using namespace PLATFORM
;
46 static const char * const edid_names
[] =
48 #if (RANDR_MAJOR > 1) || (RANDR_MAJOR == 1 && RANDR_MINOR >2)
49 RR_PROPERTY_RANDR_EDID
,
54 "XFree86_DDC_EDID1_RAWDATA"
57 #define EDID_NAME_COUNT (sizeof(edid_names)/sizeof(*edid_names))
59 uint16_t CRandrEdidParser::GetPhysicalAddress(void)
61 uint16_t physical_address
= 0;
63 /* open default X11 DISPLAY */
64 Display
*disp
= XOpenDisplay(NULL
);
67 int event_base
, error_base
;
70 if( XRRQueryExtension(disp
, &event_base
, &error_base
)
71 && XRRQueryVersion(disp
, &maj
, &min
) )
73 int version
= (maj
<< 8) | min
;
75 if( version
>= 0x0102 )
77 size_t atom_avail
= 0;
78 Atom edid_atoms
[EDID_NAME_COUNT
];
80 if( XInternAtoms(disp
, (char **)edid_names
, EDID_NAME_COUNT
, True
, edid_atoms
) )
82 /* remove missing some atoms */
84 for(size_t atom_count
=0; atom_count
<EDID_NAME_COUNT
; ++atom_count
)
86 Atom edid_atom
= edid_atoms
[atom_count
];
87 if( None
!= edid_atom
)
89 if( atom_avail
< atom_count
)
91 edid_atoms
[atom_avail
] = edid_atom
;
100 int scr_count
= ScreenCount(disp
);
103 for(screen
=0; screen
<scr_count
; ++screen
)
105 XRRScreenResources
*rsrc
= NULL
;
106 Window root
= RootWindow(disp
, screen
);
108 #if (RANDR_MAJOR > 1) || (RANDR_MAJOR == 1 && RANDR_MINOR >=3)
109 if( version
>= 0x0103 )
111 /* get cached resources if they are available */
112 rsrc
= XRRGetScreenResourcesCurrent(disp
, root
);
117 rsrc
= XRRGetScreenResources(disp
, root
);
122 for( output_id
=0; 0 == physical_address
&& output_id
< rsrc
->noutput
; ++output_id
)
124 RROutput rr_output_id
= rsrc
->outputs
[output_id
];
125 XRROutputInfo
*output_info
= XRRGetOutputInfo(disp
, rsrc
, rr_output_id
);
126 if( NULL
!= output_info
)
128 if( RR_Connected
== output_info
->connection
)
130 for(size_t atom_count
=0; 0 == physical_address
&& atom_count
<atom_avail
; ++atom_count
)
134 unsigned long nitems
;
135 unsigned long bytes_after
;
139 status
= XRRGetOutputProperty(disp
, rr_output_id
, edid_atoms
[atom_count
], 0, 128, False
, False
,
140 AnyPropertyType
, &actual_type
, &actual_format
,
141 &nitems
, &bytes_after
, &data
);
142 if( Success
== status
)
144 if((actual_type
== XA_INTEGER
) && (actual_format
== 8) )
146 physical_address
= CEDIDParser::GetPhysicalAddressFromEDID(data
, nitems
);
152 XRRFreeOutputInfo(output_info
);
155 break; /* problem ? */
157 XRRFreeScreenResources(rsrc
);
165 return physical_address
;