$NetBSD: patch-ab,v 1.1.1.1 2010/03/09 23:20:01 snj Exp $

ed46d97c106471672c571eebd51dedc0508e1225 upstream.

[PATCH] Query size of X11 gamma ramp

It seems since Xorg 7.4, the size of the gamma ramp is no longer 256
in all cases. So we will need to query the gamma size and use the
appropriate size when calling into the X11 API. Quake assumes a 256
valued gamma ramp througout the code, so we need to scale the ramp
passed down via VID_SetGammaRamp accordingly.

--- common/gl_vidlinuxglx.c.orig	2009-07-04 22:43:49.000000000 -0700
+++ common/gl_vidlinuxglx.c	2010-03-08 19:30:56.000000000 -0800
@@ -463,7 +463,8 @@ HandleEvents(void)
 }
 
 void (*VID_SetGammaRamp)(unsigned short ramp[3][256]);
-static unsigned short saved_gamma_ramp[3][256];
+static unsigned short *x11_gamma_ramp;
+static int x11_gamma_size;
 
 void
 signal_handler(int sig)
@@ -471,7 +472,10 @@ signal_handler(int sig)
     printf("Received signal %d, exiting...\n", sig);
     XAutoRepeatOn(x_disp);
     if (VID_SetGammaRamp)
-	VID_SetGammaRamp(saved_gamma_ramp);
+	XF86VidModeSetGammaRamp(x_disp, scrnum, x11_gamma_size,
+				x11_gamma_ramp,
+				x11_gamma_ramp + x11_gamma_size,
+				x11_gamma_ramp + x11_gamma_size * 2);
     XCloseDisplay(x_disp);
     Sys_Quit();
 }
@@ -589,10 +593,25 @@ CheckMultiTextureExtensions(void)
 static void
 VID_SetXF86GammaRamp(unsigned short ramp[3][256])
 {
+    int i;
+    unsigned short *r, *g, *b;
+
     if (!x_disp)
 	Sys_Error("%s: x_disp == NULL!", __func__);
 
-    XF86VidModeSetGammaRamp(x_disp, scrnum, 256, ramp[0], ramp[1], ramp[2]);
+    /*
+     * Need to scale the gamma ramp to the hardware size
+     */
+    r = Hunk_TempAlloc(3 * x11_gamma_size * sizeof(unsigned short));
+    g = r + x11_gamma_size;
+    b = r + x11_gamma_size * 2;
+    for (i = 0; i < x11_gamma_size; i++) {
+	r[i] = ramp[0][i * 256 / x11_gamma_size];
+	g[i] = ramp[1][i * 256 / x11_gamma_size];
+	b[i] = ramp[2][i * 256 / x11_gamma_size];
+    }
+
+    XF86VidModeSetGammaRamp(x_disp, scrnum, x11_gamma_size, r, g, b);
 }
 
 /*
@@ -604,10 +623,23 @@ VID_SetXF86GammaRamp(unsigned short ramp
 static void
 Gamma_Init()
 {
-    if (XF86VidModeGetGammaRamp(x_disp, scrnum, 256,
-				saved_gamma_ramp[0],
-				saved_gamma_ramp[1],
-				saved_gamma_ramp[2]))
+    Bool ret;
+    int size;
+
+    ret = XF86VidModeGetGammaRampSize(x_disp, scrnum, &x11_gamma_size);
+    if (!ret|| !x11_gamma_size) {
+	VID_SetGammaRamp = NULL;
+	return;
+    }
+
+    size = 3 * x11_gamma_size * sizeof(unsigned short);
+    x11_gamma_ramp = Hunk_AllocName(size, "x11_gamma_ramp");
+
+    ret = XF86VidModeGetGammaRamp(x_disp, scrnum, x11_gamma_size,
+				  x11_gamma_ramp,
+				  x11_gamma_ramp + x11_gamma_size,
+				  x11_gamma_ramp + x11_gamma_size * 2);
+    if (ret)
 	VID_SetGammaRamp = VID_SetXF86GammaRamp;
     else
 	VID_SetGammaRamp = NULL;
@@ -993,9 +1025,12 @@ VID_Init(unsigned char *palette)
 void
 VID_Shutdown(void)
 {
-    if (VID_SetGammaRamp)
-	VID_SetGammaRamp(saved_gamma_ramp);
-
+    if (VID_SetGammaRamp) {
+	XF86VidModeSetGammaRamp(x_disp, scrnum, x11_gamma_size,
+				x11_gamma_ramp,
+				x11_gamma_ramp + x11_gamma_size,
+				x11_gamma_ramp + x11_gamma_size * 2);
+    }
     if (x_disp != NULL) {
 	if (ctx != NULL)
 	    glXDestroyContext(x_disp, ctx);
