#include #ifndef M_PI #define M_PI 3.14159265 #endif typedef enum { EZP_NONE, EZP_AURORA, EZP_OPENSIM, EZP_SECOND_LIFE, EZP_SLEDJHAMR, EZP_TRITIUM } ezPlatform; typedef struct { char *name; char *version; // Version string. char *path; // OS filesystem path to the viewer install. char *icon; uint16_t tag; // The UUID of the texture used in the avatar bake hack. uint8_t r, g, b; // Colour used for the in world tag. } ezViewer; typedef struct { Eina_Clist accounts; Eina_Clist landmarks; char *name; char *loginURI; char *splashPage; char *helperURI; char *website; char *supportPage; char *registerPage; char *passwordPage; char *icon; ezPlatform platform; ezViewer *viewer; Elm_Object_Item *item; } ezGrid; typedef struct { Eina_Clist grid; char *name; char *password; // Think we need to pass unencrypted passwords to the viewer. B-( char *icon; ezViewer *viewer; } ezAccount; typedef struct { Eina_Clist grid; char *name; char *sim; char *screenshot; short x, y, z; } ezLandmark; Eina_Hash *grids; Eina_Hash *viewers; static char *gridTest[][3] = { {"3rd Rock Grid", "http://grid.3rdrockgrid.com:8002/", "http://grid.3rdrockgrid.com/3rg_login"}, {"Infinite Grid", "http://grid.infinitegrid.org:8002/", "http://www.infinitegrid.org/loginscreen.php"}, {"Second Life Grid", "https://login.agni.lindenlab.com/cgi-bin/login.cgi", "http://secondlife.com/"}, {NULL, NULL, NULL} }; static char *accountTest[][3] = { {"3rd Rock Grid", "onefang rejected", "password"}, {"Infinite Grid", "infinite onefang", "MyB1GSecrit"}, {"Infinite Grid", "onefang rejected", "MySecrit"}, {NULL, NULL, NULL} }; static Elm_Genlist_Item_Class *grid_gic = NULL; static Elm_Genlist_Item_Class *account_gic = NULL; static int x, y, w, h; static const char *img0 = PACKAGE_DATA_DIR "/images/logo.png"; static const char *img1 = PACKAGE_DATA_DIR "/images/plant_01.jpg"; static const char *img2 = PACKAGE_DATA_DIR "/images/rock_01.jpg"; static const char *img3 = PACKAGE_DATA_DIR "/images/sky_01.jpg"; typedef struct _Gear Gear; typedef struct _GLData GLData; struct _Gear { GLfloat *vertices; GLuint vbo; int count; }; // GL related data here.. struct _GLData { Evas_GL_API *glapi; GLuint program; GLuint vtx_shader; GLuint fgmt_shader; int initialized : 1; int mouse_down : 1; // Gear Stuff GLfloat view_rotx; GLfloat view_roty; GLfloat view_rotz; Gear *gear1; Gear *gear2; Gear *gear3; GLfloat angle; GLuint proj_location; GLuint light_location; GLuint color_location; GLfloat proj[16]; GLfloat light[3]; }; static void gears_init(GLData *gld); static void free_gear(Gear *gear); static void gears_reshape(GLData *gld, int width, int height); static void render_gears(GLData *gld); //--------------------------------// // Gear Stuff.... static GLfloat *vert(GLfloat *p, GLfloat x, GLfloat y, GLfloat z, GLfloat *n) { p[0] = x; p[1] = y; p[2] = z; p[3] = n[0]; p[4] = n[1]; p[5] = n[2]; return p + 6; } /* Draw a gear wheel. You'll probably want to call this function when * building a display list since we do a lot of trig here. * * Input: inner_radius - radius of hole at center * outer_radius - radius at center of teeth * width - width of gear * teeth - number of teeth * tooth_depth - depth of tooth */ static Gear *make_gear(GLData *gld, GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth) { GLint i; GLfloat r0, r1, r2; GLfloat da; GLfloat *v; Gear *gear; double s[5], c[5]; GLfloat normal[3]; const int tris_per_tooth = 20; Evas_GL_API *gl = gld->glapi; gear = (Gear*)malloc(sizeof(Gear)); if (gear == NULL) return NULL; r0 = inner_radius; r1 = outer_radius - tooth_depth / 2.0; r2 = outer_radius + tooth_depth / 2.0; da = 2.0 * M_PI / teeth / 4.0; gear->vertices = calloc(teeth * tris_per_tooth * 3 * 6, sizeof *gear->vertices); s[4] = 0; c[4] = 1; v = gear->vertices; for (i = 0; i < teeth; i++) { s[0] = s[4]; c[0] = c[4]; s[1] = sin(i * 2.0 * M_PI / teeth + da); c[1] = cos(i * 2.0 * M_PI / teeth + da); s[2] = sin(i * 2.0 * M_PI / teeth + da * 2); c[2] = cos(i * 2.0 * M_PI / teeth + da * 2); s[3] = sin(i * 2.0 * M_PI / teeth + da * 3); c[3] = cos(i * 2.0 * M_PI / teeth + da * 3); s[4] = sin(i * 2.0 * M_PI / teeth + da * 4); c[4] = cos(i * 2.0 * M_PI / teeth + da * 4); normal[0] = 0.0; normal[1] = 0.0; normal[2] = 1.0; v = vert(v, r2 * c[1], r2 * s[1], width * 0.5, normal); v = vert(v, r2 * c[1], r2 * s[1], width * 0.5, normal); v = vert(v, r2 * c[2], r2 * s[2], width * 0.5, normal); v = vert(v, r1 * c[0], r1 * s[0], width * 0.5, normal); v = vert(v, r1 * c[3], r1 * s[3], width * 0.5, normal); v = vert(v, r0 * c[0], r0 * s[0], width * 0.5, normal); v = vert(v, r1 * c[4], r1 * s[4], width * 0.5, normal); v = vert(v, r0 * c[4], r0 * s[4], width * 0.5, normal); v = vert(v, r0 * c[4], r0 * s[4], width * 0.5, normal); v = vert(v, r0 * c[0], r0 * s[0], width * 0.5, normal); v = vert(v, r0 * c[4], r0 * s[4], -width * 0.5, normal); v = vert(v, r0 * c[0], r0 * s[0], -width * 0.5, normal); normal[0] = 0.0; normal[1] = 0.0; normal[2] = -1.0; v = vert(v, r0 * c[4], r0 * s[4], -width * 0.5, normal); v = vert(v, r0 * c[4], r0 * s[4], -width * 0.5, normal); v = vert(v, r1 * c[4], r1 * s[4], -width * 0.5, normal); v = vert(v, r0 * c[0], r0 * s[0], -width * 0.5, normal); v = vert(v, r1 * c[3], r1 * s[3], -width * 0.5, normal); v = vert(v, r1 * c[0], r1 * s[0], -width * 0.5, normal); v = vert(v, r2 * c[2], r2 * s[2], -width * 0.5, normal); v = vert(v, r2 * c[1], r2 * s[1], -width * 0.5, normal); v = vert(v, r1 * c[0], r1 * s[0], width * 0.5, normal); v = vert(v, r1 * c[0], r1 * s[0], width * 0.5, normal); v = vert(v, r1 * c[0], r1 * s[0], -width * 0.5, normal); v = vert(v, r2 * c[1], r2 * s[1], width * 0.5, normal); v = vert(v, r2 * c[1], r2 * s[1], -width * 0.5, normal); v = vert(v, r2 * c[2], r2 * s[2], width * 0.5, normal); v = vert(v, r2 * c[2], r2 * s[2], -width * 0.5, normal); v = vert(v, r1 * c[3], r1 * s[3], width * 0.5, normal); v = vert(v, r1 * c[3], r1 * s[3], -width * 0.5, normal); v = vert(v, r1 * c[4], r1 * s[4], width * 0.5, normal); v = vert(v, r1 * c[4], r1 * s[4], -width * 0.5, normal); v = vert(v, r1 * c[4], r1 * s[4], -width * 0.5, normal); } gear->count = (v - gear->vertices) / 6; gl->glGenBuffers(1, &gear->vbo); gl->glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); gl->glBufferData(GL_ARRAY_BUFFER, gear->count * 6 * 4, gear->vertices, GL_STATIC_DRAW); return gear; } static void free_gear(Gear *gear) { free(gear->vertices); free(gear); gear = NULL; } static void multiply(GLfloat *m, const GLfloat *n) { GLfloat tmp[16]; const GLfloat *row, *column; div_t d; int i, j; for (i = 0; i < 16; i++) { tmp[i] = 0; d = div(i, 4); row = n + d.quot * 4; column = m + d.rem; for (j = 0; j < 4; j++) tmp[i] += row[j] * column[j * 4]; } memcpy(m, &tmp, sizeof tmp); } static void rotate(GLfloat *m, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { double s, c; s = sin(angle); c = cos(angle); GLfloat r[16] = { x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0, x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0, x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0, 0, 0, 0, 1 }; multiply(m, r); } static void translate(GLfloat *m, GLfloat x, GLfloat y, GLfloat z) { GLfloat t[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 }; multiply(m, t); } static void draw_gear(GLData *gld, Gear *gear, GLfloat *m, GLfloat x, GLfloat y, GLfloat angle, const GLfloat *color) { Evas_GL_API *gl = gld->glapi; GLfloat tmp[16]; memcpy(tmp, m, sizeof tmp); translate(tmp, x, y, 0); rotate(tmp, 2 * M_PI * angle / 360.0, 0, 0, 1); gl->glUniformMatrix4fv(gld->proj_location, 1, GL_FALSE, tmp); gl->glUniform3fv(gld->light_location, 1, gld->light); gl->glUniform4fv(gld->color_location, 1, color); gl->glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); gl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), NULL); gl->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLfloat *) 0 + 3); gl->glEnableVertexAttribArray(0); gl->glEnableVertexAttribArray(1); gl->glDrawArrays(GL_TRIANGLE_STRIP, 0, gear->count); } static void gears_draw(GLData *gld) { Evas_GL_API *gl = gld->glapi; static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 }; static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 }; GLfloat m[16]; gl->glClearColor(0.8, 0.8, 0.1, 0.5); gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); memcpy(m, gld->proj, sizeof m); rotate(m, 2 * M_PI * gld->view_rotx / 360.0, 1, 0, 0); rotate(m, 2 * M_PI * gld->view_roty / 360.0, 0, 1, 0); rotate(m, 2 * M_PI * gld->view_rotz / 360.0, 0, 0, 1); draw_gear(gld, gld->gear1, m, -3.0, -2.0, gld->angle, red); draw_gear(gld, gld->gear2, m, 3.1, -2.0, -2 * gld->angle - 9.0, green); draw_gear(gld, gld->gear3, m, -3.1, 4.2, -2 * gld->angle - 25.0, blue); } static void render_gears(GLData *gld) { gears_draw(gld); gld->angle += 2.0; } /* new window size or exposure */ static void gears_reshape(GLData *gld, int width, int height) { Evas_GL_API *gl = gld->glapi; GLfloat ar, m[16] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 1.0 }; if (width < height) ar = width; else ar = height; m[0] = 0.1 * ar / width; m[5] = 0.1 * ar / height; memcpy(gld->proj, m, sizeof gld->proj); gl->glViewport(0, 0, (GLint) width, (GLint) height); } static const char vertex_shader[] = "uniform mat4 proj;\n" "attribute vec4 position;\n" "attribute vec4 normal;\n" "varying vec3 rotated_normal;\n" "varying vec3 rotated_position;\n" "vec4 tmp;\n" "void main()\n" "{\n" " gl_Position = proj * position;\n" " rotated_position = gl_Position.xyz;\n" " tmp = proj * normal;\n" " rotated_normal = tmp.xyz;\n" "}\n"; static const char fragment_shader[] = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "uniform vec4 color;\n" "uniform vec3 light;\n" "varying vec3 rotated_normal;\n" "varying vec3 rotated_position;\n" "vec3 light_direction;\n" "vec4 white = vec4(0.5, 0.5, 0.5, 1.0);\n" "void main()\n" "{\n" " light_direction = normalize(light - rotated_position);\n" " gl_FragColor = color + white * dot(light_direction, rotated_normal);\n" "}\n"; static void gears_init(GLData *gld) { Evas_GL_API *gl = gld->glapi; const char *p; char msg[512]; gl->glEnable(GL_CULL_FACE); gl->glEnable(GL_DEPTH_TEST); p = vertex_shader; gld->vtx_shader = gl->glCreateShader(GL_VERTEX_SHADER); gl->glShaderSource(gld->vtx_shader, 1, &p, NULL); gl->glCompileShader(gld->vtx_shader); gl->glGetShaderInfoLog(gld->vtx_shader, sizeof msg, NULL, msg); printf("vertex shader info: %s\n", msg); p = fragment_shader; gld->fgmt_shader = gl->glCreateShader(GL_FRAGMENT_SHADER); gl->glShaderSource(gld->fgmt_shader, 1, &p, NULL); gl->glCompileShader(gld->fgmt_shader); gl->glGetShaderInfoLog(gld->fgmt_shader, sizeof msg, NULL, msg); printf("fragment shader info: %s\n", msg); gld->program = gl->glCreateProgram(); gl->glAttachShader(gld->program, gld->vtx_shader); gl->glAttachShader(gld->program, gld->fgmt_shader); gl->glBindAttribLocation(gld->program, 0, "position"); gl->glBindAttribLocation(gld->program, 1, "normal"); gl->glLinkProgram(gld->program); gl->glGetProgramInfoLog(gld->program, sizeof msg, NULL, msg); printf("info: %s\n", msg); gl->glUseProgram(gld->program); gld->proj_location = gl->glGetUniformLocation(gld->program, "proj"); gld->light_location = gl->glGetUniformLocation(gld->program, "light"); gld->color_location = gl->glGetUniformLocation(gld->program, "color"); /* make the gears */ gld->gear1 = make_gear(gld, 1.0, 4.0, 1.0, 20, 0.7); gld->gear2 = make_gear(gld, 0.5, 2.0, 2.0, 10, 0.7); gld->gear3 = make_gear(gld, 1.3, 2.0, 0.5, 10, 0.7); } static void gldata_init(GLData *gld) { gld->initialized = 0; gld->mouse_down = 0; gld->view_rotx = -20.0; gld->view_roty = -30.0; gld->view_rotz = 0.0; gld->angle = 0.0; gld->light[0] = 1.0; gld->light[1] = 1.0; gld->light[2] = -5.0; } //-------------------------// static void _init_gl(Evas_Object *obj) { GLData *gld = evas_object_data_get(obj, "gld"); gears_init(gld); } static void _del_gl(Evas_Object *obj) { GLData *gld = evas_object_data_get(obj, "gld"); if (!gld) { printf("Unable to get GLData. \n"); return; } Evas_GL_API *gl = gld->glapi; gl->glDeleteShader(gld->vtx_shader); gl->glDeleteShader(gld->fgmt_shader); gl->glDeleteProgram(gld->program); gl->glDeleteBuffers(1, &gld->gear1->vbo); gl->glDeleteBuffers(1, &gld->gear2->vbo); gl->glDeleteBuffers(1, &gld->gear3->vbo); free_gear(gld->gear1); free_gear(gld->gear2); free_gear(gld->gear3); evas_object_data_del((Evas_Object*)obj, "..gld"); free(gld); } static void _resize_gl(Evas_Object *obj) { int w, h; GLData *gld = evas_object_data_get(obj, "gld"); elm_glview_size_get(obj, &w, &h); // GL Viewport stuff. you can avoid doing this if viewport is all the // same as last frame if you want gears_reshape(gld, w, h); } static void _draw_gl(Evas_Object *obj) { Evas_GL_API *gl = elm_glview_gl_api_get(obj); GLData *gld = evas_object_data_get(obj, "gld"); if (!gld) return; render_gears(gld); gl->glFinish(); } static Eina_Bool _anim(void *data) { elm_glview_changed_set(data); return EINA_TRUE; } static void _del(void *data , Evas *evas , Evas_Object *obj, void *event_info ) { Ecore_Animator *ani = evas_object_data_get(obj, "ani"); ecore_animator_del(ani); } static void _key_down(void *data , Evas *e , Evas_Object *obj, void *event_info) { Evas_Event_Key_Down *ev; ev = (Evas_Event_Key_Down *)event_info; GLData *gld = evas_object_data_get(obj, "gld"); if (strcmp(ev->keyname, "Left") == 0) { gld->view_roty += 5.0; return; } if (strcmp(ev->keyname, "Right") == 0) { gld->view_roty -= 5.0; return; } if (strcmp(ev->keyname, "Up") == 0) { gld->view_rotx += 5.0; return; } if (strcmp(ev->keyname, "Down") == 0) { gld->view_rotx -= 5.0; return; } if ((strcmp(ev->keyname, "Escape") == 0) || (strcmp(ev->keyname, "Return") == 0)) { //_on_done(data, obj, event_info); return; } } static void _mouse_down(void *data , Evas *e , Evas_Object *obj, void *event_info ) { GLData *gld = evas_object_data_get(obj, "gld"); gld->mouse_down = 1; } static void _mouse_move(void *data , Evas *e , Evas_Object *obj, void *event_info ) { Evas_Event_Mouse_Move *ev; ev = (Evas_Event_Mouse_Move *)event_info; GLData *gld = evas_object_data_get(obj, "gld"); float dx = 0, dy = 0; if (gld->mouse_down) { dx = ev->cur.canvas.x - ev->prev.canvas.x; dy = ev->cur.canvas.y - ev->prev.canvas.y; gld->view_roty += -1.0 * dx; gld->view_rotx += -1.0 * dy; } } static void _mouse_up(void *data , Evas *e , Evas_Object *obj, void *event_info ) { GLData *gld = evas_object_data_get(obj, "gld"); gld->mouse_down = 0; } static Evas_Object *_content_image_new(Evas_Object *parent, const char *img) { Evas_Object *ic; ic = elm_icon_add(parent); elm_icon_file_set(ic, img, NULL); return ic; } static void _promote(void *data, Evas_Object *obj , void *event_info ) { elm_naviframe_item_promote(data); } static void _on_done(void *data, Evas_Object *obj, void *event_info) { evas_object_del((Evas_Object*)data); elm_exit(); } static char *_grid_label_get(void *data, Evas_Object *obj, const char *part) { ezGrid *thisGrid = data; char buf[256]; if (!strcmp(part, "elm.text")) { int count = eina_clist_count(&(thisGrid->accounts)); if (0 == count) snprintf(buf, sizeof(buf), "%s (no accounts)", thisGrid->name); else if (1 == count) snprintf(buf, sizeof(buf), "%s (%d account)", thisGrid->name, count); else snprintf(buf, sizeof(buf), "%s (%d accounts)", thisGrid->name, count); } else snprintf(buf, sizeof(buf), "%s", thisGrid->loginURI); return strdup(buf); } static Evas_Object *_grid_content_get(void *data, Evas_Object *obj, const char *part) { ezGrid *thisGrid = data; Evas_Object *ic = elm_icon_add(obj); if (!strcmp(part, "elm.swallow.icon")) elm_icon_standard_set(ic, thisGrid->icon); evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); return ic; } static char * _account_label_get(void *data, Evas_Object *obj, const char *part) { ezAccount *thisAccount = data; char buf[256]; buf[0] = '\0'; if (!strcmp(part, "elm.text")) snprintf(buf, sizeof(buf), "%s", thisAccount->name); return strdup(buf); } static Evas_Object *_account_content_get(void *data, Evas_Object *obj, const char *part) { ezAccount *thisAccount = data; Evas_Object *ic = elm_icon_add(obj); if (!strcmp(part, "elm.swallow.icon")) elm_icon_standard_set(ic, thisAccount->icon); evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); return ic; } static void _grid_sel_cb(void *data, Evas_Object *obj, void *event_info) { ezGrid *thisGrid = data; char buf[PATH_MAX]; // sprintf(buf, "dillo -f -g '%dx%d+%d+%d' %s &", w - (w / 5), h - 30, w / 5, y, thisGrid->splashPage); sprintf(buf, "uzbl -g '%dx%d+%d+%d' -u %s &", w - (w / 5), h - 30, w / 5, y, thisGrid->splashPage); printf("%s ### genlist obj [%p], item pointer [%p]\n", buf, obj, event_info); system(buf); } EAPI_MAIN int elm_main(int argc, char **argv) { Evas_Object *win, *bg, *bx, *mn, *tb, *bt, *menu, *gl, *nf, *tab, *list; Elm_Object_Item *tb_it, *menu_it, *tab_it; Ecore_Animator *ani; GLData *gld = NULL; int i; Eina_Bool gotWebKit = elm_need_web(); // Initialise ewebkit if it exists, or return EINA_FALSE if it don't. elm_config_finger_size_set(0); elm_config_scale_set(1.0); // alloc a data struct to hold our relevant gl info in if (!(gld = calloc(1, sizeof(GLData)))) return; gldata_init(gld); // new window - do the usual and give it a name, title and delete handler // Set the engine to opengl_x11 elm_config_preferred_engine_set("opengl_x11"); win = elm_win_util_standard_add("extantz", "GLView"); // Set preferred engine back to default from config elm_config_preferred_engine_set(NULL); elm_win_title_set(win, "extantz virtual world manager"); evas_object_smart_callback_add(win, "delete,request", _on_done, NULL); elm_win_screen_size_get(win, &x, &y, &w, &h); bg = elm_bg_add(win); elm_win_resize_object_add(win, bg); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(bg); bx = elm_box_add(win); elm_win_resize_object_add(win, bx); evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(bx); // A tab thingy. tb = elm_toolbar_add(win); evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(tb); // Menu. evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL); tb_it = elm_toolbar_item_append(tb, NULL, "Menu", NULL, NULL); elm_toolbar_item_menu_set(tb_it, EINA_TRUE); menu = elm_toolbar_item_menu_get(tb_it); elm_menu_item_add(menu, NULL, NULL, "preferences", NULL, NULL); menu_it = elm_menu_item_add(menu, NULL, NULL, "advanced", NULL, NULL); elm_menu_item_add(menu, menu_it, NULL, "debug settings", NULL, NULL); elm_menu_item_separator_add(menu, NULL); menu_it = elm_menu_item_add(menu, NULL, NULL, "help", NULL, NULL); elm_menu_item_add(menu, menu_it, NULL, "grid help", NULL, NULL); elm_menu_item_separator_add(menu, menu_it); elm_menu_item_add(menu, menu_it, NULL, "extantz blogs", NULL, NULL); elm_menu_item_add(menu, menu_it, NULL, "extantz forum", NULL, NULL); elm_menu_item_separator_add(menu, menu_it); elm_menu_item_add(menu, menu_it, NULL, "about extantz", NULL, NULL); elm_menu_item_separator_add(menu, menu_it); elm_menu_item_add(menu, NULL, NULL, "quit", _on_done, win); elm_toolbar_menu_parent_set(tb, win); nf = elm_naviframe_add(win); evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(nf, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(nf); grid_gic = elm_genlist_item_class_new(); grid_gic->item_style = "double_label"; grid_gic->func.text_get = _grid_label_get; grid_gic->func.content_get = _grid_content_get; grid_gic->func.state_get = NULL; grid_gic->func.del = NULL; account_gic = elm_genlist_item_class_new(); account_gic->item_style = "default"; account_gic->func.text_get = _account_label_get; account_gic->func.content_get = _account_content_get; account_gic->func.state_get = NULL; account_gic->func.del = NULL; list = elm_genlist_add(win); tab = _content_image_new(win, img1); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Accounts", _promote, tab_it); tab = _content_image_new(win, img2); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Viewers", _promote, tab_it); tab = _content_image_new(win, img3); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Landmarks", _promote, tab_it); tab = list; tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Grids", _promote, tab_it); grids = eina_hash_stringshared_new(free); for (i = 0; NULL != gridTest[i][0]; i++) { ezGrid *thisGrid = calloc(1, sizeof(ezGrid)); if (thisGrid) { eina_clist_init(&(thisGrid->accounts)); eina_clist_init(&(thisGrid->landmarks)); thisGrid->name = gridTest[i][0]; thisGrid->loginURI = gridTest[i][1]; thisGrid->splashPage = gridTest[i][2]; thisGrid->icon = "folder"; thisGrid->item = elm_genlist_item_append(list, grid_gic, thisGrid, NULL, ELM_GENLIST_ITEM_TREE, _grid_sel_cb, thisGrid); eina_hash_add(grids, thisGrid->name, thisGrid); } } for (i = 0; NULL != accountTest[i][0]; i++) { ezAccount *thisAccount = calloc(1, sizeof(ezAccount)); ezGrid *grid = eina_hash_find(grids, accountTest[i][0]); if (thisAccount && grid) { thisAccount->name = accountTest[i][1]; thisAccount->password = accountTest[i][2]; thisAccount->icon = "file"; elm_genlist_item_append(list, account_gic, thisAccount, grid->item, ELM_GENLIST_ITEM_NONE, NULL, NULL); eina_clist_add_tail(&(grid->accounts), &(thisAccount->grid)); } } // Add a GLView gl = elm_glview_add(win); evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_glview_mode_set(gl, ELM_GLVIEW_ALPHA|ELM_GLVIEW_DEPTH); elm_glview_resize_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE); elm_glview_render_policy_set(gl, ELM_GLVIEW_RENDER_POLICY_ALWAYS); elm_glview_init_func_set(gl, _init_gl); elm_glview_del_func_set(gl, _del_gl); elm_glview_resize_func_set(gl, _resize_gl); elm_glview_render_func_set(gl, (Elm_GLView_Func_Cb)_draw_gl); evas_object_show(gl); // Add Mouse/Key Event Callbacks elm_object_focus_set(gl, EINA_TRUE); evas_object_event_callback_add(gl, EVAS_CALLBACK_KEY_DOWN, _key_down, gl); evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, gl); evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_UP, _mouse_up, gl); evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, gl); // Animator and other vars ani = ecore_animator_add(_anim, gl); gld->glapi = elm_glview_gl_api_get(gl); evas_object_data_set(gl, "ani", ani); evas_object_data_set(gl, "gld", gld); evas_object_event_callback_add(gl, EVAS_CALLBACK_DEL, _del, gl); bt = elm_button_add(win); elm_object_text_set(bt, "Login"); evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); evas_object_show(bt); // evas_object_smart_callback_add(bt, "clicked", NULL, NULL); elm_box_pack_end(bx, mn); elm_box_pack_end(bx, tb); elm_box_pack_end(bx, nf); elm_box_pack_end(bx, bt); elm_box_pack_end(bx, gl); evas_object_move(win, x, y); evas_object_resize(win, w / 5, h - 30); evas_object_show(win); elm_run(); elm_shutdown(); return 0; } ELM_MAIN()