• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2010, 2011 BMW Car IT GmbH
4  * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ****************************************************************************/
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <EGL/egl.h>
23 #include <GLES2/gl2.h>
24 #include "WLEGLSurface.h"
25 #include "WLEyes.h"
26 #include "WLEyesRenderer.h"
27 #include <poll.h>
28 #include <wayland-cursor.h>
29 
30 #define WL_UNUSED(A) (A)=(A)
31 
32 extern int gNeedRedraw;
33 extern int gPointerX;
34 extern int gPointerY;
35 
WaitForEvent(struct wl_display * wlDisplay,int fd)36 int WaitForEvent(struct wl_display* wlDisplay, int fd)
37 {
38     int err;
39 
40     /* Execute every pending event in the display and stop any other thread from placing
41     * events into this display */
42     while (wl_display_prepare_read(wlDisplay) != 0) {
43         wl_display_dispatch_pending(wlDisplay);
44     }
45 
46     if (wl_display_flush(wlDisplay) == -1)
47     {
48         err = wl_display_get_error(wlDisplay);
49         printf("Error communicating with wayland: %d",err);
50         return -1;
51     }
52 
53     /*Wait till an event occurs */
54     struct pollfd pfd[1];
55     pfd[0].fd = fd;
56     pfd[0].events = POLLIN;
57     int pollret = poll(pfd, 1, -1);
58 
59     if (pollret != -1 && (pfd[0].revents & POLLIN))
60     {
61         /* Read the upcoming events from the file descriptor and execute them */
62         wl_display_read_events(wlDisplay);
63         wl_display_dispatch_pending(wlDisplay);
64     }
65     else {
66         /*Unblock other threads, if an error happens */
67         wl_display_cancel_read(wlDisplay);
68     }
69 
70     return 0;
71 }
72 
73 //////////////////////////////////////////////////////////////////////////////
74 
75 static void
set_pointer_image(struct seat_data * context,uint32_t serial)76 set_pointer_image(struct seat_data* context, uint32_t serial)
77 {
78     struct wl_cursor *cursor = NULL;
79     struct wl_cursor_image *image = NULL;
80     struct wl_buffer *buffer = NULL;
81 
82     if (!context->wlPointer || !context->ctx->GetWLCursor()) {
83         fprintf(stderr, "no wlPointer or no wlCursors\n");
84         return;
85     }
86 
87     cursor = context->ctx->GetWLCursor();
88     if (!cursor) {
89         fprintf(stderr, "no cursor pointer set\n");
90         return;
91     }
92 
93     image = cursor->images[0];
94     buffer = wl_cursor_image_get_buffer(image);
95 
96     if (!buffer) {
97         fprintf(stderr, "buffer for cursor not available\n");
98         return;
99     }
100 
101     wl_pointer_set_cursor(context->wlPointer, serial,
102                   context->ctx->GetPointerSurface(),
103                   image->hotspot_x, image->hotspot_y);
104 
105     wl_surface_attach(context->ctx->GetPointerSurface(), buffer, 0, 0);
106 
107     wl_surface_damage(context->ctx->GetPointerSurface(), 0, 0,
108                   image->width, image->height);
109 
110     wl_surface_commit(context->ctx->GetPointerSurface());
111 }
112 
113 static void
PointerHandleEnter(void * data,struct wl_pointer * wlPointer,uint32_t serial,struct wl_surface * wlSurface,wl_fixed_t sx,wl_fixed_t sy)114 PointerHandleEnter(void* data, struct wl_pointer* wlPointer, uint32_t serial,
115                    struct wl_surface* wlSurface, wl_fixed_t sx, wl_fixed_t sy)
116 {
117     WL_UNUSED(wlPointer);
118     WL_UNUSED(wlSurface);
119     WL_UNUSED(sx);
120     WL_UNUSED(sy);
121 
122     struct seat_data* context =
123                    static_cast<struct seat_data*>(data);
124 
125     set_pointer_image(context, serial);
126     printf("ENTER EGLWLINPUT PointerHandleEnter: x(%d), y(%d)\n",
127            wl_fixed_to_int(sx), wl_fixed_to_int(sy));
128 }
129 
130 static void
PointerHandleLeave(void * data,struct wl_pointer * wlPointer,uint32_t serial,struct wl_surface * wlSurface)131 PointerHandleLeave(void* data, struct wl_pointer* wlPointer, uint32_t serial,
132                    struct wl_surface* wlSurface)
133 {
134     WL_UNUSED(data);
135     WL_UNUSED(wlPointer);
136     WL_UNUSED(serial);
137     WL_UNUSED(wlSurface);
138     printf("ENTER EGLWLINPUT PointerHandleLeave: serial(%d)\n", serial);
139 }
140 
141 static void
PointerHandleMotion(void * data,struct wl_pointer * wlPointer,uint32_t time,wl_fixed_t sx,wl_fixed_t sy)142 PointerHandleMotion(void* data, struct wl_pointer* wlPointer, uint32_t time,
143                     wl_fixed_t sx, wl_fixed_t sy)
144 {
145     WL_UNUSED(data);
146     WL_UNUSED(wlPointer);
147     WL_UNUSED(time);
148     gPointerX = (int)wl_fixed_to_double(sx);
149     gPointerY = (int)wl_fixed_to_double(sy);
150     printf("ENTER EGLWLINPUT PointerHandleMotion: x(%d), y(%d)\n", gPointerX, gPointerY);
151     gNeedRedraw = 1;
152 }
153 
154 static void
PointerHandleButton(void * data,struct wl_pointer * wlPointer,uint32_t serial,uint32_t time,uint32_t button,uint32_t state)155 PointerHandleButton(void* data, struct wl_pointer* wlPointer, uint32_t serial,
156                     uint32_t time, uint32_t button, uint32_t state)
157 {
158     WL_UNUSED(data);
159     WL_UNUSED(wlPointer);
160     WL_UNUSED(serial);
161     WL_UNUSED(time);
162     WL_UNUSED(button);
163     WL_UNUSED(state);
164     printf("ENTER EGLWLINPUT PointerHandleButton: button(%d), state(%d)\n", button, state);
165 }
166 
167 static void
PointerHandleAxis(void * data,struct wl_pointer * wlPointer,uint32_t time,uint32_t axis,wl_fixed_t value)168 PointerHandleAxis(void* data, struct wl_pointer* wlPointer, uint32_t time,
169                   uint32_t axis, wl_fixed_t value)
170 {
171     WL_UNUSED(data);
172     WL_UNUSED(wlPointer);
173     WL_UNUSED(time);
174     WL_UNUSED(axis);
175     WL_UNUSED(value);
176     printf("ENTER EGLWLINPUT PointerHandleAxis: axis(%d), value(%d)\n", axis, wl_fixed_to_int(value));
177 }
178 
179 static void
PointerHandleFrame(void * data,struct wl_pointer * wlPointer)180 PointerHandleFrame(void* data, struct wl_pointer* wlPointer)
181 {
182     WL_UNUSED(data);
183     WL_UNUSED(wlPointer);
184     printf("ENTER EGLWLINPUT PointerHandleFrame\n");
185 }
186 
187 static void
PointerHandleAxisSource(void * data,struct wl_pointer * wlPointer,uint32_t axisSource)188 PointerHandleAxisSource(void* data, struct wl_pointer* wlPointer, uint32_t axisSource)
189 {
190     WL_UNUSED(data);
191     WL_UNUSED(wlPointer);
192     printf("ENTER EGLWLINPUT PointerHandleAxisSource: axisSource(%d)\n", axisSource);
193 }
194 
195 static void
PointerHandleAxisStop(void * data,struct wl_pointer * wlPointer,uint32_t time,uint32_t axis)196 PointerHandleAxisStop(void* data, struct wl_pointer* wlPointer, uint32_t time,
197                            uint32_t axis)
198 {
199     WL_UNUSED(data);
200     WL_UNUSED(wlPointer);
201     WL_UNUSED(time);
202     printf("ENTER EGLWLINPUT PointerHandleAxisStop: axis(%d)\n", axis);
203 }
204 
205 static void
PointerHandleAxisDiscrete(void * data,struct wl_pointer * wlPointer,uint32_t axis,int32_t discrete)206 PointerHandleAxisDiscrete(void* data, struct wl_pointer* wlPointer,
207                                uint32_t axis, int32_t discrete)
208 {
209     WL_UNUSED(data);
210     WL_UNUSED(wlPointer);
211     printf("ENTER EGLWLINPUT PointerHandleAxisDiscrete: axis(%d), value(%d)\n", axis, discrete);
212 }
213 
214 //////////////////////////////////////////////////////////////////////////////
215 
216 static void
KeyboardHandleKeymap(void * data,struct wl_keyboard * keyboard,uint32_t format,int fd,uint32_t size)217 KeyboardHandleKeymap(void* data, struct wl_keyboard* keyboard,
218                      uint32_t format, int fd, uint32_t size)
219 {
220     WL_UNUSED(data);
221     WL_UNUSED(keyboard);
222     WL_UNUSED(format);
223     WL_UNUSED(fd);
224     WL_UNUSED(size);
225     printf("ENTER EGLWLINPUT KeyboardHandleKeymap: format(%d), fd(%d), size(%d)\n",
226         format, fd, size);
227 }
228 
229 static void
KeyboardHandleEnter(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)230 KeyboardHandleEnter(void* data, struct wl_keyboard* keyboard, uint32_t serial,
231                     struct wl_surface* surface, struct wl_array* keys)
232 {
233     WL_UNUSED(data);
234     WL_UNUSED(keyboard);
235     WL_UNUSED(serial);
236     WL_UNUSED(surface);
237     WL_UNUSED(keys);
238     printf("ENTER EGLWLINPUT KeyboardHandleEnter: serial(%d), surface(%p)\n",
239         serial, surface);
240 }
241 
242 static void
KeyboardHandleLeave(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface)243 KeyboardHandleLeave(void* data, struct wl_keyboard* keyboard, uint32_t serial,
244                     struct wl_surface* surface)
245 {
246     WL_UNUSED(data);
247     WL_UNUSED(keyboard);
248     WL_UNUSED(serial);
249     WL_UNUSED(surface);
250     printf("ENTER EGLWLINPUT KeyboardHandleLeave: serial(%d), surface(%p)\n",
251         serial, surface);
252 }
253 
254 static void
KeyboardHandleKey(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state_w)255 KeyboardHandleKey(void* data, struct wl_keyboard* keyboard, uint32_t serial,
256                   uint32_t time, uint32_t key, uint32_t state_w)
257 {
258     WL_UNUSED(data);
259     WL_UNUSED(keyboard);
260     WL_UNUSED(serial);
261     WL_UNUSED(time);
262     WL_UNUSED(key);
263     WL_UNUSED(state_w);
264     printf("ENTER EGLWLINPUT KeyboardHandleKey: serial(%d), time(%d), key(%d), state_w(%d)\n",
265         serial, time, key, state_w);
266 }
267 
268 static void
KeyboardHandleModifiers(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)269 KeyboardHandleModifiers(void* data, struct wl_keyboard* keyboard, uint32_t serial,
270                         uint32_t mods_depressed, uint32_t mods_latched,
271                         uint32_t mods_locked, uint32_t group)
272 {
273     WL_UNUSED(data);
274     WL_UNUSED(keyboard);
275     WL_UNUSED(serial);
276     WL_UNUSED(mods_depressed);
277     WL_UNUSED(mods_latched);
278     WL_UNUSED(mods_locked);
279     WL_UNUSED(group);
280     printf("ENTER EGLWLINPUT KeyboardHandleModifiers: serial(%d), mods_depressed(%d)\n"
281           "                               mods_latched(%d), mods_locked(%d)\n"
282            "                               group(%d)\n",
283         serial, mods_depressed, mods_latched, mods_locked, group);
284 }
285 
286 static void
KeyboardHandleRepeatInfo(void * data,struct wl_keyboard * keyboard,int32_t rate,int32_t delay)287 KeyboardHandleRepeatInfo(void* data, struct wl_keyboard* keyboard, int32_t rate,
288                           int32_t delay)
289 {
290     WL_UNUSED(data);
291     WL_UNUSED(keyboard);
292     printf("ENTER EGLWLINPUT KeyboardHandleRepeatInfo: rate(%d), delay(%d)\n",
293             rate, delay);
294 }
295 
296 //////////////////////////////////////////////////////////////////////////////
297 
298 static void
TouchHandleDown(void * data,struct wl_touch * touch,uint32_t serial,uint32_t time,struct wl_surface * surface,int32_t id,wl_fixed_t xw,wl_fixed_t yw)299 TouchHandleDown(void* data, struct wl_touch* touch, uint32_t serial, uint32_t time,
300                 struct wl_surface* surface, int32_t id, wl_fixed_t xw, wl_fixed_t yw)
301 {
302     WL_UNUSED(data);
303     WL_UNUSED(touch);
304     WL_UNUSED(serial);
305     WL_UNUSED(time);
306     WL_UNUSED(surface);
307     WL_UNUSED(id);
308     WL_UNUSED(xw);
309     WL_UNUSED(yw);
310     gPointerX = (int)wl_fixed_to_double(xw);
311     gPointerY = (int)wl_fixed_to_double(yw);
312     gNeedRedraw = 1;
313     printf("ENTER EGLWLINPUT TouchHandleDown id: %d, x: %d,y: %d \n",id,gPointerX,gPointerY);
314 }
315 
316 static void
TouchHandleUp(void * data,struct wl_touch * touch,uint32_t serial,uint32_t time,int32_t id)317 TouchHandleUp(void* data, struct wl_touch* touch, uint32_t serial, uint32_t time, int32_t id)
318 {
319     WL_UNUSED(data);
320     WL_UNUSED(touch);
321     WL_UNUSED(serial);
322     WL_UNUSED(time);
323     WL_UNUSED(id);
324     printf("ENTER EGLWLINPUT TouchHandleUp\n");
325 }
326 
327 static void
TouchHandleMotion(void * data,struct wl_touch * touch,uint32_t time,int32_t id,wl_fixed_t xw,wl_fixed_t yw)328 TouchHandleMotion(void* data, struct wl_touch* touch, uint32_t time, int32_t id,
329                   wl_fixed_t xw, wl_fixed_t yw)
330 {
331     WL_UNUSED(data);
332     WL_UNUSED(touch);
333     WL_UNUSED(time);
334     WL_UNUSED(id);
335     WL_UNUSED(xw);
336     WL_UNUSED(yw);
337     gPointerX = (int)wl_fixed_to_double(xw);
338     gPointerY = (int)wl_fixed_to_double(yw);
339     printf("ENTER EGLWLINPUT TouchHandleMotion id: %d, x: %d,y: %d \n",id,gPointerX,gPointerY);
340     gNeedRedraw = 1;
341 }
342 
343 static void
TouchHandleFrame(void * data,struct wl_touch * touch)344 TouchHandleFrame(void* data, struct wl_touch* touch)
345 {
346     WL_UNUSED(data);
347     WL_UNUSED(touch);
348 }
349 
350 static void
TouchHandleCancel(void * data,struct wl_touch * touch)351 TouchHandleCancel(void* data, struct wl_touch* touch)
352 {
353     WL_UNUSED(data);
354     WL_UNUSED(touch);
355 }
356 
TouchHandleShape(void * data,struct wl_touch * touch,int32_t id,wl_fixed_t major,wl_fixed_t minor)357 static void TouchHandleShape(void* data, struct wl_touch* touch, int32_t id,
358                              wl_fixed_t major, wl_fixed_t minor)
359 {
360     WL_UNUSED(data);
361     WL_UNUSED(touch);
362     WL_UNUSED(id);
363     WL_UNUSED(major);
364     WL_UNUSED(minor);
365     printf("ENTER EGLWLINPUT TouchHandleShape\n");
366 }
367 
368 static void
TouchHandleOrientation(void * data,struct wl_touch * touch,int32_t id,wl_fixed_t orientation)369 TouchHandleOrientation(void* data, struct wl_touch* touch,
370                        int32_t id, wl_fixed_t orientation)
371 {
372     WL_UNUSED(data);
373     WL_UNUSED(touch);
374     WL_UNUSED(id);
375     WL_UNUSED(orientation);
376     printf("ENTER EGLWLINPUT TouchHandleOrientation\n");
377 }
378 
379 const struct wl_pointer_listener PointerListener = {
380     PointerHandleEnter,
381     PointerHandleLeave,
382     PointerHandleMotion,
383     PointerHandleButton,
384     PointerHandleAxis,
385     PointerHandleFrame,
386     PointerHandleAxisSource,
387     PointerHandleAxisStop,
388     PointerHandleAxisDiscrete
389 };
390 
391 const struct wl_keyboard_listener KeyboardListener = {
392     KeyboardHandleKeymap,
393     KeyboardHandleEnter,
394     KeyboardHandleLeave,
395     KeyboardHandleKey,
396     KeyboardHandleModifiers,
397     KeyboardHandleRepeatInfo
398 };
399 
400 const struct wl_touch_listener TouchListener = {
401     TouchHandleDown,
402     TouchHandleUp,
403     TouchHandleMotion,
404     TouchHandleFrame,
405     TouchHandleCancel,
406     TouchHandleShape,
407     TouchHandleOrientation
408 };
409 
410 //////////////////////////////////////////////////////////////////////////////
411 
412 typedef struct _es2shaderobject {
413     GLuint fragmentShaderId;
414     GLuint vertexShaderId;
415     GLuint shaderProgramId;
416     GLint  matrixLocation;
417     GLint  colorLocation;
418 } ES2ShaderObject;
419 
420 typedef struct _es2vertexbufferobject {
421     GLuint vbo;
422 } ES2VertexBuffer;
423 
424 static ES2ShaderObject gShaderObject;
425 static ES2VertexBuffer gVertexBuffer;
426 
427 // Fragment shader code
428 const char* sourceFragShader = "  \
429     uniform mediump vec4 u_color; \
430     void main(void)               \
431     {                             \
432         gl_FragColor = u_color;   \
433     }";
434 
435 // Vertex shader code
436 const char* sourceVertexShader = " \
437     attribute highp vec4 a_vertex; \
438     uniform mediump mat4 u_matrix; \
439     void main(void)                \
440     {                              \
441         gl_Position = u_matrix * a_vertex; \
442     }";
443 
444 //////////////////////////////////////////////////////////////////////////////
445 
446 bool
InitRenderer()447 InitRenderer()
448 {
449     glViewport(0, 0, 400, 240);
450 
451     if (!InitShader()){
452         return false;
453     }
454 
455     if (!InitVertexBuffer()){
456         return false;
457     }
458 
459     glClearColor(0.2, 0.2, 0.2, 1.0);
460     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
461     glEnable(GL_BLEND);
462     return true;
463 }
464 
465 void
TerminateRenderer()466 TerminateRenderer()
467 {
468     glDeleteProgram(gShaderObject.shaderProgramId);
469     glDeleteShader(gShaderObject.fragmentShaderId);
470     glDeleteShader(gShaderObject.vertexShaderId);
471 
472     glDeleteBuffers(1, &gVertexBuffer.vbo);
473 }
474 
475 char*
BuildShaderErrorLog(GLuint id)476 BuildShaderErrorLog(GLuint id)
477 {
478     int l, nChar;
479     glGetShaderiv(id, GL_INFO_LOG_LENGTH, &l);
480 
481     char* info = (char*)malloc(sizeof(char) * l);
482     glGetShaderInfoLog(id, l, &nChar, info);
483 
484     return info;
485 }
486 
487 bool
InitShader()488 InitShader()
489 {
490     GLint result = 0;
491     char* log = NULL;
492 
493     // Create the fragment shader object
494     gShaderObject.fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
495     glShaderSource(gShaderObject.fragmentShaderId, 1,
496         (const char**)&sourceFragShader, NULL);
497     glCompileShader(gShaderObject.fragmentShaderId);
498 
499     glGetShaderiv(gShaderObject.fragmentShaderId, GL_COMPILE_STATUS, &result);
500     if (!result){
501         log = BuildShaderErrorLog(gShaderObject.fragmentShaderId);
502         fprintf(stderr, "Failed to compile fragment shader: %s\n", log);
503         if (log) free(log);
504         return false;
505     }
506 
507     // Create the vertex shader object
508     gShaderObject.vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
509     glShaderSource(gShaderObject.vertexShaderId, 1,
510         (const char**)&sourceVertexShader, NULL);
511     glCompileShader(gShaderObject.vertexShaderId);
512 
513     glGetShaderiv(gShaderObject.vertexShaderId, GL_COMPILE_STATUS, &result);
514     if (!result){
515         log = BuildShaderErrorLog(gShaderObject.vertexShaderId);
516         fprintf(stderr, "Failed to compile fragment shader: %s\n", log);
517         if (log) free(log);
518         return false;
519     }
520 
521     gShaderObject.shaderProgramId = glCreateProgram();
522 
523     glAttachShader(gShaderObject.shaderProgramId, gShaderObject.fragmentShaderId);
524     glAttachShader(gShaderObject.shaderProgramId, gShaderObject.vertexShaderId);
525 
526     glBindAttribLocation(gShaderObject.shaderProgramId, 0, "a_vertex");
527 
528     glLinkProgram(gShaderObject.shaderProgramId);
529 
530     glGetProgramiv(gShaderObject.shaderProgramId, GL_LINK_STATUS, &result);
531     if (!result){
532         log = BuildShaderErrorLog(gShaderObject.shaderProgramId);
533         fprintf(stderr, "Failed to compile fragment shader: %s\n", log);
534         if (log) free(log);
535         return false;
536     }
537 
538     glUseProgram(gShaderObject.shaderProgramId);
539     gShaderObject.matrixLocation = glGetUniformLocation(
540         gShaderObject.shaderProgramId, "u_matrix");
541     gShaderObject.colorLocation = glGetUniformLocation(
542         gShaderObject.shaderProgramId, "u_color");
543 
544     return true;
545 }
546 
547 bool
InitVertexBuffer()548 InitVertexBuffer()
549 {
550     glGenBuffers(1, &gVertexBuffer.vbo);
551     glBindBuffer(GL_ARRAY_BUFFER, gVertexBuffer.vbo);
552 
553     unsigned int uiSize = 100 * (sizeof(GLfloat) * 2);
554     glBufferData(GL_ARRAY_BUFFER, uiSize, NULL, GL_STATIC_DRAW);
555 
556     return true;
557 }
558 
559 void
AttachVertexBuffer()560 AttachVertexBuffer()
561 {
562     glBindBuffer(GL_ARRAY_BUFFER, gVertexBuffer.vbo);
563     glEnableVertexAttribArray(0);
564     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
565 }
566 
567 void
DetachVertexBuffer()568 DetachVertexBuffer()
569 {
570     glBindBuffer(GL_ARRAY_BUFFER, 0);
571 }
572 
FrameListenerFunc(void *,struct wl_callback * cb,uint32_t)573 static void FrameListenerFunc(void*, struct wl_callback* cb, uint32_t)
574 {
575     if (cb){
576         wl_callback_destroy(cb);
577     }
578 }
579 
580 static const struct wl_callback_listener FrameListener = {
581     FrameListenerFunc,
582 };
583 
584 void
DrawFillPoly(const int nPoint,const float * points,const float color[4])585 DrawFillPoly(const int nPoint, const float* points, const float color[4])
586 {
587     glUniform4fv(gShaderObject.colorLocation, 1, color);
588 
589     unsigned int uiSize = nPoint * (sizeof(GLfloat) * 2);
590     glBufferSubData(GL_ARRAY_BUFFER, 0, uiSize, points);
591 
592     glDrawArrays(GL_TRIANGLE_FAN, 0, nPoint);
593 }
594 
595 void
DrawPoly(const int nPoint,const float * points,const float color[4],int width)596 DrawPoly(const int nPoint, const float* points, const float color[4], int width)
597 {
598     glLineWidth(width);
599 
600     glUniform4fv(gShaderObject.colorLocation, 1, color);
601 
602     unsigned int uiSize = nPoint * (sizeof(GLfloat) * 2);
603     glBufferSubData(GL_ARRAY_BUFFER, 0, uiSize, points);
604 
605     glDrawArrays(GL_LINE_STRIP, 0, nPoint);
606 }
607 
608 bool
DrawEyes(WLEGLSurface * surface,WLEyes * eyes)609 DrawEyes(WLEGLSurface* surface, WLEyes* eyes)
610 {
611     glClear(GL_COLOR_BUFFER_BIT);
612     glUseProgram(gShaderObject.shaderProgramId);
613 
614     AttachVertexBuffer();
615     {
616         float a = 2.0 / 400.0;
617         float b = 2.0 / 240.0;
618         float mtx[16] = {   a,  0.0, 0.0, 0.0,
619                           0.0,    b, 0.0, 0.0,
620                           0.0,  0.0, 1.0, 0.0,
621                          -1.0, -1.0, 0.0, 1.0};
622 
623         glUniformMatrix4fv(gShaderObject.matrixLocation, 1, GL_FALSE, mtx);
624 
625         eyes->SetPointOfView(gPointerX, gPointerY);
626 
627         float black[] = {0.0, 0.0, 0.0, 1.0};
628         float white[] = {1.0, 1.0, 1.0, 1.0};
629         int nPoint = 0;
630         float* points = NULL;
631         for (int ii = 0; ii < 2; ++ii){
632             // eye liner
633             eyes->GetEyeLinerGeom(ii, &nPoint, &points);
634             if (nPoint <= 0 || points == NULL){
635                 continue;
636             }
637             DrawFillPoly(nPoint, points, black);
638 
639             // eye shape (white eye)
640             eyes->GetWhiteEyeGeom(ii, &nPoint, &points);
641             if (nPoint <= 0 || points == NULL){
642                 continue;
643             }
644             DrawFillPoly(nPoint, points, white);
645 
646             // pupil
647             eyes->GetPupilGeom(ii, &nPoint, &points);
648             if (nPoint <= 0 || points == NULL){
649                 continue;
650             }
651             DrawFillPoly(nPoint, points, black);
652             /*same array is used for both eyes, execute finish for each eye*/
653             glFinish();
654         }
655     }
656     DetachVertexBuffer();
657     eglSwapBuffers(surface->GetEGLDisplay(), surface->GetEGLSurface());
658 
659     struct wl_callback* cb = wl_surface_frame(surface->GetWLSurface());
660     wl_callback_add_listener(cb, &FrameListener, NULL);
661     wl_surface_commit(surface->GetWLSurface());
662     wl_display_flush(surface->GetWLDisplay());
663 
664     return true;
665 }
666