Report no pressed keys -- now it properly plays the input.
[synaesthesia.git] / xlibwrap.cc
blobc8e93d619be18c600b001fce1d99c6f2f8c2260b
1 /* Synaesthesia - program to display sound graphically
2 Copyright (C) 1997 Paul Francis Harrison
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 675 Mass Ave, Cambridge, MA 02139, USA.
18 The author may be contacted at:
19 pfh@yoyo.cc.monash.edu.au
21 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdint.h>
28 #include "syna.h"
30 #ifndef X_DISPLAY_MISSING
32 extern "C" {
33 #include "xlib.h"
36 static xlibparam xparams = { 0, 0, 0 };
37 static xdisplay *d;
39 static bool lowColor, paletteInstalled;
40 static unsigned char mapping[64];
42 static int setOnePalette(int i,int r,int g,int b) {
43 return xalloc_color(d,r*257,g*257,b*257,0);
46 bool XScreen::init(int xHint,int yHint,int widthHint,int heightHint,bool fullscreen) {
47 d = xalloc_display("Synaesthesia",xHint,yHint,widthHint,heightHint,&xparams);
48 if (d == 0) {
49 printf("Opening an X window failed.\n");
50 return false;
53 if (!alloc_image(d)) error("allocating window buffer");
54 outWidth = widthHint;
55 outHeight = heightHint;
57 //XMoveWindow(d->display,d->window,xHint,yHint);
59 #define BOUND(x) ((x) > 255 ? 255 : (x))
60 #define PEAKIFY(x) BOUND((x) - (x)*(255-(x))/255/2)
62 lowColor = (d->depth <= 8);
64 /* if (!lowColor) {
65 for(i=0;i<256;i++)
66 attempt(setPalette(i,PEAKIFY((i&15*16)),
67 PEAKIFY((i&15)*16+(i&15*16)/4),
68 PEAKIFY((i&15)*16)),
69 " in X: could not allocate sufficient palette entries");
70 } else {
71 for(i=0;i<64;i++)
72 attempt(mapping[i] = setPalette(i,PEAKIFY((i&7*8)*4),
73 PEAKIFY((i&7)*32+(i&7*8)*2),
74 PEAKIFY((i&7)*32)),
75 " in X: could not allocate sufficient palette entries");
76 }*/
77 return true;
80 void XScreen::setPalette(unsigned char *palette) {
81 int i;
83 if (paletteInstalled)
84 xfree_colors(d);
86 if (!lowColor) {
87 for(i=0;i<256;i++)
88 attempt(setOnePalette(i,palette[i*3],palette[i*3+1],palette[i*3+2]),
89 " in X: could not allocate sufficient palette entries");
90 } else {
91 const int array[8] = {0,2,5,7,9,11,13,15};
92 for(i=0;i<64;i++) {
93 int p = (array[i&7]+array[i/8]*16) *3;
94 attempt(mapping[i] = setOnePalette(i,palette[p],palette[p+1],palette[p+2]),
95 " in X: could not allocate sufficient palette entries");
99 paletteInstalled = true;
102 void XScreen::end() {
103 if (paletteInstalled)
104 xfree_colors(d);
105 xfree_display(d);
108 void XScreen::inputUpdate(int &mouseX,int &mouseY,int &mouseButtons,char &keyHit) {
109 int newWidth,newHeight;
110 if (xsize_update(d,&newWidth,&newHeight))
111 if (newWidth != outWidth || newHeight != outHeight)
112 allocOutput(newWidth,newHeight);
114 xmouse_update(d);
115 mouseX = xmouse_x(d);
116 mouseY = xmouse_y(d);
117 mouseButtons = xmouse_buttons(d);
118 keyHit = xkeyboard_query(d);
121 void XScreen::show(void) {
122 register uint32_t *ptr2 = (uint32_t*)output;
123 uint32_t *ptr1 = (uint32_t*)d->back;
124 int i = outWidth*outHeight/sizeof(uint32_t);
125 if (lowColor)
126 do {
127 register uint32_t const r1 = *(ptr2++);
128 register uint32_t const r2 = *(ptr2++);
130 //if (r1 || r2) {
131 #ifdef LITTLEENDIAN
132 register uint32_t const v =
133 mapping[((r1&0xe0ul)>>5)|((r1&0xe000ul)>>10)]
134 |mapping[((r1&0xe00000ul)>>21)|((r1&0xe0000000ul)>>26)]*256U;
135 *(ptr1++) = v |
136 mapping[((r2&0xe0ul)>>5)|((r2&0xe000ul)>>10)]*65536U
137 |mapping[((r2&0xe00000ul)>>21)|((r2&0xe0000000ul)>>26)]*16777216U;
138 #else
139 register uint32_t const v =
140 mapping[((r2&0xe0ul)>>5)|((r2&0xe000ul)>>10)]
141 |mapping[((r2&0xe00000ul)>>21)|((r2&0xe0000000ul)>>26)]*256U;
142 *(ptr1++) = v |
143 mapping[((r1&0xe0ul)>>5)|((r1&0xe000ul)>>10)]*65536U
144 |mapping[((r1&0xe00000ul)>>21)|((r1&0xe0000000ul)>>26)]*16777216U;
145 #endif
146 //} else ptr1++;
147 } while (--i);
148 else
149 do {
150 // Asger Alstrup Nielsen's (alstrup@diku.dk)
151 // optimized 32 bit screen loop
152 register uint32_t const r1 = *(ptr2++);
153 register uint32_t const r2 = *(ptr2++);
155 //if (r1 || r2) {
156 #ifdef LITTLEENDIAN
157 register uint32_t const v =
158 ((r1 & 0x000000f0ul) >> 4)
159 | ((r1 & 0x0000f000ul) >> 8)
160 | ((r1 & 0x00f00000ul) >> 12)
161 | ((r1 & 0xf0000000ul) >> 16);
162 *(ptr1++) = v |
163 ((r2 & 0x000000f0ul) << 16 -4)
164 | ((r2 & 0x0000f000ul) << 16 -8)
165 | ((r2 & 0x00f00000ul) << 16 -12)
166 | ((r2 & 0xf0000000ul) << 16 -16);
167 #else
168 register uint32_t const v =
169 ((r2 & 0x000000f0ul) >> 4)
170 | ((r2 & 0x0000f000ul) >> 8)
171 | ((r2 & 0x00f00000ul) >> 12)
172 | ((r2 & 0xf0000000ul) >> 16);
173 *(ptr1++) = v |
174 ((r1 & 0x000000f0ul) << 16 -4)
175 | ((r1 & 0x0000f000ul) << 16 -8)
176 | ((r1 & 0x00f00000ul) << 16 -12)
177 | ((r1 & 0xf0000000ul) << 16 -16);
178 #endif
179 //} else ptr1++;
180 } while (--i);
182 xflip_buffers(d);
183 draw_screen(d);
184 XFlush(d->display);
187 #endif