2 * Copyright (C) 2007-2008 Kim Woelders
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies of the Software, its documentation and marketing & publicity
13 * materials, and acknowledgment shall be given in the documentation, materials
14 * and software packages that this Software was used.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 #include <X11/keysym.h>
44 #define ENABLE_DEBUG 1
46 #define Dprintf(fmt...) do { if(EDebug(EDBUG_TYPE_GLX))Eprintf(fmt); } while(0)
47 #define D2printf(fmt...) do { if(EDebug(EDBUG_TYPE_GLX)>1)Eprintf(fmt); } while(0)
49 #define Dprintf(fmt...)
50 #define D2printf(fmt...)
51 #endif /* ENABLE_DEBUG */
67 static void GlwinExit(void);
69 static GLWindow GLWin;
70 static const char *image = "pix/about.png";
72 static char light; /* Lighting on/off */
73 static GLfloat rot_x; /* X rotation */
74 static GLfloat rot_y; /* Y rotation */
75 static GLfloat speed_x; /* X rotation speed */
76 static GLfloat speed_y; /* Y rotation speed */
77 static GLfloat bg_z; /* Background z */
81 static unsigned int sel_bg;
82 static unsigned int filter;
83 static ETexture *texture[N_TEXTURES];
102 /* Texture 0 - None */
107 im = ThemeImageLoad(image);
110 Eprintf("Could not load: %s\n", image);
114 /* Texture 1 - Filter: None */
115 texture[1] = EGlTextureFromImage(im, 0);
117 /* Texture 2 - Filter: Linear */
118 texture[2] = EGlTextureFromImage(im, 1);
120 /* Texture 3 - Mipmap */
121 texture[3] = EGlTextureFromImage(im, 2);
129 /* Texture 4 - BG pixmap */
131 EGlTextureFromDrawable(DeskGetBackgroundPixmap(DesksGetCurrent()),
137 SceneResize(unsigned int width, unsigned int height)
139 Dprintf("SceneResize\n");
141 glViewport(0, 0, width, height);
142 glMatrixMode(GL_PROJECTION);
144 glOrtho(0, width, 0, height, -1000.f, 1000.f);
145 glMatrixMode(GL_MODELVIEW);
148 static GLfloat light_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
149 static GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
150 static GLfloat light_position[] = { 0.0f, 0.0f, 2.0f, 1.0f };
155 glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
156 glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
157 glLightfv(GL_LIGHT1, GL_POSITION, light_position);
167 DrawBackground(ETexture * et, GLfloat w, GLfloat h)
172 glBindTexture(et->target, et->texture);
175 glNormal3f(0.0f, 0.0f, 1.0f);
177 glVertex3f(0, 0, bg_z);
179 glVertex3f(0, h, bg_z);
181 glVertex3f(w, h, bg_z);
183 glVertex3f(w, 0, bg_z);
188 DrawQube(ETexture * et, GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h,
189 GLfloat rx, GLfloat ry)
196 glBindTexture(et->target, et->texture);
202 glTexParameteri(et->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
203 glTexParameteri(et->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
206 glTexParameteri(et->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
207 glTexParameteri(et->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
218 glTranslatef(x, y, z);
220 glScalef(sz, sz, sz);
222 glRotatef(rx, 1.0f, 0.0f, 0.0f); /* Rotate around X axis */
223 glRotatef(ry, 0.0f, 1.0f, 0.0f); /* Rotate around Y axis */
232 glNormal3f(0.0f, 0.0f, 1.0f);
234 glVertex3f(-w2, -h2, t);
236 glVertex3f(w2, -h2, t);
238 glVertex3f(w2, h2, t);
240 glVertex3f(-w2, h2, t);
244 glNormal3f(0.0f, 0.0f, 1.0f);
246 glVertex3f(w2, -h2, -t);
248 glVertex3f(-w2, -h2, -t);
250 glVertex3f(-w2, h2, -t);
252 glVertex3f(w2, h2, -t);
256 glNormal3f(1.0f, 0.0f, 0.0f);
258 glVertex3f(w2, -h2, t);
260 glVertex3f(w2, -h2, -t);
262 glVertex3f(w2, h2, -t);
264 glVertex3f(w2, h2, t);
268 glNormal3f(-1.0f, 0.0f, 0.0f);
270 glVertex3f(-w2, -h2, -t);
272 glVertex3f(-w2, -h2, t);
274 glVertex3f(-w2, h2, t);
276 glVertex3f(-w2, h2, -t);
280 glNormal3f(0.0f, 1.0f, 0.0f);
282 glVertex3f(w2, h2, t);
284 glVertex3f(w2, h2, -t);
286 glVertex3f(-w2, h2, -t);
288 glVertex3f(-w2, h2, t);
292 glNormal3f(0.0f, -1.0f, 0.0f);
294 glVertex3f(w2, -h2, -t);
296 glVertex3f(w2, -h2, t);
298 glVertex3f(-w2, -h2, t);
300 glVertex3f(-w2, -h2, -t);
308 SceneDraw2(double t, EWin ** ewins, int num)
311 GLfloat x, y, w, h, dx, dy, sz;
314 w = EobjGetW(GLWin.eo);
315 h = EobjGetH(GLWin.eo);
318 DrawBackground(texture[sel_bg], w, h);
320 i = sqrt(w * h / (1.0 * num));
321 nx = (w + i - 1) / i;
324 ny = (num + nx - 1) / nx;
328 Eprintf("wxh=%fx%f num=%d nx,ny=%d,%d\n", w, h, num, nx, ny);
330 w = EobjGetW(GLWin.eo) / nx;
331 h = EobjGetH(GLWin.eo) / ny;
334 for (j = 0; j < ny; j++)
336 for (i = 0; i < nx; i++)
342 eo = EoObj(ewins[k]);
343 dx = 100.0f * exp(-t);
344 dx = (fabs(dx) < 1.0) ? 0. : dx * sin(5. * t);
345 dy = 100.0f * exp(-t);
346 dy = (fabs(dy) < 1.0) ? 0. : dy * cos(5. * t);
347 sz = (k == sel_ewin) ? 0.6f : 0.5f;
348 DrawQube(EobjGetTexture(eo),
349 dx + (0.5f + i) * w, dy + (0.5f + j) * h, 500.0f,
350 sz * EobjGetW(eo), sz * EobjGetH(eo), rot_x, rot_y);
354 glColor3f(1., 0., 0.);
355 glRectf(x, y, x + w, y + h);
361 glColor3f(0., 1., 0.);
362 glBegin(GL_LINE_LOOP);
363 glVertex3f(X0, Y0, 0);
364 glVertex3f(X0 + W, Y0, 0);
365 glVertex3f(X0 + W, Y0 + H, 0);
366 glVertex3f(X0, Y0 + H, 0);
368 glColor4f(1., 1., 1., 1.);
377 SceneDraw1(double t, EWin ** ewins, int num)
381 GLfloat w, h, dx, dy, sz;
384 w = EobjGetW(GLWin.eo);
385 h = EobjGetH(GLWin.eo);
387 t1 = 2 * M_PI * (-exp(-(20. * (t - tn))) / num);
389 DrawBackground(texture[sel_bg], w, h);
391 for (i = 0; i < num; i++)
393 arg = t1 + M_PI / 2. - (i - sel_ewin) * 2. * M_PI / num;
394 dx = (.5 + .3 * cos(arg)) * w;
395 dy = (.5 - .3 * sin(arg)) * h;
397 eo = EoObj(ewins[i]);
399 sz = 0.5 + .01 * cos(10. * (t - tn));
402 DrawQube(EobjGetTexture(eo), dx, dy, 500.0,
403 sz * EobjGetW(eo), sz * EobjGetH(eo), rot_x, rot_y);
408 GlwinEwins(int *pnum)
414 ewins = EwinListGetAll(&num);
415 lst = EMALLOC(EWin *, num);
417 for (i = j = 0; i < num; i++)
420 if (!EoIsShown(ewin))
422 if (ewin->props.skip_focuslist || ewin->props.skip_ext_task)
438 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
443 ewins = GlwinEwins(&num);
446 else if (sel_ewin >= num)
448 GLWin.ewin = ewins[sel_ewin];
450 switch (Conf_glwin.mode)
453 SceneDraw1(t, ewins, num);
456 SceneDraw2(t, ewins, num);
460 glXSwapBuffers(disp, EobjGetXwin(GLWin.eo));
469 GlwinRun(void *data __UNUSED__)
478 GlwinKeyPress(GLWindow * gw, KeySym key)
488 if (sel_bg >= N_TEXTURES)
497 case XK_g: /* Toggle grabs */
500 GrabPointerRelease();
501 GrabKeyboardRelease();
506 GrabPointerSet(EobjGetWin(gw->eo), ECSR_GRAB, 0);
507 GrabKeyboardSet(EobjGetWin(gw->eo));
515 glDisable(GL_LIGHTING);
517 glEnable(GL_LIGHTING);
548 Conf_glwin.mode %= 2;
566 EwinOpActivate(gw->ewin, OPSRC_USER, Conf.warplist.raise_on_select);
569 #define TI(no) ((texture[no]) ? (int)texture[no]->texture : -1)
570 Dprintf("bg=%d(%d) filter=%d l=%d z=%.2f spx/y=%.2f/%.2f\n",
571 sel_bg, TI(sel_bg), filter, light, bg_z, speed_x, speed_y);
577 GlwinEvent(Win win __UNUSED__, XEvent * ev, void *prm)
579 GLWindow *gw = (GLWindow *) prm;
587 case EX_EVENT_DAMAGE_NOTIFY:
591 Dprintf("GlwinEvent ev %d\n", ev->type);
598 key = XLookupKeysym(&ev->xkey, ev->xkey.state);
599 done = GlwinKeyPress(gw, key);
603 GrabKeyboardSet(EobjGetWin(GLWin.eo));
606 GrabKeyboardRelease();
610 GlwinKeyPress(gw, XK_g);
611 AnimatorAdd(GlwinRun, NULL);
614 case ConfigureNotify:
615 if (ev->xconfigure.width == EobjGetW(GLWin.eo) &&
616 ev->xconfigure.height == EobjGetH(GLWin.eo))
618 SceneResize(ev->xconfigure.width, ev->xconfigure.height);
628 GlwinCreate(const char *title __UNUSED__, int width, int height)
638 x = ((win->w - width) / 2);
639 y = ((win->h - height) / 2);
641 GLWin.eo = EobjWindowCreate(EOBJ_TYPE_GLX, x, y, width, height, 0, "GLwin");
644 win = EobjGetWin(GLWin.eo);
645 GLWin.eo->fade = GLWin.eo->shadow = 1;
647 EventCallbackRegister(win, 0, GlwinEvent, &GLWin);
649 ESelectInput(win, ExposureMask | KeyPressMask | ButtonPressMask |
650 StructureNotifyMask);
652 EGlWindowConnect(WinGetXwin(win));
657 EobjMap(GLWin.eo, 1);
674 if (GlwinCreate("GLwin", 640, 480))
676 Eprintf("Failed to create window\n");
680 Mode_glwin.active = 1;
684 SceneResize(EobjGetW(GLWin.eo), EobjGetW(GLWin.eo));
694 if (!Mode_glwin.active)
697 Dprintf("GlTestExit\n");
701 EventCallbackUnregister(EobjGetWin(GLWin.eo), 0, GlwinEvent, &GLWin);
703 EobjDestroy(GLWin.eo);
710 for (i = 0; i < N_TEXTURES; i++)
712 EGlTextureDestroy(texture[i]);
717 Mode_glwin.active = 0;
725 GlwinSighan(int sig, void *prm __UNUSED__)
739 GlwinIpc(const char *params)
751 static const IpcItem GlwinIpcArray[] = {
759 #define N_IPC_FUNCS (sizeof(GlwinIpcArray)/sizeof(IpcItem))
761 static const CfgItem GlwinCfgItems[] = {
762 CFG_ITEM_INT(Conf_glwin, mode, 0),
764 #define N_CFG_ITEMS (sizeof(GlwinCfgItems)/sizeof(CfgItem))
769 const EModule ModGlwin = {
772 {N_IPC_FUNCS, GlwinIpcArray},
773 {N_CFG_ITEMS, GlwinCfgItems}