ddc1reader.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 144 行

JAVA
144
字号
/*
 * $Id: DDC1Reader.java,v 1.2 2003/12/21 07:59:16 epr Exp $
 */
package org.jnode.driver.video.ddc;

/**
 * Class used to read DDC1 data from a display device
 * 
 * @author Ewout Prangsma (epr@users.sourceforge.net)
 */
public class DDC1Reader implements EDIDConstants {

	private final DisplayDataChannelAPI api;

	/**
	 * Create a new instance
	 * @param api
	 */
	public DDC1Reader(DisplayDataChannelAPI api) {
		this.api = api;
	}

	/**
	 * Read a DDC1 EDID packet
	 * @return The parsed EDID packet
	 * @throws DDC1NoSignalException No DDC1 signal is found, the monitor does not send it, or the videocard does not support it.
	 * @throws DDC1ParseException No valid EDID datablock was found. This can be the result of a small hickup in the connection, so is does not hurd to try it again.
	 */
	public EDID read() throws DDC1NoSignalException, DDC1ParseException {
		api.setupDDC1();
		try {
			testSignal();

			final boolean[] bits = readBits();
			final int start = findStartBit(bits);
			final int length = bits.length;
			final byte[] data = new byte[EDID1_LEN];

			// Convert bits to bytes
			int idx = start;
			for (int i = 0; i < EDID1_LEN; i++) {
				int v = 0;
				for (int j = 0; j < 8; j++) {
					v = v << 1;
					if (bits[idx++]) {
						v |= 0x01;
					}
					if (idx == length) {
						idx = 0;
					}
				}
				data[i] = (byte) v;
				idx++;
				if (idx == length) {
					idx = 0;
				}
			}

			return new EDID(resort(data));
		} finally {
			api.closeDDC1();
		}
	}

	/**
	 * Read a complete packet of EDID1 bits
	 * @return
	 */
	private boolean[] readBits() {
		final int max = EDID1_LEN * BITS_PER_BYTE;
		final boolean[] bits = new boolean[max];
		for (int i = 0; i < max; i++) {
			bits[i] = api.getDDC1Bit();
		}
		return bits;
	}

	/**
	 * Find the start bit
	 * @param bits
	 * @return
	 */
	private int findStartBit(boolean[] bits)
	throws DDC1ParseException {
		final boolean[] comp = new boolean[BITS_PER_BYTE];
		final boolean[] test = new boolean[BITS_PER_BYTE];
		int idx = 0;
		for (int i = 0; i < 9; i++) {
			comp[i] = bits[idx++];
			test[i] = true;
		}
		for (int i = 0; i < 127; i++) {
			for (int j = 0; j < 9; j++) {
				test[j] = test[j] & !(comp[j] ^ bits[idx++]);
			}
		}
		for (int i = 0; i < 9; i++) {
			if (test[i]) {
				return (i + 1);
			}
		}
		throw new DDC1ParseException("Start bit not found");
	}
	
	private byte[] resort(byte[] data)
	throws DDC1ParseException {
		final int max = data.length;
		final byte[] dbldata = new byte[max*2];
		System.arraycopy(data, 0, dbldata, 0, max);
		System.arraycopy(data, 0, dbldata, max, max);
		final int hdrmax = HEADER_SIGNATURE.length;
		for (int i = 0; i < max; i++) {
			int j;
			for (j = 0; j < hdrmax; j++) {
				if (data[i+j] != HEADER_SIGNATURE[j]) {
					break;
				}
			}
			if (j == hdrmax) {
				// We found the header signature at index i
				final byte[] result = new byte[max];
				System.arraycopy(dbldata, i, result, 0, max);
				return result;
			}
		}
		throw new DDC1ParseException("Header not found");
	}

	/**
	 * Test for the presence of a DDC1 signal
	 * @throws DDC1NoSignalException
	 */
	private void testSignal() throws DDC1NoSignalException {
		final boolean old = api.getDDC1Bit();
		for (int count = HEADER * BITS_PER_BYTE; count > 0; count--) {
			if (old != api.getDDC1Bit()) {
				return;
			}
		}
		throw new DDC1NoSignalException("No DDC1 signal detected");
	}

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?