function [window,rect] = OpenWindow(whichScreen,color,rect,pixelSize)
% [window,rect] = OpenWindow(whichScreen,[color],[rect],[pixelSize])
% 
% OBSOLETE: SetClut and the other files in the PsychBeta:TenBitInterface
% directory represent an initial attempt to provide support for 10-bit
% DACs. It was successful, but has been superceded by a more universal
% solution provided by LoadClut. Please use LoadClut, which works with
% the standard Screen 'OpenWindow', without the artificial restrictions
% of OpenWindow.m.
% 
% Call Screen('OpenWindow', ...) and set linear clut/gamma.
% Handles more-than-8-bit-DAC cards (Radius, Radeon) transparently.
% 
% The Radius Thunder, ATI Radeon, and perhaps NVIDIO, have 10-bit DACs.
% The BITS++ adapter from Cambridge Research Systems has 14-bit DACs.
% http://www.crsltd.com/catalog/bits++/
%
% NOTES
%  1) Can only open one window per screen
%  2) Only works for pixel size 8 or 32
%  3) Loads a default gray ramp clut that in 8-bit-pixel
%  mode is backwards from what Screen OpenWindow loads.
%  4) Does not take res structure as a substitute for pixel size.
% 
% This routine is solely for use with SetClut and SetColor.
% Most of the hardware-dependence is in those two routines,
% but doing the open through this routine makes the whole
% suite a little more hardware-independent.
% 
% The attempt to save and restore the CLUT doesn't work because Screen
% GetClut (based on Apple's cscGetEntries) returns the clut AFTER
% transformation by the gamma table. This makes restoring hard.
%
% See also SetClut, SetColor, CloseWindow.

% 9/14/00  dhb  Wrote it.
% 2/1/02   dhb  Simplify.  Assume 8-bits unless explicitly otherwise.
%          dhb  Add global for linear clut in 10-bit mode, to save read in SetClut/SetColor.
%					 dhb  Add global OpenWindowTrue for error checking.
% 2/20/02  dgp	Use Is10Bit instead of the brand-specific calls.
% 2/20/02  dgp	Call ScreenUsesHighGammaBits and shift if necessary.
% 3/26/02  dhb  A few checks for pixel size.
% 3/27/02  dhb  Added code to save/restore clut and gamma, but this doesn't work right.
% 4/03/02  awi  set the default pixel size to be 8 instead of [].  
% 4/19/02  dgp	Cosmetic. Made GAMMA10 a struct. Made OpenWindowTrue a field of that struct.
% 6/6/02   dgp  Updated to use new routine names. Generalized for any ScreenDacBits.

global GAMMA10;

% Handle default args
if nargin < 2 | isempty(color)
	color = [];
end
if nargin < 3 | isempty(rect)
	rect = [];
end
if nargin < 4 | isempty(pixelSize)
	pixelSize = 8;
end

% Check pixel size
if pixelSize ~= 8 & pixelSize ~= 32
	Screen('CloseAll');
	error('OpenWindow only works for pixel size 8 or 32');
end

% Check that we haven't already opened a window on this screen
if exist('GAMMA10','var') & isfield(GAMMA10,'openWindowTrue') & ~isempty(GAMMA10.openWindowTrue) & GAMMA10.openWindowTrue(whichScreen+1)
	Screen('CloseAll');
	error('OpenWindow can open only one window per screen');
end

% Set up GAMMA10 global
if ~exist('GAMMA10','var') | ~isfield(GAMMA10,'openWindowsTrue') | isempty(GAMMA10.openWindowTrue)
	screens = Screen('Screens');
	GAMMA10.openWindowTrue = zeros(size(screens));
	GAMMA10.clut = cell(size(screens));
	GAMMA10.oldClut = cell(size(screens));
	GAMMA10.oldGamma = cell(size(screens));
end

% Create linear tables.
clut = (0:255)'*ones(1,3); % Appropriate only for pixelsize of 8 and 32. Wrong for 1,2,4, or 16.
dacBits=ScreenDacBits(whichScreen);
gammaTable = 257*(0:255)'*ones(1,3); % Ok for all pixelsizes.
gammaTable=bitshift(gammaTable,dacBits-16);% For dacBits-bit-DAC cards. Ok for all pixelsizes.
if ScreenUsesHighGammaBits(whichScreen)
	gammaTable=bitshift(gammaTable,16-dacBits);
end

[window,rect] = Screen(whichScreen,'OpenWindow',color,rect,pixelSize);

GAMMA10.oldClut{whichScreen+1} = Screen(window,'GetClut');
if dacBits>8
	GAMMA10.oldGamma{whichScreen+1} = Screen(window,'Gamma',gammaTable,dacBits);
end
Screen(window,'SetClut',clut);

if 1
	% NOTE: I recommend removing this code because i think the slow performance has been addressed
	% by a Radeon-specific enhancement to Screen.mex (minimum priority and priority dipping). 6/6/02 dgp.
	
	% For ATI Radeon, turn off wait for blanking as driver is terrible if it's
	% on.  SetClut and SetColor put the wait back in explicitly.
	if IsATIRadeon10(whichScreen) | IsATIRadeon10Gen2(whichScreen)
		Screen(window,'Preference','AskSetClutDriverToWaitForBlanking',0);
	end
end

% Set globals for SetClut/SetColor to use later.
GAMMA10.clut{whichScreen+1} = clut;
GAMMA10.openWindowTrue(whichScreen+1) = 1;

