nux-4.0.6+14.04.20140409/0000755000015301777760000000000012321344711014732 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/tools/0000755000015301777760000000000012321344711016072 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/tools/Makefile.am0000644000015301777760000000033412321344237020131 0ustar pbusernogroup00000000000000CLEANFILES = DISTCLEANFILES = EXTRA_DIST = pkglibexec_PROGRAMS = unity_support_test unity_support_test_CFLAGS = $(UNITY_SUPPORT_TEST_CFLAGS) $(MAINTAINER_CFLAGS) unity_support_test_LDFLAGS = $(UNITY_SUPPORT_TEST_LIBS) nux-4.0.6+14.04.20140409/tools/unity_support_test.c0000644000015301777760000006446612321344237022264 0ustar pbusernogroup00000000000000// Copyright © 2011 Canonical Ltd // // This program is free software: you can redistribute it and/or modify it under // the terms of the GNU General Public License version 3 as published by the // Free Software Foundation. This program is distributed in the hope that it // will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General // Public License for more details. You should have received a copy of the GNU // General Public License along with this program. If not, see // . // // Authored by: // Loïc Molinari // Jay Taoko // unity_support_test checks for Unity support on a X11 display. All the checks // are based on what's done in Compiz (core/plugins/opengl/src/screen.cpp). // // $ gcc -std=c99 unity_support_test.c -o unity_support_test `pkg-config // > --cflags --libs gl x11 libpci xcomposite xdamage` #include #include #include #include #include #ifndef NUX_OPENGLES_20 #include #define GLX_GLXEXT_PROTOTYPES #include #undef GLX_GLXEXT_PROTOTYPES #else #include #include #include #endif #include #include #include #include #include #include #ifndef NUX_OPENGLES_20 typedef GLXContext NUXContext; #else typedef EGLConfig NUXContext; #endif // Enables colored console output at build time. #define COLORED_OUTPUT 1 // Gets the number of elements in an array. #define ARRAY_SIZE(array) (sizeof (array) / sizeof ((array)[0])) enum { // Extension flags. FLAG_GLX_SGIX_FBCONFIG = (1 << 0), FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP = (1 << 1), FLAG_GL_ARB_NON_POWER_OF_TWO = (1 << 2), FLAG_GL_NV_TEXTURE_RECTANGLE = (1 << 3), FLAG_GL_EXT_TEXTURE_RECTANGLE = (1 << 4), FLAG_GL_ARB_TEXTURE_RECTANGLE = (1 << 5), FLAG_GL_ARB_VERTEX_PROGRAM = (1 << 6), FLAG_GL_ARB_FRAGMENT_PROGRAM = (1 << 7), FLAG_GL_ARB_VERTEX_BUFFER_OBJECT = (1 << 8), FLAG_GL_EXT_FRAMEBUFFER_OBJECT = (1 << 9), FLAG_GL_ARB_FRAMEBUFFER_OBJECT = (1 << 10), FLAG_SOFTWARE_RENDERING = (1 << 11), FLAG_BLACKLISTED = (1 << 12), FLAG_GL_OES_EGL_IMAGE = (1 << 13), FLAG_EGL_KHR_IMAGE_PIXMAP = (1 << 14), // Extension masks. MASK_GL_NON_POWER_OF_TWO = (FLAG_GL_ARB_NON_POWER_OF_TWO | FLAG_GL_NV_TEXTURE_RECTANGLE | FLAG_GL_EXT_TEXTURE_RECTANGLE | FLAG_GL_ARB_TEXTURE_RECTANGLE), MASK_GL_FRAMEBUFFER_OBJECT = (FLAG_GL_EXT_FRAMEBUFFER_OBJECT | FLAG_GL_ARB_FRAMEBUFFER_OBJECT) }; // PCI device identity. struct PciDevice { unsigned short vendor; unsigned short device; }; // Blacklists of GPUs for Compiz. struct PciDevice gpu_blacklist[] = { { 0x8086, 0x3577 }, // Intel : 82830M/MG { 0x8086, 0x2562 }, // Intel : 82845G aka Poulsbo { 0x1002, 0x4c57 }, // ATI : Radeon Mobility 7500 { 0x10de, 0x0322 }, // nVidia: GeForce FX 5200 { 0x10de, 0x0326 }, // nVidia: GeForce FX 5500 { 0x10de, 0x0240 }, // nVidia: GeForce 6150 { 0x10de, 0x01d3 }, // nVidia: GeForce Go 7300 SE / 7200 GS { 0x10de, 0x01d7 }, // nVidia: GeForce Go 7300 / Quadro NVS 110M { 0x10de, 0x01d8 } // nVidia: GeForce Go 7400 }; typedef struct _TestResults { char *vendor, *renderer, *version; int result, major, minor; int indirect; int compiz; unsigned int flags; char *error; } TestResults; // Checks whether an extension is supported by the GLX/OpenGL implementation // given the extension name and the list of supported extensions. static int is_extension_supported (const char* extensions, const char* extension) { if (extensions != NULL && extension != NULL) { const size_t len = strlen (extension); char* p = (char*) extensions; char* end = p + strlen (p); while (p < end) { const size_t size = strcspn (p, " "); if (len == size && strncmp (extension, p, size) == 0) return 1; p += size + 1; } } return 0; } // Gets the OpenGL version number given the string. static void get_opengl_version (const char *version, int* major, int* minor) { int tmp = 0, i; if (!version) { *major = 0; *minor = 0; return; } for (i = 0; isdigit (version[i]); i++) tmp = tmp * 10 + (version[i] - 48); if (version[i++] == '.') { *major = tmp; *minor = (version[i] - 48); } else { *major = 0; *minor = 0; } } static void print_help () { fprintf (stdout, "Check for Unity support on a X11 display.\n" "\n" "Usage:\n" " unity-support-test [ options ]\n" " -d, --display name: Specify the X11 display\n" " -i, --indirect: Force an indirect rendering context\n" " -p, --print: Print detection results on stdout\n" " -c, --compiz: Only check for Compiz support\n" " -h, --help: Show help\n"); } static void print_report (const char* vendor, const char* renderer, const char* version, int major, int minor, unsigned int flags, int compiz, int result, const char* error) { if (error == NULL) { #if COLORED_OUTPUT == 1 const char* yes = "\033[32;01myes\033[00m"; const char* no = "\033[31;01mno\033[00m"; #else const char* yes = "yes"; const char* no = "no"; #endif fprintf (stdout, "OpenGL vendor string: %s\n" "OpenGL renderer string: %s\n" "OpenGL version string: %s\n" "\n" "Not software rendered: %s\n" "Not blacklisted: %s\n" "GLX fbconfig: %s\n" "GLX texture from pixmap: %s\n" "GL npot or rect textures: %s\n", vendor, renderer, version, flags & FLAG_SOFTWARE_RENDERING ? no : yes, flags & FLAG_BLACKLISTED ? no : yes, flags & FLAG_GLX_SGIX_FBCONFIG ? yes : no, flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP ? yes : no, flags & MASK_GL_NON_POWER_OF_TWO ? yes : no); if (compiz == 0) { #ifndef NUX_OPENGLES_20 fprintf (stdout, "GL vertex program: %s\n" "GL fragment program: %s\n" "GL vertex buffer object: %s\n" "GL framebuffer object: %s\n" "GL version is 1.4+: %s\n" "\n" "Unity 3D supported: %s\n", flags & FLAG_GL_ARB_VERTEX_PROGRAM ? yes : no, flags & FLAG_GL_ARB_FRAGMENT_PROGRAM ? yes : no, flags & FLAG_GL_ARB_VERTEX_BUFFER_OBJECT ? yes : no, flags & MASK_GL_FRAMEBUFFER_OBJECT ? yes : no, (major >= 2 || (major == 1 && minor >= 4)) ? yes : no, result == 0 ? yes : no); #else fprintf (stdout, "GL OES EGL image: %s\n" "EGL KHR image pixmap: %s\n" "EGL version is 1.4+: %s\n" "\n" "Unity supported: %s\n", flags & FLAG_GL_OES_EGL_IMAGE ? yes : no, flags & FLAG_EGL_KHR_IMAGE_PIXMAP ? yes : no, (major >= 2 || (major == 1 && minor >= 4)) ? yes : no, result == 0 ? yes : no); #endif } else { fprintf (stdout, "\nCompiz supported: %s\n", result == 0 ? yes : no); } } else { fprintf (stdout, "Error: %s\n", error); } } static int check_root_visual (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { // Retrieve root window visual. XWindowAttributes attr; XVisualInfo vinfo_template; int nr_vinfos; if (XGetWindowAttributes (display, root, &attr) == 0) { results->error = strdup ("unable to get root window attributes"); results->result = 1; return 0; } vinfo_template.visualid = XVisualIDFromVisual (attr.visual); *vinfos = XGetVisualInfo (display, VisualIDMask, &vinfo_template, &nr_vinfos); if (nr_vinfos == 0) { results->error = strdup ("unable to get visual informations for default visual"); results->result = 1; return 0; } return 1; } static int check_xcomposite (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { // Check for XComposite int composite_major, composite_minor; int composite_tmp; if (!XQueryExtension (display, COMPOSITE_NAME, &composite_tmp, &composite_tmp, &composite_tmp)) { results->error = strdup ("no composite extension"); results->result = 1; return 0; } XCompositeQueryVersion (display, &composite_major, &composite_minor); if (composite_major == 0 && composite_minor < 2) { results->error = strdup ("old composite extension"); results->result = 1; return 0; } return 1; } static int check_damage_extension (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { int damage_tmp; if (!XDamageQueryExtension (display, &damage_tmp, &damage_tmp)) { results->error = strdup ("no damage extension"); results->result = 1; return 0; } return 1; } static int check_fixes_extension (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { int fixes_tmp; if (!XFixesQueryExtension (display, &fixes_tmp, &fixes_tmp)) { results->error = strdup ("no fixes extension"); results->result = 1; return 0; } return 1; } #ifdef NUX_OPENGLES_20 static int check_egl_config (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_NONE }; EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; XVisualInfo *visInfo, visTemplate; XSetWindowAttributes attr; Window win; int num_visuals; unsigned long mask; const int width = 400, height = 300; const char* name = "Unity Support Test"; EGLDisplay egl_dpy; EGLSurface egl_surf; EGLContext egl_ctx; EGLConfig config; EGLint num_configs; EGLint vid; egl_dpy = eglGetDisplay(display); if (!eglChooseConfig (egl_dpy, attribs, &config, 1, &num_configs)) { results->error = strdup ("OpenGLES: couldn't get an EGL visual config"); results->result = 1; return 0; } if (num_configs <= 0) { results->error = strdup ("OpenGLES: no valid config found (!num_configs)"); results->result = 1; return 0; } if (!eglGetConfigAttrib (egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { results->error = strdup ("OpenGLES: eglGetConfigAttrib() failed"); results->result = 1; return 0; } /* The X window visual must match the EGL config */ visTemplate.visualid = vid; visInfo = XGetVisualInfo (display, VisualIDMask, &visTemplate, &num_visuals); if (!visInfo) { results->error = strdup ("OpenGLES: unable to get a matching X visual"); results->result = 1; return 0; } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap (display, root, visInfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow (display, root, 0, 0, width, height, 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr); /* set hints and properties */ { XSizeHints sizehints; sizehints.x = 0; sizehints.y = 0; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints (display, win, &sizehints); XSetStandardProperties (display, win, name, name, None, (char **)NULL, 0, &sizehints); } eglBindAPI (EGL_OPENGL_ES_API); egl_surf = eglCreateWindowSurface (egl_dpy, config, win, NULL); if (egl_surf == EGL_NO_SURFACE) { results->error = strdup ("OpenGLES: eglCreateWindowSurface failed"); results->result = 1; return 0; } context = eglCreateContext (egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs); if (context == EGL_NO_CONTEXT) { results->error = strdup ("OpenGLES: eglCreateContext failed"); results->result = 1; return 0; } if (!eglMakeCurrent (egl_dpy, egl_surf, egl_surf, context)) { results->error = strdup ("OpenGLES: eglMakeCurrent() failed"); results->result = 1; return 0; } XFree(visInfo); eglDestroySurface (egl_dpy, egl_surf); XDestroyWindow (display, win); return 1; } #else static int check_glx_config (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { // Check root window visual capabilities. int value; glXGetConfig (display, *vinfos, GLX_USE_GL, &value); if (value == 0) { results->error = strdup ("OpenGL rendering is not supported by the root visual"); results->result = 1; return 0; } return 1; } static int check_colorbuffers (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { int value; glXGetConfig (display,*vinfos, GLX_DOUBLEBUFFER, &value); if (value == 0) { results->error = strdup ("color buffers of the root visual are not double-buffered"); results->result = 1; return 0; } return 1; } #endif static int check_context (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { #ifndef NUX_OPENGLES_20 // Create and map the OpenGL context to the root window and get the strings. *context = glXCreateContext (display, *vinfos, NULL, !results->indirect); if (*context == NULL) { results->error = strdup ("unable to create the OpenGL context"); results->result = 1; return 0; } glXMakeCurrent (display, root, *context); #endif results->vendor = (char*) glGetString (GL_VENDOR); results->renderer = (char*) glGetString (GL_RENDERER); results->version = (char*) glGetString (GL_VERSION); return 1; } static int check_extensions (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { // Fill flags with the supported OpenGL extensions. const char* gl_extensions = (char*)glGetString (GL_EXTENSIONS); if (gl_extensions == NULL) { results->error = strdup ("invalid OpenGL extensions string"); results->result = 1; return 0; } const struct { const char* name; const unsigned int flag; } gl_extension[] = { { "GL_ARB_texture_non_power_of_two", FLAG_GL_ARB_NON_POWER_OF_TWO }, { "GL_NV_texture_rectangle", FLAG_GL_NV_TEXTURE_RECTANGLE }, { "GL_EXT_texture_rectangle", FLAG_GL_EXT_TEXTURE_RECTANGLE }, { "GL_ARB_texture_rectangle", FLAG_GL_ARB_TEXTURE_RECTANGLE }, { "GL_ARB_vertex_program", FLAG_GL_ARB_VERTEX_PROGRAM }, { "GL_ARB_fragment_program", FLAG_GL_ARB_FRAGMENT_PROGRAM }, { "GL_ARB_vertex_buffer_object", FLAG_GL_ARB_VERTEX_BUFFER_OBJECT }, { "GL_EXT_framebuffer_object", FLAG_GL_EXT_FRAMEBUFFER_OBJECT }, { "GL_ARB_framebuffer_object", FLAG_GL_ARB_FRAMEBUFFER_OBJECT }, { "GL_OES_EGL_image", FLAG_GL_OES_EGL_IMAGE }, { NULL, 0 } }; for (int i = 0; gl_extension[i].name != NULL; i++) if (is_extension_supported (gl_extensions, gl_extension[i].name) == 1) results->flags |= gl_extension[i].flag; #ifndef NUX_OPENGLES_20 // Fill results->flags with the supported GLX extensions. const char* glx_extensions = glXQueryExtensionsString (display, screen); const struct { const char* name; const unsigned int flag; } glx_extension[] = { { "GLX_SGIX_fbconfig", FLAG_GLX_SGIX_FBCONFIG }, { "GLX_EXT_texture_from_pixmap", FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP }, { NULL, 0 } }; for (int i = 0; glx_extension[i].name != NULL; i++) if (is_extension_supported (glx_extensions, glx_extension[i].name) == 1) results->flags |= glx_extension[i].flag; if (results->flags & FLAG_GLX_SGIX_FBCONFIG) { if (glXGetProcAddressARB ((unsigned char*)"glXQueryDrawable") == NULL || glXGetProcAddressARB ((unsigned char*)"glXGetFBConfigs") == NULL || glXGetProcAddressARB ((unsigned char*)"glXGetFBConfigAttrib") == NULL || glXGetProcAddressARB ((unsigned char*)"glXCreatePixmap") == NULL || glXGetProcAddressARB ((unsigned char*)"glXDestroyPixmap") == NULL) { results->flags &= ~FLAG_GLX_SGIX_FBCONFIG; } } if (results->flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) { if (glXGetProcAddressARB ((unsigned char*)"glXBindTexImageEXT") == NULL || glXGetProcAddressARB ((unsigned char*)"glXReleaseTexImageEXT") == NULL) { results->flags &= ~FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP; } } #else EGLDisplay egl_dpy = eglGetDisplay(display); const char* egl_extensions = eglQueryString (egl_dpy, EGL_EXTENSIONS); const struct { const char* name; const unsigned int flag; } egl_extension[] = { { "EGL_KHR_image_pixmap", FLAG_EGL_KHR_IMAGE_PIXMAP }, { NULL, 0 } }; for (int i = 0; egl_extension[i].name != NULL; i++) if (is_extension_supported (egl_extensions, egl_extension[i].name) == 1) results->flags |= egl_extension[i].flag; #endif return 1; } static int check_blacklist (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) { // Check for software rendering. if (results->renderer != NULL && (strncmp (results->renderer, "Software Rasterizer", 19) == 0 || strncmp (results->renderer, "Mesa X11", 8) == 0 || strstr (results->renderer, "on softpipe") != NULL)) { results->flags |= FLAG_SOFTWARE_RENDERING; } // jaytaoko: Balcklist the Geforce FX cards if (results->renderer != NULL) { char* str = strstr (results->renderer, "GeForce FX"); if (str != NULL) { results->flags |= FLAG_BLACKLISTED; } } // FIXME(loicm): Compiz does a last check to test whether there's a fbconfig // available for the default depth or not. // Scan the PCI devices searching for blacklisted GPUs. // FIXME: pci or not is not actually related with PCI, it's just that if pci_init // fails it exit directly :-( #ifndef NUX_OPENGLES_20 const int gpu_blacklist_size = ARRAY_SIZE (gpu_blacklist); struct pci_access* access; struct pci_dev* dev; access = pci_alloc (); pci_init (access); pci_scan_bus (access); dev = access->devices; while (dev != NULL) { pci_fill_info (dev, PCI_FILL_IDENT); for (int i = 0; i < gpu_blacklist_size; i++) { if (dev->vendor_id == gpu_blacklist[i].vendor && dev->device_id == gpu_blacklist[i].device) { results->flags |= FLAG_BLACKLISTED; } } dev = dev->next; } pci_cleanup (access); #endif return 1; } int (*tests[]) (Display *display, unsigned int screen, Window root, NUXContext *context, XVisualInfo **vinfos, TestResults *results) = { check_root_visual, check_xcomposite, check_damage_extension, check_fixes_extension, #ifndef NUX_OPENGLES_20 check_glx_config, check_colorbuffers, #else check_egl_config, #endif check_context, check_extensions, check_blacklist }; #ifndef NUX_OPENGLES_20 const unsigned int c_num_tests = 9; #else const unsigned int c_num_tests = 8; #endif int main (int argc, char* argv[]) { char *display_name = NULL; int screen; unsigned int print = 0; Window root; XVisualInfo *vinfos = NULL; Display *display = NULL; NUXContext context = NULL; TestResults results; #ifdef NUX_OPENGLES_20 EGLDisplay egl_dpy; #endif char resultfilename[30]; int resultfile; int forcecheck = 0; memset(&results, 0, sizeof(TestResults)); // Basic command-line parsing. for (int i = 1; i < argc; i++) { if (((strncmp (argv[i], "-d", 2) == 0) || (strncmp (argv[i], "--display", 9) == 0)) && (i + 1 < argc)) { display_name = argv[i + 1]; i++; } else if ((strncmp (argv[i], "-i", 2) == 0) || (strncmp (argv[i], "--indirect", 10) == 0)) { results.indirect = 1; } else if ((strncmp (argv[i], "-p", 2) == 0) || (strncmp (argv[i], "--print", 7) == 0)) { print = 1; } else if ((strncmp (argv[i], "-c", 2) == 0) || (strncmp (argv[i], "--compiz", 8) == 0)) { results.compiz = 1; } else if ((strncmp (argv[i], "-f", 2) == 0) || (strncmp (argv[i], "--force-check", 13) == 0)) { forcecheck = 1; } else if ((strncmp (argv[i], "-h", 2) == 0) || (strncmp (argv[i], "--help", 6) == 0)) { print_help (); return 2; } else { fprintf (stderr, "Error: unknown command-line option `%s'\n\n", argv[i]); print_help (); return 2; } } // can skip some tests if not forced if (!forcecheck && !print) { if (access("/tmp/unity_support_test.0", F_OK) == 0) { return 0; } if (getenv ("UNITY_FORCE_START")) { fprintf (stdout, "Warning: UNITY_FORCE_START enabled, no check for unity or compiz support.\n"); return 0; } } // Open a X11 connection and get the root window. display = XOpenDisplay (display_name); #ifndef NUX_OPENGLES_20 // Before doing anything with GLX, check that it is supported on the system. Bool glx_supported = False; int dummy0, dummy1; if (display) glx_supported = glXQueryExtension(display, &dummy0, &dummy1); #endif if (!display) { results.error = strdup ("unable to open display"); // exit with 5, to tell "it's not an error we should cache" results.result = 5; } #ifndef NUX_OPENGLES_20 else if (!glx_supported) { results.error = strdup ("GLX is not available on the system"); // exit with 5, to tell "it's not an error we should cache" results.result = 5; } #endif else { screen = DefaultScreen (display); root = XRootWindow (display, screen); #ifndef NUX_OPENGLES_20 // Do the tests, if one of them fails break out of the loop for (unsigned int i = 0; i < c_num_tests; i++) if (!(*tests[i]) (display, screen, root, &context, &vinfos, &results)) break; if (results.compiz == 0) { // Unity compatibility checks. get_opengl_version (results.version, &results.major, &results.minor); if ((results.major >= 2 || (results.major == 1 && results.minor >= 4)) && (results.flags & FLAG_GLX_SGIX_FBCONFIG) && (results.flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) && (results.flags & MASK_GL_NON_POWER_OF_TWO) && (results.flags & FLAG_GL_ARB_VERTEX_PROGRAM) && (results.flags & FLAG_GL_ARB_FRAGMENT_PROGRAM) && (results.flags & FLAG_GL_ARB_VERTEX_BUFFER_OBJECT) && (results.flags & MASK_GL_FRAMEBUFFER_OBJECT) && (~results.flags & FLAG_SOFTWARE_RENDERING) && (~results.flags & FLAG_BLACKLISTED)) { results.result = 0; } else { results.result = 1; } } else { // Compiz compatibility checks. if ((results.flags & FLAG_GLX_SGIX_FBCONFIG) && (results.flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) && (results.flags & MASK_GL_NON_POWER_OF_TWO) && (~results.flags & FLAG_SOFTWARE_RENDERING) && (~results.flags & FLAG_BLACKLISTED)) { results.result = 0; } else { results.result = 1; } } #else egl_dpy = eglGetDisplay(display); if (!eglInitialize (egl_dpy, &results.major, &results.minor)) { results.error = strdup ("OpenGLES: eglInitialize() failed"); results.result = 1; } else { // Do the tests, if one of them fails break out of the loop for (unsigned int i = 0; i < c_num_tests; i++) if (!(*tests[i]) (display, screen, root, &context, &vinfos, &results)) break; if (results.compiz == 0) { // Unity compatibility checks. if ((results.major >= 2 || (results.major == 1 && results.minor >= 4)) && (results.flags & FLAG_GL_OES_EGL_IMAGE) && (results.flags & FLAG_EGL_KHR_IMAGE_PIXMAP) && (~results.flags & FLAG_SOFTWARE_RENDERING) && (~results.flags & FLAG_BLACKLISTED)) { results.result = 0; } else { results.result = 1; } } else { // Compiz compatibility checks. if ((results.flags & FLAG_GL_OES_EGL_IMAGE) && (results.flags & FLAG_EGL_KHR_IMAGE_PIXMAP) && (~results.flags & FLAG_SOFTWARE_RENDERING) && (~results.flags & FLAG_BLACKLISTED)) { results.result = 0; } else { results.result = 1; } } } #endif } if (print == 1) { print_report (results.vendor, results.renderer, results.version, results.major, results.minor, results.flags, results.compiz, results.result, results.error); } if (vinfos != NULL) XFree (vinfos); #ifndef NUX_OPENGLES_20 if (context != NULL) glXDestroyContext (display, context); #else if (context == EGL_NO_CONTEXT) eglDestroyContext (egl_dpy, context); if (egl_dpy) eglTerminate (egl_dpy); #endif if (display != NULL) XCloseDisplay (display); if (results.error != NULL) free (results.error); // drop result file if (results.result != 5) { snprintf(resultfilename, sizeof(resultfilename), "/tmp/unity_support_test.%i", results.result); resultfile = open(resultfilename, O_CREAT|O_WRONLY|O_EXCL, 0666); if (resultfile > 0) close(resultfile); } return results.result; } nux-4.0.6+14.04.20140409/tools/compose_key_list_generator.py0000755000015301777760000001021212321344237024064 0ustar pbusernogroup00000000000000#!/usr/bin/python # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # # Convert XOrg libX11 compose sequences such as # http://cgit.freedesktop.org/xorg/lib/libX11/plain/nls/en_US.UTF-8/Compose.pre # # To use it, just download the Compose.pre file you want, then launch this # script like: # ./compose_key_list_generator.py /path/Compose.pre [/path/output_file.c] # # Marco Trevisan (Treviño) -- Copyright 2012 # # Released under the GPLv2 terms. import os, sys, re, codecs from gi.repository import Gdk DEFAULT_OUTPUT = "/tmp/parsed_keys.cpp" input_file = sys.argv[1] output_file = sys.argv[2] if len(sys.argv) > 2 else DEFAULT_OUTPUT keys_match = re.compile("(?P<[^:]+)[\s]*:[\s]*\"(\\\)?(?P.*)\"[\s]*(?P[^\s]+)?[\s]*#[\s]*(?P.+)") unicode_keys = re.compile("^U[0-9A-Fa-f]{4,6}$"); blacklisted_keys = ["EZH", "ezh", "dead_double_grave", "dead_inverted_breve", "dead_greek", "greaterthanequal", "lessthanequal", "underbar", "rightarrow", "leftarrow"] combinations = {u"": ["ubuntu", "UBUNTU"]} descriptions = {u"": "UBUNTU CIRCLE"} def key_list_has_invalid_keys(keys): if len([k for k in keys if unicode_keys.match(k)]): return True if 0 in [Gdk.keyval_from_name(k) for k in keys]: return True if len([k for k in keys if k in blacklisted_keys]): return True return False def escape_char(char): escape_list = ["\\", "\""] for e in escape_list: char = char.replace(e, "\\"+e) return char def make_cpp_output(output_file): keycode = """/* This file has been automatically generated using the * compose_key_list_generator.py script. */ #include #include struct ComposeSequence { const static unsigned int MAX_SYMBOLS = %d; KeySym symbols[MAX_SYMBOLS]; const char* result; }; static const size_t COMPOSE_SEQUENCES_SIZE = %d; static const ComposeSequence COMPOSE_SEQUENCES[] = { %s}; """ keyarray = "" sequencies_size = 0; max_values = 0 for c in combinations.keys(): thiscombo = combinations[c] if not len(thiscombo): continue first = True for combo in thiscombo: # Fix manually set combinations if (type(combo) is str): combo = [k for k in combo] combo.insert(0, "Multi_key") # Add 'XK_' prefix to key names combo = ["XK_" + k for k in combo] combo.append("XK_VoidSymbol") combosize = len(combo) if combosize > max_values: max_values = combosize desc = " // " + descriptions[c] if first else "" keyarray += " {{%s}, \"%s\"},%s\n" % (", ".join(combo), escape_char(c), desc) sequencies_size += 1 first = False output = keycode % (max_values, sequencies_size, keyarray) out = file(output_file, "w") out.write(output.encode('utf-8')) out.close() if not os.path.exists(input_file): print("Missing argument, you need to pass a Compose.pre file to this!") sys.exit() print "Parsing "+input_file+", saving it to "+output_file+"..." composefile = codecs.open(input_file, 'r', 'utf-8') for line in composefile: parts = re.match(keys_match, line) if not parts: continue keybinding = parts.group("keybinding") if not keybinding: print "Error while matching keybinding in line\n\t"+line char = parts.group("char") keys = re.compile("<([^>]+)>").findall(keybinding) desc = parts.group("desc") if parts.group("charcode"): desc = parts.group("charcode") + " | " + desc # Ignore the group if it contains unknown values if key_list_has_invalid_keys(keys): continue # Ignoring unknown keys if 0 in [Gdk.keyval_from_name(k) for k in keys]: continue if not char in combinations: combinations[char] = [keys] else: if not keys in combinations[char]: combinations[char] += [keys] if not char in descriptions: descriptions[char] = desc composefile.close(); make_cpp_output(output_file) nux-4.0.6+14.04.20140409/doxygen-include.am0000644000015301777760000001304512321344237020355 0ustar pbusernogroup00000000000000# --------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --------------------------------------------------------------------------- # Copyright (C) 2004 Oren Ben-Kiki # This file is distributed under the same terms as the Automake macro files. # Generate automatic documentation using Doxygen. Goals and variables values # are controlled by the various DX_COND_??? conditionals set by autoconf. # # The provided goals are: # doxygen-doc: Generate all doxygen documentation. # doxygen-run: Run doxygen, which will generate some of the documentation # (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post # processing required for the rest of it (PS, PDF, and some MAN). # doxygen-man: Rename some doxygen generated man pages. # doxygen-ps: Generate doxygen PostScript documentation. # doxygen-pdf: Generate doxygen PDF documentation. # # Note that by default these are not integrated into the automake goals. If # doxygen is used to generate man pages, you can achieve this integration by # setting man3_MANS to the list of man pages generated and then adding the # dependency: # # $(man3_MANS): doxygen-doc # # This will cause make to run doxygen and generate all the documentation. # # The following variable is intended for use in Makefile.am: # # DX_CLEANFILES = everything to clean. # # This is usually added to MOSTLYCLEANFILES. ## --------------------------------- ## ## Format-independent Doxygen rules. ## ## --------------------------------- ## if DX_COND_doc ## ------------------------------- ## ## Rules specific for HTML output. ## ## ------------------------------- ## if DX_COND_html DX_CLEAN_HTML = @DX_DOCDIR@/html endif DX_COND_html ## ------------------------------ ## ## Rules specific for CHM output. ## ## ------------------------------ ## if DX_COND_chm DX_CLEAN_CHM = @DX_DOCDIR@/chm if DX_COND_chi DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi endif DX_COND_chi endif DX_COND_chm ## ------------------------------ ## ## Rules specific for MAN output. ## ## ------------------------------ ## if DX_COND_man DX_CLEAN_MAN = @DX_DOCDIR@/man endif DX_COND_man ## ------------------------------ ## ## Rules specific for RTF output. ## ## ------------------------------ ## if DX_COND_rtf DX_CLEAN_RTF = @DX_DOCDIR@/rtf endif DX_COND_rtf ## ------------------------------ ## ## Rules specific for XML output. ## ## ------------------------------ ## if DX_COND_xml DX_CLEAN_XML = @DX_DOCDIR@/xml endif DX_COND_xml ## ----------------------------- ## ## Rules specific for PS output. ## ## ----------------------------- ## if DX_COND_ps DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps DX_PS_GOAL = doxygen-ps doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag cd @DX_DOCDIR@/latex; \ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ $(DX_LATEX) refman.tex; \ $(MAKEINDEX_PATH) refman.idx; \ $(DX_LATEX) refman.tex; \ countdown=5; \ while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ refman.log > /dev/null 2>&1 \ && test $$countdown -gt 0; do \ $(DX_LATEX) refman.tex; \ countdown=`expr $$countdown - 1`; \ done; \ $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi endif DX_COND_ps ## ------------------------------ ## ## Rules specific for PDF output. ## ## ------------------------------ ## if DX_COND_pdf DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf DX_PDF_GOAL = doxygen-pdf doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag cd @DX_DOCDIR@/latex; \ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ $(DX_PDFLATEX) refman.tex; \ $(DX_MAKEINDEX) refman.idx; \ $(DX_PDFLATEX) refman.tex; \ countdown=5; \ while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ refman.log > /dev/null 2>&1 \ && test $$countdown -gt 0; do \ $(DX_PDFLATEX) refman.tex; \ countdown=`expr $$countdown - 1`; \ done; \ mv refman.pdf ../@PACKAGE@.pdf endif DX_COND_pdf ## ------------------------------------------------- ## ## Rules specific for LaTeX (shared for PS and PDF). ## ## ------------------------------------------------- ## if DX_COND_latex DX_CLEAN_LATEX = @DX_DOCDIR@/latex endif DX_COND_latex .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) rm -rf @DX_DOCDIR@ $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) DX_CLEANFILES = \ @DX_DOCDIR@/@PACKAGE@.tag \ -r \ $(DX_CLEAN_HTML) \ $(DX_CLEAN_CHM) \ $(DX_CLEAN_CHI) \ $(DX_CLEAN_MAN) \ $(DX_CLEAN_RTF) \ $(DX_CLEAN_XML) \ $(DX_CLEAN_PS) \ $(DX_CLEAN_PDF) \ $(DX_CLEAN_LATEX) endif DX_COND_doc nux-4.0.6+14.04.20140409/Makefile.am0000644000015301777760000000055212321344237016773 0ustar pbusernogroup00000000000000SUBDIRS = data NuxCore NuxGraphics Nux examples gputests tests tools CXXFLAGS += -fno-permissive include $(top_srcdir)/Makefile.am.coverage include doxygen-include.am if BUILD_DOCUMENTATION all: doxygen-doc endif DISTCLEANFILES = doc/html/* doc/* EXTRA_DIST = $(DX_CONFIG) autogen.sh COPYING.gpl .bzrignore check-headless: cd tests; $(MAKE) check-headless nux-4.0.6+14.04.20140409/examples/0000755000015301777760000000000012321344711016550 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/examples/coverflow.cpp0000644000015301777760000000644612321344237021277 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith * Authored by: Jay Taoko */ const char* movie_list[] = { "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", "nux.png", 0 }; #include "Nux/Nux.h" #include "Nux/HLayout.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLShader.h" #include "NuxGraphics/GpuDevice.h" #include "NuxGraphics/GLDeviceObjects.h" #include "NuxGraphics/GLShader.h" #include "NuxGraphics/GraphicsEngine.h" #include "Nux/Coverflow.h" #include "Nux/CoverflowItem.h" namespace nux { //class BaseTexture; class BasicCoverflowItem : public CoverflowItem { public: BasicCoverflowItem(std::string const& name, std::string const& filename); ObjectPtr GetTexture() const; private: ObjectPtr texture_; }; BasicCoverflowItem::BasicCoverflowItem(std::string const& name, std::string const& filename) : CoverflowItem(name) { texture_.Adopt(LoadTextureFromFile(filename)); } ObjectPtr BasicCoverflowItem::GetTexture() const { return texture_; } } void CoverflowThread(nux::NThread* thread, void* /* InitData */) { nux::Coverflow* coverflow = new nux::Coverflow(); coverflow->fov = 45; coverflow->true_perspective = false; coverflow->folding_angle = 45; coverflow->reflection_size = 0.5f; coverflow->show_reflection = true; nux::HLayout* main_layout(new nux::HLayout(NUX_TRACKER_LOCATION)); main_layout->AddView(coverflow, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); static_cast(thread)->SetLayout(main_layout); int i = 0; nux::CoverflowModel::Ptr model = coverflow->model(); std::string base_path = PKGDATADIR"/UITextures/"; while(movie_list[i] != NULL) { std::string name = "Nux The Movie"; std::string movie_path = base_path + movie_list[i]; nux::CoverflowItem::Ptr item(new nux::BasicCoverflowItem(name, movie_path)); model->AddItem(item); i++; } } int main() { nux::NuxInitialize(0); std::unique_ptr wt(nux::CreateGUIThread("CoverFlow", 1100, 480, 0, &CoverflowThread, 0)); wt->Run(0); return 0; } nux-4.0.6+14.04.20140409/examples/abstract-separator.h0000644000015301777760000000254512321344237022533 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ABSTRACTSEPARATOR_H #define ABSTRACTSEPARATOR_H #include "Nux/View.h" namespace nux { class AbstractSeparator: public View { public: AbstractSeparator (NUX_FILE_LINE_PROTO); AbstractSeparator (const Color &color, float Alpha0, float Alpha1, int Border, NUX_FILE_LINE_PROTO); ~AbstractSeparator(); void SetColor (const Color &color); void SetAlpha (float Alpha0, float Alpha1); void SetBorderSize (int Border); protected: Color m_Color; float m_Alpha0; float m_Alpha1; int m_BorderSize; }; } #endif // ABSTRACTSEPARATOR_H nux-4.0.6+14.04.20140409/examples/line-separator.cpp0000644000015301777760000000446112321344237022211 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "line-separator.h" namespace nux { HSeparator::HSeparator() { SetMinimumHeight (1); SetMaximumHeight (1); } HSeparator::HSeparator (const Color &color, float Alpha0, float Alpha1, int Border) : AbstractSeparator (color, Alpha0, Alpha1, Border) { SetMinimumHeight (1); SetMaximumHeight (1); } HSeparator::~HSeparator() { } void HSeparator::Draw (GraphicsEngine &GfxContext, bool /* force_draw */) { Geometry base = GetGeometry(); base.OffsetPosition(3, 0); base.OffsetSize(-6, 0); int y0 = base.y + base.GetHeight() / 2; GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetBlend (TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (base.GetWidth() - 2 * m_BorderSize > 0) { Color color0 = m_Color; Color color1 = m_Color; color0.alpha = m_Alpha0; color1.alpha = m_Alpha1; GetPainter().Draw2DLine (GfxContext, base.x, y0, base.x + m_BorderSize, y0, color0, color1); GetPainter().Draw2DLine (GfxContext, base.x + m_BorderSize, y0, base.x + base.GetWidth() - m_BorderSize, y0, color1, color1); GetPainter().Draw2DLine (GfxContext, base.x + base.GetWidth() - m_BorderSize, y0, base.x + base.GetWidth(), y0, color1, color0); } else { Color color1 = m_Color; color1.alpha = m_Alpha1; GetPainter().Draw2DLine (GfxContext, base.x, y0, base.x + base.GetWidth(), y0, color1, color1); } GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetBlend (FALSE); } } nux-4.0.6+14.04.20140409/examples/Makefile.am0000644000015301777760000000732612321344237020617 0ustar pbusernogroup00000000000000CLEANFILES = DISTCLEANFILES = EXTRA_DIST = if BUILD_EXAMPLES # This tells automake that we want to build binaries, but they shouldn't be # installed. For each individual example, add it's binary name here noinst_PROGRAMS = text_entry_focus \ shortcut_keys \ coverflow \ kinetic_scroll_view #button \ # cairo \ # cairo_wrapper \ # canvas \ # checkbox \ # combobox \ # gridlayout \ # layeredlayout \ # moveable_view \ # pango_combobox \ # pangotextedit \ # rotate_texture_area \ # scrollview \ # tab_view \ # textedit \ # tiles_view \ # timegraph \ # timeline \ # tooltip if HAVE_GEIS noinst_PROGRAMS += gestures endif # We only have to do this AM_ once to affect all the binaries we build from # this Makefile AM_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir) \ -I$(top_builddir)/Nux \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxExamples\" \ -DPKGDATADIR=\""$(pkgdatadir)/@NUX_API_VERSION@"\" \ $(GCC_FLAGS) \ $(NUX_CORE_CFLAGS) \ $(NUX_EXAMPLES_CFLAGS) \ $(NUX_CFLAGS) \ $(IBUS_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(GEIS_CFLAGS) ALL_LIBS = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(top_builddir)/NuxGraphics/libnux-graphics-@NUX_API_VERSION@.la \ $(top_builddir)/Nux/libnux-@NUX_API_VERSION@.la \ $(NUX_EXAMPLES_LIBS) \ $(NUX_LIBS) \ $(IBUS_LIBS) \ $(GEIS_LIBS) # This is the individual executable build. For every $exe in noinst_PROGRAMS # you need a $exe_SOURCES and $exe_LDADD so it builds #combobox_SOURCES = combobox.cpp #combobox_LDADD = $(ALL_LIBS) #cairo_SOURCES = cairo.cpp #cairo_LDADD = $(ALL_LIBS) #cairo_wrapper_SOURCES = cairo_wrapper.cpp #cairo_wrapper_LDADD = $(ALL_LIBS) #canvas_SOURCES = canvas.cpp #canvas_LDADD = $(ALL_LIBS) #textedit_SOURCES = textedit.cpp #textedit_LDADD = $(ALL_LIBS) #button_SOURCES = button.cpp #button_LDADD = $(ALL_LIBS) #checkbox_SOURCES = checkbox.cpp #checkbox_LDADD = $(ALL_LIBS) #tooltip_SOURCES = tooltip.cpp #tooltip_LDADD = $(ALL_LIBS) #timeline_SOURCES = timeline.cpp #timeline_LDADD = $(ALL_LIBS) #timegraph_SOURCES = timegraph.cpp #timegraph_LDADD = $(ALL_LIBS) #gridlayout_SOURCES = gridlayout.cpp #gridlayout_LDADD = $(ALL_LIBS) #pangotextedit_SOURCES = pangotextedit.cpp #pangotextedit_LDADD = $(ALL_LIBS) #moveable_view_SOURCES = moveable_view.cpp #moveable_view_LDADD = $(ALL_LIBS) #layeredlayout_SOURCES = layeredlayout.cpp #layeredlayout_LDADD = $(ALL_LIBS) #scrollview_SOURCES = scrollview.cpp #scrollview_LDADD = $(ALL_LIBS) #tab_view_SOURCES = tab_view.cpp #tab_view_LDADD = $(ALL_LIBS) #pango_combobox_SOURCES = pango_combobox.cpp #pango_combobox_LDADD = $(ALL_LIBS) #rotate_texture_area_SOURCES = rotate_texture_area.cpp #rotate_texture_area_LDADD = $(ALL_LIBS) #tiles_view_SOURCES = tiles_view.cpp #tiles_view_LDADD = $(ALL_LIBS) text_entry_focus_SOURCES = text_entry_focus.cpp text_entry_focus_LDADD = $(ALL_LIBS) shortcut_keys_SOURCES = shortcut-keys.cpp line-separator.cpp line-separator.h abstract-separator.h abstract-separator.cpp shortcut_keys_LDADD = $(ALL_LIBS) coverflow_SOURCES = coverflow.cpp coverflow_LDADD = $(ALL_LIBS) kinetic_scroll_view_SOURCES = kinetic_scroll_view.cpp TestButton.h TestButton.cpp kinetic_scroll_view_LDADD = $(ALL_LIBS) if HAVE_GEIS gestures_SOURCES = gestures.cpp gestures_LDADD = $(ALL_LIBS) endif # To distribute source add the source code here #sourceexampledir = "$(pkgdatadir)/examples" #sourceexample_DATA = $(combobox_SOURCES) \ # endif nux-4.0.6+14.04.20140409/examples/kinetic_scroll_view.cpp0000644000015301777760000000402412321344237023315 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include #include #include #include "TestButton.h" using namespace nux; View *CreateKineticScrollView() { VLayout *layout = new VLayout (NUX_TRACKER_LOCATION); char buffer[500]; for (int i = 0; i < 100; i++) { sprintf(buffer, "TestButton %d", i+1); Button *button = new TestButton(buffer, NUX_TRACKER_LOCATION); button->SetMinimumHeight(50); layout->AddView(button, 1, eLeft, eFull); } KineticScrollView *kinetic_scroll_view = new KineticScrollView(NUX_TRACKER_LOCATION); kinetic_scroll_view->SetLayout(layout); kinetic_scroll_view->SetScrollableDirections(ScrollableDirectionsVertical); return kinetic_scroll_view; } void UserInterfaceInitialization(NThread* /* thread */, void* /* InitData */) { HLayout* mainLayout = new HLayout(NUX_TRACKER_LOCATION); mainLayout->AddView(CreateKineticScrollView(), 1, eCenter, eFull); GetWindowThread()->SetLayout(mainLayout); } int main() { NuxInitialize(0); WindowThread* window_thread = CreateGUIThread( "KineticScrollView Example", 640, 300, 0, &UserInterfaceInitialization, 0); // Start the main loop. window_thread->Run(NULL); delete window_thread; return 0; } nux-4.0.6+14.04.20140409/examples/button.cpp0000644000015301777760000000656512321344237020606 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/WindowThread.h" #include "Nux/CheckBox.h" #include "Nux/ToggleButton.h" #include "Nux/Button.h" #include "Nux/TextureArea.h" void UserInterfaceInitialization(nux::NThread* thread, void* init_data) { // Create a vertical Layout nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); //Create a button of type Button nux::Button* button = new nux::Button ("Party on Garth", NUX_TRACKER_LOCATION); // Add the button to the layout layout->AddView ( button, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); // Create a button with an image nux::ColorLayer color (nux::Color (0.6, 0.4, 0.7, 1.0)); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); nux::Button* button_with_image = new nux::Button("Party on Wayne", texture_area, NUX_TRACKER_LOCATION); //button_with_image->image_position = nux::NUX_POSITION_BOTTOM; // Add the button to the layout layout->AddView ( button_with_image, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); color = nux::Color (0.6, 0.4, 0.7, 1.0); texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); nux::Button* button_without_image = new nux::Button(texture_area, NUX_TRACKER_LOCATION); // Add the button to the layout layout->AddView ( button_without_image, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); nux::ToggleButton *toggle_button = new nux::ToggleButton ("This is a Toggle button, nux just doesn't have a theme for that", NUX_TRACKER_LOCATION); layout->AddView ( toggle_button, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); nux::CheckBox *check_button = new nux::CheckBox ("Check box widget? Check!", NUX_TRACKER_LOCATION); layout->AddView ( check_button, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); // Control the position of elements inside the layout layout->SetContentDistribution (nux::MAJOR_POSITION_CENTER); // Set the layout as the container of the window thread nux::GetWindowThread ()->SetLayout (layout); // Set the background color of the window nux::ColorLayer background (nux::Color (0xFF222222)); static_cast (thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { // Initialize Nux subsystem nux::NuxInitialize (0); // Create a Window thread nux::WindowThread* wt = nux::CreateGUIThread( TEXT("Button"), 800, 600, 0, &UserInterfaceInitialization, 0); // Start the main loop wt->Run (0); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/textedit.cpp0000644000015301777760000000324612321344237021116 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/EditTextBox.h" void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::VLayout* MainVLayout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION); nux::EditTextBox* text_box_edit = new nux::EditTextBox(TEXT("Hello World!"), NUX_TRACKER_LOCATION); text_box_edit->SetMaximumWidth(300); MainVLayout->AddView(text_box_edit, 0, nux::eCenter, nux::eFull); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Edit Text Box"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/TestButton.cpp0000644000015301777760000000435012321344237021374 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include "TestButton.h" #include using namespace nux; TestButton::TestButton(const std::string& button_label, NUX_FILE_LINE_DECL) : nux::Button(button_label, NUX_FILE_LINE_PARAM) { persistent_active_state_ = true; } TestButton::~TestButton() { } void TestButton::Draw(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); GetPainter().PaintBackground(graphics_engine, base); if (visual_state_ == VISUAL_STATE_PRESSED) { GetPainter().PaintTextureShape(graphics_engine, base, eBUTTON_FOCUS); } else if (visual_state_ == VISUAL_STATE_PRELIGHT) { GetPainter().PaintTextureShape(graphics_engine, base, eBUTTON_PRELIGHT); } else if (!active_) { GetPainter().PaintTextureShape(graphics_engine, base, eBUTTON_NORMAL); } if (GetCompositionLayout()) { GetPainter().PushPaintLayerStack(); { Geometry clip_geo = base; clip_geo.OffsetPosition(left_clip_, top_clip_); clip_geo.OffsetSize(-left_clip_ - right_clip_, -top_clip_ - bottom_clip_); graphics_engine.PushClippingRectangle(clip_geo); GetPainter().PushPaintLayerStack(); GetCompositionLayout()->ProcessDraw(graphics_engine, force_draw); GetPainter().PopPaintLayerStack(); graphics_engine.PopClippingRectangle(); } GetPainter().PopPaintLayerStack(); } graphics_engine.PopClippingRectangle(); } nux-4.0.6+14.04.20140409/examples/tooltip.cpp0000644000015301777760000007312412321344237020760 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/WindowCompositor.h" #include "Nux/BaseWindow.h" #include "Nux/Button.h" #include "NuxGraphics/GraphicsEngine.h" #include "NuxGraphics/Events.h" #include "Nux/TextureArea.h" #include "NuxImage/CairoGraphics.h" #include #include #if defined(NUX_OS_LINUX) #include #endif #define ANCHOR_WIDTH 10.0f #define ANCHOR_HEIGHT 18.0f #define RADIUS 5.0f #define BLUR_INTENSITY 8 #define LINE_WIDTH 1.0f #define PADDING_SIZE 1 #define H_MARGIN 30 #define V_MARGIN 4 #define FONT_FACE "Ubuntu 13" namespace nux { class Tooltip : public BaseWindow { NUX_DECLARE_OBJECT_TYPE(Tooltip, BaseWindow); public: Tooltip (int x, int y, NString text); ~Tooltip (); long ProcessEvent (IEvent& iEvent, long traverseInfo, long processEventInfo); void Draw (GraphicsEngine& gfxContext, bool forceDraw); void DrawContent (GraphicsEngine& gfxContext, bool forceDraw); protected: void PreLayoutManagement (); long PostLayoutManagement (long layoutResult); void PositionChildLayout (float offsetX, float offsetY); void LayoutWindowElements (); void NotifyConfigurationChange (int width, int height); ObjectPtr _texture2D; int _anchorX; int _anchorY; nux::NString _labelText; int _dpiX; int _dpiY; cairo_font_options_t* _fontOpts; private: void ComputeFullMaskPath (cairo_t* cr, gfloat anchor_width, gfloat anchor_height, gint width, gint height, gint upper_size, gfloat radius, guint pad); void DrawDraw (cairo_t* cr, gboolean outline, gfloat line_width, gfloat* rgba, gboolean negative, gboolean stroke); void DrawTintDotHighlight (cairo_t* cr, gint width, gint height, gfloat hl_x, gfloat hl_y, gfloat hl_size, gfloat* rgba_tint, gfloat* rgba_hl); void DrawOutlineShadow (cairo_t* cr, gint width, gint height, gfloat anchor_width, gfloat anchor_height, gint upper_size, gfloat corner_radius, guint blur_coeff, gfloat* rgba_shadow, gfloat line_width, gint padding_size, gfloat* rgba_line); void ComputeOutline (cairo_t* cr, gfloat line_width, gfloat* rgba_line, gint width, gfloat anchor_width, gfloat corner_radius, gint padding_size); void DrawMask (cairo_t* cr, gint width, gint height, gfloat radius, guint shadow_radius, gfloat anchor_width, gfloat anchor_height, gint upper_size, gboolean negative, gboolean outline, gfloat line_width, gint padding_size, gfloat* rgba); void GetDPI (); void GetTextExtents (char* font, int* width, int* height); void DrawLabel (cairo_t* cr, gint width, gint height, gfloat* rgba); }; NUX_IMPLEMENT_OBJECT_TYPE(Tooltip); void DrawCairo (cairo_t* cr, gboolean outline, gfloat line_width, gfloat* rgba, gboolean negative, gboolean stroke) { // prepare drawing cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); // actually draw the mask if (outline) { cairo_set_line_width (cr, line_width); cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]); } else { if (negative) cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); else cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f); } // stroke or fill? if (stroke) cairo_stroke_preserve (cr); else cairo_fill_preserve (cr); } void Tooltip::ComputeFullMaskPath (cairo_t* cr, gfloat anchor_width, gfloat anchor_height, gint width, gint height, gint upper_size, gfloat radius, guint pad) { // 0 1 2 3 // +--+--------+--+ // | | // + 14 + 4 // | | // | | // | | // + 13 | // / | // / | // + 12 | // \ | // \ | // 11 + | // | | // | | // | | // 10 + + 5 // | | // +--+--------+--+ 6 // 9 8 7 gfloat padding = pad; float ZEROPOINT5 = 0.5f; gfloat HeightToAnchor = 0.0f; HeightToAnchor = ((gfloat) height - 2.0f * radius - anchor_height -2*padding) / 2.0f; if (HeightToAnchor < 0.0f) { g_warning ("Anchor-height and corner-radius a higher than whole texture!"); return; } //gint dynamic_size = height - 2*radius - 2*padding - anchor_height; //gint upper_dynamic_size = upper_size; //gint lower_dynamic_size = dynamic_size - upper_dynamic_size; if (upper_size >= 0) { if(upper_size > height - 2.0f * radius - anchor_height -2 * padding) { //g_warning ("[_compute_full_mask_path] incorrect upper_size value"); HeightToAnchor = 0; } else { HeightToAnchor = height - 2.0f * radius - anchor_height -2 * padding - upper_size; } } else { HeightToAnchor = (height - 2.0f * radius - anchor_height -2*padding) / 2.0f; } cairo_translate (cr, -0.5f, -0.5f); // create path cairo_move_to (cr, padding + anchor_width + radius + ZEROPOINT5, padding + ZEROPOINT5); // Point 1 cairo_line_to (cr, width - padding - radius, padding + ZEROPOINT5); // Point 2 cairo_arc (cr, width - padding - radius + ZEROPOINT5, padding + radius + ZEROPOINT5, radius, -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); // Point 4 cairo_line_to (cr, (gdouble) width - padding + ZEROPOINT5, (gdouble) height - radius - padding + ZEROPOINT5); // Point 5 cairo_arc (cr, (gdouble) width - padding - radius + ZEROPOINT5, (gdouble) height - padding - radius + ZEROPOINT5, radius, 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); // Point 7 cairo_line_to (cr, anchor_width + padding + radius + ZEROPOINT5, (gdouble) height - padding + ZEROPOINT5); // Point 8 cairo_arc (cr, anchor_width + padding + radius + ZEROPOINT5, (gdouble) height - padding - radius, radius, 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); // Point 10 cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, (gdouble) height - padding - radius - HeightToAnchor + ZEROPOINT5 ); // Point 11 cairo_line_to (cr, padding + ZEROPOINT5, (gdouble) height - padding - radius - HeightToAnchor - anchor_height / 2.0f + ZEROPOINT5); // Point 12 cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, (gdouble) height - padding - radius - HeightToAnchor - anchor_height + ZEROPOINT5); // Point 13 cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, padding + radius + ZEROPOINT5); // Point 14 cairo_arc (cr, padding + anchor_width + radius + ZEROPOINT5, padding + radius + ZEROPOINT5, radius, 180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); cairo_close_path (cr); } void ComputeMask (cairo_t* cr) { cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_fill_preserve (cr); } void Tooltip::ComputeOutline (cairo_t* cr, gfloat line_width, gfloat* rgba_line, gint width, gfloat anchor_width, gfloat corner_radius, gint padding_size) { cairo_pattern_t* pattern = NULL; double offset = 0.0; if (width == 0) { g_warning ("%s(): passed in width is 0!", G_STRFUNC); return; } offset = ((double) padding_size + anchor_width + corner_radius) / (double) width; cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_line_width (cr, line_width); pattern = cairo_pattern_create_linear (0.0, 0.0, (double) width, 0.0); cairo_pattern_add_color_stop_rgba (pattern, 0.0, rgba_line[0], rgba_line[1], rgba_line[2], 0.7); cairo_pattern_add_color_stop_rgba (pattern, offset, rgba_line[0], rgba_line[1], rgba_line[2], 0.7); cairo_pattern_add_color_stop_rgba (pattern, offset + 0.0125, rgba_line[0], rgba_line[1], rgba_line[2], 0.4); cairo_pattern_add_color_stop_rgba (pattern, 1.0, rgba_line[0], rgba_line[1], rgba_line[2], 0.4); cairo_set_source (cr, pattern); cairo_stroke (cr); cairo_pattern_destroy (pattern); } void Tooltip::DrawTintDotHighlight (cairo_t* cr, gint width, gint height, gfloat hl_x, gfloat hl_y, gfloat hl_size, gfloat* rgba_tint, gfloat* rgba_hl) { cairo_surface_t* dots_surf = NULL; cairo_t* dots_cr = NULL; cairo_pattern_t* dots_pattern = NULL; cairo_pattern_t* hl_pattern = NULL; // create context for dot-pattern dots_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4, 4); dots_cr = cairo_create (dots_surf); // clear normal context cairo_scale (cr, 1.0f, 1.0f); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); // prepare drawing for normal context cairo_set_operator (cr, CAIRO_OPERATOR_OVER); // create path in normal context ComputeFullMaskPath (cr, ANCHOR_WIDTH, ANCHOR_HEIGHT, width, height, -1, RADIUS, PADDING_SIZE); //cairo_rectangle (cr, 0.0f, 0.0f, (gdouble) width, (gdouble) height); // fill path of normal context with tint cairo_set_source_rgba (cr, rgba_tint[0], rgba_tint[1], rgba_tint[2], rgba_tint[3]); cairo_fill_preserve (cr); // create pattern in dot-context cairo_set_operator (dots_cr, CAIRO_OPERATOR_CLEAR); cairo_paint (dots_cr); cairo_scale (dots_cr, 1.0f, 1.0f); cairo_set_operator (dots_cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (dots_cr, rgba_hl[0], rgba_hl[1], rgba_hl[2], rgba_hl[3]); cairo_rectangle (dots_cr, 0.0f, 0.0f, 1.0f, 1.0f); cairo_fill (dots_cr); cairo_rectangle (dots_cr, 2.0f, 2.0f, 1.0f, 1.0f); cairo_fill (dots_cr); dots_pattern = cairo_pattern_create_for_surface (dots_surf); // fill path of normal context with dot-pattern // FIXME: using the path from ComputeFullMaskPath() and not a plain rect. // path triggers a bug in cairo (yet to be filed), so repeating of the dot- // pattern produces wrong pattern in the end, a viable work-around still // needs to be thought up cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source (cr, dots_pattern); cairo_pattern_set_extend (dots_pattern, CAIRO_EXTEND_REPEAT); cairo_fill_preserve (cr); cairo_pattern_destroy (dots_pattern); cairo_surface_destroy (dots_surf); cairo_destroy (dots_cr); // draw highlight cairo_set_operator (cr, CAIRO_OPERATOR_OVER); hl_pattern = cairo_pattern_create_radial ((double)hl_x, (double)hl_y, (double)0.0f, (double)hl_x, (double)hl_y, (double)hl_size); cairo_pattern_add_color_stop_rgba (hl_pattern, 0.0f, 1.0f, 1.0f, 1.0f, 0.65f); cairo_pattern_add_color_stop_rgba (hl_pattern, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); cairo_set_source (cr, hl_pattern); cairo_fill (cr); cairo_pattern_destroy (hl_pattern); } void Tooltip::DrawMask (cairo_t* cr, gint width, gint height, gfloat radius, guint shadow_radius, gfloat anchor_width, gfloat anchor_height, gint upper_size, gboolean negative, gboolean outline, gfloat line_width, gint padding_size, gfloat* rgba) { ComputeFullMaskPath (cr, anchor_width, anchor_height, width, height, upper_size, radius, padding_size); } void Tooltip::GetDPI () { #if defined(NUX_OS_LINUX) Display* display = NULL; int screen = 0; double dpyWidth = 0.0; double dpyHeight = 0.0; double dpyWidthMM = 0.0; double dpyHeightMM = 0.0; double dpiX = 0.0; double dpiY = 0.0; display = XOpenDisplay (NULL); screen = DefaultScreen (display); dpyWidth = (double) DisplayWidth (display, screen); dpyHeight = (double) DisplayHeight (display, screen); dpyWidthMM = (double) DisplayWidthMM (display, screen); dpyHeightMM = (double) DisplayHeightMM (display, screen); dpiX = dpyWidth * 25.4 / dpyWidthMM; dpiY = dpyHeight * 25.4 / dpyHeightMM; _dpiX = (int) (dpiX + 0.5); _dpiY = (int) (dpiY + 0.5); XCloseDisplay (display); #elif defined(NUX_OS_WINDOWS) _dpiX = 72; _dpiY = 72; #endif } void Tooltip::GetTextExtents (char* font, int* width, int* height) { cairo_surface_t* surface = NULL; cairo_t* cr = NULL; PangoLayout* layout = NULL; PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; PangoRectangle logRect = {0, 0, 0, 0}; // sanity check if (!font || !width || !height) return; surface = cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1); cr = cairo_create (surface); layout = pango_cairo_create_layout (cr); desc = pango_font_description_from_string (font); pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL); pango_layout_set_font_description (layout, desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_text (layout, _labelText.GetTCharPtr(), -1); pangoCtx = pango_layout_get_context (layout); // is not ref'ed pango_cairo_context_set_font_options (pangoCtx, _fontOpts); pango_cairo_context_set_resolution (pangoCtx, _dpiX); pango_layout_context_changed (layout); pango_layout_get_extents (layout, NULL, &logRect); *width = logRect.width / PANGO_SCALE; *height = logRect.height / PANGO_SCALE; // clean up pango_font_description_free (desc); g_object_unref (layout); cairo_destroy (cr); cairo_surface_destroy (surface); } void Tooltip::DrawLabel (cairo_t* cr, gint width, gint height, gfloat* rgba) { int textWidth = 0; int textHeight = 0; PangoLayout* layout = NULL; PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; GetTextExtents ((char*) FONT_FACE, &textWidth, &textHeight); cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]); cairo_set_font_options (cr, _fontOpts); layout = pango_cairo_create_layout (cr); desc = pango_font_description_from_string ((char*) FONT_FACE); pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL); pango_layout_set_font_description (layout, desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_text (layout, _labelText.GetTCharPtr(), -1); pangoCtx = pango_layout_get_context (layout); // is not ref'ed pango_cairo_context_set_font_options (pangoCtx, _fontOpts); pango_cairo_context_set_resolution (pangoCtx, (double) _dpiX); pango_layout_context_changed (layout); cairo_move_to (cr, ANCHOR_WIDTH + (float) ((width - ANCHOR_WIDTH) - textWidth) / 2.0f, (float) (height - textHeight) / 2.0f); pango_cairo_show_layout (cr, layout); cairo_fill (cr); // clean up pango_font_description_free (desc); g_object_unref (layout); } void Tooltip::DrawOutlineShadow (cairo_t* cr, gint width, gint height, gfloat anchor_width, gfloat anchor_height, gint upper_size, gfloat corner_radius, guint blur_coeff, gfloat* rgba_shadow, gfloat line_width, gint padding_size, gfloat* rgba_line) { ComputeFullMaskPath (cr, anchor_width, anchor_height, width, height, upper_size, corner_radius, padding_size); //DrawCairo (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE); //ctk_surface_blur (surf, blur_coeff); //ComputeMask (cr); ComputeOutline (cr, line_width, rgba_line, width, anchor_width, corner_radius, padding_size); } Tooltip::Tooltip (int x, int y, NString text) : BaseWindow("", NUX_TRACKER_LOCATION) { _anchorX = x; _anchorY = y; _labelText = text; _fontOpts = cairo_font_options_create (); // FIXME: hard-coding these for the moment, as we don't have // gsettings-support in place right now cairo_font_options_set_antialias (_fontOpts, CAIRO_ANTIALIAS_SUBPIXEL); cairo_font_options_set_hint_metrics (_fontOpts, CAIRO_HINT_METRICS_ON); cairo_font_options_set_hint_style (_fontOpts, CAIRO_HINT_STYLE_SLIGHT); cairo_font_options_set_subpixel_order (_fontOpts, CAIRO_SUBPIXEL_ORDER_RGB); // make sure _dpiX and _dpiY are initialized correctly GetDPI (); } Tooltip::~Tooltip () { cairo_font_options_destroy(_fontOpts); } long Tooltip::ProcessEvent (IEvent& ievent, long TraverseInfo, long ProcessEventInfo) { return 0; } void Tooltip::Draw (GraphicsEngine& gfxContext, bool forceDraw) { Geometry base = GetGeometry(); // the elements position inside the window are referenced to top-left window // corner. So bring base to (0, 0). base.SetX (0); base.SetY (0); gfxContext.PushClippingRectangle (base); gPainter.PushDrawShapeLayer (gfxContext, base, eSHAPE_CORNER_ROUND10, nux::Color(0xFF707070), eAllCorners, true); TexCoordXForm texxform; texxform.SetWrap(TEXWRAP_REPEAT, TEXWRAP_REPEAT); texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD); gfxContext.QRP_GLSL_1Tex (base.x, base.y, base.width, base.height, _texture2D->GetDeviceTexture(), texxform, Color(1.0f, 1.0f, 1.0f, 1.0f)); gPainter.PopBackground (); gfxContext.PopClippingRectangle (); } void Tooltip::DrawContent (GraphicsEngine &GfxContext, bool force_draw) { /*Geometry base = GetGeometry(); int x = base.x; int y = base.y; // The elements position inside the window are referenced to top-left window corner. So bring base to (0, 0). base.SetX (0); base.SetY (0); if (UseBlurredBackground() ) { TexCoordXForm texxform; texxform.uoffset = (float) x / (float) GetThreadWindowCompositor().GetScreenBlurTexture()->GetWidth(); texxform.voffset = (float) y / (float) GetThreadWindowCompositor().GetScreenBlurTexture()->GetHeight(); texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD); gPainter.PushTextureLayer (GfxContext, base, GetThreadWindowCompositor().GetScreenBlurTexture(), texxform, Color::White, true); } else { //nuxDebugMsg(TEXT("[BaseWindow::DrawContent]")); gPainter.PushShapeLayer (GfxContext, base, eSHAPE_CORNER_ROUND10, m_background_color, eAllCorners, true); //GfxContext.QRP_GLSL_Color(base.x, base.y, base.width, base.height, Color(1.0f, 0.0f, 0.0f, 1.0f)); //GfxContext.QRP_GLSL_Color(base.x, base.y, base.width, base.height, Color(1.0f / (float) (std::rand () % 100), 1.0f / (float) (std::rand () % 100), 1.0f / (float) (std::rand () % 100), 0.5f)); } if (m_layout) { GfxContext.PushClippingRectangle (base); m_layout->ProcessDraw (GfxContext, force_draw); GfxContext.PopClippingRectangle(); } gPainter.PopBackground();*/ } void Tooltip::PreLayoutManagement () { } long Tooltip::PostLayoutManagement (long LayoutResult) { long result = BaseWindow::PostLayoutManagement (LayoutResult); int textWidth = 0; int textHeight = 0; Geometry base; float rgbaTint[4] = {0.0f, 0.0f, 0.0f, 0.7f}; float rgbaHighlight[4] = {1.0f, 1.0f, 1.0f, 0.15f}; float rgbaLine[4] = {1.0f, 1.0f, 1.0f, 0.75f}; float rgbaShadow[4] = {0.0f, 0.0f, 0.0f, 0.48f}; float rgbaText[4] = {1.0f, 1.0f, 1.0f, 1.0f}; GetTextExtents ((char*) FONT_FACE, &textWidth, &textHeight); base.x = _anchorX; base.y = _anchorY; base.width = textWidth + 2 * H_MARGIN + ANCHOR_WIDTH + 2 * PADDING_SIZE; base.height = textHeight + 2 * V_MARGIN + 2 * PADDING_SIZE; SetGeometry (base); CairoGraphics* cairo_graphics = new CairoGraphics (CAIRO_FORMAT_ARGB32, base.GetWidth (), base.GetHeight ()); cairo_t *cr = cairo_graphics->GetContext (); DrawTintDotHighlight (cr, base.GetWidth (), base.GetHeight (), base.GetWidth () / 2.0f, 15.0f, base.GetWidth () / 2.0f, rgbaTint, rgbaHighlight); DrawOutlineShadow (cr, base.GetWidth (), base.GetHeight (), ANCHOR_WIDTH, ANCHOR_HEIGHT, -1, RADIUS, BLUR_INTENSITY, rgbaShadow, LINE_WIDTH, PADDING_SIZE, rgbaLine); DrawLabel (cr, base.GetWidth (), base.GetHeight (), rgbaText); nux::NBitmapData* bitmap = cairo_graphics->GetBitmap(); // Texture2D is the high level representation of an image that is backed by // an actual opengl texture. _texture2D = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture (); // It is initially owned, and now we have a pointer to it, so unref _texture2D->UnReference(); _texture2D->Update(bitmap); delete bitmap; delete cairo_graphics; return result; } void Tooltip::PositionChildLayout (float offsetX, float offsetY) { } void Tooltip::LayoutWindowElements () { } void Tooltip::NotifyConfigurationChange (int width, int height) { } } void initGUIThread (nux::NThread* thread, void* data) { nux::VLayout* layout = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); nux::GetWindowThread ()->SetLayout (layout); } int main (int argc, char const** argv) { nux::WindowThread* thread = NULL; nux::NuxInitialize (0); thread = nux::CreateGUIThread (TEXT ("NUX/Unity Tooltips"), 600, 400, 0, &initGUIThread, 0); nux::Tooltip* tooltip1 = new nux::Tooltip (64, 64, TEXT("GEdit")); nux::Tooltip* tooltip2 = new nux::Tooltip (64, 128, TEXT("Firefox")); nux::Tooltip* tooltip3 = new nux::Tooltip (64, 192, TEXT("Chromium")); tooltip1->ShowWindow(true); tooltip2->ShowWindow(true); tooltip3->ShowWindow(true); thread->Run (NULL); tooltip3->UnReference(); tooltip2->UnReference(); tooltip1->UnReference(); delete thread; return 0; } nux-4.0.6+14.04.20140409/examples/TestButton.h0000644000015301777760000000221712321344237021041 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef DAN_TESTBUTTON_H #define DAN_TESTBUTTON_H #include #include class TestButton : public nux::Button { public: TestButton(const std::string& button_label, NUX_FILE_LINE_PROTO); virtual ~TestButton(); protected: virtual void Draw(nux::GraphicsEngine &graphics_engine, bool force_draw); }; #endif nux-4.0.6+14.04.20140409/examples/abstract-separator.cpp0000644000015301777760000000323512321344237023063 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "abstract-separator.h" namespace nux { AbstractSeparator::AbstractSeparator (NUX_FILE_LINE_DECL) : View (NUX_FILE_LINE_PARAM) , m_Color(0xFFFFFFFF) , m_Alpha0(0.0f) , m_Alpha1(0.592f) , m_BorderSize(10) { } AbstractSeparator::AbstractSeparator (const Color &color, float Alpha0, float Alpha1, int Border, NUX_FILE_LINE_DECL) : View (NUX_FILE_LINE_PARAM) , m_Color (color) , m_Alpha0 (Alpha0) , m_Alpha1 (Alpha1) , m_BorderSize (Border) { } AbstractSeparator::~AbstractSeparator() { } void AbstractSeparator::SetColor (const Color &color) { m_Color = color; } void AbstractSeparator::SetAlpha (float Alpha0, float Alpha1) { m_Alpha0 = Alpha0; m_Alpha1 = Alpha1; } void AbstractSeparator::SetBorderSize (int Border) { m_BorderSize = Border; } } nux-4.0.6+14.04.20140409/examples/layeredlayout.cpp0000644000015301777760000001061312321344237022143 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Neil Jagdish Patel * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "NuxGraphics/GraphicsEngine.h" #include "Nux/TextureArea.h" #include "Nux/HLayout.h" #include "Nux/VLayout.h" #include "Nux/LayeredLayout.h" #include "Nux/ToggleButton.h" #include "Nux/ComboBoxSimple.h" class Foo { public: Foo () { nux::VLayout *main_layout((new nux::VLayout(NUX_TRACKER_LOCATION))); nux::ComboBoxSimple *combo = new nux::ComboBoxSimple (NUX_TRACKER_LOCATION); combo->SetMinimumWidth (150); combo->sigTriggered.connect (sigc::mem_fun (this, &Foo::OnComboChangedFoRealz)); main_layout->AddView (combo, 0, nux::eCenter, nux::eFix); layered_layout = new nux::LayeredLayout (NUX_TRACKER_LOCATION); for (int i = 0; i < 10; i++) { gchar *text = g_strdup_printf ("Button %d", i); nux::LayeredLayout *layered = new nux::LayeredLayout (NUX_TRACKER_LOCATION); nux::ColorLayer color (nux::color::RandomColor ()); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); layered->AddLayer (texture_area); nux::HLayout *hori = new nux::HLayout (NUX_TRACKER_LOCATION); nux::Button* button = new nux::Button ("Big Button", NUX_TRACKER_LOCATION); button->SetMinMaxSize (200, 100); hori->AddView (button, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); hori->SetContentDistribution (nux::MAJOR_POSITION_CENTER); layered->AddLayer (hori); hori = new nux::HLayout (NUX_TRACKER_LOCATION); button = new nux::ToggleButton (text, NUX_TRACKER_LOCATION); button->SetMinMaxSize (100, 50); hori->AddView (button, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); hori->SetContentDistribution (nux::MAJOR_POSITION_CENTER); layered->AddLayout (hori); button = new nux::ToggleButton ("This button is insensitive", NUX_TRACKER_LOCATION); button->SetSensitive (false); layered->AddLayer (button, false, 10, 10, 180, 40); button = new nux::ToggleButton ("This button has x, y, w, h set", NUX_TRACKER_LOCATION); layered->AddLayer (button, false, 400, 10, 180, 40); nux::ROPConfig rop; rop.Blend = true; rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; nux::Color col (0x55005500); nux::ColorLayer c (col, true, rop); texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&c); layered->AddLayer (texture_area, false, 0, 100, 600, 200); button = new nux::ToggleButton ("YOU CANT SEE ME!!!!!", NUX_TRACKER_LOCATION); layered->AddLayer (button, true); button->SetVisible (false); layered->SetPaintAll (true); layered->SetInputMode (nux::LayeredLayout::INPUT_MODE_COMPOSITE); layered->Raise (hori, texture_area); button = new nux::ToggleButton ("YOU CANT SEE ME!!!!!", NUX_TRACKER_LOCATION); layered->AddLayer (button, true); layered->RemoveLayer (button); layered_layout->AddLayout (layered); combo->AddItem (text); g_free (text); } main_layout->AddLayout (layered_layout, 1); nux::GetWindowThread ()->SetLayout(main_layout); } ~Foo () { } void OnComboChangedFoRealz (nux::ComboBoxSimple *simple) { g_debug ("Active: %d", simple->GetSelectionIndex ()); layered_layout->SetActiveLayerN (simple->GetSelectionIndex ()); } nux::LayeredLayout *layered_layout; }; void LayeredLayoutInit(nux::NThread* thread, void* InitData) { } int main(int argc, char **argv) { Foo *foo; nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Layered Layout"), 600, 400, 0, &LayeredLayoutInit, 0); foo = new Foo (); wt->Run(NULL); delete wt; delete foo; return 0; } nux-4.0.6+14.04.20140409/examples/rotate_texture_area.cpp0000644000015301777760000000570312321344237023332 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/WindowThread.h" #include "Nux/TextureArea.h" #include "Nux/TimerProc.h" nux::TimerFunctor *timer_functor = 0; nux::TimerHandle timer_handle; float angle = 0.0f; void UpdateAngle (void *v) { angle += 0.1f; if (angle >= nux::Const::pi) { angle = 0.0f; } nux::TextureArea* texture_area = NUX_STATIC_CAST (nux::TextureArea*, v); if (texture_area) { texture_area->Set2DRotation (angle); timer_handle = nux::GetTimer().AddTimerHandler (10, timer_functor, texture_area); if (angle == 0) { nux::ColorLayer color_layer (nux::color::RandomColor ()); texture_area->SetPaintLayer (&color_layer); } } } void UserInterfaceInitialization(nux::NThread* thread, void* init_data) { // Create a vertical Layout nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); //Create a button of type PushButton nux::TextureArea* texture_area = new nux::TextureArea(NUX_TRACKER_LOCATION); // Set the button maximum width/height texture_area->SetMaximumWidth (160); texture_area->SetMaximumHeight (80); texture_area->SetTextColor (nux::color::Pink); texture_area->Set2DRotation (0.0); // Add the button to the layout layout->AddView ( texture_area, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); // Control the position of elements inside the layout layout->SetContentDistribution (nux::MAJOR_POSITION_CENTER); // Set the layout as the container of the window thread nux::GetWindowThread ()->SetLayout (layout); // Set the background color of the window nux::ColorLayer background (nux::Color (0xFF222222)); static_cast (thread)->SetWindowBackgroundPaintLayer(&background); timer_functor = new nux::TimerFunctor; timer_functor->OnTimerExpired.connect (sigc::ptr_fun (&UpdateAngle)); timer_handle = nux::GetTimer().AddTimerHandler (5, timer_functor, texture_area); } int main(int argc, char **argv) { // Initialize Nux subsystem nux::NuxInitialize (0); // Create a Window thread nux::WindowThread* wt = nux::CreateGUIThread( TEXT("Rotate Texture Area"), 400, 300, 0, &UserInterfaceInitialization, 0); // Start the main loop wt->Run (0); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/pangotextedit.cpp0000644000015301777760000000331212321344237022135 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/TextEntry.h" void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::VLayout* MainVLayout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::TextEntry* text_entry = new nux::TextEntry(TEXT("0123456789 abcdefghijklmnopqrstuvwxyz"), NUX_TRACKER_LOCATION); text_entry->SetMaximumWidth(300); text_entry->SetMinimumHeight (20); MainVLayout->AddView(text_entry, 0, nux::eCenter, nux::eFull); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Text Entry"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/combobox.cpp0000644000015301777760000000364412321344237021076 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/ComboBoxSimple.h" #include "Nux/TableCtrl.h" void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::VLayout* MainVLayout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION); nux::ComboBoxSimple* combobox = new nux::ComboBoxSimple(NUX_TRACKER_LOCATION); combobox->AddItem("A"); combobox->AddItem("B"); combobox->AddItem("C"); combobox->AddItem("D"); combobox->AddItem("E"); combobox->RemoveAllItem (); combobox->AddItem("N"); combobox->AddItem("U"); combobox->AddItem("X"); combobox->SetMaximumWidth(150); MainVLayout->AddView(combobox, 0, nux::eCenter, nux::eFull); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("ComboBox"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/gestures.cpp0000644000015301777760000000537612321344237021133 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #include "Nux/FloatingWindow.h" #include "Nux/GesturesSubscription.h" #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include using namespace nux; BaseWindow *window = nullptr; class GesturalWindow : public FloatingWindow { NUX_DECLARE_OBJECT_TYPE(GesturalWindow, FloatingWindow); public: GesturalWindow(const char *window_name = "", NUX_FILE_LINE_PROTO) : FloatingWindow(window_name, NUX_FILE_LINE_PARAM) { CreateGesturesSubscription(TOUCH_GESTURE, 3); event_count = 0; } virtual ~GesturalWindow() {} virtual GestureDeliveryRequest GestureEvent(const nux::GestureEvent & /* event */) { std::cout << "GesturalWindow got GestureEvent " << ++event_count << "\n"; return GestureDeliveryRequest::NONE; } int event_count; }; NUX_IMPLEMENT_OBJECT_TYPE(GesturalWindow); int GesturesEventInspector(Area* /* area */, Event* event, void* /* data */) { if (event->type < EVENT_GESTURE_BEGIN || event->type > EVENT_GESTURE_END) return false; GestureEvent *gesture_event = static_cast(event); if (gesture_event->type == EVENT_GESTURE_BEGIN) { std::cout << "Gesture begun\n"; } else if (gesture_event->type == EVENT_GESTURE_UPDATE) std::cout << "Gesture updated\n"; else std::cout << "Gesture ended\n"; return false; } void UserInterfaceInitialization(NThread* /* thread */, void* /* InitData */) { window = new GesturalWindow(TEXT("Gestural Window"), NUX_TRACKER_LOCATION); window->SetBaseXY(100, 20); window->ShowWindow(true); } int main() { // Initialize Nux. NuxInitialize(0); // Create a window thread. WindowThread* window_thread = CreateGUIThread( "Gestures", 640, 300, 0, &UserInterfaceInitialization, 0); window_thread->InstallEventInspector(GesturesEventInspector, nullptr); // Start the main loop. window_thread->Run(NULL); window->Dispose(); // will cause the window to be deleted (as ref count is zeroed) delete window_thread; return 0; } nux-4.0.6+14.04.20140409/examples/cairo.cpp0000644000015301777760000000446512321344237020365 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "NuxGraphics/GraphicsEngine.h" #include "Nux/TextureArea.h" #include "NuxGraphics/CairoGraphics.h" void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, 64, 64); cairo_t *cr = cairo_graphics.GetContext(); cairo_set_line_width (cr, 1); cairo_set_source_rgba (cr, 0.0f, 1.0f, 0.5f, 1.0f); cairo_rectangle (cr, 0, 0, 32, 32); cairo_fill (cr); cairo_set_source_rgba (cr, 1.0f, 0.0f, 0.5f, 1.0f); cairo_rectangle (cr, 32, 32, 32, 32); cairo_fill (cr); cairo_destroy (cr); nux::NBitmapData* bitmap = cairo_graphics.GetBitmap(); // Texture2D is the high level representation of an image that is backed by an actual opengl texture. nux::Texture2D* texture2D = new nux::Texture2D(); texture2D->Update(bitmap); nux::VLayout* MainVLayout((new nux::VLayout())); // TextureArea is a widget that uses the image we have created above to render on the screen. nux::TextureArea* texture_area = new nux::TextureArea(); texture_area->SetTexture(texture2D); texture_area->SetMinMaxSize(64, 64); MainVLayout->AddView(texture_area, 1, nux::eCenter, nux::eFix); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Cairo Graphics"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/checkbox.cpp0000644000015301777760000000324412321344237021050 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/CheckBox.h" void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::VLayout* MainVLayout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION); nux::CheckBox* checkbox = new nux::CheckBox("Hello World!", NUX_TRACKER_LOCATION); checkbox->SetMaximumWidth(80); checkbox->SetMaximumHeight(60); MainVLayout->AddView(checkbox, 1, nux::eCenter, nux::eFull); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Edit Text Box"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/tiles_view.cpp0000644000015301777760000003221312321344237021432 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/TextEntry.h" #include "Nux/ScrollView.h" #include "Nux/GridHLayout.h" #include "Nux/GridVLayout.h" #include "Nux/TextureArea.h" #include "Nux/Panel.h" #include "Nux/MenuPage.h" #include "NuxCore/Logger.h" #include "NuxGraphics/IOpenGLFrameBufferObject.h" #include "NuxGraphics/IOpenGLBaseTexture.h" nux::NString tile_vertex_shader = TEXT (" \n\ #version 110 \n\ attribute vec4 position; \n\ attribute vec4 texcoord; \n\ attribute vec4 color; \n\ uniform mat4 mvp_matrix; \n\ varying vec4 texcoord0; \n\ varying vec4 color0; \n\ void main() \n\ { \n\ texcoord0 = texcoord; \n\ color0 = color; \n\ gl_Position = mvp_matrix * position; \n\ }"); nux::NString tile_fragment_shader = TEXT (" \n\ #version 110 \n\ varying vec4 texcoord0; \n\ varying vec4 color0; \n\ uniform sampler2D texture_unit0; \n\ void main() \n\ { \n\ gl_FragColor = color0; \n\ }"); class Tile; class TilesView: public nux::View { NUX_DECLARE_OBJECT_TYPE(TilesView, View); public: TilesView(NUX_FILE_LINE_PROTO); ~TilesView(); void AddTile(Tile *tile); protected: nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type); void OnMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); void ShowPopupMenu(int x, int y); void Draw(nux::GraphicsEngine &graphics_engine, bool force_draw); void DrawContent(nux::GraphicsEngine &graphics_engine, bool force_draw); private: Tile *focus_tile_; nux::GridHLayout *grid_layout_; nux::MenuPage *popup_menu_; nux::ColorLayer background_color_layer_; }; class Tile: public nux::TextureArea { NUX_DECLARE_OBJECT_TYPE(Tile, TextureArea); public: Tile(NUX_FILE_LINE_PROTO); ~Tile(); protected: void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void Draw(nux::GraphicsEngine &graphics_engine, bool force_draw); private: nux::ObjectPtr fbo_; nux::ObjectPtr texture_; nux::ObjectPtr depth_texture_; nux::ObjectPtr fragment_shader_prog_; nux::ObjectPtr vertex_shader_prog_; nux::ObjectPtr shader_prog_; }; NUX_IMPLEMENT_OBJECT_TYPE(TilesView); TilesView::TilesView(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , background_color_layer_(nux::color::Orange, true) { popup_menu_ = new nux::MenuPage("", NUX_TRACKER_LOCATION); popup_menu_->AddAction("Position"); popup_menu_->AddAction("Remove"); popup_menu_->AddAction("Configure"); popup_menu_->SetParentObject(this); popup_menu_->SetOnClosureContinueEventCycle(true); background_color_layer_.SetColor(nux::color::Orange); mouse_up.connect(sigc::mem_fun(this, &TilesView::OnMouseDown)); grid_layout_ = new nux::GridHLayout(NUX_TRACKER_LOCATION); grid_layout_->ForceChildrenSize(true); grid_layout_->SetChildrenSize(64, 64); grid_layout_->EnablePartialVisibility(false); grid_layout_->SetVerticalExternalMargin(32); grid_layout_->SetHorizontalExternalMargin(32); grid_layout_->SetVerticalInternalMargin(32); grid_layout_->SetHorizontalInternalMargin(32); grid_layout_->SetStretchFactor(1); grid_layout_->SetHeightMatchContent(false); SetLayout(grid_layout_); } TilesView::~TilesView() { popup_menu_->UnParentObject(); } void TilesView::AddTile(Tile *tile) { if (tile == NULL) return; grid_layout_->AddView(tile, 1, nux::eLeft, nux::eFull); } nux::Area* TilesView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if(mouse_inside == false) return NULL; if (event_type == nux::NUX_MOUSE_PRESSED) { focus_tile_ = static_cast(grid_layout_->FindAreaUnderMouse(mouse_position, event_type)); } else { //focus_tile_ = NULL; } if((event_type == nux::NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } void TilesView::OnMouseDown(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { if (nux::GetEventButton(mouse_button_state) == nux::NUX_MOUSE_BUTTON3) { if (focus_tile_) { ShowPopupMenu(x + 2, y + 2); } } } void TilesView::ShowPopupMenu(int x, int y) { popup_menu_->StopMenu(); popup_menu_->StartMenu(x, y, 0, 0, false); } void TilesView::Draw(nux::GraphicsEngine &graphics_engine, bool force_draw) { background_color_layer_.SetGeometry(GetGeometry()); background_color_layer_.Renderlayer(graphics_engine); } void TilesView::DrawContent(nux::GraphicsEngine &graphics_engine, bool force_draw) { nux::GetWindowThread()->GetPainter().PushLayer(graphics_engine, GetGeometry(), &background_color_layer_); if (m_CompositionLayout) m_CompositionLayout->ProcessDraw(graphics_engine, force_draw); nux::GetWindowThread()->GetPainter().PopBackground(); } class TileManager { public: TileManager(); ~TileManager(); Tile* CreateTile(); TilesView* GetTilesView(); private: TilesView* tiles_view_; nux::ObjectPtr fbo_; nux::ObjectPtr texture_; nux::ObjectPtr depth_texture_; }; TileManager::TileManager() { tiles_view_ = new TilesView(NUX_TRACKER_LOCATION); } TileManager::~TileManager() { } Tile* TileManager::CreateTile() { Tile *tile = new Tile(NUX_TRACKER_LOCATION); tiles_view_->AddTile(tile); return tile; } TilesView* TileManager::GetTilesView() { return tiles_view_; } NUX_IMPLEMENT_OBJECT_TYPE(Tile); Tile::Tile(NUX_FILE_LINE_DECL) : nux::TextureArea(NUX_FILE_LINE_PARAM) { fbo_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject(); texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(1, 1, 1, nux::BITFMT_R8G8B8A8); depth_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(1, 1, 1, nux::BITFMT_D24S8); fragment_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); vertex_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); vertex_shader_prog_->SetShaderCode(TCHAR_TO_ANSI(*tile_vertex_shader)); fragment_shader_prog_->SetShaderCode(TCHAR_TO_ANSI(*tile_fragment_shader)); shader_prog_->ClearShaderObjects(); shader_prog_->AddShaderObject(vertex_shader_prog_); shader_prog_->AddShaderObject(fragment_shader_prog_); shader_prog_->Link(); } Tile::~Tile() { } void Tile::Draw(nux::GraphicsEngine &graphics_engine, bool force_draw) { int width = GetBaseWidth(); int height = GetBaseHeight(); if ((texture_->GetWidth() != width) || (texture_->GetHeight() != height)) { texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, nux::BITFMT_R8G8B8A8); } if ((depth_texture_->GetWidth() != width) || (depth_texture_->GetHeight() != height)) { depth_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, nux::BITFMT_D24S8); } //nux::ObjectPtr prev_fbo = nux::GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); fbo_->FormatFrameBufferObject(width, height, nux::BITFMT_R8G8B8A8); fbo_->SetRenderTarget(0, texture_->GetSurfaceLevel(0)); fbo_->SetDepthSurface(depth_texture_->GetSurfaceLevel(0)); fbo_->Activate(); fbo_->EmptyClippingRegion(); nux::GetGraphicsDisplay()->GetGraphicsEngine()->SetContext(0, 0, width, height); nux::GetGraphicsDisplay()->GetGraphicsEngine()->SetViewport(0, 0, width, height); nux::GetGraphicsDisplay()->GetGraphicsEngine()->Push2DWindow(width, height); nux::Geometry geo = GetAbsoluteGeometry(); { nux::Color color = nux::color::RandomColor(); float w = width; float h = height; float vertex_buffer[] = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0, 0, color.red, color.green, color.blue, color.alpha, 0.0f, h, 0.0f, 1.0f, 0.0f, 1.0f, 0, 0, color.red, color.green, color.blue, color.alpha, w, h, 0.0f, 1.0f, 1.0f, 1.0f, 0, 0, color.red, color.green, color.blue, color.alpha, w, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0, 0, color.red, color.green, color.blue, color.alpha, }; CHECKGL(glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); shader_prog_->Begin(); int texture_unit0_location = shader_prog_->GetUniformLocationARB("texture_unit0"); int vertex_attrib_location = shader_prog_->GetAttributeLocation("position"); int texture_coord_attrib_location = shader_prog_->GetAttributeLocation("texture"); int color_attrib_location = shader_prog_->GetAttributeLocation("color"); if (texture_unit0_location != -1) { graphics_engine.SetTexture(GL_TEXTURE0, 0); CHECKGL(glUniform1iARB(texture_unit0_location, 0)); } int mvp_matrix_location = shader_prog_->GetUniformLocationARB ("mvp_matrix"); nux::Matrix4 mvp_matrix = graphics_engine.GetOpenGLModelViewProjectionMatrix(); shader_prog_->SetUniformLocMatrix4fv((GLint) mvp_matrix_location, 1, false, (GLfloat *) &(mvp_matrix.m)); CHECKGL(glEnableVertexAttribArrayARB(vertex_attrib_location)); CHECKGL(glVertexAttribPointerARB ( (GLuint) vertex_attrib_location, 4, GL_FLOAT, GL_FALSE, 48, vertex_buffer)); if (texture_coord_attrib_location != -1) { CHECKGL ( glEnableVertexAttribArrayARB (texture_coord_attrib_location) ); CHECKGL ( glVertexAttribPointerARB ( (GLuint) texture_coord_attrib_location, 4, GL_FLOAT, GL_FALSE, 48, vertex_buffer + 4) ); } if (color_attrib_location != -1) { CHECKGL ( glEnableVertexAttribArrayARB (color_attrib_location) ); CHECKGL ( glVertexAttribPointerARB ( (GLuint) color_attrib_location, 4, GL_FLOAT, GL_FALSE, 48, vertex_buffer + 8) ); } CHECKGL ( glDrawArrays (GL_TRIANGLE_FAN, 0, 4) ); CHECKGL ( glDisableVertexAttribArrayARB (vertex_attrib_location) ); if (texture_coord_attrib_location != -1) CHECKGL ( glDisableVertexAttribArrayARB (texture_coord_attrib_location) ); if (color_attrib_location != -1) CHECKGL ( glDisableVertexAttribArrayARB (color_attrib_location) ); shader_prog_->End(); } //nux::GetGraphicsDisplay()->GetGraphicsEngine()->QRP_Color(0, 0, geo.width, geo.height, nux::color::Aubergine); nux::GetWindowCompositor().RestoreRenderingSurface(); nux::TexCoordXForm texxform; nux::GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(geo.x, geo.y, geo.width, geo.height, texture_, texxform, nux::color::White); //nux::TextureArea::Draw(graphics_engine, force_draw); } void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::VLayout* MainVLayout = new nux::VLayout(NUX_TRACKER_LOCATION); TileManager *tile_manager = new TileManager(); for (int i = 0; i < 10; i++) { tile_manager->CreateTile(); tile_manager->CreateTile(); tile_manager->CreateTile(); tile_manager->CreateTile(); tile_manager->CreateTile(); } MainVLayout->AddView(tile_manager->GetTilesView(), 1, nux::eCenter, nux::MINOR_SIZE_FULL); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::logging::Logger logger("test.tile_view"); logger.SetLogLevel(nux::logging::Debug); LOG_DEBUG(logger) << "\nTest\n"; nux::WindowThread* wt = nux::CreateGUIThread(TEXT("ScrollView"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/timegraph.cpp0000644000015301777760000000623312321344237021243 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/WindowThread.h" #include "Nux/TimeGraph.h" #include "Nux/TimerProc.h" nux::TimerFunctor *timer_functor; nux::TimerHandle timer_handler; float time_value = 0; void GraphTimerInterrupt (void *data) { time_value += 0.001f; nux::TimeGraph* timegraph = NUX_STATIC_CAST (nux::TimeGraph*, data); for (int i = 0; i < 3; i++) { if (i == 0) timegraph->UpdateGraph (i, nux::GetWindowThread ()->GetFrameRate() ); if (i == 1) timegraph->UpdateGraph (i, nux::RandomUInt (25) + 25); if (i == 2) timegraph->UpdateGraph (i, 30 * (std::sin (time_value) + 1) + nux::RandomUInt (10) ); } timer_handler = nux::GetTimer().AddTimerHandler (100, timer_functor, timegraph); } void UserInterfaceInitialization(nux::NThread* thread, void* init_data) { // Create a vertical Layout nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::TimeGraph* timegraph = new nux::TimeGraph(TEXT("Graph")); timegraph->ShowColumnStyle (); timegraph->SetYAxisBounds (0.0, 200.0f); timegraph->AddGraph (nux::Color (0xFF9AD61F), nux::Color (0x50191919) ); timegraph->AddGraph (nux::Color (0xFF00FF00), nux::Color (0x5000FF00) ); timegraph->AddGraph (nux::Color (0xFFFF0022), nux::Color (0x50BB0022) ); timer_functor = new nux::TimerFunctor (); timer_functor->OnTimerExpired.connect (sigc::ptr_fun (&GraphTimerInterrupt)); timer_handler = nux::GetTimer ().AddTimerHandler (1000, timer_functor, timegraph); // Add the timegraph to the layout layout->AddView ( timegraph, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); // Control the position of elements inside the layout layout->SetContentDistribution (nux::MAJOR_POSITION_CENTER); layout->SetHorizontalExternalMargin (4); layout->SetVerticalExternalMargin (4); // Set the layout as the container of the window thread nux::GetWindowThread ()->SetLayout (layout); // Set the background color of the window nux::ColorLayer background (nux::Color (0xFF2D2D2D)); static_cast (thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { // Initialize Nux subsystem nux::NuxInitialize (0); // Create a Window thread nux::WindowThread* wt = nux::CreateGUIThread( TEXT("Time Graph"), 300, 200, 0, &UserInterfaceInitialization, 0); // Start the main loop wt->Run (0); delete timer_functor; delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/text_entry_focus.cpp0000644000015301777760000000454412321344237022672 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/TextEntry.h" void ThreadWidgetInit(nux::NThread* thread, void* /* InitData */) { nux::VLayout* MainVLayout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::TextEntry* text_entry_0 = new nux::TextEntry(TEXT("0123456789 abcdefghijklmnopqrstuvwxyz"), NUX_TRACKER_LOCATION); nux::TextEntry* text_entry_1 = new nux::TextEntry(TEXT("0123456789 abcdefghijklmnopqrstuvwxyz"), NUX_TRACKER_LOCATION); nux::TextEntry* text_entry_2 = new nux::TextEntry(TEXT("0123456789 abcdefghijklmnopqrstuvwxyz"), NUX_TRACKER_LOCATION); text_entry_0->SetMaximumWidth(300); text_entry_0->SetMinimumHeight (20); text_entry_0->SetCompletion("test completion"); text_entry_1->SetMaximumWidth(300); text_entry_1->SetMinimumHeight (20); text_entry_2->SetMaximumWidth(300); text_entry_2->SetMinimumHeight (20); MainVLayout->AddView(text_entry_0, 0, nux::eCenter, nux::eFull); MainVLayout->AddView(text_entry_1, 0, nux::eCenter, nux::eFull); MainVLayout->AddView(text_entry_2, 0, nux::eCenter, nux::eFull, 1.0, nux::NUX_LAYOUT_BEGIN); MainVLayout->SetVerticalInternalMargin(10); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main() { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Text Entry"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/scrollview.cpp0000644000015301777760000000477612321344237021466 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/TextEntry.h" #include "Nux/ScrollView.h" #include "Nux/GridHLayout.h" #include "Nux/GridVLayout.h" #include "Nux/TextureArea.h" #include "Nux/Panel.h" void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::VLayout* MainVLayout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::GridHLayout *grid_h_layout ((new nux::GridHLayout (NUX_TRACKER_LOCATION))); for (int i = 0; i < 5360; i++) { nux::ColorLayer color (nux::color::RandomColor ()); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); grid_h_layout->AddView (texture_area, 1, nux::eLeft, nux::eFull); } grid_h_layout->ForceChildrenSize (true); grid_h_layout->SetChildrenSize (64, 42); grid_h_layout->EnablePartialVisibility (true); grid_h_layout->SetVerticalExternalMargin (4); grid_h_layout->SetHorizontalExternalMargin (4); grid_h_layout->SetVerticalInternalMargin (4); grid_h_layout->SetHorizontalInternalMargin (4); nux::ScrollView *scroll_view = new nux::ScrollView(NUX_TRACKER_LOCATION); grid_h_layout->SetStretchFactor(1); scroll_view->SetLayout(grid_h_layout); MainVLayout->AddView(scroll_view, 1, nux::eCenter, nux::eFull); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("ScrollView"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/moveable_view.cpp0000644000015301777760000000671612321344237022115 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/WindowThread.h" #include "Nux/TimeGraph.h" #include "Nux/TimerProc.h" #include "Nux/FloatingWindow.h" nux::TimerFunctor *timer_functor; nux::TimerHandle timer_handler; float time_value = 0; nux::FloatingWindow* moveable_view = NULL; void GraphTimerInterrupt (void *data) { time_value += 0.001f; nux::TimeGraph* timegraph = NUX_STATIC_CAST (nux::TimeGraph*, data); for (int i = 0; i < 3; i++) { if (i == 0) timegraph->UpdateGraph (i, nux::GetWindowThread ()->GetFrameRate() ); if (i == 1) timegraph->UpdateGraph (i, nux::RandomUInt (25) + 25); if (i == 2) timegraph->UpdateGraph (i, 30 * (std::sin (time_value) + 1) + nux::RandomUInt (10) ); } timer_handler = nux::GetTimer().AddTimerHandler (100, timer_functor, timegraph); } void UserInterfaceInitialization(nux::NThread* thread, void* init_data) { // Create a vertical Layout nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::TimeGraph* timegraph = new nux::TimeGraph(TEXT("Graph")); timegraph->ShowColumnStyle (); timegraph->SetYAxisBounds (0.0, 200.0f); timegraph->AddGraph (nux::Color (0xFF9AD61F), nux::Color (0x50191919) ); timegraph->AddGraph (nux::Color (0xFF00FF00), nux::Color (0x5000FF00) ); timegraph->AddGraph (nux::Color (0xFFFF0022), nux::Color (0x50BB0022) ); timer_functor = new nux::TimerFunctor (); timer_functor->OnTimerExpired.connect (sigc::ptr_fun (&GraphTimerInterrupt)); timer_handler = nux::GetTimer ().AddTimerHandler (1000, timer_functor, timegraph); // Add the timegraph to the layout layout->AddView ( timegraph, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); // Control the position of elements inside the layout layout->SetContentDistribution (nux::MAJOR_POSITION_CENTER); layout->SetHorizontalExternalMargin (4); layout->SetVerticalExternalMargin (4); moveable_view = new nux::FloatingWindow(TEXT("Moveable View"), NUX_TRACKER_LOCATION); moveable_view->SetLayout(layout); moveable_view->ShowWindow(true); moveable_view->SetBaseXY(10, 10); // Set the layout as the container of the window thread //nux::GetWindowThread ()->SetLayout (layout); // Set the background color of the window nux::ColorLayer background (nux::Color (0xFF202020)); static_cast (thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { // Initialize Nux subsystem nux::NuxInitialize (0); // Create a Window thread nux::WindowThread* wt = nux::CreateGUIThread( TEXT("Moveable View"), 600, 400, 0, &UserInterfaceInitialization, 0); // Start the main loop wt->Run (0); moveable_view->Dispose(); delete timer_functor; delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/cairo_wrapper.cpp0000644000015301777760000000777612321344237022135 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller TerminateThread (); } void example (void* data) { nux::Geometry geom = {0, 0, 200, 150}; g_canvas = new nux::CairoWrapper (geom, sigc::ptr_fun (callback)); std::string filename = "/tmp/cairo-wrapper-example.png"; g_canvas->DumpToFile (filename); } void ThreadWidgetInit (nux::NThread* thread, void* initData) { g_timer = new nux::TimerFunctor (); g_timer->OnTimerExpired.connect (sigc::ptr_fun (&example)); g_handler = nux::GetTimer().AddTimerHandler (1000, g_timer, nux::GetWindowThread ()); } int main (int argc, char** argv) { nux::NuxInitialize (0); nux::WindowThread* wt = NULL; wt = nux::CreateGUIThread (TEXT ("Cairo-Wrapper Example"), 400, 400, 0, &ThreadWidgetInit, 0); wt->Run (NULL); delete wt; delete g_canvas; delete g_timer; return 0; } nux-4.0.6+14.04.20140409/examples/gridlayout.cpp0000644000015301777760000000555012321344237021447 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "NuxGraphics/GraphicsEngine.h" #include "Nux/TextureArea.h" #include "Nux/HLayout.h" #include "Nux/VLayout.h" #include "Nux/GridHLayout.h" #include "Nux/GridVLayout.h" void GridLayoutInit(nux::NThread* thread, void* InitData) { int a = 0; nux::HLayout *main_layout((new nux::HLayout(NUX_TRACKER_LOCATION))); nux::GridHLayout *grid_h_layout ((new nux::GridHLayout (NUX_TRACKER_LOCATION))); for (int i = 0; i < 30; i++) { nux::ColorLayer color (nux::color::RandomColor ()); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); texture_area->SetVisible (a % 2); grid_h_layout->AddView (texture_area, 1, nux::eLeft, nux::eFull); a++; } grid_h_layout->ForceChildrenSize (true); grid_h_layout->SetChildrenSize (64, 42); grid_h_layout->EnablePartialVisibility (false); grid_h_layout->SetVerticalExternalMargin (4); grid_h_layout->SetHorizontalExternalMargin (4); grid_h_layout->SetVerticalInternalMargin (4); grid_h_layout->SetHorizontalInternalMargin (4); nux::GridVLayout *grid_v_layout ((new nux::GridVLayout (NUX_TRACKER_LOCATION))); for (int i = 0; i < 30; i++) { nux::ColorLayer color (nux::color::RandomColor()); nux::TextureArea* texture_area = new nux::TextureArea(); texture_area->SetPaintLayer (&color); texture_area->SetVisible (a % 2); grid_v_layout->AddView(texture_area, 1, nux::eLeft, nux::eFull); a++; } grid_v_layout->ForceChildrenSize (true); grid_v_layout->SetChildrenSize (64, 64); grid_v_layout->EnablePartialVisibility (false); grid_v_layout->SetVerticalExternalMargin (6); grid_v_layout->SetHorizontalExternalMargin (6); grid_v_layout->SetVerticalInternalMargin (6); grid_v_layout->SetHorizontalInternalMargin (6); main_layout->AddLayout (grid_h_layout, 1); main_layout->AddLayout (grid_v_layout, 1); nux::GetWindowThread ()->SetLayout(main_layout); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Grid Layout"), 1024, 600, 0, &GridLayoutInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/canvas.cpp0000644000015301777760000001175212321344237020540 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller AddView (foocanvas, 1, nux::eCenter, nux::eFull); layout->AddView (barcanvas, 1, nux::eCenter, nux::eFull); layout->SetContentDistribution (nux::eStackCenter); nux::GetWindowThread()->SetLayout (layout); } int main (int argc, char** argv) { nux::NuxInitialize (0); nux::WindowThread* wt = NULL; wt = nux::CreateGUIThread (TEXT ("Canvas Example"), 400, 400, 0, &ThreadWidgetInit, 0); wt->Run (NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/shortcut-keys.cpp0000644000015301777760000001417212321344237022110 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/StaticText.h" #include "line-separator.h" int SECTION_NAME_FONT_SIZE = 17; int SHORTKEY_ENTRY_FONT_SIZE = 13; int INTER_SPACE_SHORTKEY_DESCRIPTION = 0; int SHORTKEY_COLUMN_WIDTH = 150 + 100; int DESCRIPTION_COLUMN_WIDTH = 265 + 100; nux::LinearLayout *CreateSectionLayout(const char *section_name) { nux::VLayout *layout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::StaticText* section_name_view = new nux::StaticText(section_name, NUX_TRACKER_LOCATION); section_name_view->SetTextPointSize(SECTION_NAME_FONT_SIZE); section_name_view->SetFontName("Ubuntu Bold"); layout->AddView(section_name_view, 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT); layout->AddView(new nux::SpaceLayout(30, 30, 30, 30), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT); return layout; } nux::LinearLayout *CreateShortKeyEntryLayout(const char *shortkey, const char *description) { nux::HLayout *layout = new nux::HLayout("EntryLayout", NUX_TRACKER_LOCATION); nux::HLayout *shortkey_layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::HLayout *description_layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::StaticText* shortkey_view = new nux::StaticText(shortkey, NUX_TRACKER_LOCATION); shortkey_view->SetTextAlignment(nux::StaticText::ALIGN_LEFT); shortkey_view->SetTextPointSize(SHORTKEY_ENTRY_FONT_SIZE); shortkey_view->SetMinimumWidth(SHORTKEY_COLUMN_WIDTH); shortkey_view->SetMaximumWidth(SHORTKEY_COLUMN_WIDTH); nux::StaticText* description_view = new nux::StaticText(description, NUX_TRACKER_LOCATION); description_view->SetTextAlignment(nux::StaticText::ALIGN_LEFT); description_view->SetTextPointSize(SHORTKEY_ENTRY_FONT_SIZE); description_view->SetMinimumWidth(DESCRIPTION_COLUMN_WIDTH); description_view->SetMaximumWidth(DESCRIPTION_COLUMN_WIDTH); shortkey_layout->AddView(shortkey_view, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); shortkey_layout->SetContentDistribution(nux::MAJOR_POSITION_START); shortkey_layout->SetMinimumWidth(SHORTKEY_COLUMN_WIDTH); shortkey_layout->SetMaximumWidth(SHORTKEY_COLUMN_WIDTH); description_layout->AddView(description_view, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); description_layout->SetContentDistribution(nux::MAJOR_POSITION_START); description_layout->SetMinimumWidth(DESCRIPTION_COLUMN_WIDTH); description_layout->SetMaximumWidth(DESCRIPTION_COLUMN_WIDTH); layout->AddLayout(shortkey_layout, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->AddLayout(description_layout, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->SetSpaceBetweenChildren(INTER_SPACE_SHORTKEY_DESCRIPTION); description_layout->SetContentDistribution(nux::MAJOR_POSITION_START); return layout; } nux::LinearLayout *CreateIntermediateLayout() { nux::VLayout *layout = new nux::VLayout(NUX_TRACKER_LOCATION); return layout; } void UserInterfaceInitialization(nux::NThread* thread, void* /* InitData */) { nux::VLayout *root_layout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::LinearLayout *section_layout = CreateSectionLayout("Launcher"); nux::LinearLayout *intermediate_layout = CreateIntermediateLayout(); intermediate_layout->SetContentDistribution(nux::MAJOR_POSITION_START); intermediate_layout->AddLayout(CreateShortKeyEntryLayout("Super (Press)", "Open Launcher, displays shortcuts."), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL); intermediate_layout->AddLayout(CreateShortKeyEntryLayout("Alt + F1 (Press)", "Open Launcher keyboard navigation mode."), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); intermediate_layout->AddLayout(CreateShortKeyEntryLayout("Super + Tab", "Switch application via Launcher."), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); intermediate_layout->AddLayout(CreateShortKeyEntryLayout("Super + 1 to 9", "Same as clicking on a Launcher icon."), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); intermediate_layout->AddLayout(CreateShortKeyEntryLayout("Super + Shift + 1 to 9", "Open a new window of the app."), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); intermediate_layout->AddLayout(CreateShortKeyEntryLayout("Super + T", "Open the Rubbish Bin."), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); section_layout->AddLayout(intermediate_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); // Add space before the line section_layout->AddView(new nux::SpaceLayout(30, 30, 30, 30), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT); section_layout->AddView(new nux::HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); // Add space after the line section_layout->AddView(new nux::SpaceLayout(30, 30, 30, 30), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT); root_layout->AddView(section_layout, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL); nux::GetWindowThread ()->SetLayout(root_layout); nux::ColorLayer background(nux::Color(0xFF222222)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main() { // Initialize Nux. nux::NuxInitialize(0); // Create a window thread. nux::WindowThread* wt = nux::CreateGUIThread("Shortcut Keys", 640, 300, 0, &UserInterfaceInitialization, 0); // Start the main loop. wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/line-separator.h0000644000015301777760000000237212321344237021655 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef HSEPARATOR_H #define HSEPARATOR_H #include "abstract-separator.h" namespace nux { class HSeparator: public AbstractSeparator { public: HSeparator(); HSeparator (const Color &color, float Alpha0, float Alpha1, int Border); ~HSeparator(); protected: virtual void Draw (GraphicsEngine &GfxContext, bool force_draw); virtual void DrawContent (GraphicsEngine & /* GfxContext */, bool /* force_draw */) {}; }; } #endif // HSEPARATOR_H nux-4.0.6+14.04.20140409/examples/timeline.cpp0000644000015301777760000000447712321344237021101 0ustar pbusernogroup00000000000000#include "Nux/Nux.h" #include "Nux/TimelineEasings.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/Button.h" #include "Nux/ColorPreview.h" #include "Nux/TextureArea.h" #include "Nux/PaintLayer.h" class TimelineTestClass { public: nux::Timeline *timeline_1; nux::Timeline *timeline_2; nux::TextureArea *texture_area; nux::TextureArea *texture_area_2; void OnNewFrame (unsigned long msecs) { nux::Color color = nux::Color ((float)timeline_1->GetProgress (), 0.5, 0.6, 1.0); nux::ColorLayer *colorlayer = new nux::ColorLayer(color); texture_area->SetPaintLayer (colorlayer); } void OnNewFrame2 (unsigned long msecs) { nux::Color color = nux::Color (0.6, (float)timeline_2->GetProgress (), 0.5, 1.0); nux::ColorLayer *colorlayer = new nux::ColorLayer(color); texture_area_2->SetPaintLayer (colorlayer); } void Init (nux::Layout *layout) { texture_area = new nux::TextureArea (); layout->AddView(texture_area, 1, nux::eCenter, nux::eFull); texture_area_2 = new nux::TextureArea (); layout->AddView (texture_area_2, 1, nux::eCenter, nux::eFull); timeline_1 = new nux::TimelineEaseInOutQuad (1000, "Timeline_1", NUX_TRACKER_LOCATION); timeline_1->Looping = true; timeline_1->NewFrame.connect (sigc::mem_fun (this, &TimelineTestClass::OnNewFrame)); timeline_2 = new nux::TimelineEaseOutQuad (2000, "Timeline_2", NUX_TRACKER_LOCATION); //timeline_2->Looping = true; timeline_2->NewFrame.connect (sigc::mem_fun (this, &TimelineTestClass::OnNewFrame2)); } }; void ThreadWidgetInit(nux::NThread* thread, void* InitData) { TimelineTestClass *self = (TimelineTestClass*) InitData; nux::VLayout* MainVLayout = new nux::VLayout("", NUX_TRACKER_LOCATION); self->Init (MainVLayout); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { TimelineTestClass *test_class = new TimelineTestClass (); nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Timeline Test"), 400, 300, 0, ThreadWidgetInit, test_class); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/tab_view.cpp0000644000015301777760000000452112321344237021061 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/WindowThread.h" #include "Nux/TabView.h" #include "Nux/TextureArea.h" #include "Nux/PaintLayer.h" void UserInterfaceInitialization(nux::NThread* thread, void* init_data) { // Create a vertical Layout nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::TabView* tabview(new nux::TabView()); nux::ColorLayer color_layer (nux::color::Black, true); nux::VLayout *tab_view_layout = 0; nux::TextureArea *texture_area = 0; for (int i = 0; i < 50; i++) { tab_view_layout = new nux::VLayout (); texture_area = new nux::TextureArea (); color_layer.SetColor (nux::color::RandomColor ()); texture_area->SetPaintLayer (&color_layer); tab_view_layout->AddView (texture_area, 1); nux::NString str = nux::NString::Printf("View %d", i); tabview->AddTab (str.GetTCharPtr (), tab_view_layout); } // Add the button to the layout layout->AddView ( tabview, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); // Set the layout as the container of the window thread nux::GetWindowThread ()->SetLayout (layout); // Set the background color of the window nux::ColorLayer background (nux::Color (0xFF2D2D2D)); static_cast (thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { // Initialize Nux subsystem nux::NuxInitialize (0); // Create a Window thread nux::WindowThread* wt = nux::CreateGUIThread( TEXT("Tab View"), 400, 300, 0, &UserInterfaceInitialization, 0); // Start the main loop wt->Run (0); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/focus.cpp0000644000015301777760000001737012321344237020406 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "NuxGraphics/GraphicsEngine.h" #include "Nux/TextureArea.h" #include "Nux/TextEntry.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/GridHLayout.h" #include "Nux/ScrollView.h" #include "Nux/TextureArea.h" #include "Nux/ComboBoxSimple.h" float frand () { return ((float)rand ()) / RAND_MAX; } static void OnFocusChildChanged (nux::Area *layout, nux::Area *view) { g_debug ("focus has changed, woo %i", rand ()); } static void OnFocusChanged (nux::Area *view) { g_debug ("focus on a specific child has changed %i", rand ()); nux::TextureArea *texarea = (nux::TextureArea *)view; if (view->GetFocused ()) { nux::ColorLayer color (nux::Color (0.2, 1.0, 0.2, 1.0)); texarea->SetPaintLayer (&color); } else { nux::ColorLayer color (nux::Color (0.6, 0.+ frand ()*0.3, 0.2+ frand ()*0.3, 1.0)); texarea->SetPaintLayer (&color); } } void UserInterfaceInitialization(nux::NThread* thread, void* init_data) { // Create a vertical Layout nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::VLayout* layout_left = new nux::VLayout (NUX_TRACKER_LOCATION); nux::HLayout* content_layout = new nux::HLayout (NUX_TRACKER_LOCATION); nux::VLayout* layout_right = new nux::VLayout (NUX_TRACKER_LOCATION); //nux::HLayout* layout_top = new nux::HLayout(NUX_TRACKER_LOCATION); nux::TextEntry* text_entry = new nux::TextEntry ("This is some text", NUX_TRACKER_LOCATION); text_entry->SetTextColor (nux::Color (1.0, 1.0, 1.0, 1.0)); nux::ComboBoxSimple *combo = new nux::ComboBoxSimple (NUX_TRACKER_LOCATION); combo->SetMinimumWidth (150); combo->SetCanFocus (true); combo->AddItem ("Item A"); combo->AddItem ("Item B"); combo->AddItem ("Item C"); combo->AddItem ("Item D"); combo->AddItem ("Item E"); //layout->AddView (_combo, 0, nux::eCenter, nux::eFix); //nux::ScrollView *layout_scroll = new nux::ScrollView (NUX_TRACKER_LOCATION); nux::VLayout* layout_scroll_container = new nux::VLayout (NUX_TRACKER_LOCATION); nux::VLayout* layout_scroll_1 = new nux::VLayout(NUX_TRACKER_LOCATION); nux::HLayout* layout_scroll_11 = new nux::HLayout(NUX_TRACKER_LOCATION); nux::ScrollView *layout_scroll_12 = new nux::ScrollView (NUX_TRACKER_LOCATION); nux::GridHLayout* layout_scroll_12_content = new nux::GridHLayout (NUX_TRACKER_LOCATION); layout_scroll_12->EnableHorizontalScrollBar (false); layout_scroll_12->EnableVerticalScrollBar (true); layout_scroll_12->SetLayout (layout_scroll_12_content); layout_scroll_1->AddLayout (layout_scroll_11, 0, nux::MINOR_POSITION_TOP); layout_scroll_1->AddView (layout_scroll_12, 1, nux::MINOR_POSITION_TOP); nux::VLayout* layout_scroll_2 = new nux::VLayout(NUX_TRACKER_LOCATION); nux::HLayout* layout_scroll_21 = new nux::HLayout(NUX_TRACKER_LOCATION); nux::GridHLayout* layout_scroll_22 = new nux::GridHLayout (NUX_TRACKER_LOCATION); layout_scroll_2->AddLayout (layout_scroll_21, 0, nux::MINOR_POSITION_TOP); layout_scroll_2->AddLayout (layout_scroll_22, 1, nux::MINOR_POSITION_TOP); //layout_scroll_container->AddView (text_entry, 0, nux::MINOR_POSITION_TOP); layout_scroll_container->AddView (combo, 0, nux::eCenter, nux::eFix); //layout_scroll->SetLayout (layout_scroll_container); layout_scroll_container->AddLayout (layout_scroll_1, 1, nux::MINOR_POSITION_TOP); layout_scroll_container->AddLayout (layout_scroll_2, 1, nux::MINOR_POSITION_TOP); content_layout->AddLayout (layout_scroll_container, 1, nux::MINOR_POSITION_TOP); layout->AddLayout (layout_left, 0); layout->AddLayout (content_layout, 1); layout->AddLayout (layout_right, 0); layout->ChildFocusChanged.connect (sigc::ptr_fun(&OnFocusChildChanged)); // for (int i = 0; i < 6; i++) // { // nux::ColorLayer color (nux::Color (0.2, 0.2, 0.2+ frand ()*0.3, 1.0)); // nux::TextureArea* texture_area = new nux::TextureArea (); // texture_area->SetPaintLayer (&color); // texture_area->FocusChanged.connect (sigc::ptr_fun (&OnFocusChanged)); // // layout_top->AddView (texture_area, 1, nux::eLeft, nux::eFull); // } for (int i = 0; i < 6; i++) { nux::ColorLayer color (nux::Color (0.2, 0.2, 0.4+ frand ()*0.3, 1.0)); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); texture_area->FocusChanged.connect (sigc::ptr_fun (&OnFocusChanged)); //~ //~ layout_scroll_11->AddView (texture_area, 1, nux::eLeft, nux::eFull); } for (int i = 0; i < 128; i++) { nux::ColorLayer color (nux::Color (0.2, 0.2, 0.4+ frand ()*0.3, 1.0)); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); texture_area->FocusChanged.connect (sigc::ptr_fun (&OnFocusChanged)); //~ //~ layout_scroll_12_content->AddView (texture_area, 1, nux::eLeft, nux::eFull); } for (int i = 0; i < 6; i++) { nux::ColorLayer color (nux::Color (0.2, 0.2, 0.4+ frand ()*0.3, 1.0)); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); texture_area->FocusChanged.connect (sigc::ptr_fun (&OnFocusChanged)); //~ //~ layout_scroll_21->AddView (texture_area, 1, nux::eLeft, nux::eFull); } for (int i = 0; i < 16; i++) { nux::ColorLayer color (nux::Color (0.2, 0.2, 0.4+ frand ()*0.3, 1.0)); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); texture_area->FocusChanged.connect (sigc::ptr_fun (&OnFocusChanged)); //~ //~ layout_scroll_22->AddView (texture_area, 1, nux::eLeft, nux::eFull); } for (int i = 0; i < 16; i++) { nux::ColorLayer color (nux::Color (0.2, 0.2, 0.4+ frand ()*0.3, 1.0)); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); texture_area->FocusChanged.connect (sigc::ptr_fun (&OnFocusChanged)); //~ //~ layout_left->AddView (texture_area, 1, nux::eLeft, nux::eFull); } for (int i = 0; i < 16; i++) { nux::ColorLayer color (nux::Color (0.2, 0.2, 0.4+ frand ()*0.3, 1.0)); nux::TextureArea* texture_area = new nux::TextureArea (); texture_area->SetPaintLayer (&color); texture_area->FocusChanged.connect (sigc::ptr_fun (&OnFocusChanged)); //~ //~ layout_right->AddView (texture_area, 1, nux::eLeft, nux::eFull); } // Control the position of elements inside the layout layout->SetContentDistribution (nux::MAJOR_POSITION_CENTER); // Set the layout as the container of the window thread nux::GetWindowThread ()->SetLayout (layout); layout->SetFocused (true); // Set the background color of the window nux::ColorLayer background (nux::Color (0xFF2D2D2D)); static_cast (thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { // Initialize Nux subsystem nux::NuxInitialize (0); // Create a Window thread nux::WindowThread* wt = nux::CreateGUIThread( TEXT("Push Button"), 800, 600, 0, &UserInterfaceInitialization, 0); // Start the main loop wt->Run (0); delete wt; return 0; } nux-4.0.6+14.04.20140409/examples/pango_combobox.cpp0000644000015301777760000000421212321344237022252 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/ComboBoxSimple.h" #include "Nux/TableCtrl.h" void ThreadWidgetInit(nux::NThread* thread, void* InitData) { nux::VLayout* MainVLayout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION); nux::ComboBoxSimple* combobox = new nux::ComboBoxSimple(NUX_TRACKER_LOCATION); combobox->AddItem (TEXT("Hello Unity Team0"), 0); combobox->AddItem (TEXT("Hello Unity Team11"), 1); combobox->AddItem (TEXT("Hello Unity Team222"), 2); combobox->AddItem (TEXT("Hello Unity Team3333"), 3); combobox->AddItem (TEXT("Hello Unity Team44444"), 4); combobox->AddItem (TEXT("Bonjour Unity Team"), 5); combobox->AddItem (TEXT("Hola Unity Team"), 6); combobox->AddItem (TEXT("Guten Tag Unity Team"), 7); //combobox->SetPopupWindowSize(120, 150); combobox->SetMaximumWidth(250); MainVLayout->AddView(combobox, 0, nux::eCenter, nux::eFull); MainVLayout->SetContentDistribution(nux::eStackCenter); nux::GetWindowThread ()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } int main(int argc, char **argv) { nux::NuxInitialize(0); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("ComboBox"), 400, 300, 0, &ThreadWidgetInit, 0); wt->Run(NULL); delete wt; return 0; } nux-4.0.6+14.04.20140409/doxygen.cfg0000644000015301777760000020513412321344237017100 0ustar pbusernogroup00000000000000# Doxyfile 1.7.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = $(PROJECT)-$(VERSION) # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = $(DOCDIR) # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = $(SRCDIR) # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = $(SRCDIR) # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = NO # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = NO # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = NO # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = doxy-warnings.log #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = $(SRCDIR) # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.cpp \ *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = $(SRCDIR) # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = YES # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = $(GENERATE_HTML) # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = $(GENERATE_CHM) # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = ../$(PROJECT).chm # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = $(HHC_PATH) # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = $(GENERATE_CHI) # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = YES # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = $(GENERATE_LATEX) # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = $(PAPER_SIZE) # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = YES # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = $(GENERATE_RTF) # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = $(GENERATE_MAN) # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .1 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = $(GENERATE_XML) # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = $(DOCDIR)/$(PROJECT).tag # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = $(PERL_PATH) #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = $(HAVE_DOT) # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans.ttf # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = $(DOT_PATH) # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES nux-4.0.6+14.04.20140409/gputests/0000755000015301777760000000000012321344711016610 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/gputests/texture_power_of_2.cpp0000644000015301777760000001077012321344237023145 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxGraphics/BitmapFormats.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLWindowManager.h" #include "NuxGraphics/GraphicsEngine.h" /* * Tests: * - load 2d textures of various size from the hard drive * - textures have power of two size 256x256, 128x128, ...., 2x2, 1x1 * - manually load bitmap data into device texture: IOpenGLTexture2D * - Lock/Unlock device texture data pointer * - Use immediate mode rendering with glBegin, glEnd */ void RenderTexturePowerOfTwo () { nux::GraphicsDisplay* m_GLWindow = gGLWindowManager.CreateGLWindow("Window", 570, 270, nux::WINDOWSTYLE_NORMAL, 0, false); nux::GraphicsEngine* m_GraphicsContext = m_GLWindow->GetGraphicsEngine(); m_GLWindow->ShowWindow(); const TCHAR* texture_list [] = { TEXT("./data/mipmap256x256.png"), TEXT("./data/mipmap128x128.png"), TEXT("./data/mipmap64x64.png"), TEXT("./data/mipmap32x32.png"), TEXT("./data/mipmap16x16.png"), TEXT("./data/mipmap8x8.png"), TEXT("./data/mipmap4x4.png"), TEXT("./data/mipmap2x2.png"), TEXT("./data/mipmap1x1.png") }; nux::ObjectPtr tex [9]; for (int i = 0; i < 9; i++) { nux::NBitmapData *bitmap = nux::LoadImageFile(texture_list[i]); nux::ImageSurface surface = bitmap->GetSurface(0); surface.GetFormat(); tex[i] = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture( surface.GetWidth(), surface.GetHeight(), 1, surface.GetFormat()); nux::SURFACE_LOCKED_RECT lockrect; tex[i]->LockRect(0, &lockrect, 0); BYTE *dest = (BYTE *) lockrect.pBits; const BYTE *src = surface.GetPtrRawData(); int RowByteSize = surface.GetPitch(); int num_row = surface.GetBlockHeight(); for (int Y = 0; Y < num_row; Y++ ) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. nux::Memcpy (dest + Y * lockrect.Pitch, &src[Y * RowByteSize], nux::Min (RowByteSize, lockrect.Pitch) ); } tex[i]->UnlockRect (0); } int w, h; m_GraphicsContext->GetWindowSize(w, h); m_GraphicsContext->SetViewport(0, 0, w, h); m_GraphicsContext->SetContext(0, 0, w, h); m_GraphicsContext->Push2DWindow(w, h); nux::Event event; memset(&event, 0, sizeof(nux::Event)); do { CHECKGL( glClearColor(0, 0, 0, 1) ); CHECKGL( glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ); m_GLWindow->GetSystemEvent(&event); if(event.type == nux::NUX_SIZE_CONFIGURATION) { m_GraphicsContext->DisableAllTextureMode(0); m_GraphicsContext->DisableAllTextureMode(1); m_GraphicsContext->DisableAllTextureMode(2); m_GraphicsContext->DisableAllTextureMode(3); m_GraphicsContext->GetWindowSize(w, h); m_GraphicsContext->SetViewport(0, 0, w, h); m_GraphicsContext->SetScissor(0, 0, w, h); m_GraphicsContext->SetContext(0, 0, w, h); m_GraphicsContext->Push2DWindow(w, h); } int x = 10; int y = 10; for (int i = 0; i < 9; i++) { m_GraphicsContext->SetTexture(GL_TEXTURE0, tex [i]); if (i > 0) x += tex[i-1]->GetWidth () + 5; int width = tex[i]->GetWidth (); int height = tex[i]->GetHeight (); nux::TexCoordXForm texxform; m_GraphicsContext->QRP_GLSL_1Tex(x, y, width, height, tex[i], texxform, nux::color::White); } m_GLWindow->SwapBuffer(); } while(event.type != nux::NUX_TERMINATE_APP); for (int i = 0; i < 9; i++) { tex[i].Release (); } delete m_GLWindow; } int main() { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); RenderTexturePowerOfTwo (); return 0; } nux-4.0.6+14.04.20140409/gputests/Makefile.am0000644000015301777760000000415112321344237020650 0ustar pbusernogroup00000000000000CLEANFILES = DISTCLEANFILES = EXTRA_DIST = if BUILD_GPUTESTS # This tells automake that we want to build binaries, but they shouldn't be # installed. For each individual test, add it's binary name here noinst_PROGRAMS = texture_power_of_2 framebufferobject quad_2texmod texture_copy_blur texture_blur texture_data if !NUX_OPENGLES_20 noinst_PROGRAMS += arb_programs_limits endif # We only have to do this AM_ once to affect all the binaries we build from # this Makefile AM_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxGpuTests\" \ $(GCC_FLAGS) \ $(NUX_CORE_CFLAGS) \ $(NUX_GPUTESTS_CFLAGS) \ $(NUX_CFLAGS) \ $(MAINTAINER_CFLAGS) ALL_LIBS = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(top_builddir)/NuxGraphics/libnux-graphics-@NUX_API_VERSION@.la \ $(top_builddir)/Nux/libnux-@NUX_API_VERSION@.la \ $(NUX_GPUTESTS_LIBS) \ $(NUX_LIBS) # This is the individual executable build. For every $exe in noinst_PROGRAMS # you need a $exe_SOURCES and $exe_LDADD so it builds texture_power_of_2_SOURCES = texture_power_of_2.cpp texture_power_of_2_LDADD = $(ALL_LIBS) framebufferobject_SOURCES = framebufferobject.cpp framebufferobject_LDADD = $(ALL_LIBS) quad_2texmod_SOURCES = quad_2texmod.cpp quad_2texmod_LDADD = $(ALL_LIBS) texture_copy_blur_SOURCES = texture_copy_blur.cpp texture_copy_blur_LDADD = $(ALL_LIBS) texture_blur_SOURCES = texture_blur.cpp texture_blur_LDADD = $(ALL_LIBS) texture_data_SOURCES = texture_data.cpp texture_data_LDADD = $(ALL_LIBS) arb_programs_limits_SOURCES = arb_programs_limits.cpp arb_programs_limits_LDADD = $(ALL_LIBS) # distribute source along to the documentation sourcegputestsdir = $(pkgdatadir)/gputests sourcegputests_DATA = $(texture_power_of_2_SOURCES) \ $(framebufferobject_SOURCES) \ $(quad_2texmod) \ $(texture_copy_blur_SOURCES) \ $(texture_blur_SOURCES) \ $(texture_data_SOURCES) \ $(arb_programs_limits_SOURCES) endif nux-4.0.6+14.04.20140409/gputests/data/0000755000015301777760000000000012321344711017521 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/gputests/data/mipmap256x256.png0000755000015301777760000000646712321344237022417 0ustar pbusernogroup00000000000000PNG  IHDR\rf pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FbIDATx1ð`$z&/``````````````````````````````````````````````````````````````pYqIENDB`nux-4.0.6+14.04.20140409/gputests/data/mipmap128x128.png0000755000015301777760000000571112321344237022402 0ustar pbusernogroup00000000000000PNG  IHDR>a pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATx ð`V²d[-0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0ܰ_Vb3%IENDB`nux-4.0.6+14.04.20140409/gputests/data/mipmap64x64.png0000755000015301777760000000547612321344237022250 0ustar pbusernogroup00000000000000PNG  IHDR@@iq pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FiIDATxӿ3=" OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxb?`b@aIENDB`nux-4.0.6+14.04.20140409/gputests/data/mipmap2x2.png0000755000015301777760000000536012321344237022060 0ustar pbusernogroup00000000000000PNG  IHDRr $ pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxbl` %ώ IENDB`nux-4.0.6+14.04.20140409/gputests/data/mipmap32x32.png0000755000015301777760000000540712321344237022230 0ustar pbusernogroup00000000000000PNG  IHDR szz pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F2IDATx1i3$`46?=)8IENDB`nux-4.0.6+14.04.20140409/gputests/data/mipmap1x1.png0000755000015301777760000000535112321344237022056 0ustar pbusernogroup00000000000000PNG  IHDRĉ pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxb ?&HIENDB`nux-4.0.6+14.04.20140409/gputests/data/mipmap16x16.png0000755000015301777760000000537112321344237022234 0ustar pbusernogroup00000000000000PNG  IHDRa pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F$IDATxb?B0j aIENDB`nux-4.0.6+14.04.20140409/gputests/data/mipmap8x8.png0000755000015301777760000000536212321344237022076 0ustar pbusernogroup00000000000000PNG  IHDR pHYsnu> OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxbd?@  92(IENDB`nux-4.0.6+14.04.20140409/gputests/texture_data.cpp0000644000015301777760000001101512321344237022006 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxGraphics/BitmapFormats.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLWindowManager.h" #include "NuxGraphics/GraphicsEngine.h" #include /* * Tests: * - load 2d textures of various size from the hard drive * - textures have power of two size 256x256, 128x128, ...., 2x2, 1x1 * - manually load bitmap data into device texture: IOpenGLTexture2D * - Lock/Unlock device texture data pointer * - Use immediate mode rendering with glBegin, glEnd */ void RenderTexturePowerOfTwo () { nux::GraphicsDisplay* m_GLWindow = gGLWindowManager.CreateGLWindow("Window", 570, 270, nux::WINDOWSTYLE_NORMAL, 0, false); nux::GraphicsEngine* m_GraphicsContext = m_GLWindow->GetGraphicsEngine(); m_GLWindow->ShowWindow(); const TCHAR* texture_list [] = { TEXT("./data/mipmap256x256.png"), TEXT("./data/mipmap128x128.png"), TEXT("./data/mipmap64x64.png"), TEXT("./data/mipmap32x32.png"), TEXT("./data/mipmap16x16.png"), TEXT("./data/mipmap8x8.png"), TEXT("./data/mipmap4x4.png"), TEXT("./data/mipmap2x2.png"), TEXT("./data/mipmap1x1.png") }; nux::ObjectPtr tex [9]; for (int i = 0; i < 9; i++) { nux::NBitmapData *bitmap = nux::LoadImageFile (texture_list[i]); nux::ImageSurface surface = bitmap->GetSurface (0); surface.GetFormat (); tex[i] = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture ( surface.GetWidth(), surface.GetHeight (), 1, surface.GetFormat ()); nux::SURFACE_LOCKED_RECT lockrect; tex[i]->LockRect(0, &lockrect, 0); BYTE *dest = (BYTE *) lockrect.pBits; const BYTE *src = surface.GetPtrRawData(); int RowByteSize = surface.GetPitch(); int num_row = surface.GetBlockHeight(); for (int Y = 0; Y < num_row; Y++ ) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. nux::Memcpy (dest + Y * lockrect.Pitch, &src[Y * RowByteSize], nux::Min (RowByteSize, lockrect.Pitch) ); } tex[i]->UnlockRect (0); } int w, h; m_GraphicsContext->GetWindowSize(w, h); m_GraphicsContext->SetViewport(0, 0, w, h); m_GraphicsContext->SetContext(0, 0, w, h); m_GraphicsContext->Push2DWindow(w, h); nux::Event event; memset(&event, 0, sizeof(nux::Event)); { CHECKGL( glClearColor(0, 0, 0, 1) ); CHECKGL( glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ); m_GLWindow->GetSystemEvent(&event); if(event.type == nux::NUX_SIZE_CONFIGURATION) { m_GraphicsContext->DisableAllTextureMode(0); m_GraphicsContext->DisableAllTextureMode(1); m_GraphicsContext->DisableAllTextureMode(2); m_GraphicsContext->DisableAllTextureMode(3); m_GraphicsContext->GetWindowSize(w, h); m_GraphicsContext->SetViewport(0, 0, w, h); m_GraphicsContext->SetScissor(0, 0, w, h); m_GraphicsContext->SetContext(0, 0, w, h); m_GraphicsContext->Push2DWindow(w, h); } int level = 0; int width = 0; int height = 0; int format = 0; unsigned char* data = (unsigned char*) tex [6]->GetSurfaceData (level, width, height, format); cairo_surface_t *surface; surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, width, height, width*4); cairo_surface_write_to_png (surface, "tmp.png"); cairo_surface_destroy (surface); nuxDebugMsg (TEXT("size: %dx%d"), width, height); delete data; } for (int i = 0; i < 9; i++) { tex[i].Release (); } delete m_GLWindow; } int main() { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); RenderTexturePowerOfTwo (); return 0; } nux-4.0.6+14.04.20140409/gputests/arb_programs_limits.cpp0000644000015301777760000003227212321344237023364 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxGraphics/BitmapFormats.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLWindowManager.h" #include "NuxGraphics/GraphicsEngine.h" /* * Tests: * - Display arb programs limits */ void ARBProgramLimits () { nux::GraphicsDisplay* graphics_display = gGLWindowManager.CreateGLWindow("Window", 570, 270, nux::WINDOWSTYLE_NORMAL, 0, false); int OPENGL_MAX_PROGRAM_INSTRUCTIONS_ARB; int OPENGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB; int OPENGL_MAX_PROGRAM_TEMPORARIES_ARB; int OPENGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB; int OPENGL_MAX_PROGRAM_PARAMETERS_ARB; int OPENGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB; int OPENGL_MAX_PROGRAM_ATTRIBS_ARB; int OPENGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB; int OPENGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB; int OPENGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB; int OPENGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB; int OPENGL_MAX_PROGRAM_ENV_PARAMETERS_ARB; int OPENGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB; int OPENGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB; int OPENGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB; int OPENGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB; int OPENGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB; int OPENGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB; CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &OPENGL_MAX_PROGRAM_TEMPORARIES_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &OPENGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ATTRIBS_ARB, &OPENGL_MAX_PROGRAM_ATTRIBS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, &OPENGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_ENV_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, &OPENGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB) ); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_NONE, "---------------------------------------------"); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_NONE, "Vertex Program"); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_NONE, "---------------------------------------------"); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_TEMPORARIES_ARB = %d", OPENGL_MAX_PROGRAM_TEMPORARIES_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ATTRIBS_ARB = %d", OPENGL_MAX_PROGRAM_ATTRIBS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_ATTRIBS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ADDRESS_REGISTERS_ARB = %d", OPENGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_LOCAL_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ENV_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_ENV_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_TEX_INDIRECTIONS_ARB = %d", OPENGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &OPENGL_MAX_PROGRAM_TEMPORARIES_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &OPENGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ATTRIBS_ARB, &OPENGL_MAX_PROGRAM_ATTRIBS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, &OPENGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &OPENGL_MAX_PROGRAM_ENV_PARAMETERS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, &OPENGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB) ); CHECKGL (glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, &OPENGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB) ); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_NONE, "---------------------------------------------"); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_NONE, "Fragment Program"); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_NONE, "---------------------------------------------"); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_TEMPORARIES_ARB = %d", OPENGL_MAX_PROGRAM_TEMPORARIES_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ATTRIBS_ARB = %d", OPENGL_MAX_PROGRAM_ATTRIBS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_ATTRIBS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ADDRESS_REGISTERS_ARB = %d", OPENGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_LOCAL_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ENV_PARAMETERS_ARB = %d", OPENGL_MAX_PROGRAM_ENV_PARAMETERS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_TEX_INDIRECTIONS_ARB = %d", OPENGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB); nux::LogOutputSeverityMessage(nux::NUX_MSG_SEVERITY_INFO, "MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = %d", OPENGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB); delete graphics_display; } int main() { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); ARBProgramLimits(); return 0; } nux-4.0.6+14.04.20140409/gputests/framebufferobject.cpp0000644000015301777760000001143412321344237022775 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxGraphics/BitmapFormats.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLWindowManager.h" #include "NuxGraphics/GraphicsEngine.h" /* * Tests: * - frame buffer object * - Set a texture in the fbo * - Set fbo as a render target * - Render Quad to fbo * - Use fbo texture to draw a full screen quad on the default render target */ void RenderToFrameBufferObject () { nux::GraphicsDisplay* graphics_display = gGLWindowManager.CreateGLWindow("Window", 200, 200, nux::WINDOWSTYLE_NORMAL, 0, false); nux::GraphicsEngine* graphics_engine = graphics_display->GetGraphicsEngine(); graphics_display->ShowWindow(); nux::ObjectPtr fbo; nux::ObjectPtr texture_rt; nux::ObjectPtr depth_rt; fbo = graphics_display->GetGpuDevice ()->CreateFrameBufferObject (); texture_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_R8G8B8A8); depth_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_D24S8); int w, h; graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->SetScissor(0, 0, w, h); graphics_engine->Push2DWindow(w, h); nux::Event event; memset(&event, 0, sizeof(nux::Event)); bool first_time = true; do { CHECKGL( glClearColor(0, 0, 0, 1) ); CHECKGL( glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ); graphics_display->GetSystemEvent(&event); if(first_time || (event.type == nux::NUX_SIZE_CONFIGURATION)) { first_time = false; graphics_engine->DisableAllTextureMode(0); graphics_engine->DisableAllTextureMode(1); graphics_engine->DisableAllTextureMode(2); graphics_engine->DisableAllTextureMode(3); graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetScissor(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); fbo = graphics_display->GetGpuDevice()->CreateFrameBufferObject (); texture_rt = graphics_display->GetGpuDevice()->CreateSystemCapableDeviceTexture(graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_R8G8B8A8); depth_rt = graphics_display->GetGpuDevice()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_D24S8); } fbo->FormatFrameBufferObject (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), nux::BITFMT_R8G8B8A8); if (texture_rt.IsValid()) { fbo->SetRenderTarget(0, texture_rt->GetSurfaceLevel(0)); } if (depth_rt.IsValid()) { fbo->SetDepthSurface(depth_rt->GetSurfaceLevel(0)); } fbo->Activate(); graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); nux::Rect geo (nux::RandomUInt(graphics_display->GetWindowWidth()), nux::RandomUInt(graphics_display->GetWindowHeight()), nux::RandomUInt(200), nux::RandomUInt(200)); graphics_engine->QRP_Color(geo.x, geo.y, geo.width, geo.height, nux::color::RandomColor()); // Restore the back buffer graphics_display->GetGpuDevice()->DeactivateFrameBuffer(); nux::TexCoordXForm texxform; graphics_engine->QRP_1Tex(0, 0, graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), texture_rt, texxform, nux::color::White); graphics_display->SwapBuffer(); } while(event.type != nux::NUX_TERMINATE_APP); fbo.Release (); texture_rt.Release (); depth_rt.Release (); delete graphics_display; } int main() { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); RenderToFrameBufferObject (); return 0; } nux-4.0.6+14.04.20140409/gputests/texture_blur.cpp0000644000015301777760000001371612321344237022053 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxGraphics/BitmapFormats.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLWindowManager.h" #include "NuxGraphics/GraphicsEngine.h" /* * Tests: * - frame buffer object * - Set a texture in the fbo * - Set fbo as a render target * - Render Quad to fbo * - Deactivate fbo * - Blur the render target texture * - Render to default back buffer */ void RenderBlurredTexture () { nux::GraphicsDisplay* graphics_display = gGLWindowManager.CreateGLWindow("Window", 600, 300, nux::WINDOWSTYLE_NORMAL, 0, false); nux::GraphicsEngine* graphics_engine = graphics_display->GetGraphicsEngine(); graphics_display->ShowWindow(); nux::ObjectPtr fbo; nux::ObjectPtr texture_rt; nux::ObjectPtr depth_rt; fbo = graphics_display->GetGpuDevice ()->CreateFrameBufferObject (); texture_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_R8G8B8A8); depth_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_D24S8); int w, h; graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->SetScissor(0, 0, w, h); graphics_engine->Push2DWindow(w, h); nux::Event event; memset(&event, 0, sizeof(nux::Event)); /*char fps [25]; int frame_counter = 0; int frame_periode = 0; float frame_rate = 0; float periode_time = 0; */ bool first_time = true; do { CHECKGL( glClearColor(0, 0, 0, 1) ); CHECKGL( glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ); graphics_display->GetSystemEvent(&event); if(first_time || (event.type == nux::NUX_SIZE_CONFIGURATION)) { first_time = false; graphics_engine->DisableAllTextureMode(0); graphics_engine->DisableAllTextureMode(1); graphics_engine->DisableAllTextureMode(2); graphics_engine->DisableAllTextureMode(3); graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetScissor(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); fbo = graphics_display->GetGpuDevice()->CreateFrameBufferObject(); texture_rt = graphics_display->GetGpuDevice()->CreateSystemCapableDeviceTexture(graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_R8G8B8A8); depth_rt = graphics_display->GetGpuDevice()->CreateSystemCapableDeviceTexture(graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_D24S8); } fbo->FormatFrameBufferObject(graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), nux::BITFMT_R8G8B8A8); if (texture_rt.IsValid()) { fbo->SetRenderTarget(0, texture_rt->GetSurfaceLevel (0)); } if (depth_rt.IsValid()) { fbo->SetDepthSurface(depth_rt->GetSurfaceLevel (0)); } fbo->Activate(); graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); for (int i = 0; i < 1; i++) { nux::Rect geo (nux::RandomUInt(graphics_display->GetWindowWidth()), nux::RandomUInt(graphics_display->GetWindowHeight()), nux::RandomUInt(200), nux::RandomUInt(200)); graphics_engine->QRP_Color(geo.x, geo.y, geo.width, geo.height, nux::color::RandomColor()); } // Restore the back buffer graphics_display->GetGpuDevice()->DeactivateFrameBuffer(); nux::ObjectPtr tex_blur; nux::TexCoordXForm texxform; //Make a blurred copy of the previous render target if (texture_rt.IsValid() && graphics_engine) { tex_blur = graphics_engine->QRP_GLSL_GetBlurTexture( 0, 0, texture_rt->GetWidth(), texture_rt->GetHeight(), texture_rt, texxform, nux::color::White, 7.0f); } graphics_engine->QRP_1Tex(0, 0, tex_blur->GetWidth(), tex_blur->GetHeight(), tex_blur, texxform, nux::color::White); /* sprintf(fps, "FPS: %3.2f", frame_rate); nux::PageBBox page; page.xmin = 0; page.xmax = 100; page.ymin = 0; page.ymax = 20; page.x_margin = 0; page.y_margin = 0; graphics_engine->RenderColorTextLineStatic(graphics_engine->GetBoldFont (), page, fps, nux::color::White, false, nux::eAlignTextLeft); float frame_time = graphics_display->GetFrameTime(); graphics_display->ResetFrameTime(); periode_time += frame_time; frame_counter++; frame_periode++; if (frame_periode >= 100) { frame_rate = frame_periode * 1000.0f / periode_time; periode_time = 0.0f; frame_periode = 0; } */ graphics_display->SwapBuffer(); } while((event.type != nux::NUX_TERMINATE_APP)); fbo.Release (); texture_rt.Release (); depth_rt.Release (); delete graphics_display; } int main() { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); RenderBlurredTexture (); return 0; } nux-4.0.6+14.04.20140409/gputests/texture_copy_blur.cpp0000644000015301777760000001375012321344237023103 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxGraphics/BitmapFormats.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLWindowManager.h" #include "NuxGraphics/GraphicsEngine.h" /* * Tests: * - Frame buffer object * - Set a texture in the fbo * - Set fbo as a render target * - Render Quad to fbo * - Make a copy of the render target: CreateTextureFromBackBuffer * - Deactivate fbo * - Blur the copied render target texture * - Render to default back buffer */ void RenderBlurredCopyOfRenderTarget () { nux::GraphicsDisplay* graphics_display = gGLWindowManager.CreateGLWindow("Window", 600, 300, nux::WINDOWSTYLE_NORMAL, 0, false); nux::GraphicsEngine* graphics_engine = graphics_display->GetGraphicsEngine(); graphics_display->ShowWindow(); nux::ObjectPtr fbo; nux::ObjectPtr texture_rt; nux::ObjectPtr depth_rt; fbo = graphics_display->GetGpuDevice ()->CreateFrameBufferObject (); texture_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_R8G8B8A8); depth_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_D24S8); int w, h; graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); nux::Event event; memset(&event, 0, sizeof(nux::Event)); /*char fps [25]; int frame_counter = 0; int frame_periode = 0; float frame_rate = 0; float periode_time = 0; */ bool first_time = true; do { CHECKGL( glClearColor(0, 0, 0, 1) ); CHECKGL( glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ); graphics_display->GetSystemEvent(&event); if(first_time || (event.type == nux::NUX_SIZE_CONFIGURATION)) { first_time = false; graphics_engine->DisableAllTextureMode(0); graphics_engine->DisableAllTextureMode(1); graphics_engine->DisableAllTextureMode(2); graphics_engine->DisableAllTextureMode(3); graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetScissor(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); fbo = graphics_display->GetGpuDevice ()->CreateFrameBufferObject (); texture_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_R8G8B8A8); depth_rt = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), 1, nux::BITFMT_D24S8); } fbo->FormatFrameBufferObject (graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), nux::BITFMT_R8G8B8A8); fbo->SetRenderTarget (0, texture_rt->GetSurfaceLevel (0)); fbo->SetDepthSurface (depth_rt->GetSurfaceLevel (0)); fbo->Activate(); for (int i = 0; i < 1; i++) { nux::Rect geo (nux::RandomUInt(graphics_display->GetWindowWidth()), nux::RandomUInt(graphics_display->GetWindowHeight()), nux::RandomUInt(200), nux::RandomUInt(200)); graphics_engine->QRP_Color(geo.x, geo.y, geo.width, geo.height, nux::color::RandomColor()); } nux::TexCoordXForm texxform; // Make a copy of the render target nux::ObjectPtr tex_copy = graphics_engine->CreateTextureFromBackBuffer (0, 0, graphics_display->GetWindowWidth (), graphics_display->GetWindowHeight ()); // Restore the back buffer graphics_display->GetGpuDevice ()->DeactivateFrameBuffer (); // Make a blurred version of the back buffer nux::ObjectPtr tex_blur = graphics_engine->QRP_GetBlurTexture ( 0, 0, tex_copy->GetWidth (), tex_copy->GetHeight (), tex_copy, texxform, nux::color::White, 1.0f); // Render the blurred texture graphics_engine->QRP_1Tex(0, 0, tex_blur->GetWidth(), tex_blur->GetHeight(), tex_blur, texxform, nux::color::White); /*sprintf(fps, "FPS: %3.2f", frame_rate); nux::PageBBox page; page.xmin = 0; page.xmax = 100; page.ymin = 0; page.ymax = 20; page.x_margin = 0; page.y_margin = 0; graphics_engine->RenderColorTextLineStatic(graphics_engine->GetBoldFont (), page, fps, nux::color::White, false, nux::eAlignTextLeft); graphics_display->SwapBuffer(); float frame_time = graphics_display->GetFrameTime(); graphics_display->ResetFrameTime(); periode_time += frame_time; frame_counter++; frame_periode++; if (frame_periode >= 100) { frame_rate = frame_periode * 1000.0f / periode_time; periode_time = 0.0f; frame_periode = 0; } */ graphics_display->SwapBuffer(); } while((event.type != nux::NUX_TERMINATE_APP) && (event.GetVirtualKeyState(NUX_VK_ESCAPE) == 0)); fbo.Release (); texture_rt.Release (); depth_rt.Release (); delete graphics_display; } int main() { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); RenderBlurredCopyOfRenderTarget (); return 0; } nux-4.0.6+14.04.20140409/gputests/quad_2texmod.cpp0000755000015301777760000001210612321344237021716 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxGraphics/BitmapFormats.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLWindowManager.h" #include "NuxGraphics/GraphicsEngine.h" /* * Tests: * - Create a check board texture * - Create a second texture and fill it manually with color values * - Render full window background quad * - enable blending * - Render the two textures with QRP_2TexMod: result = (Tex0*Color0) * (Tex1*color1) * - Disable blending */ void QuadRendering_2TexMod () { nux::GraphicsDisplay* graphics_display = gGLWindowManager.CreateGLWindow("QuadRendering: 2TexMod", 570, 270, nux::WINDOWSTYLE_NORMAL, 0, false); nux::GraphicsEngine* graphics_engine = graphics_display->GetGraphicsEngine(); graphics_display->ShowWindow(); int size = 256; nux::NTextureData checkboard_texture_data; MakeCheckBoardImage (checkboard_texture_data.GetSurface (0), size, size, nux::Color (0xff000000), nux::color::LightSeaGreen, 4, 4); nux::BaseTexture* checkboard_texture = graphics_display->GetGpuDevice ()->CreateSystemCapableTexture (); checkboard_texture->Update (&checkboard_texture_data); // Create a Texture map of size 256x1 nux::NTextureData texture_data (nux::BITFMT_R8G8B8A8, size, 1, 1); // Get the first surface (mip 0) of the texture map nux::ImageSurface surface = texture_data.GetSurface (0); nux::ObjectPtr gradient_texture = graphics_display->GetGpuDevice ()->CreateSystemCapableDeviceTexture ( texture_data.GetWidth (), texture_data.GetHeight (), 1, texture_data.GetFormat ()); nux::SURFACE_LOCKED_RECT lockrect; gradient_texture->LockRect (0, &lockrect, 0); BYTE *dest = (BYTE *) lockrect.pBits; int num_row = surface.GetBlockHeight (); // Fill the gradient texture with White and an alpha value going from 1.0f to 0.0f for (int y = 0; y < num_row; y++) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. for (int x = 0; x < texture_data.GetWidth (); x++) { *(dest + y * lockrect.Pitch + 4*x + 0) = 0xff; //red *(dest + y * lockrect.Pitch + 4*x + 1) = 0xff; //green *(dest + y * lockrect.Pitch + 4*x + 2) = 0xff; //blue *(dest + y * lockrect.Pitch + 4*x + 3) = 255 - 255 * ((float)x/(float)texture_data.GetWidth ()); } } gradient_texture->UnlockRect (0); int w, h; nux::Event event; memset(&event, 0, sizeof(nux::Event)); graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetScissor(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); do { CHECKGL( glClearColor(0, 0, 0, 1) ); CHECKGL( glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ); graphics_display->GetSystemEvent(&event); if(event.type == nux::NUX_SIZE_CONFIGURATION) { graphics_engine->GetWindowSize(w, h); graphics_engine->SetViewport(0, 0, w, h); graphics_engine->SetScissor(0, 0, w, h); graphics_engine->SetContext(0, 0, w, h); graphics_engine->Push2DWindow(w, h); } nux::Rect geo ( ((int)graphics_display->GetWindowWidth() - size) /2, ((int)graphics_display->GetWindowHeight() - size) /2, size, size); // Paint a rectangular quad over the entire window graphics_engine->QRP_Color(0, 0, graphics_display->GetWindowWidth(), graphics_display->GetWindowHeight(), nux::color::Aubergine); // Enable blending graphics_display->GetGraphicsEngine()->GetRenderStates ().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); nux::TexCoordXForm texxform0; nux::TexCoordXForm texxform1; // Modulate the checkboard and the gradient texture graphics_engine->QRP_2TexMod(geo.x, geo.y, geo.width, geo.height, gradient_texture, texxform0, nux::color::White, checkboard_texture->GetDeviceTexture (), texxform1, nux::color::White); graphics_display->GetGraphicsEngine()->GetRenderStates ().SetBlend(false); graphics_display->SwapBuffer(); } while(event.type != nux::NUX_TERMINATE_APP); gradient_texture.Release (); checkboard_texture->UnReference (); delete graphics_display; } int main() { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); QuadRendering_2TexMod (); return 0; } nux-4.0.6+14.04.20140409/tests/0000755000015301777760000000000012321344711016074 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/tests/gtest-nux-inputarea-proximity.cpp0000644000015301777760000002044712321344237024600 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Brandon Schaefer * */ #include using namespace testing; #include "Nux/Nux.h" #include "Nux/InputAreaProximity.h" #include "Nux/WindowCompositor.h" #include "Nux/ProgramFramework/TestView.h" #include namespace { const int VIEW_WIDTH = 500; const int VIEW_HEIGHT = 500; class TestInputAreaProximity : public Test { public: TestInputAreaProximity() : top_proximity_(0) , near_signal_recived_(false) , beyond_signal_recived_(false) , approaching_signal_recived_(false) { nux::NuxInitialize(0); wnd_thread.reset(nux::CreateNuxWindow("View Test", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL)); MoveMouse(VIEW_WIDTH+200, VIEW_HEIGHT+200); } ~TestInputAreaProximity() { while (!prox_areas_.empty()) RemoveInputAreaProximity(); } void AddNInputAreaProximities(int n, int proximity = 10) { for (int i = 0; i < n; i++) AddInputAreaProximity(proximity); } void AddInputAreaProximity(int proximity = 10) { nux::TestView* test_view = new nux::TestView(""); test_view->SetGeometry(nux::Geometry(0, 0, VIEW_WIDTH, VIEW_HEIGHT)); top_proximity_ = proximity; auto prox_area = std::make_shared(test_view, proximity); prox_area->mouse_near.connect([&] (const nux::Point&) { near_signal_recived_ = true; }); prox_area->mouse_beyond.connect([&] (const nux::Point&) { beyond_signal_recived_ = true; }); prox_area->mouse_approaching.connect([&] (const nux::Point&, const nux::Point& difference) { approaching_signal_recived_ = true; last_approaching_point_ = difference; }); prox_areas_.push(std::make_pair(prox_area, test_view)); } void RemoveInputAreaProximity() { if (!prox_areas_.empty()) { auto prox_area = prox_areas_.top(); prox_areas_.pop(); prox_area.second->UnReference(); } } void ResetSignalRecivedValues() { near_signal_recived_ = false; beyond_signal_recived_ = false; approaching_signal_recived_ = false; } bool NearSignalRecived() const { return near_signal_recived_; } bool BeyondSignalRecived() const { return beyond_signal_recived_; } bool ApproachingSignalRecived() const { return approaching_signal_recived_; } nux::Point GetLastApprochingPoint() { return last_approaching_point_; } void MoveMouseNear() { MoveMouse(VIEW_WIDTH+(top_proximity_-1), VIEW_HEIGHT+(top_proximity_-1)); } void MoveMouseBeyond() { MoveMouse(VIEW_WIDTH+(top_proximity_+1), VIEW_HEIGHT+(top_proximity_+1)); } void MoveMouse(int x, int y) { nux::Event event; event.type = nux::NUX_MOUSE_MOVE; event.x = x; event.y = y; nux::GetWindowCompositor().ProcessEvent(event); } void MoveMouseBeyondWindow() { nux::Event event; event.type = nux::NUX_WINDOW_MOUSELEAVE; event.x = VIEW_WIDTH + top_proximity_ + 10; event.y = VIEW_HEIGHT + top_proximity_ + 10; nux::GetWindowCompositor().ProcessEvent(event); } int GetProxListSize() { return nux::GetWindowCompositor().GetProximityListSize(); } private: std::unique_ptr wnd_thread; std::stack, nux::TestView*> > prox_areas_; nux::Point last_approaching_point_; int top_proximity_; bool near_signal_recived_; bool beyond_signal_recived_; bool approaching_signal_recived_; }; TEST_F(TestInputAreaProximity, TestAtemptToAddNullToList) { const int prox_size = GetProxListSize(); nux::InputAreaProximity* prox_area = new nux::InputAreaProximity(NULL, 10); MoveMouseNear(); MoveMouseBeyond(); delete prox_area; ASSERT_EQ(GetProxListSize(), prox_size); } TEST_F(TestInputAreaProximity, TestHandlesDeletedInputArea) { const int prox_size = GetProxListSize(); nux::TestView* test_view = new nux::TestView(""); test_view->SetGeometry(nux::Geometry(0, 0, VIEW_WIDTH, VIEW_HEIGHT)); nux::InputAreaProximity* prox_area = new nux::InputAreaProximity(test_view, 10); test_view->UnReference(); MoveMouseNear(); MoveMouseBeyond(); delete prox_area; ASSERT_EQ(GetProxListSize(), prox_size); } TEST_F(TestInputAreaProximity, TestAddsNullProximity) { const int prox_size = nux::GetWindowCompositor().GetProximityListSize(); nux::GetWindowThread()->GetWindowCompositor().AddAreaInProximityList(NULL); MoveMouseNear(); MoveMouseBeyond(); nux::GetWindowThread()->GetWindowCompositor().RemoveAreaInProximityList(NULL); ASSERT_EQ(nux::GetWindowCompositor().GetProximityListSize(), prox_size); } TEST_F(TestInputAreaProximity, TestProximityAreaAddsToList) { ASSERT_EQ(nux::GetWindowCompositor().GetProximityListSize(), 0); AddNInputAreaProximities(2); ASSERT_EQ(nux::GetWindowCompositor().GetProximityListSize(), 2); } TEST_F(TestInputAreaProximity, TestRemovesFromProximityList) { int num_prox_areas = 10; AddNInputAreaProximities(num_prox_areas); ASSERT_EQ(GetProxListSize(), num_prox_areas); for (int i = 0; i < num_prox_areas; i++) { RemoveInputAreaProximity(); ASSERT_EQ(GetProxListSize(), num_prox_areas - (i + 1)); } } TEST_F(TestInputAreaProximity, TestNearSignal) { AddInputAreaProximity(); MoveMouseBeyond(); ASSERT_FALSE(NearSignalRecived()); MoveMouseNear(); ASSERT_TRUE(NearSignalRecived()); } TEST_F(TestInputAreaProximity, TestApproachingSignal) { AddInputAreaProximity(); MoveMouseBeyond(); ASSERT_FALSE(ApproachingSignalRecived()); MoveMouseNear(); ASSERT_TRUE(ApproachingSignalRecived()); } TEST_F(TestInputAreaProximity, TestApproachingDoesNotEmitInsideArea) { AddInputAreaProximity(); MoveMouse(VIEW_WIDTH/2, VIEW_HEIGHT/2); ResetSignalRecivedValues(); MoveMouse(VIEW_WIDTH/4, VIEW_HEIGHT/4); ASSERT_FALSE(ApproachingSignalRecived()); MoveMouseNear(); ASSERT_TRUE(ApproachingSignalRecived()); } TEST_F(TestInputAreaProximity, TestApproachingSignalHorizontal) { int proximity = 10; AddInputAreaProximity(proximity); nux::Point difference; int expected_result; for (int i = 1; i <= proximity; i++) { MoveMouse(VIEW_WIDTH+(proximity-i), VIEW_HEIGHT+(proximity-1)); difference = GetLastApprochingPoint(); expected_result = -(proximity - i); ASSERT_EQ(expected_result, difference.x); ASSERT_EQ(-(proximity-1), difference.y); } } TEST_F(TestInputAreaProximity, TestApproachingSignalVertical) { int proximity = 10; AddInputAreaProximity(proximity); nux::Point difference; int expected_result; for (int i = 1; i <= proximity; i++) { MoveMouse(VIEW_WIDTH+(proximity-1), VIEW_HEIGHT+(proximity-i)); difference = GetLastApprochingPoint(); expected_result = -(proximity - i); ASSERT_EQ(-(proximity-1), difference.x); ASSERT_EQ(expected_result, difference.y); } } TEST_F(TestInputAreaProximity, TestApproachingSignalDiagonal) { int proximity = 10; AddInputAreaProximity(proximity); nux::Point difference; int expected_result; for (int i = 1; i <= proximity; i++) { MoveMouse(VIEW_WIDTH+(proximity-i), VIEW_HEIGHT+(proximity-i)); difference = GetLastApprochingPoint(); expected_result = -(proximity - i); ASSERT_EQ(expected_result, difference.x); ASSERT_EQ(expected_result, difference.y); } } TEST_F(TestInputAreaProximity, TestBeyondSignal) { AddInputAreaProximity(); MoveMouseNear(); ASSERT_FALSE(BeyondSignalRecived()); MoveMouseBeyond(); ASSERT_TRUE(BeyondSignalRecived()); } TEST_F(TestInputAreaProximity, TestBeyondSignalEmitWhenLeavingWindow) { AddInputAreaProximity(); MoveMouseNear(); ASSERT_FALSE(BeyondSignalRecived()); MoveMouseBeyondWindow(); ASSERT_TRUE(BeyondSignalRecived()); } } nux-4.0.6+14.04.20140409/tests/gtest-nux-windowcompositor.cpp0000644000015301777760000007244112321344237024175 0ustar pbusernogroup00000000000000#include #include #include #include #include #include #include #include "Nux/Nux.h" #include "Nux/BaseWindow.h" #include "Nux/InputAreaProximity.h" #include "Nux/HLayout.h" #include "Nux/VLayout.h" #include "Nux/ProgramFramework/TestView.h" #ifdef NUX_GESTURES_SUPPORT #include "NuxGraphics/GestureEvent.h" #include "FakeGestureEvent.h" #endif using namespace testing; namespace { #ifdef NUX_GESTURES_SUPPORT class TestWindow : public nux::BaseWindow { public: virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event) { gesture_events_received.push_back(event); return nux::GestureDeliveryRequest::NONE; } std::list gesture_events_received; }; class TestInputArea : public nux::InputArea { public: virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event) { gesture_events_received.push_back(event); return nux::GestureDeliveryRequest::NONE; } std::list gesture_events_received; }; #endif struct TestBaseWindow : public nux::BaseWindow { TestBaseWindow() : input_area(new nux::InputArea()) { ShowWindow(true); } nux::Area* FindAreaUnderMouse(const nux::Point& /* mouse_position */, nux::NuxEventType /* event_type */) { return input_area.GetPointer(); } Area* FindKeyFocusArea(unsigned int /* key_symbol */, unsigned long /* x11_key_code */, unsigned long /* special_keys_state */) { return input_area.GetPointer(); } nux::ObjectPtr input_area; }; struct TestHLayout : public nux::HLayout { TestHLayout() : input_area(new nux::InputArea()) {} nux::Area* FindAreaUnderMouse(const nux::Point& /* mouse_position */, nux::NuxEventType /* event_type */) { return input_area.GetPointer(); } Area* FindKeyFocusArea(unsigned int /* key_symbol */, unsigned long /* x11_key_code */, unsigned long /* special_keys_state */) { return input_area.GetPointer(); } nux::ObjectPtr input_area; }; } namespace nux { struct TestWindowCompositor : public testing::Test { TestWindowCompositor() {} void SetUp() { nux::NuxInitialize(0); wnd_thread.reset(nux::CreateNuxWindow("WindowCompositor Test", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL)); } void ForceSetKeyFocusArea(nux::InputArea* area) { nux::GetWindowCompositor().key_focus_area_ = area; } ObjectWeakPtr const& GetMouseOwnerArea() const { return nux::GetWindowCompositor().GetMouseOwnerArea(); } void SetMouseOwnerArea(InputArea* area) { nux::GetWindowCompositor().mouse_owner_area_ = area; } InputArea* GetMouseOverArea() { return nux::GetWindowCompositor().mouse_over_area_.GetPointer(); } void SetMouseOverArea(InputArea* area) { nux::GetWindowCompositor().mouse_over_area_ = area; } void GetAreaUnderMouse(const Point& mouse_position, NuxEventType event_type, ObjectWeakPtr& area) { return nux::GetWindowCompositor().FindAreaUnderMouse(mouse_position, event_type, area); } void FindKeyFocusArea(NuxEventType event_type, unsigned int key_symbol, unsigned int state, ObjectWeakPtr& key_focus_area, ObjectWeakPtr& window) { return nux::GetWindowCompositor().FindKeyFocusArea(event_type, key_symbol, state, key_focus_area, window); } boost::shared_ptr wnd_thread; }; namespace { typedef void (*NGLGenFramebuffers)(GLsizei, GLuint *); typedef void (*NGLGenRenderbuffers)(GLsizei, GLuint *); typedef void (*NGLBindFramebuffer)(GLenum, GLuint); typedef void (*NGLBindRenderbuffer)(GLenum, GLuint); typedef void (*NGLRenderbufferStorage)(GLenum, GLenum, GLsizei, GLsizei); typedef void (*NGLFramebufferRenderbuffer)(GLenum, GLenum, GLenum, GLuint); typedef void (*NGLDeleteFramebuffers)(GLsizei, const GLuint *); typedef void (*NGLDeleteRenderbuffers)(GLsizei, const GLuint *); #ifdef NUX_OPENGLES_20 GLuint NGL_RENDERBUFFER = GL_RENDERBUFFER; /* No separate draw or read targets on OpenGL|ES */ GLuint NGL_DRAW_FRAMEBUFFER = GL_FRAMEBUFFER; GLuint NGL_READ_FRAMEBUFFER = GL_FRAMEBUFFER; GLuint NGL_DRAW_FRAMEBUFFER_BINDING = GL_FRAMEBUFFER_BINDING; GLuint NGL_READ_FRAMEBUFFER_BINDING = GL_FRAMEBUFFER_BINDING; GLuint NGL_COLOR_ATTACHMENT0 = GL_COLOR_ATTACHMENT0; GLuint NGL_RGBA_STORAGE = GL_RGBA4; #else GLuint NGL_RENDERBUFFER = GL_RENDERBUFFER_EXT; GLuint NGL_DRAW_FRAMEBUFFER = GL_DRAW_FRAMEBUFFER_EXT; GLuint NGL_READ_FRAMEBUFFER = GL_READ_FRAMEBUFFER_EXT; GLuint NGL_DRAW_FRAMEBUFFER_BINDING = GL_DRAW_FRAMEBUFFER_BINDING_EXT; GLuint NGL_READ_FRAMEBUFFER_BINDING = GL_DRAW_FRAMEBUFFER_BINDING_EXT; GLuint NGL_COLOR_ATTACHMENT0 = GL_COLOR_ATTACHMENT0_EXT; GLuint NGL_RGBA_STORAGE = GL_RGBA8_EXT; #endif class ReferenceFramebuffer { public: ReferenceFramebuffer () { #ifdef NUX_OPENGLES_20 nglGenFramebuffers = &glGenFramebuffers; nglGenRenderbuffers = &glGenRenderbuffers; nglBindRenderbuffer = &glBindRenderbuffer; nglBindFramebuffer = &glBindFramebuffer; nglRenderbufferStorage = &glRenderbufferStorage; nglFramebufferRenderbuffer = &glFramebufferRenderbuffer; nglDeleteRenderbuffers = &glDeleteRenderbuffers; nglDeleteFramebuffers = &glDeleteFramebuffers; #else nglGenFramebuffers = glGenFramebuffersEXT; nglGenRenderbuffers = glGenRenderbuffersEXT; nglBindRenderbuffer = glBindRenderbufferEXT; nglBindFramebuffer = glBindFramebufferEXT; nglRenderbufferStorage = glRenderbufferStorageEXT; nglFramebufferRenderbuffer = glFramebufferRenderbufferEXT; nglDeleteRenderbuffers = glDeleteRenderbuffersEXT; nglDeleteFramebuffers = glDeleteFramebuffersEXT; #endif nglGenFramebuffers(1, &fboName); nglGenRenderbuffers(1, &rbName); nglBindRenderbuffer(NGL_RENDERBUFFER, rbName); nglRenderbufferStorage(NGL_RENDERBUFFER, NGL_RGBA_STORAGE, 300, 200); nglBindFramebuffer(NGL_DRAW_FRAMEBUFFER, fboName); nglBindFramebuffer(NGL_READ_FRAMEBUFFER, fboName); nglFramebufferRenderbuffer(NGL_DRAW_FRAMEBUFFER, NGL_COLOR_ATTACHMENT0, NGL_RENDERBUFFER, rbName); } ~ReferenceFramebuffer () { nglBindFramebuffer(NGL_DRAW_FRAMEBUFFER, 0); nglBindFramebuffer(NGL_READ_FRAMEBUFFER, 0); nglDeleteRenderbuffers(1, &rbName); nglDeleteFramebuffers(1, &fboName); } GLuint fboName, rbName; /* Each instance of the class needs to keep its own * copy of the extension functions as glewInit () needs * to be called in the desktop case before they are available */ NGLGenFramebuffers nglGenFramebuffers; NGLGenRenderbuffers nglGenRenderbuffers; NGLBindRenderbuffer nglBindRenderbuffer; NGLBindFramebuffer nglBindFramebuffer; NGLRenderbufferStorage nglRenderbufferStorage; NGLFramebufferRenderbuffer nglFramebufferRenderbuffer; NGLDeleteRenderbuffers nglDeleteRenderbuffers; NGLDeleteFramebuffers nglDeleteFramebuffers; }; } TEST_F(TestWindowCompositor, TestRestoreReferenceFramebufferDirect) { ReferenceFramebuffer reference; GLint dfbBinding, rfbBinding; glGetIntegerv(NGL_DRAW_FRAMEBUFFER_BINDING, &dfbBinding); glGetIntegerv(NGL_READ_FRAMEBUFFER_BINDING, &rfbBinding); ASSERT_EQ (dfbBinding, reference.fboName); wnd_thread->GetWindowCompositor().SetReferenceFramebuffer(dfbBinding, rfbBinding, nux::Geometry (0, 0, 300, 200)); ASSERT_TRUE (wnd_thread->GetWindowCompositor().RestoreReferenceFramebuffer()); glGetIntegerv(NGL_DRAW_FRAMEBUFFER_BINDING, &dfbBinding); glGetIntegerv(NGL_READ_FRAMEBUFFER_BINDING, &rfbBinding); ASSERT_EQ (dfbBinding, reference.fboName); ASSERT_EQ (rfbBinding, reference.fboName); } TEST_F(TestWindowCompositor, TestRestoreReferenceFramebufferThroughRestoreMain) { ReferenceFramebuffer reference; GLint dfbBinding, rfbBinding; glGetIntegerv(NGL_DRAW_FRAMEBUFFER_BINDING, &dfbBinding); glGetIntegerv(NGL_READ_FRAMEBUFFER_BINDING, &rfbBinding); ASSERT_EQ(dfbBinding, reference.fboName); wnd_thread->GetWindowCompositor().SetReferenceFramebuffer(dfbBinding, rfbBinding, nux::Geometry (0, 0, 300, 200)); wnd_thread->GetWindowCompositor().RestoreMainFramebuffer(); glGetIntegerv(NGL_DRAW_FRAMEBUFFER_BINDING, &dfbBinding); glGetIntegerv(NGL_READ_FRAMEBUFFER_BINDING, &rfbBinding); ASSERT_EQ(dfbBinding, reference.fboName); ASSERT_EQ(rfbBinding, reference.fboName); } TEST_F(TestWindowCompositor, TestRestoreBackbufferThroughRestoreMain) { ReferenceFramebuffer reference; GLint dfbBinding, rfbBinding; glGetIntegerv(NGL_DRAW_FRAMEBUFFER_BINDING, &dfbBinding); glGetIntegerv(NGL_READ_FRAMEBUFFER_BINDING, &rfbBinding); ASSERT_EQ (dfbBinding, reference.fboName); wnd_thread->GetWindowCompositor().RestoreMainFramebuffer(); glGetIntegerv(NGL_DRAW_FRAMEBUFFER_BINDING, &dfbBinding); glGetIntegerv(NGL_READ_FRAMEBUFFER_BINDING, &rfbBinding); ASSERT_EQ(dfbBinding, 0); ASSERT_EQ(rfbBinding, 0); } TEST_F(TestWindowCompositor, TestSetKeyFocusArea) { nux::TestView* test_view0 = new nux::TestView(); nux::TestView* test_view1 = new nux::TestView(); nux::HLayout* layout = new nux::HLayout(); layout->AddView(test_view0, 1); layout->AddView(test_view1, 1); wnd_thread->SetLayout(layout); // Set keyboard focus on test_view0 { wnd_thread->GetWindowCompositor().SetKeyFocusArea(test_view0); // Check that test_view0 has registered a keynav focus event EXPECT_EQ(test_view0->registered_begin_keynav_focus_, true); EXPECT_EQ(test_view0->registered_end_keynav_focus_, false); EXPECT_EQ(test_view1->registered_begin_keynav_focus_, false); EXPECT_EQ(test_view1->registered_end_keynav_focus_, false); test_view0->ResetKeyFocusEvents(); } // Set keyboard focus on test_view1 { wnd_thread->GetWindowCompositor().SetKeyFocusArea(test_view1); EXPECT_EQ(test_view0->registered_begin_keynav_focus_, false); // Check that test_view0 has loast the keynav focus. EXPECT_EQ(test_view0->registered_end_keynav_focus_, true); // Check that test_view1 has registered a keynav focus event EXPECT_EQ(test_view1->registered_begin_keynav_focus_, true); EXPECT_EQ(test_view1->registered_end_keynav_focus_, false); } } TEST_F(TestWindowCompositor, TestInputAreaProximityNullValue) { const int prox_size = nux::GetWindowCompositor().GetProximityListSize(); nux::InputAreaProximity* prox_area = new nux::InputAreaProximity(NULL, 10); ASSERT_EQ(nux::GetWindowCompositor().GetProximityListSize(), prox_size); delete prox_area; } #ifdef NUX_GESTURES_SUPPORT /* We have two windows: one subscribed to 2-touches' pinch (A) and another without any subscriptions (B). Send events of a 2-touches' pinch within window A's boundaries. Check that the gesture got accepted, that window A got the gesture events and that window B didn't get anything. */ TEST_F(TestWindowCompositor, GestureEventsDelivery_1) { nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor(); nux::FakeGestureEvent fake_event; TestWindow *target_window = new TestWindow; target_window->SetBaseXY(10, 10); target_window->SetBaseWidth(90); target_window->SetBaseHeight(90); target_window->ShowWindow(true); target_window->CreateGesturesSubscription(nux::PINCH_GESTURE, 2); TestWindow *innocent_window = new TestWindow; innocent_window->SetBaseXY(300, 300); innocent_window->SetBaseWidth(100); innocent_window->SetBaseHeight(100); innocent_window->ShowWindow(true); g_gesture_acceptance[0] = 0; fake_event.type = nux::EVENT_GESTURE_BEGIN; fake_event.gesture_id = 0; fake_event.gesture_classes = nux::PINCH_GESTURE | nux::ROTATE_GESTURE; fake_event.is_direct_touch = false; fake_event.focus.x = 30.0f; // hits target_window fake_event.focus.y = 30.0f; // in touch device's coordinate system (because it's not a direct device). // Thus not used by WindowCompositor fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); fake_event.is_construction_finished = false; wnd_compositor.ProcessEvent(fake_event.ToGestureEvent()); ASSERT_EQ(0, g_gesture_acceptance[0]); ASSERT_EQ(0, target_window->gesture_events_received.size()); ASSERT_EQ(0, innocent_window->gesture_events_received.size()); fake_event.type = nux::EVENT_GESTURE_UPDATE; fake_event.focus.x += 2.0f; fake_event.focus.y += 2.0f; fake_event.touches.clear(); fake_event.touches.push_back(nux::TouchPoint(0, 11.0f, 11.0f)); fake_event.touches.push_back(nux::TouchPoint(1, 21.0f, 21.0f)); fake_event.is_construction_finished = true; wnd_compositor.ProcessEvent(fake_event.ToGestureEvent()); ASSERT_EQ(1, g_gesture_acceptance[0]); ASSERT_EQ(2, target_window->gesture_events_received.size()); ASSERT_EQ(0, innocent_window->gesture_events_received.size()); target_window->Dispose(); innocent_window->Dispose(); } /* We have two windows: one subscribed to 2-touches' pinch (A) and another without any subscriptions (B). Send events of a 2-touches' pinch within window B's boundaries. Check that the gesture got rejected and that no window got any gesture event. */ TEST_F(TestWindowCompositor, GestureEventsDelivery_2) { nux::FakeGestureEvent fake_event; nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor(); TestWindow *subscribed_window = new TestWindow; subscribed_window->SetBaseXY(10, 10); subscribed_window->SetBaseWidth(90); subscribed_window->SetBaseHeight(90); subscribed_window->ShowWindow(true); subscribed_window->CreateGesturesSubscription(nux::PINCH_GESTURE, 2); TestWindow *innocent_window = new TestWindow; innocent_window->SetBaseXY(300, 300); innocent_window->SetBaseWidth(100); innocent_window->SetBaseHeight(100); innocent_window->ShowWindow(true); g_gesture_acceptance[0] = 0; fake_event.type = nux::EVENT_GESTURE_BEGIN; fake_event.gesture_id = 0; fake_event.gesture_classes = nux::PINCH_GESTURE | nux::ROTATE_GESTURE; fake_event.is_direct_touch = false; fake_event.focus.x = 350.0f; // hits innocent_window fake_event.focus.y = 350.0f; // in touch device's coordinate system (because it's not a direct device). // Thus not used by WindowCompositor fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); fake_event.is_construction_finished = false; wnd_compositor.ProcessEvent(fake_event.ToGestureEvent()); ASSERT_EQ(-1, g_gesture_acceptance[0]); ASSERT_EQ(0, subscribed_window->gesture_events_received.size()); ASSERT_EQ(0, innocent_window->gesture_events_received.size()); subscribed_window->Dispose(); innocent_window->Dispose(); } /* There are two input areas in main window's layout. They're both subscribed to 2-touches' pinch gestures. There's also a window on top that is subscribed to 2-touches' drag gestures. Send events of a 2-touches' pinch within that window's boundaries. Check that the gesture gets accepted and that only the input area behind that window gets the gesture events. */ TEST_F(TestWindowCompositor, GestureEventsDelivery_3) { nux::FakeGestureEvent fake_event; nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor(); TestWindow *window = new TestWindow; window->SetBaseXY(10, 10); window->SetBaseWidth(90); window->SetBaseHeight(90); window->ShowWindow(true); window->CreateGesturesSubscription(nux::DRAG_GESTURE, 2); TestInputArea *target_input_area = new TestInputArea; target_input_area->CreateGesturesSubscription(nux::PINCH_GESTURE, 2); TestInputArea *other_input_area = new TestInputArea; other_input_area->CreateGesturesSubscription(nux::PINCH_GESTURE, 2); nux::VLayout *root_layout = new nux::VLayout; root_layout->AddView(target_input_area); // should have geometry (0, 0, 500, 250) root_layout->AddView(other_input_area); // should have geometry (0, 250, 500, 250) wnd_thread->SetLayout(root_layout); g_gesture_acceptance[0] = 0; fake_event.type = nux::EVENT_GESTURE_BEGIN; fake_event.gesture_id = 0; fake_event.gesture_classes = nux::PINCH_GESTURE | nux::ROTATE_GESTURE; fake_event.is_direct_touch = false; fake_event.focus.x = 30.0f; // hits window and target_input_area behind it fake_event.focus.y = 30.0f; // in touch device's coordinate system (because it's not a direct device). // Thus not used by WindowCompositor fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); fake_event.is_construction_finished = false; wnd_compositor.ProcessEvent(fake_event.ToGestureEvent()); // shouldn't be accepted right away because is_construction_finished == false ASSERT_EQ(0, g_gesture_acceptance[0]); ASSERT_EQ(0, window->gesture_events_received.size()); ASSERT_EQ(0, target_input_area->gesture_events_received.size()); ASSERT_EQ(0, other_input_area->gesture_events_received.size()); fake_event.type = nux::EVENT_GESTURE_UPDATE; fake_event.focus.x += 2.0f; fake_event.focus.y += 2.0f; fake_event.touches.clear(); fake_event.touches.push_back(nux::TouchPoint(0, 11.0f, 11.0f)); fake_event.touches.push_back(nux::TouchPoint(1, 21.0f, 21.0f)); fake_event.is_construction_finished = true; wnd_compositor.ProcessEvent(fake_event.ToGestureEvent()); ASSERT_EQ(1, g_gesture_acceptance[0]); ASSERT_EQ(0, window->gesture_events_received.size()); ASSERT_EQ(2, target_input_area->gesture_events_received.size()); ASSERT_EQ(0, other_input_area->gesture_events_received.size()); window->Dispose(); } /* Check that if a gesture gets its construction finished only on its end event, it still gets accepted and delivered. */ TEST_F(TestWindowCompositor, GestureEventsDelivery_4) { nux::FakeGestureEvent fake_event; nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor(); TestWindow *window = new TestWindow; window->SetBaseXY(10, 10); window->SetBaseWidth(90); window->SetBaseHeight(90); window->ShowWindow(true); window->CreateGesturesSubscription(nux::DRAG_GESTURE, 2); TestInputArea *target_input_area = new TestInputArea; target_input_area->CreateGesturesSubscription(nux::PINCH_GESTURE, 2); TestInputArea *other_input_area = new TestInputArea; other_input_area->CreateGesturesSubscription(nux::PINCH_GESTURE, 2); nux::VLayout *root_layout = new nux::VLayout; root_layout->AddView(target_input_area); // should have geometry (0, 0, 500, 250) root_layout->AddView(other_input_area); // should have geometry (0, 250, 500, 250) wnd_thread->SetLayout(root_layout); g_gesture_acceptance[0] = 0; fake_event.type = nux::EVENT_GESTURE_BEGIN; fake_event.gesture_id = 0; fake_event.gesture_classes = nux::PINCH_GESTURE | nux::ROTATE_GESTURE; fake_event.is_direct_touch = false; fake_event.focus.x = 30.0f; // hits window and target_input_area behind it fake_event.focus.y = 30.0f; // in touch device's coordinate system (because it's not a direct device). // Thus not used by WindowCompositor fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f)); fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f)); fake_event.is_construction_finished = false; wnd_compositor.ProcessEvent(fake_event.ToGestureEvent()); // shouldn't be accepted right away because is_construction_finished == false ASSERT_EQ(0, g_gesture_acceptance[0]); ASSERT_EQ(0, window->gesture_events_received.size()); ASSERT_EQ(0, target_input_area->gesture_events_received.size()); ASSERT_EQ(0, other_input_area->gesture_events_received.size()); fake_event.type = nux::EVENT_GESTURE_END; fake_event.focus.x += 2.0f; fake_event.focus.y += 2.0f; fake_event.touches.clear(); fake_event.touches.push_back(nux::TouchPoint(0, 11.0f, 11.0f)); fake_event.touches.push_back(nux::TouchPoint(1, 21.0f, 21.0f)); fake_event.is_construction_finished = true; wnd_compositor.ProcessEvent(fake_event.ToGestureEvent()); ASSERT_EQ(1, g_gesture_acceptance[0]); ASSERT_EQ(0, window->gesture_events_received.size()); ASSERT_EQ(2, target_input_area->gesture_events_received.size()); ASSERT_EQ(0, other_input_area->gesture_events_received.size()); window->Dispose(); } TEST_F(TestWindowCompositor, KeyFocusAreaAutomaticallyUnsets) { nux::WindowCompositor& wnd_compositor = nux::GetWindowCompositor(); nux::InputArea* test_area = new TestInputArea(); ForceSetKeyFocusArea(test_area); ASSERT_EQ(wnd_compositor.GetKeyFocusArea(), test_area); test_area->UnReference(); EXPECT_EQ(wnd_compositor.GetKeyFocusArea(), nullptr); } TEST_F(TestWindowCompositor, MouseOverAreaAutomaticallyUnsets) { nux::InputArea* test_area = new TestInputArea(); SetMouseOverArea(test_area); ASSERT_EQ(GetMouseOverArea(), test_area); test_area->UnReference(); EXPECT_EQ(GetMouseOverArea(), nullptr); } TEST_F(TestWindowCompositor, MouseOwnerAreaAutomaticallyUnsets) { nux::InputArea* test_area = new TestInputArea(); SetMouseOwnerArea(test_area); ASSERT_EQ(GetMouseOwnerArea(), test_area); test_area->UnReference(); EXPECT_EQ(GetMouseOwnerArea(), nullptr); } TEST_F(TestWindowCompositor, GetAreaUnderMouse) { ObjectWeakPtr area; TestBaseWindow* test_win = new TestBaseWindow(); GetAreaUnderMouse(Point(1, 2), NUX_MOUSE_MOVE, area); EXPECT_EQ(area.GetPointer(), test_win->input_area.GetPointer()); test_win->UnReference(); EXPECT_EQ(area.GetPointer(), nullptr); } TEST_F(TestWindowCompositor, GetAreaUnderMouseFallback) { ObjectWeakPtr area; TestHLayout* layout = new TestHLayout(); wnd_thread->SetLayout(layout); GetAreaUnderMouse(Point(1, 2), NUX_MOUSE_MOVE, area); EXPECT_EQ(area.GetPointer(), layout->input_area.GetPointer()); wnd_thread->SetLayout(nullptr); layout->UnReference(); EXPECT_EQ(area.GetPointer(), nullptr); } TEST_F(TestWindowCompositor, GetFocusedArea) { ObjectWeakPtr area; ObjectWeakPtr window; TestBaseWindow* test_win = new TestBaseWindow(); FindKeyFocusArea(NUX_KEYUP, 0, 0, area, window); EXPECT_EQ(area.GetPointer(), test_win->input_area.GetPointer()); EXPECT_EQ(window.GetPointer(), test_win); test_win->UnReference(); EXPECT_EQ(area.GetPointer(), nullptr); EXPECT_EQ(window.GetPointer(), nullptr); } TEST_F(TestWindowCompositor, GetFocusedAreaFallback) { ObjectWeakPtr area; ObjectWeakPtr window; TestHLayout* layout = new TestHLayout(); wnd_thread->SetLayout(layout); FindKeyFocusArea(NUX_KEYUP, 0, 0, area, window); EXPECT_EQ(area.GetPointer(), layout->input_area.GetPointer()); EXPECT_EQ(window.GetPointer(), nullptr); wnd_thread->SetLayout(nullptr); layout->UnReference(); EXPECT_EQ(area.GetPointer(), nullptr); } class DraggedWindow : public nux::BaseWindow { public: DraggedWindow() : mouse_drag_emission_count(0) , mouse_drag_x(0) , mouse_drag_y(0) , mouse_drag_dx(0) , mouse_drag_dy(0) {} protected: virtual void EmitMouseDragSignal(int x, int y, int dx, int dy, unsigned long /*mouse_button_state*/, unsigned long /*special_keys_state*/) { ++mouse_drag_emission_count; mouse_drag_x = x; mouse_drag_y = y; mouse_drag_dx = dx; mouse_drag_dy = dy; } public: int mouse_drag_emission_count; int mouse_drag_x; int mouse_drag_y; int mouse_drag_dx; int mouse_drag_dy; }; /* Regression test for lp1057995 */ TEST_F(TestWindowCompositor, MouseDrag) { nux::Event event; DraggedWindow *window = new DraggedWindow; window->SetBaseXY(60, 70); window->SetBaseWidth(200); window->SetBaseHeight(200); window->ShowWindow(true); event.type = NUX_MOUSE_PRESSED; event.x = 100; event.y = 200; nux::GetWindowCompositor().ProcessEvent(event); event.type = NUX_MOUSE_MOVE; event.x = 50; event.y = 250; nux::GetWindowCompositor().ProcessEvent(event); ASSERT_EQ(1, window->mouse_drag_emission_count); /* OBS: they're in local window coordinates */ ASSERT_EQ(50 - 60, window->mouse_drag_x); ASSERT_EQ(250 - 70, window->mouse_drag_y); ASSERT_EQ(50 - 100, window->mouse_drag_dx); ASSERT_EQ(250 - 200, window->mouse_drag_dy); window->Dispose(); } class TrackerWindow : public nux::BaseWindow { public: TrackerWindow() : mouse_up_emission_count(0) , mouse_drag_emission_count(0) , mouse_drag_dx(0) , mouse_drag_dy(0) {} virtual bool ChildMouseEvent(const nux::Event& event) { child_mouse_events_received.push_back(event); return wants_mouse_ownership; } std::vector child_mouse_events_received; bool wants_mouse_ownership; protected: virtual void EmitMouseUpSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { ++mouse_up_emission_count; } virtual void EmitMouseDragSignal(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state) { ++mouse_drag_emission_count; mouse_drag_dx = dx; mouse_drag_dy = dy; } public: int mouse_up_emission_count; int mouse_drag_emission_count; int mouse_drag_dx; int mouse_drag_dy; }; class TrackedArea : public nux::InputArea { public: TrackedArea() : mouse_down_emission_count(0) , mouse_up_emission_count(0) , mouse_drag_emission_count(0) , mouse_cancel_emission_count(0) {} protected: virtual void EmitMouseDownSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { ++mouse_down_emission_count; } virtual void EmitMouseUpSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { ++mouse_up_emission_count; } virtual void EmitMouseDragSignal(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state) { ++mouse_drag_emission_count; } virtual void EmitMouseCancelSignal() { ++mouse_cancel_emission_count; } public: int mouse_down_emission_count; int mouse_up_emission_count; int mouse_drag_emission_count; int mouse_cancel_emission_count; }; TEST_F(TestWindowCompositor, TrackingChildMouseEvents) { nux::WindowCompositor &wnd_compositor = wnd_thread->GetWindowCompositor(); TrackedArea *tracked_area = new TrackedArea; tracked_area->SetGeometry(0, 0, 100, 1000); tracked_area->SetMinimumSize(100, 1000); nux::VLayout *layout = new VLayout(NUX_TRACKER_LOCATION); layout->AddView(tracked_area, 1, eLeft, eFull); layout->Set2DTranslation(0, -123, 0); // x, y, z TrackerWindow *tracker_window = new TrackerWindow; tracker_window->SetBaseXY(0, 0); tracker_window->SetBaseWidth(100); tracker_window->SetBaseHeight(100); tracker_window->SetTrackChildMouseEvents(true); tracker_window->SetLayout(layout); tracker_window->ShowWindow(true); // Mouse pressed goes both to child and tracker window tracker_window->wants_mouse_ownership = false; tracked_area->mouse_down_emission_count = 0; nux::Event event; event.type = NUX_MOUSE_PRESSED; event.x = 50; // right in the center of tracker_window event.y = 50; wnd_compositor.ProcessEvent(event); ASSERT_EQ(1, tracker_window->child_mouse_events_received.size()); ASSERT_EQ(1, tracked_area->mouse_down_emission_count); // Mouse move goes both to child and tracker window, but tracker asks // for mouse ownership. Therefore child also gets a mouse cancel. tracker_window->child_mouse_events_received.clear(); tracker_window->wants_mouse_ownership = true; tracked_area->mouse_drag_emission_count = 0; tracked_area->mouse_cancel_emission_count = 0; event.type = NUX_MOUSE_MOVE; event.y = 60; wnd_compositor.ProcessEvent(event); ASSERT_EQ(1, tracker_window->child_mouse_events_received.size()); ASSERT_EQ(1, tracked_area->mouse_drag_emission_count); ASSERT_EQ(1, tracked_area->mouse_cancel_emission_count); // The second mouse move goes only to the window, but now as a regular // mouse event since he's mouse owner now. tracker_window->child_mouse_events_received.clear(); tracker_window->mouse_drag_emission_count = 0; tracked_area->mouse_drag_emission_count = 0; event.type = NUX_MOUSE_MOVE; event.y = 70; wnd_compositor.ProcessEvent(event); ASSERT_EQ(0, tracker_window->child_mouse_events_received.size()); ASSERT_EQ(1, tracker_window->mouse_drag_emission_count); ASSERT_EQ(0, tracked_area->mouse_drag_emission_count); ASSERT_EQ(10, tracker_window->mouse_drag_dy); // Mouse release goes only to the window, again as a regular // mouse event. tracker_window->child_mouse_events_received.clear(); tracker_window->mouse_up_emission_count = 0; tracked_area->mouse_up_emission_count = 0; event.type = NUX_MOUSE_RELEASED; wnd_compositor.ProcessEvent(event); ASSERT_EQ(0, tracker_window->child_mouse_events_received.size()); ASSERT_EQ(1, tracker_window->mouse_up_emission_count); ASSERT_EQ(0, tracked_area->mouse_up_emission_count); tracker_window->Dispose(); } #endif // NUX_GESTURES_SUPPORT } nux-4.0.6+14.04.20140409/tests/xtest-focus-on-mouse-enter.cpp0000644000015301777760000001121712321344237023744 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" class FocusOnMouseEnterTest: public ProgramTemplate { public: FocusOnMouseEnterTest(const char* program_name, int window_width, int window_height, int program_life_span); ~FocusOnMouseEnterTest(); virtual void UserInterfaceSetup(); nux::TestView* focus_view_; nux::TestView* no_focus_view_; }; FocusOnMouseEnterTest::FocusOnMouseEnterTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) , focus_view_(nullptr) , no_focus_view_(nullptr) { } FocusOnMouseEnterTest::~FocusOnMouseEnterTest() {} void FocusOnMouseEnterTest::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); main_layout->SetSpaceBetweenChildren(10); main_layout->SetPadding(10, 10); no_focus_view_ = new nux::TestView(NUX_TRACKER_LOCATION); no_focus_view_->can_focus_ = true; no_focus_view_->SetAcceptKeyNavFocusOnMouseEnter(false); main_layout->AddView(no_focus_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); focus_view_ = new nux::TestView(NUX_TRACKER_LOCATION); focus_view_->can_focus_ = true; focus_view_->SetAcceptKeyNavFocusOnMouseEnter(true); main_layout->AddView(focus_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } FocusOnMouseEnterTest* focus_on_mouse_enter_test = nullptr; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (focus_on_mouse_enter_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); test.TestReportMsg(focus_on_mouse_enter_test->focus_view_, "Focus view created"); test.TestReportMsg(focus_on_mouse_enter_test->no_focus_view_, "No focus view created"); // Move mouse to center of no_focus_view_ test.ViewSendMouseMotionToCenter(focus_on_mouse_enter_test->no_focus_view_); nux::SleepForMilliseconds(500); test.TestReportMsg(!focus_on_mouse_enter_test->no_focus_view_->has_focus_, "no_focus_view_ did not take the focus"); // Move mouse to center of focus_view_ test.ViewSendMouseMotionToCenter(focus_on_mouse_enter_test->focus_view_); nux::SleepForMilliseconds(500); test.TestReportMsg(focus_on_mouse_enter_test->focus_view_->has_focus_, "focus_view_ has the focus"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); focus_on_mouse_enter_test = new FocusOnMouseEnterTest("Focus On Mouse Enter Test", 300, 300, 15000); focus_on_mouse_enter_test->Startup(); focus_on_mouse_enter_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(focus_on_mouse_enter_test->GetWindowThread(), &TestingThread, focus_on_mouse_enter_test->GetWindowThread()); test_thread->Start(focus_on_mouse_enter_test); focus_on_mouse_enter_test->Run(); delete test_thread; delete focus_on_mouse_enter_test; return 0; } nux-4.0.6+14.04.20140409/tests/xtest-vlayout-key-navigation.cpp0000644000015301777760000001401212321344237024374 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" unsigned int const NUM_VIEWS = 5; unsigned int const ID_UNFOCUSABLE_VIEW = 1; // Please don't make this the last/first one :) class VLayoutKeyNavigationTest : public ProgramTemplate { public: VLayoutKeyNavigationTest(const char* program_name, int window_width, int window_height, int program_life_span); ~VLayoutKeyNavigationTest(); virtual void UserInterfaceSetup(); nux::TestView* CreateView(); void AddView(nux::TestView* view); nux::VLayout* vlayout_; nux::TestView* views_[NUM_VIEWS]; }; VLayoutKeyNavigationTest::VLayoutKeyNavigationTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { } VLayoutKeyNavigationTest::~VLayoutKeyNavigationTest() { } nux::TestView* VLayoutKeyNavigationTest::CreateView() { nux::TestView* view = new nux::TestView(); return view; } void VLayoutKeyNavigationTest::AddView(nux::TestView* view) { vlayout_->AddView(view, 1); } void VLayoutKeyNavigationTest::UserInterfaceSetup() { vlayout_ = new nux::VLayout(NUX_TRACKER_LOCATION); vlayout_->SetPadding(20, 20); vlayout_->SetSpaceBetweenChildren(10); for (unsigned int i=0; ican_focus_ = false; nux::GetWindowCompositor().SetKeyFocusArea(views_[0]); static_cast(window_thread_)->SetLayout(vlayout_); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } VLayoutKeyNavigationTest* key_navigation_test = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (key_navigation_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); test.TestReportMsg(key_navigation_test->vlayout_, "TestView created"); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Top left tile has key focus"); // Down key for (unsigned int i=0; iviews_[i]->has_focus_, "Down: key focus out"); if ((i + 1) == ID_UNFOCUSABLE_VIEW) { test.TestReportMsg(!key_navigation_test->views_[i+1]->has_focus_, "Down: key focus skipped"); test.TestReportMsg(key_navigation_test->views_[i+2]->has_focus_, "Down: key focus in"); ++i; } else { test.TestReportMsg(key_navigation_test->views_[i+1]->has_focus_, "Down: key focus in"); } } // Another down key, should do nothing test.SendFakeKeyEvent(XK_Down, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[NUM_VIEWS-1]->has_focus_, "Down key, last element"); // Up key for (int i=NUM_VIEWS-1; i>0; --i) { test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(!key_navigation_test->views_[i]->has_focus_, "Up: key focus out"); if ((i - 1) == (int)ID_UNFOCUSABLE_VIEW) { test.TestReportMsg(!key_navigation_test->views_[i-1]->has_focus_, "Up: key focus skipped"); test.TestReportMsg(key_navigation_test->views_[i-2]->has_focus_, "Up: key focus in"); --i; } else { test.TestReportMsg(key_navigation_test->views_[i-1]->has_focus_, "Up: key focus in"); } } // Another up key, should do nothing test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Up key, fist element"); // Keft key, should do nothing test.SendFakeKeyEvent(XK_Left, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Left key"); // Right key, should do nothing test.SendFakeKeyEvent(XK_Right, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Right key"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); key_navigation_test = new VLayoutKeyNavigationTest("Key navigation Test", 500, 400, 8000); key_navigation_test->Startup(); key_navigation_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(key_navigation_test->GetWindowThread(), &TestingThread, key_navigation_test->GetWindowThread()); test_thread->Start(key_navigation_test); key_navigation_test->Run(); delete test_thread; delete key_navigation_test; return 0; } nux-4.0.6+14.04.20140409/tests/xtest-focus-on-mouse-down.cpp0000644000015301777760000001303512321344237023576 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" class FocusOnMouseDownTest: public ProgramTemplate { public: FocusOnMouseDownTest(const char* program_name, int window_width, int window_height, int program_life_span); ~FocusOnMouseDownTest(); virtual void UserInterfaceSetup(); nux::TestView* focus_view_; nux::TestView* no_focus_view_; }; FocusOnMouseDownTest::FocusOnMouseDownTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) , focus_view_(nullptr) , no_focus_view_(nullptr) { } FocusOnMouseDownTest::~FocusOnMouseDownTest() { } void FocusOnMouseDownTest::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); main_layout->SetSpaceBetweenChildren(10); main_layout->SetPadding(10, 10); focus_view_ = new nux::TestView(NUX_TRACKER_LOCATION); focus_view_->can_focus_ = true; focus_view_->SetAcceptKeyNavFocusOnMouseDown(true); main_layout->AddView(focus_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); no_focus_view_ = new nux::TestView(NUX_TRACKER_LOCATION); no_focus_view_->can_focus_ = true; no_focus_view_->SetAcceptKeyNavFocusOnMouseDown(false); main_layout->AddView(no_focus_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } FocusOnMouseDownTest* focus_on_mouse_down_test = nullptr; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (focus_on_mouse_down_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); test.TestReportMsg(focus_on_mouse_down_test->focus_view_, "Focus view created"); test.TestReportMsg(focus_on_mouse_down_test->no_focus_view_, "No focus view created"); // Move mouse to center of focus_view test.ViewSendMouseMotionToCenter(focus_on_mouse_down_test->focus_view_); // Mouse down/up on focus_view_ test.ViewSendMouseClick(focus_on_mouse_down_test->focus_view_, 1); nux::SleepForMilliseconds(500); test.TestReportMsg(focus_on_mouse_down_test->focus_view_->has_focus_, "Mouse down: focus_view_ got the focus"); test.ViewSendMouseUp(focus_on_mouse_down_test->focus_view_, 1); nux::SleepForMilliseconds(500); test.TestReportMsg(focus_on_mouse_down_test->focus_view_->has_focus_, "Mouse up: focus is still on focus_view_"); // Move mouse to center of no_focus_view test.ViewSendMouseMotionToCenter(focus_on_mouse_down_test->no_focus_view_); // Mouse down/up on no_focus_view_ test.ViewSendMouseDown(focus_on_mouse_down_test->no_focus_view_, 1); nux::SleepForMilliseconds(500); test.TestReportMsg(!focus_on_mouse_down_test->no_focus_view_->has_focus_, "Mouse down: no_focus_view_ did not take the focus"); test.TestReportMsg(focus_on_mouse_down_test->focus_view_->has_focus_, "Mouse down: focus is still on focus_view_"); test.ViewSendMouseUp(focus_on_mouse_down_test->no_focus_view_, 1); nux::SleepForMilliseconds(500); test.TestReportMsg(!focus_on_mouse_down_test->no_focus_view_->has_focus_, "Mouse up: no_focus_view_ still doesn't have the focus"); test.TestReportMsg(focus_on_mouse_down_test->focus_view_->has_focus_, "Mouse up: focus is still on focus_view_"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); focus_on_mouse_down_test = new FocusOnMouseDownTest("Focus On Mouse Down Test", 300, 300, 15000); focus_on_mouse_down_test->Startup(); focus_on_mouse_down_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(focus_on_mouse_down_test->GetWindowThread(), &TestingThread, focus_on_mouse_down_test->GetWindowThread()); test_thread->Start(focus_on_mouse_down_test); focus_on_mouse_down_test->Run(); delete test_thread; delete focus_on_mouse_down_test; return 0; } nux-4.0.6+14.04.20140409/tests/test-canvas.cpp0000644000015301777760000000147612321344237021043 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller UnReference(); } nux-4.0.6+14.04.20140409/tests/xtest-mouse-events.cpp0000644000015301777760000001117112321344237022403 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/Layout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" class EventsTest: public ProgramTemplate { public: EventsTest(const char* program_name, int window_width, int window_height, int program_life_span); ~EventsTest(); virtual void UserInterfaceSetup(); void ResetEvents(); nux::TestView* test_view_; }; EventsTest::EventsTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { ResetEvents(); test_view_ = NULL; } EventsTest::~EventsTest() { } void EventsTest::ResetEvents() { if (test_view_) test_view_->ResetEvents(); } void EventsTest::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); test_view_ = new nux::TestView(NUX_TRACKER_LOCATION); main_layout->AddView(test_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->SetPadding(10, 10); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } EventsTest* event_test = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (event_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); test.TestReportMsg(event_test->test_view_, "TestView created"); event_test->ResetEvents(); test.ViewSendMouseMotionToCenter(event_test->test_view_); test.TestReportMsg(event_test->test_view_->registered_mouse_move_, "Mouse move event"); test.TestReportMsg(event_test->test_view_->registered_mouse_enter_, "Mouse enter event"); test.ViewSendMouseClick(0, 1); test.TestReportMsg(event_test->test_view_->registered_mouse_down_, "Mouse down event"); test.TestReportMsg(event_test->test_view_->registered_mouse_up_, "Mouse up event"); test.TestReportMsg(event_test->test_view_->registered_mouse_click_, "Mouse click event"); test.ViewSendMouseDrag(event_test->test_view_, 1, 0, 0, 50, 50); test.TestReportMsg(event_test->test_view_->registered_mouse_click_, "Mouse drag event"); test.ViewSendMouseMotionTo(event_test->test_view_, -5, -5); test.TestReportMsg(event_test->test_view_->registered_mouse_leave_, "Mouse leave event"); event_test->test_view_->EnableDoubleClick(true); test.ViewSendMouseDoubleClick(event_test->test_view_, 1); test.TestReportMsg(event_test->test_view_->registered_mouse_double_click_, "Mouse double click event"); event_test->ResetEvents(); // Deactivate double click and test if the view still receives it. event_test->test_view_->EnableDoubleClick(false); test.ViewSendMouseDoubleClick(event_test->test_view_, 1); test.TestReportMsg(!event_test->test_view_->registered_mouse_double_click_, "Mouse double click de-activated"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); event_test = new EventsTest("Events Test", 300, 300, 20000); event_test->Startup(); event_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(event_test->GetWindowThread(), &TestingThread, event_test->GetWindowThread()); test_thread->Start(event_test); event_test->Run(); delete test_thread; delete event_test; return 0; } nux-4.0.6+14.04.20140409/tests/test-scrollview.h0000644000015301777760000000252112321344237021416 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #ifndef TEST_SCROLLVIEW_H #define TEST_SCROLLVIEW_H #include "Nux/ScrollView.h" #include "Nux/VScrollBar.h" class TestScrollView: public nux::ScrollView { NUX_DECLARE_OBJECT_TYPE(TestView, ScrollView); public: TestScrollView(NUX_FILE_LINE_PROTO); ~TestScrollView(); nux::Color GetColor() const; void ResetEvents(); nux::VScrollBar* GetVScrollbar() {return _vscrollbar;} bool registered_scroll_; protected: void Draw(nux::GraphicsEngine &graphics_engine, bool force_draw); void OnScrolling(int hscroll, int vscroll); private: nux::Color normal_color_; nux::Color current_color_; }; #endif // TEST_VIEW_H nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-async-file-writer.cpp0000644000015301777760000000513612321344237024761 0ustar pbusernogroup00000000000000#include #include #include #include #include #include #include "NuxCore/AsyncFileWriter.h" #include "Helpers.h" namespace bf = boost::filesystem; using namespace testing; using namespace nux::testing; namespace { const std::string TEST_ROOT("/tmp/nux-test-cases"); class TestAsyncfileWriter : public ::testing::Test { protected: virtual void SetUp() { // Make sure that the tests start with and empty TEST_ROOT. bf::remove_all(TEST_ROOT); bf::create_directories(TEST_ROOT); } virtual void TearDown() { // Delete the unity test directory bf::remove_all(TEST_ROOT); } bool WaitForOpen(nux::AsyncFileWriter& writer, unsigned timeout = 5) { TestCallback opened; TestCallback timed_out; g_timeout_add_seconds(timeout, &TestCallback::glib_callback, &timed_out); writer.opened.connect(opened.sigc_callback()); while (!opened.happened && !timed_out.happened) { PumpGObjectMainLoop(); } return opened.happened; } bool WaitForClose(nux::AsyncFileWriter& writer, unsigned timeout = 5) { TestCallback closed; TestCallback timed_out; g_timeout_add_seconds(timeout, &TestCallback::glib_callback, &timed_out); writer.closed.connect(closed.sigc_callback()); while (!closed.happened && !timed_out.happened) { PumpGObjectMainLoop(); } return closed.happened; } }; TEST_F(TestAsyncfileWriter, TestConstructor) { std::string filename(TEST_ROOT + "/empty-file"); { nux::AsyncFileWriter writer(filename); bool opened = WaitForOpen(writer); EXPECT_TRUE(opened); } EXPECT_TRUE(bf::exists(filename)); EXPECT_THAT(ReadFile(filename), Eq("")); } TEST_F(TestAsyncfileWriter, TestWrites) { std::string filename(TEST_ROOT + "/write-file"); std::string data(200, 'x'); { nux::AsyncFileWriter writer(filename); writer.Write(data); writer.Close(); bool closed = WaitForClose(writer); EXPECT_TRUE(closed); } EXPECT_THAT(ReadFile(filename), Eq(data)); } TEST_F(TestAsyncfileWriter, TestWriteLots) { std::string filename(TEST_ROOT + "/lots-file"); std::string data(200, 'x'); const int loop_count = 1000; { nux::AsyncFileWriter writer(filename); for (int i = 0; i < loop_count; ++i) { writer.Write(data); } writer.Close(); bool closed = WaitForClose(writer); EXPECT_TRUE(closed); } std::string file_content = ReadFile(filename); EXPECT_THAT(file_content.size(), Eq(data.size() * loop_count)); // They are all x's. EXPECT_THAT(file_content, MatchesRegex("^x+$")); } } // anon namespace nux-4.0.6+14.04.20140409/tests/gtest-nux-input-area.cpp0000644000015301777760000000545712321344237022617 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Marco Trevisan */ #include #include #include "Nux/Nux.h" namespace { struct TestInputArea : public testing::Test { void SetUp() { nux::NuxInitialize(0); wnd_thread.reset(nux::CreateNuxWindow("InputArea Test", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL)); area = new nux::InputArea("InputArea"); } boost::shared_ptr wnd_thread; nux::ObjectPtr area; }; TEST_F(TestInputArea, GrabKeyboard) { area->GrabKeyboard(); EXPECT_TRUE(nux::GetWindowCompositor().IsInKeyboardGrabStack(area.GetPointer())); } TEST_F(TestInputArea, GrabPointer) { area->GrabPointer(); EXPECT_TRUE(nux::GetWindowCompositor().IsInPointerGrabStack(area.GetPointer())); } TEST_F(TestInputArea, UngrabsOnDestroy) { nux::InputArea* area1 = new nux::InputArea("InputArea1"); nux::InputArea* area2 = new nux::InputArea("InputArea2"); // Adding some grabs area1->GrabKeyboard(); area1->GrabPointer(); area2->GrabPointer(); area2->GrabKeyboard(); area1->GrabKeyboard(); ASSERT_TRUE(nux::GetWindowCompositor().IsInKeyboardGrabStack(area1)); ASSERT_TRUE(nux::GetWindowCompositor().IsInPointerGrabStack(area1)); ASSERT_TRUE(nux::GetWindowCompositor().IsInKeyboardGrabStack(area2)); ASSERT_TRUE(nux::GetWindowCompositor().IsInPointerGrabStack(area2)); // This should cleanup the references in the compositor area1->UnReference(); EXPECT_FALSE(nux::GetWindowCompositor().IsInKeyboardGrabStack(area1)); EXPECT_FALSE(nux::GetWindowCompositor().IsInPointerGrabStack(area1)); area2->UnReference(); EXPECT_FALSE(nux::GetWindowCompositor().IsInKeyboardGrabStack(area2)); EXPECT_FALSE(nux::GetWindowCompositor().IsInPointerGrabStack(area2)); } TEST_F(TestInputArea, IsTrackingChildMouseEvents) { ASSERT_FALSE(area->IsTrackingChildMouseEvents()); area->SetTrackChildMouseEvents(true); ASSERT_TRUE(area->IsTrackingChildMouseEvents()); area->SetTrackChildMouseEvents(false); ASSERT_FALSE(area->IsTrackingChildMouseEvents()); } } nux-4.0.6+14.04.20140409/tests/nux_automated_test_framework.cpp0000644000015301777760000004457512321344237024613 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include #include #include "nux_automated_test_framework.h" #define MAX_KEYS 4 // Max keys int NuxAutomatedTestFramework::mouse_motion_time_span = 1000; // milliseconds int NuxAutomatedTestFramework::mouse_click_time_span = 300; // milliseconds int NuxAutomatedTestFramework::minimum_sleep_time = 600; // milliseconds int NuxAutomatedTestFramework::safety_border_inside_view = 1; // pixels NuxAutomatedTestFramework::NuxAutomatedTestFramework(nux::WindowThread *window_thread) : ready_to_start_(false) , display_(NULL) , window_thread_(window_thread) , window_x_(0) , window_y_(0) , window_width_(0) , window_height_(0) , terminate_when_test_over_(false) , composition_keys_supported_(false) { } NuxAutomatedTestFramework::~NuxAutomatedTestFramework() { XCloseDisplay(display_); } void NuxAutomatedTestFramework::WarnCompositionKeysNotSupported() { nuxWarningMsg("Composition keys are not supported by your server, " "not running the composition keys tests"); } bool NuxAutomatedTestFramework::CompositionKeysSupported() { return composition_keys_supported_; } void NuxAutomatedTestFramework::SetTerminateProgramWhenDone(bool terminate) { terminate_when_test_over_ = terminate; } bool NuxAutomatedTestFramework::WhenDoneTerminateProgram() { return terminate_when_test_over_; } void NuxAutomatedTestFramework::Startup() { display_ = XOpenDisplay(NULL); nux::Geometry rect = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); //nuxDebugMsg("Window geometry: (%d, %d, %d, %d)", rect.x, rect.y, rect.width, rect.height); int min, max, per_keycode; // Get the min and max keycodes XDisplayKeycodes(display_, &min, &max); // Must be called with: // first_keycode: min, // keycode_count: max - min KeySym *syms = XGetKeyboardMapping(display_, min, max - min, &per_keycode); // Number of keysyms is (max - min) * keysyms_per_keycode for (int i = 0; i < (max - min) * per_keycode; ++i) { if (syms[i] == XK_Multi_key) composition_keys_supported_ = true; } XFree(syms); window_x_ = rect.x; window_y_ = rect.y; window_width_ = rect.width; window_height_ = rect.height; } void NuxAutomatedTestFramework::ViewSendMouseClick(nux::View *view, int button) { nux::Rect r; if (view) { r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2); } else { r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); r.OffsetPosition(r.width/2, r.height/2); } SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span); SendFakeMouseEvent(button, true); nux::SleepForMilliseconds(NuxAutomatedTestFramework::mouse_click_time_span); SendFakeMouseEvent(button, false); XSync(display_, False); nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time); } void NuxAutomatedTestFramework::ViewSendMouseDoubleClick(nux::View *view, int button) { nux::Rect r; if (view) { r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2); } else { r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); r.OffsetPosition(r.width/2, r.height/2); } // Send the mouse to the center of the view SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span); XTestFakeButtonEvent(display_, button, true, CurrentTime); XTestFakeButtonEvent(display_, button, false, CurrentTime); XTestFakeButtonEvent(display_, button, true, CurrentTime); XTestFakeButtonEvent(display_, button, false, CurrentTime); XSync(display_, False); nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time); } void NuxAutomatedTestFramework::ViewSendMouseDown(nux::View *view, int button) { XEvent event; /* Get the current pointer position */ XQueryPointer(display_, RootWindow(display_, 0), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state); int current_x = event.xbutton.x - window_x_; int current_y = event.xbutton.y - window_y_; nux::Rect r = view->GetAbsoluteGeometry(); if (!r.IsInside(nux::Point(current_x, current_y))) { // The mouse pointer is not inside the view. // Move the mouse pointer to the center of the view. r.OffsetPosition(window_x_, window_y_); // Go to the center of the view int view_center_x = r.x + r.width/2; int view_center_y = r.y + r.height/2; SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span); nux::SleepForMilliseconds(minimum_sleep_time); } SendFakeMouseEvent(button, true); } void NuxAutomatedTestFramework::ViewSendMouseUp(nux::View * /* view */, int button) { // nux::Rect r = view->GetAbsoluteGeometry(); // r.OffsetPosition(window_x_, window_y_); // int view_center_x = r.x + r.width/2; // int view_center_y = r.y + r.height/2; // SendFakeMouseMotionEvent(view_center_x, view_center_y, 1000); // nux::SleepForMilliseconds(minimum_sleep_time); SendFakeMouseEvent(button, false); } void NuxAutomatedTestFramework::ViewSendMouseDrag(nux::View *view, int button_index, int x0, int y0, int x1, int y1) { nux::Rect r0 = view->GetAbsoluteGeometry(); nux::Rect r1 = view->GetAbsoluteGeometry(); r0.OffsetPosition(window_x_ + x0, window_y_ + y0); r1.OffsetPosition(window_x_ + x1, window_y_ + y1); // Go to first point SendFakeMouseMotionEvent(r0.x, r0.y, NuxAutomatedTestFramework::mouse_motion_time_span); nux::SleepForMilliseconds(minimum_sleep_time); // Mouse down ViewSendMouseDown(view, button_index); // Drag to second point SendFakeMouseMotionEvent(r1.x, r1.y, NuxAutomatedTestFramework::mouse_motion_time_span); nux::SleepForMilliseconds(minimum_sleep_time); // Mouse up ViewSendMouseUp(view, button_index); } void NuxAutomatedTestFramework::ViewSendMouseMotionTo(nux::View *view, int x, int y) { nux::Rect r; if (view) { r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_ + x, window_y_ + y); } else { r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); r.OffsetPosition(x, y); } SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span); } void NuxAutomatedTestFramework::ViewSendMouseMotionToCenter(nux::View *view) { nux::Rect r; if (view) { r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_, window_y_); } else { r = window_thread_->GetGraphicsDisplay().GetWindowGeometry(); } int view_center_x = r.x + r.width/2; int view_center_y = r.y + r.height/2; SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span); } void NuxAutomatedTestFramework::ViewSendMouseMotionToTopLeft(nux::View *view) { nux::Rect r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_, window_y_); SendFakeMouseMotionEvent(r.x + safety_border_inside_view, r.y + safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span); } void NuxAutomatedTestFramework::ViewSendMouseMotionToTopRight(nux::View *view) { nux::Rect r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_, window_y_); SendFakeMouseMotionEvent(r.x + r.width-1, r.y+safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span); } void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomLeft(nux::View *view) { nux::Rect r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_, window_y_); SendFakeMouseMotionEvent(r.x+safety_border_inside_view, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span); } void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomRight(nux::View *view) { nux::Rect r = view->GetAbsoluteGeometry(); r.OffsetPosition(window_x_, window_y_); SendFakeMouseMotionEvent(r.x + r.width-1, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span); } void NuxAutomatedTestFramework::ViewSendChar(const char c) { KeySym modifier = 0; if ((c >= 'A') && (c <= 'Z')) { modifier = XK_Shift_L; } std::string s(1, c); if (c == ' ') { SendFakeKeyEvent(XK_space, modifier); } else { SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier); } nux::SleepForMilliseconds(300); } void NuxAutomatedTestFramework::ViewSendString(const std::string &str) { int l = str.length(); if (l == 0) return; int i = 0; while (i < l) { KeySym modifier = 0; char c = str[i++]; if ((c >= 'A') && (c <= 'Z')) { modifier = XK_Shift_L; } std::string s(1, c); if (c == ' ') { SendFakeKeyEvent(XK_space, modifier); } else if (c == '^') { SendFakeKeyEvent(XK_asciicircum, XK_Shift_L); } else if (c == '~') { SendFakeKeyEvent(XK_asciitilde, XK_Shift_L); } else if (c == '`') { SendFakeKeyEvent(XK_asciitilde, 0); } else if (c == '=') { SendFakeKeyEvent(XK_equal, 0); } else if (c == '\"') { SendFakeKeyEvent(XK_quotedbl, XK_Shift_L); } else if (c == '!') { SendFakeKeyEvent(XK_exclam, XK_Shift_L); } else if (c == '|') { SendFakeKeyEvent(XK_bar, XK_Shift_L); } else if (c == '/') { SendFakeKeyEvent(XK_slash, 0); } else if (c == '\\') { SendFakeKeyEvent(XK_backslash, 0); } else if (c == '-') { SendFakeKeyEvent(XK_minus, 0); } else if (c == '+') { SendFakeKeyEvent(XK_plus, XK_Shift_L); } else if (c == ',') { SendFakeKeyEvent(XK_comma, 0); } else if (c == '_') { SendFakeKeyEvent(XK_underscore, XK_Shift_L); } else if (c == '<') { SendFakeKeyEvent(XK_comma, XK_Shift_L); } else if (c == '>') { SendFakeKeyEvent(XK_greater, XK_Shift_L); } else if (c == '.') { SendFakeKeyEvent(XK_period, 0); } else if (c == '?') { SendFakeKeyEvent(XK_question, XK_Shift_L); } else if (c == '\'') { SendFakeKeyEvent(XK_quoteright, 0); } else if (c == ';') { SendFakeKeyEvent(XK_semicolon, 0); } else if (c == ':') { SendFakeKeyEvent(XK_colon, XK_Shift_L); } else if (c == '%') { SendFakeKeyEvent(XK_percent, XK_Shift_L); } else if (c == '(') { SendFakeKeyEvent(XK_parenleft, XK_Shift_L); } else if (c == ')') { SendFakeKeyEvent(XK_parenright, XK_Shift_L); } else { SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier); } nux::SleepForMilliseconds(300); } XFlush(display_); } void NuxAutomatedTestFramework::ViewSendCompositionKeys(const std::string& str) { int l = str.length(); if (l == 0) return; SendFakeKeyEvent(XK_Multi_key, 0); ViewSendString(str); } // Send strings in the format of "key+key+key" up to 4 where the last key is not a modifier // example "ctrl+alt+= void NuxAutomatedTestFramework::ViewSendKeys(const std::string& str) { std::string keys[MAX_KEYS]; KeySym keys_sym[MAX_KEYS] = {0}; size_t f_ptr = 0, s_ptr = 0; int i = 0; //Split up keys on the + while (s_ptr != std::string::npos && i < MAX_KEYS) { s_ptr = str.find("+", f_ptr); keys[i] = str.substr(f_ptr, (s_ptr-f_ptr)); f_ptr = s_ptr+1; i++; } // Find what the key_sym should be for each key for (int i = 0; i < MAX_KEYS; i++) { if (keys[i].empty()) { break; } else if (keys[i] == "ctrl") { keys_sym[i] = XK_Control_L; } else if (keys[i] == "alt") { keys_sym[i] = XK_Alt_L; } else if (keys[i] == "space") { keys_sym[i] = XK_space; } else if (keys[i] == "enter" || keys[i] == "return") { keys_sym[i] = XK_Return; } else if (keys[i] == "=") { keys_sym[i] = XK_equal; } else if (keys[i] == "[") { keys_sym[i] = XK_bracketleft; } else if (keys[i] =="shift") { keys_sym[i] = XK_Shift_L; } else { // If nothing is found try and find it... if (!(keys_sym[i] = XStringToKeysym(keys[i].c_str()))) printf("Undefinded Key: %s (Add it to this list)\n", keys[i].c_str()); } } XTestGrabControl(display_, True); KeyCode modcode[MAX_KEYS] = {0}; // Press the keys from 0,1,2,3 for (int i = 0; i < MAX_KEYS; i++) { if (keys_sym[i] != 0) { modcode[i] = XKeysymToKeycode(display_, keys_sym[i]); XTestFakeKeyEvent(display_, modcode[i], True, 0); } } // Release the keys from 3,2,1,0 for (int i = MAX_KEYS-1; i >= 0; i--) { if (keys_sym[i] != 0) { XTestFakeKeyEvent(display_, modcode[i], False, 0); } } XTestGrabControl(display_, False); XFlush(display_); } void NuxAutomatedTestFramework::ViewSendKeyCombo(KeySym modsym0, KeySym modsym1, KeySym modsym2, const char c) { KeyCode keycode = 0; KeyCode modcode0 = 0; KeyCode modcode1 = 0; KeyCode modcode2 = 0; if (c != 0) { printf("ViewSendKeyCombo"); std::string s(1, c); keycode = XKeysymToKeycode(display_, XStringToKeysym(s.c_str())); } XTestGrabControl(display_, True); /* Generate modkey press */ if (modsym0 != 0) { modcode0 = XKeysymToKeycode(display_, modsym0); XTestFakeKeyEvent(display_, modcode0, True, 0); } if (modsym1 != 0) { modcode1 = XKeysymToKeycode(display_, modsym1); XTestFakeKeyEvent(display_, modcode1, True, 0); } if (modsym2 != 0) { modcode2 = XKeysymToKeycode(display_, modsym2); XTestFakeKeyEvent(display_, modcode2, True, 0); } /* Generate regular key press and release */ if (keycode) { XTestFakeKeyEvent(display_, keycode, True, 0); XTestFakeKeyEvent(display_, keycode, False, 0); } /* Generate modkey release */ if (modsym0 != 0) { XTestFakeKeyEvent(display_, modcode0, False, 0); } if (modsym1 != 0) { XTestFakeKeyEvent(display_, modcode1, False, 0); } if (modsym2 != 0) { XTestFakeKeyEvent(display_, modcode2, False, 0); } XSync(display_, False); XTestGrabControl(display_, False); } void NuxAutomatedTestFramework::ViewSendCtrlA() { ViewSendKeyCombo(XK_Control_L, 0, 0, 'a'); } void NuxAutomatedTestFramework::ViewSendDelete() { SendFakeKeyEvent(XK_Delete, 0); } void NuxAutomatedTestFramework::ViewSendBackspace() { SendFakeKeyEvent(XK_BackSpace, 0); } void NuxAutomatedTestFramework::ViewSendEscape() { SendFakeKeyEvent(XK_Escape, 0); } void NuxAutomatedTestFramework::ViewSendTab() { SendFakeKeyEvent(XK_Tab, 0); } void NuxAutomatedTestFramework::ViewSendReturn() { SendFakeKeyEvent(XK_Return, 0); } void NuxAutomatedTestFramework::ViewSendRight() { SendFakeKeyEvent(XK_Right, 0); } void NuxAutomatedTestFramework::ViewSendLeft() { SendFakeKeyEvent(XK_Left, 0); } void NuxAutomatedTestFramework::ViewSendUp() { SendFakeKeyEvent(XK_Up, 0); } void NuxAutomatedTestFramework::ViewSendDown() { SendFakeKeyEvent(XK_Down, 0); } void NuxAutomatedTestFramework::ViewSendIBusToggle() { KeyCode modcode0 = 0; KeyCode modcode1 = 0; modcode0 = XKeysymToKeycode(display_, XK_Control_L); XTestFakeKeyEvent(display_, modcode0, True, 0); modcode1 = XKeysymToKeycode(display_, XK_space); XTestFakeKeyEvent(display_, modcode1, True, 0); // release /* Generate modkey release */ XTestFakeKeyEvent(display_, modcode1, False, 0); XTestFakeKeyEvent(display_, modcode0, False, 0); XFlush(display_); } void NuxAutomatedTestFramework::PutMouseAt(int x, int y) { XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime); XSync(display_, False); } void NuxAutomatedTestFramework::SendFakeKeyEvent(KeySym keysym, KeySym modsym) { KeyCode keycode = 0; KeyCode modcode = 0; keycode = XKeysymToKeycode(display_, keysym); XTestGrabControl(display_, True); /* Generate modkey press */ if (modsym != 0) { modcode = XKeysymToKeycode(display_, modsym); XTestFakeKeyEvent(display_, modcode, True, 0); } /* Generate regular key press and release */ XTestFakeKeyEvent(display_, keycode, True, 0); XTestFakeKeyEvent(display_, keycode, False, 0); /* Generate modkey release */ if (modsym != 0) { XTestFakeKeyEvent(display_, modcode, False, 0); } XSync(display_, False); XTestGrabControl(display_, False); } void NuxAutomatedTestFramework::SendFakeMouseEvent(int mouse_button_index, bool pressed) { XTestFakeButtonEvent(display_, mouse_button_index, pressed, CurrentTime); XSync(display_, False); } void NuxAutomatedTestFramework::SendFakeMouseMotionEvent(int x, int y, int ms_delay) { XEvent event; /* Get the current pointer position */ XQueryPointer(display_, RootWindow(display_, 0), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state); int old_x = event.xbutton.x; int old_y = event.xbutton.y; int n_iteration = ms_delay / 16.0f; //nuxDebugMsg("n_iteration: %d", n_iteration); if (n_iteration < 1) { n_iteration = 1; } XSync(display_, False); for (int i = 0; i < n_iteration; i++) { float t = ((float)i + 1.0f) / n_iteration; int cx = (1.0f - t) * old_x + t * x; int cy = (1.0f - t) * old_y + t * y; XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), cx, cy, CurrentTime); XSync(display_, False); usleep(16*1000); } XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime); XSync(display_, False); nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time); } void NuxAutomatedTestFramework::TestReportMsg(bool b, const char* msg) { if (b) { nuxOkMsg("%s: %s", msg, "Ok"); } else { nuxAlertMsg("%s: %s", msg, "Failed"); } } nux-4.0.6+14.04.20140409/tests/Makefile.am0000644000015301777760000002704512321344237020143 0ustar pbusernogroup00000000000000if BUILD_TESTS nodist_libgtest_a_SOURCES = \ $(GMOCK_PREFIX)/src/gmock-all.cc \ $(GTEST_PREFIX)/src/gtest-all.cc libgtest_a_CPPFLAGS = $(GMOCK_CPPFLAGS) $(GTEST_CPPFLAGS) -w check_LIBRARIES = libgtest.a check_PROGRAMS = \ gtest-nux \ gtest-nux-slow \ gtest-nuxcore \ gtest-nuxgraphics \ test-graphics-display \ test-empty-window \ xtest-button \ xtest-mouse-events \ xtest-mouse-buttons \ xtest-hgrid-key-navigation \ xtest-hlayout-key-navigation \ xtest-vlayout-key-navigation \ xtest-scrollbar \ xtest-focus-on-mouse-down \ xtest-keynav-directions \ xtest-text-entry \ xtest-text-entry-deadkeys \ xtest-text-entry-compositionkeys \ xtest-text-entry-logic \ xtest-text-entry-xim \ xtest-focus-on-mouse-enter ##### gtest-nuxcore ###### gtest_nuxcore_SOURCES = \ Helpers.h \ Helpers.cpp \ $(top_builddir)/NuxCore/ColorPrivate.cpp \ $(top_builddir)/NuxCore/ColorPrivate.h \ gtest-nuxcore-animation.cpp \ gtest-nuxcore-async-file-writer.cpp \ gtest-nuxcore-color.cpp \ gtest-nuxcore-colorprivate.cpp \ gtest-nuxcore-logger.cpp \ gtest-nuxcore-main.cpp \ gtest-nuxcore-object.cpp \ gtest-nuxcore-properties.cpp \ gtest-nuxcore-rolling-file-appender.cpp gtest_nuxcore_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxTests\" \ -DTESTDIR=\""$(top_srcdir)/tests"\" \ $(GCC_TESTS_FLAGS) \ $(GMOCK_CPPFLAGS) \ $(GTEST_CPPFLAGS) \ $(NUX_CORE_CFLAGS) \ $(NUX_EXAMPLES_CFLAGS) \ $(NUX_CFLAGS) \ $(MAINTAINER_CFLAGS) gtest_nuxcore_LDADD = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(NUX_LIBS) \ libgtest.a gtest_nuxcore_LDFLAGS = -lboost_system \ -lboost_filesystem ##### gtest-nux ###### gtest_nux_SOURCES = \ FakeGestureEvent.h \ gtest-nux-axisdecelerationanimation.cpp \ gtest-nux-emmetrics.cpp \ gtest-nux-globals.cpp \ gtest-nux-globals.h \ gtest-nux-kineticscroller.cpp \ gtest-nux-inputmethodibus.cpp \ gtest-nux-velocitycalculator.cpp \ gtest-nux-main.cpp if HAVE_GEIS gtest_nux_SOURCES += \ geis_mock.h \ geis_mock.cpp \ gtest-nux-geisadapter.cpp \ gtest-nux-gesturebroker.cpp endif gtest_nux_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxTests\" \ -DTESTDIR=\""$(top_srcdir)/tests"\" \ $(GCC_TESTS_FLAGS) \ $(GMOCK_CPPFLAGS) \ $(GTEST_CPPFLAGS) \ $(NUX_CORE_CFLAGS) \ $(NUX_EXAMPLES_CFLAGS) \ $(NUX_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(IBUS_CFLAGS) \ $(GEIS_CFLAGS) gtest_nux_LDADD = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(top_builddir)/NuxGraphics/libnux-graphics-@NUX_API_VERSION@.la \ $(top_builddir)/Nux/libnux-@NUX_API_VERSION@.la \ $(NUX_LIBS) \ libgtest.a ##### gtest-nux-slow ###### gtest_nux_slow_SOURCES = \ gtest-nux-area.cpp \ gtest-nux-cairo-wrapper.cpp \ gtest-nux-input-area.cpp \ gtest-nux-main.cpp \ gtest-nux-inputarea-proximity.cpp \ gtest-nux-statictext.cpp \ gtest-nux-scrollview.cpp \ gtest-nux-textentry.cpp \ gtest-nux-utils.h \ gtest-nux-view.cpp \ gtest-nux-windowcompositor.cpp \ gtest-nux-windowthread.cpp gtest_nux_slow_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxTests\" \ -DTESTDIR=\""$(top_srcdir)/tests"\" \ $(GCC_TESTS_FLAGS) \ $(GMOCK_CPPFLAGS) \ $(GTEST_CPPFLAGS) \ $(NUX_CORE_CFLAGS) \ $(NUX_EXAMPLES_CFLAGS) \ $(NUX_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(IBUS_CFLAGS) \ $(GEIS_CFLAGS) gtest_nux_slow_LDADD = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(top_builddir)/NuxGraphics/libnux-graphics-@NUX_API_VERSION@.la \ $(top_builddir)/Nux/libnux-@NUX_API_VERSION@.la \ $(NUX_LIBS) \ libgtest.a gtest_nux_slow_LDFLAGS = -lboost_system \ -lboost_filesystem ##### gtest-nuxgraphics ###### gtest_nuxgraphics_SOURCES = \ gtest-nuxgraphics-main.cpp \ gtest-nuxgraphics-texture.cpp \ gtest-nuxgraphics-graphic-display.cpp gtest_nuxgraphics_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxTests\" \ -DTESTDIR=\""$(top_srcdir)/tests"\" \ $(GCC_TESTS_FLAGS) \ $(GMOCK_CPPFLAGS) \ $(GTEST_CPPFLAGS) \ $(NUX_CORE_CFLAGS) \ $(NUX_EXAMPLES_CFLAGS) \ $(NUX_CFLAGS) \ $(MAINTAINER_CFLAGS) gtest_nuxgraphics_LDADD = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(top_builddir)/NuxGraphics/libnux-graphics-@NUX_API_VERSION@.la \ $(top_builddir)/Nux/libnux-@NUX_API_VERSION@.la \ $(NUX_LIBS) \ libgtest.a TestFlags = -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxTests\" \ -DTESTDIR=\""$(top_srcdir)/tests"\" \ $(GCC_TESTS_FLAGS) \ $(NUX_CORE_CFLAGS) \ $(NUX_EXAMPLES_CFLAGS) \ $(NUX_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(IBUS_CFLAGS) \ $(GEIS_CFLAGS) TestLibs = $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(top_builddir)/NuxGraphics/libnux-graphics-@NUX_API_VERSION@.la \ $(top_builddir)/Nux/libnux-@NUX_API_VERSION@.la \ $(NUX_LIBS) test_graphics_display_SOURCES = test_graphics_display.cpp test_graphics_display_CPPFLAGS = $(TestFlags) test_graphics_display_LDADD = $(TestLibs) test_graphics_display_LDFLAGS = -lpthread test_empty_window_SOURCES = test_empty_window.cpp test_empty_window_CPPFLAGS = $(TestFlags) test_empty_window_LDADD = $(TestLibs) test_empty_window_LDFLAGS = -lpthread xtest_button_SOURCES = xtest-button.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_button_CPPFLAGS = $(TestFlags) xtest_button_LDADD = $(TestLibs) xtest_button_LDFLAGS = -lpthread -lXtst xtest_mouse_events_SOURCES = xtest-mouse-events.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_mouse_events_CPPFLAGS = $(TestFlags) xtest_mouse_events_LDADD = $(TestLibs) xtest_mouse_events_LDFLAGS = -lpthread -lXtst xtest_mouse_buttons_SOURCES = xtest-mouse-buttons.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_mouse_buttons_CPPFLAGS = $(TestFlags) xtest_mouse_buttons_LDADD = $(TestLibs) xtest_mouse_buttons_LDFLAGS = -lpthread -lXtst xtest_hgrid_key_navigation_SOURCES = xtest-hgrid-key-navigation.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_hgrid_key_navigation_CPPFLAGS = $(TestFlags) xtest_hgrid_key_navigation_LDADD = $(TestLibs) xtest_hgrid_key_navigation_LDFLAGS = -lpthread -lXtst xtest_hlayout_key_navigation_SOURCES = xtest-hlayout-key-navigation.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_hlayout_key_navigation_CPPFLAGS = $(TestFlags) xtest_hlayout_key_navigation_LDADD = $(TestLibs) xtest_hlayout_key_navigation_LDFLAGS = -lpthread -lXtst xtest_vlayout_key_navigation_SOURCES = xtest-vlayout-key-navigation.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_vlayout_key_navigation_CPPFLAGS = $(TestFlags) xtest_vlayout_key_navigation_LDADD = $(TestLibs) xtest_vlayout_key_navigation_LDFLAGS = -lpthread -lXtst xtest_focus_on_mouse_down_SOURCES = xtest-focus-on-mouse-down.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_focus_on_mouse_down_CPPFLAGS = $(TestFlags) xtest_focus_on_mouse_down_LDADD = $(TestLibs) xtest_focus_on_mouse_down_LDFLAGS = -lpthread -lXtst xtest_focus_on_mouse_enter_SOURCES = xtest-focus-on-mouse-enter.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_focus_on_mouse_enter_CPPFLAGS = $(TestFlags) xtest_focus_on_mouse_enter_LDADD = $(TestLibs) xtest_focus_on_mouse_enter_LDFLAGS = -lpthread -lXtst xtest_scrollbar_SOURCES = xtest-scrollbar.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h \ test-scrollview.cpp \ test-scrollview.h xtest_scrollbar_CPPFLAGS = $(TestFlags) xtest_scrollbar_LDADD = $(TestLibs) xtest_scrollbar_LDFLAGS = -lpthread -lXtst xtest_keynav_directions_SOURCES = xtest-keynav-directions.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_keynav_directions_CPPFLAGS = $(TestFlags) xtest_keynav_directions_LDADD = $(TestLibs) xtest_keynav_directions_LDFLAGS = -lpthread -lXtst xtest_text_entry_SOURCES = xtest-text-entry.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_text_entry_CPPFLAGS = $(TestFlags) xtest_text_entry_LDADD = $(TestLibs) xtest_text_entry_LDFLAGS = -lpthread -lXtst -libus-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 xtest_text_entry_logic_SOURCES = xtest-text-entry-logic.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_text_entry_logic_CPPFLAGS = $(TestFlags) xtest_text_entry_logic_LDADD = $(TestLibs) xtest_text_entry_logic_LDFLAGS = -lpthread -lXtst xtest_text_entry_deadkeys_SOURCES = xtest-text-entry-deadkeys.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_text_entry_deadkeys_CPPFLAGS = $(TestFlags) xtest_text_entry_deadkeys_LDADD = $(TestLibs) xtest_text_entry_deadkeys_LDFLAGS = -lpthread -lXtst xtest_text_entry_compositionkeys_SOURCES = xtest-text-entry-compositionkeys.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_text_entry_compositionkeys_CPPFLAGS = $(TestFlags) xtest_text_entry_compositionkeys_LDADD = $(TestLibs) xtest_text_entry_compositionkeys_LDFLAGS = -lpthread -lXtst xtest_text_entry_xim_SOURCES = xtest-text-entry-xim.cpp \ nux_automated_test_framework.cpp \ nux_automated_test_framework.h xtest_text_entry_xim_CPPFLAGS = $(TestFlags) xtest_text_entry_xim_LDADD = $(TestLibs) xtest_text_entry_xim_LDFLAGS = -lpthread -lXtst #run make test as part of make check check-local: test gtest test-apps test: @gtester --verbose -k -o=gtest-nux-results.xml ./gtest-nux gtest: gtest-nuxcore gtest-nuxgraphics gtest-nux ./gtest-nuxcore ./gtest-nuxgraphics ./gtest-nux check-headless: gtest-nuxcore @gtester --verbose -k -o=test-nux-results.xml ./gtest-nuxcore test-apps: test-graphics-display test-empty-window xtest-text-entry-xim xtest-text-entry xtest-button xtest-mouse-events xtest-mouse-buttons xtest-hgrid-key-navigation xtest-hlayout-key-navigation xtest-vlayout-key-navigation xtest-scrollbar xtest-focus-on-mouse-down xtest-focus-on-mouse-enter xtest-keynav-directions xtest-text-entry-logic xtest-text-entry-deadkeys xtest-text-entry-compositionkeys ./test-graphics-display ./test-empty-window ./xtest-text-entry ./xtest-button ./xtest-mouse-events ./xtest-mouse-buttons ./xtest-hgrid-key-navigation ./xtest-hlayout-key-navigation ./xtest-vlayout-key-navigation ./xtest-scrollbar ./xtest-focus-on-mouse-down ./xtest-focus-on-mouse-enter ./xtest-keynav-directions ./xtest-text-entry-logic ./xtest-text-entry-deadkeys ./xtest-text-entry-compositionkeys check-report: @gtester -k -o=test-nux-results.xml -k ./test-nux \ && ( gtester-report test-nux-results.xml \ | sed 's/GTester Unit Test ReportGTester Unit Test Report (normal) test-nux-results.html ) \ && gnome-open ./test-nux-results.html full-report: @gtester -k -o=test-nux-results.xml -k -m=slow ./test-nux \ && ( gtester-report test-nux-results.xml \ | sed 's/>GTester Unit Test ReportGTester Unit Test Report (normal) test-nux-results.html ) CLEANFILES = \ test-nux-results.xml test-nux-results.html \ gtest-nux-results.xml .PHONY: check check-report full-report gtest test check-headless endif nux-4.0.6+14.04.20140409/tests/xtest-text-entry.cpp0000644000015301777760000003462312321344237022103 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/TextEntry.h" #include "Nux/InputMethodIBus.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" namespace { std::string RESET_KEY_FOCUS_AREA_MSG = "r"; std::string KEY_FOCUS_AREA_RESET_MSG = "d"; } class TextTextEntry: public ProgramTemplate { public: TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span); ~TextTextEntry(); virtual void UserInterfaceSetup(); void TextEntryClick(nux::TextEntry* text_entry); void OnActivated(); void OnCursorMoved(int); void ResetEvents(); void SendResetKeyFocusAreaMessageToProgram(); nux::TextEntry* text_entry_; bool clicked_; bool activated_; bool cursor_moved_; private: /* Handled inside the TextEntry WindowThread */ void HandleProgramMessage(const std::string &); }; TextTextEntry::TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) , clicked_(false) , activated_(false) , cursor_moved_(false) { ResetEvents(); text_entry_ = NULL; } TextTextEntry::~TextTextEntry() { } void TextTextEntry::ResetEvents() { clicked_ = false; activated_ = false; cursor_moved_ = false; } void TextTextEntry::SendResetKeyFocusAreaMessageToProgram() { SendMessageToProgram(RESET_KEY_FOCUS_AREA_MSG); WaitForMessageFromProgram(KEY_FOCUS_AREA_RESET_MSG); } void TextTextEntry::HandleProgramMessage(const std::string &m) { if (m == RESET_KEY_FOCUS_AREA_MSG) { GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(NULL); GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(text_entry_); SendMessageToTest(KEY_FOCUS_AREA_RESET_MSG); } } void TextTextEntry::TextEntryClick(nux::TextEntry* text_entry) { if (text_entry_ == text_entry) { clicked_ = true; } } void TextTextEntry::OnActivated() { activated_ = true; } void TextTextEntry::OnCursorMoved(int /* position */) { cursor_moved_ = true; } void TextTextEntry::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); text_entry_ = new nux::TextEntry("", NUX_TRACKER_LOCATION); text_entry_->activated.connect(sigc::mem_fun(this, &TextTextEntry::OnActivated)); text_entry_->cursor_moved.connect(sigc::mem_fun(this, &TextTextEntry::OnCursorMoved)); text_entry_->SetFontSize(76); main_layout->AddView(text_entry_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->SetSpaceBetweenChildren(10); main_layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } bool SetEngineActive (IBusBus* bus_, std::string engine) { GList* engines = ibus_bus_list_active_engines(bus_); if (!engines) return false; GList* start = engines; bool found = false; gboolean global_flag = ibus_bus_get_use_global_engine(bus_); // Iterates through the active engines do { IBusEngineDesc *engine_desc = IBUS_ENGINE_DESC (engines->data); // Found Engine, make it active! if (engine == ibus_engine_desc_get_name(engine_desc)) { found = true; // Set ibus to use global engines if (!global_flag) ibus_config_set_value(ibus_bus_get_config(bus_), "general", "use_global_engine", g_variant_new_boolean(true)); // Set and activate the engine ibus_bus_set_global_engine(bus_, engine.c_str()); } } while ((engines = g_list_next(engines)) != NULL); // Restores the global setting back to what it was ibus_config_set_value(ibus_bus_get_config(bus_), "general", "use_global_engine", g_variant_new_boolean(global_flag)); g_list_free(start); return found; } TextTextEntry* test_textentry = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (test_textentry->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1300); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); test.TestReportMsg(test_textentry->text_entry_, "TextEntry created"); test_textentry->ResetEvents(); test.ViewSendMouseMotionToCenter(test_textentry->text_entry_); test.ViewSendMouseClick(0, 1); // Type "Nux" // The cursor is at the end of the line // Unset/Set the focus on the text entry // Move the cursor { test.ViewSendString("Nux"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Nux", "Typed \"Nux\""); test_textentry->SendResetKeyFocusAreaMessageToProgram(); test_textentry->ResetEvents(); test.ViewSendLeft(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->cursor_moved_, "Cursor moved."); test.ViewSendCtrlA(); test.ViewSendDelete(); } // Type "Nux" // The cursor is at the end of the line // Unset/Set the focus on the text entry // Press enter { test.ViewSendString("Nux"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Nux", "Typed \"Nux\""); test_textentry->SendResetKeyFocusAreaMessageToProgram(); test_textentry->ResetEvents(); test.ViewSendReturn(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->activated_, "Activated."); test.ViewSendCtrlA(); test.ViewSendDelete(); } // Type "Nux" // The cursor is at the end of the line // Simulate CTRL+A to select the entire text // Simulate DELETE key to delete the text { test.ViewSendString("Nux"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Nux", "Typed \"Nux\""); test.ViewSendCtrlA(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetTextSelection() == "Nux", "Selection is \"Nux\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is empty"); } // Type "0123456789" // The cursor is at the end of the line // Simulate BACKSPACE key until the text is enpty { test.ViewSendString("Ubuntu"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ubuntu", "Typed \"Ubuntu\""); test.ViewSendBackspace(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ubunt", "Text is \"Ubunt\""); test.ViewSendBackspace(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ubun", "Text is \"Ubun\""); test.ViewSendBackspace(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ubu", "Text is \"Ubu\""); test.ViewSendBackspace(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ub", "Text is \"Ub\""); test.ViewSendBackspace(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "U", "Text is \"U\""); test.ViewSendBackspace(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is empty"); } // Type "0123456789" // Move cursor to start of line // Simulate DELETE key until the text is 6789 // Simulate CTRL+A to select the entire text // Simulate DELETE key to delete the text { test.ViewSendString("0123456789"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "0123456789", "Typed \"0123456789\""); test_textentry->text_entry_->MoveCursorToLineStart(); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "123456789", "Text is \"123456789\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "23456789", "Text is \"23456789\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "3456789", "Text is \"3456789\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "456789", "Text is \"456789\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "56789", "Text is \"56789\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "6789", "Text \"6789\""); test.ViewSendCtrlA(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetTextSelection() == "6789", "Selection is \"6789\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is empty"); } // Send invalid keys { test.ViewSendKeyCombo(XK_Control_L, 0, 0, 'r'); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "Invalid key: TextEntry is empty"); nux::SleepForMilliseconds(500); test.ViewSendKeyCombo(XK_Control_L, 0, 0, 'w'); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "Invalid key: TextEntry is empty"); nux::SleepForMilliseconds(500); test.ViewSendKeyCombo(XK_Control_L, 0, 0, 'g'); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "Invalid key: TextEntry is empty"); nux::SleepForMilliseconds(500); test.ViewSendKeyCombo(XK_Control_L, 0, 0, 'h'); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "Invalid key: TextEntry is empty"); nux::SleepForMilliseconds(500); nux::SleepForMilliseconds(500); test.ViewSendCtrlA(); test.ViewSendDelete(); } // Toggle IBus // Type "qwerty" // Simulate key '1' to select the first IM option { // CTRL+Space to initiate iBus //test.ViewSendIBusToggle(); IBusBus* bus_; ibus_init(); bus_ = ibus_bus_new(); bool active = false; // Test for ibus-pinyin if (bus_ && SetEngineActive(bus_,"pinyin")) { // Type random stuff { test.ViewSendString("ninhao"); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is only Preedit"); test.ViewSendChar('1'); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "您好", "TextEntry is \"您好\""); test.ViewSendCtrlA(); nux::SleepForMilliseconds(500); test.ViewSendDelete(); nux::SleepForMilliseconds(500); } // Testing Cursor in the preedit window { test.ViewSendString("ming"); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is only Preedit"); test.ViewSendLeft(); nux::SleepForMilliseconds(500); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.ViewSendChar('1'); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "民", "TextEntry is \"民\""); test.ViewSendCtrlA(); nux::SleepForMilliseconds(500); test.ViewSendDelete(); nux::SleepForMilliseconds(500); } active = true; } // Test for ibus-hangul if (bus_ && SetEngineActive(bus_,"hangul")) { // Test for the the space in ibus-hangul working correctlly { test.ViewSendString("asd abc "); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ㅁㄴㅇ 뮻 ", "TextEntry is \"ㅁㄴㅇ 뮻 \""); test.ViewSendCtrlA(); nux::SleepForMilliseconds(500); test.ViewSendDelete(); nux::SleepForMilliseconds(500); } active = true; } // Checking for ibus-anthy - Japanese if (bus_ && SetEngineActive(bus_,"anthy")) { { test.ViewSendString("shisutemu "); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is only Preedit"); // Ctrl + J commits for ibus-anthy test.ViewSendKeyCombo(XK_Control_L, 0, 0, 'j'); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "システム", "TextEntry is \"システム\""); test.ViewSendCtrlA(); nux::SleepForMilliseconds(500); test.ViewSendDelete(); nux::SleepForMilliseconds(500); } active = true; } g_object_unref (bus_); // CTRL+Space to deactivate iBus if (active) test.ViewSendIBusToggle(); } if (test.WhenDoneTerminateProgram()) { wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); test_textentry = new TextTextEntry("Text Entry", 600, 200, 40000); test_textentry->Startup(); test_textentry->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(NULL, &TestingThread, test_textentry->GetWindowThread()); test_thread->Start(test_textentry); test_textentry->Run(); delete test_thread; delete test_textentry; return 0; } nux-4.0.6+14.04.20140409/tests/gtest-nux-globals.cpp0000644000015301777760000000017012321344237022160 0ustar pbusernogroup00000000000000#include gint64 g_fake_monotonic_time = 0; gint64 g_get_monotonic_time() { return g_fake_monotonic_time; } nux-4.0.6+14.04.20140409/tests/test_graphics_display.cpp0000644000015301777760000000313712321344237023173 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Brandon Schaefer * */ #include #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/WindowThread.h" void ThreadWidgetInit(nux::NThread* /* thread */, void* /* InitData */) { nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION); nux::GetWindowThread()->SetLayout(layout); } int main() { nux::NuxInitialize(0); // When the GUI thread is created, it creates the GraphicsDisplay. nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Graphics Display"), 300, 200, 0, &ThreadWidgetInit, 0); // Test to see if the variable in GraphicsDisplay is initialized int result = 1; if (!nux::GetGraphicsDisplay()->PointerIsGrabbed()) { // Zero return code is good. result = 0; } else { std::cerr << "FAIL: GraphicsDisplay hasn't correctly initialized.\n"; } delete wt; return result; } nux-4.0.6+14.04.20140409/tests/gtest-nuxgraphics-main.cpp0000644000015301777760000000050212321344237023201 0ustar pbusernogroup00000000000000#include #include #include "NuxCore/NuxCore.h" int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); #if G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION) <= GLIB_VERSION_2_34 g_type_init(); #endif nux::NuxCoreInitialize(0); return RUN_ALL_TESTS(); } nux-4.0.6+14.04.20140409/tests/gtest-nux-area.cpp0000644000015301777760000001106412321344237021451 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Jay Taoko * Marco Trevisan */ #include #include #include "Nux/Nux.h" #include "Nux/HLayout.h" #include "Nux/StaticText.h" #include "Nux/ProgramFramework/TestView.h" using namespace testing; namespace { struct MockTestView : nux::TestView { MockTestView() : nux::TestView("MockTestView") {} void SetNextObjectToKeyFocusArea(nux::Area* area) { TestView::SetNextObjectToKeyFocusArea(area); } nux::Area* GetNextObjectToKeyFocusArea() { return TestView::GetNextObjectToKeyFocusArea(); } }; struct TestArea : public testing::Test { void SetUp() { nux::NuxInitialize(0); wnd_thread.reset(nux::CreateNuxWindow("Area Test", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL)); test_view = new MockTestView(); } boost::shared_ptr wnd_thread; nux::ObjectPtr test_view; }; TEST_F(TestArea, TestAreaSize) { EXPECT_EQ(test_view->GetMinimumWidth(), nux::AREA_MIN_WIDTH); EXPECT_EQ(test_view->GetMaximumWidth(), nux::AREA_MAX_WIDTH); EXPECT_EQ(test_view->GetMinimumHeight(), nux::AREA_MIN_HEIGHT); EXPECT_EQ(test_view->GetMaximumHeight(), nux::AREA_MAX_HEIGHT); test_view->SetMinimumWidth(100); EXPECT_EQ(test_view->GetMinimumWidth(), 100); test_view->SetMaximumWidth(1111); EXPECT_EQ(test_view->GetMaximumWidth(), 1111); test_view->SetMinimumHeight(123); EXPECT_EQ(test_view->GetMinimumHeight(), 123); test_view->SetMaximumHeight(1234); EXPECT_EQ(test_view->GetMaximumHeight(), 1234); test_view->SetMaximumSize(4321, 1234); test_view->SetMinimumSize(123, 432); EXPECT_EQ(test_view->GetMinimumWidth(), 123); EXPECT_EQ(test_view->GetMaximumWidth(), 4321); EXPECT_EQ(test_view->GetMinimumHeight(), 432); EXPECT_EQ(test_view->GetMaximumHeight(), 1234); } TEST_F(TestArea, TestAreaGeometry) { static_cast(test_view.GetPointer())->SetGeometry(0, 0, 100, 100); EXPECT_EQ(test_view->GetBaseX(), 0); EXPECT_EQ(test_view->GetBaseX(), 0); EXPECT_EQ(test_view->GetBaseWidth(), 100); EXPECT_EQ(test_view->GetBaseHeight(), 100); } static bool object_destroyed = false; void OnObjectDestroyed(nux::Object* /* object */) { object_destroyed = true; } TEST_F(TestArea, TestUnParentKeyFocus) { nux::TestView* test_view1 = new nux::TestView(""); nux::HLayout* layout = new nux::HLayout(); test_view1->object_destroyed.connect(sigc::ptr_fun(&OnObjectDestroyed)); test_view1->Reference(); layout->AddView(test_view1, 1); wnd_thread->SetLayout(layout); EXPECT_EQ(test_view1->HasKeyFocus(), false); nux::GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(test_view1); EXPECT_EQ(test_view1->HasKeyFocus(), true); layout->RemoveChildObject(test_view1); EXPECT_EQ(test_view1->HasKeyFocus(), false); test_view1->UnReference(); EXPECT_EQ(object_destroyed, true); } TEST_F(TestArea, NextObjectToKeyFocusSetReset) { MockTestView* parent = new MockTestView(); MockTestView* brother = new MockTestView(); MockTestView* child1 = new MockTestView(); MockTestView* child2 = new MockTestView(); MockTestView* child3 = new MockTestView(); parent->SetNextObjectToKeyFocusArea(brother); ASSERT_EQ(parent->GetNextObjectToKeyFocusArea(), brother); child1->SetParentObject(parent); child1->SetNextObjectToKeyFocusArea(child2); ASSERT_EQ(child1->GetNextObjectToKeyFocusArea(), child2); child2->SetParentObject(parent); child2->SetNextObjectToKeyFocusArea(child3); ASSERT_EQ(child2->GetNextObjectToKeyFocusArea(), child3); child3->SetParentObject(parent); ASSERT_EQ(child3->GetNextObjectToKeyFocusArea(), nullptr); child1->UnReference(); EXPECT_EQ(child2->GetNextObjectToKeyFocusArea(), nullptr); EXPECT_EQ(parent->GetNextObjectToKeyFocusArea(), nullptr); parent->UnReference(); } } nux-4.0.6+14.04.20140409/tests/gtest-nux-axisdecelerationanimation.cpp0000644000015301777760000000534712321344237025773 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include using namespace nux; TEST(AxisDecelerationAnimation, ComesToAHalt) { AxisDecelerationAnimation animation; float min_pos = 0.0f; float max_pos = 100.0f; float start_pos = 10.0f; animation.SetMinimumPosition(min_pos); animation.SetMaximumPosition(max_pos); animation.SetStartPosition(start_pos); animation.SetStartVelocity(100.0f); animation.SetOvershootBoundsEnabled(false); animation.Start(); float last_pos = start_pos; float last_movement = 0.0f; for (int i = 0; i < 1000 && animation.IsActive(); ++i) { animation.Update(16); /* Check that it's moving along the velocity direction */ ASSERT_TRUE(animation.GetPosition() > last_pos); float movement = animation.GetPosition() - last_pos; if (i > 0) { /* Check that it's decelerating */ ASSERT_TRUE(movement - last_movement); } last_pos = animation.GetPosition(); last_movement = movement; } /* Check that it came to a halt */ ASSERT_FALSE(animation.IsActive()); } TEST(AxisDecelerationAnimation, StopAtBounds) { AxisDecelerationAnimation animation; float min_pos = 0.0f; float max_pos = 100.0f; float start_pos = 50.0f; animation.SetMinimumPosition(min_pos); animation.SetMaximumPosition(max_pos); /* test different velocities on both directions */ std::vector velocities; for (int i = 1; i <= 100; ++i) { velocities.push_back(i); } for (int i = -1; i >= -100; --i) { velocities.push_back(i); } for (size_t i = 0; i < velocities.size(); ++i) { animation.SetStartPosition(start_pos); animation.SetStartVelocity(velocities[i]); animation.Start(); for (int j = 0; j < 1000 && animation.IsActive(); ++j) { animation.Update(16); } ASSERT_FALSE(animation.IsActive()); ASSERT_LE(animation.GetPosition(), max_pos); ASSERT_GE(animation.GetPosition(), min_pos); } } nux-4.0.6+14.04.20140409/tests/Helpers.cpp0000644000015301777760000000336012321344237020207 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Tim Penhey * */ #include "Helpers.h" #include "NuxCore/LoggingWriter.h" #include #include namespace nux { namespace testing { std::string ReadFile(std::string const& filename) { std::ifstream input(filename.c_str()); if (input.bad()) throw std::runtime_error("bad file"); return std::string((std::istreambuf_iterator(input)), std::istreambuf_iterator()); } void PumpGObjectMainLoop() { GMainContext* context(g_main_context_get_thread_default()); while (g_main_context_pending(context)) { g_main_context_iteration(context, false); } } CaptureLogOutput::CaptureLogOutput() { logging::Writer::Instance().SetOutputStream(sout_); } CaptureLogOutput::~CaptureLogOutput() { logging::Writer::Instance().SetOutputStream(std::cout); } std::string CaptureLogOutput::GetOutput() { std::string result = sout_.str(); sout_.str(""); return result; } } } nux-4.0.6+14.04.20140409/tests/xtest-text-entry-logic.cpp0000644000015301777760000001105212321344237023165 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/TextEntry.h" #include "Nux/InputMethodIBus.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include "Nux/ProgramFramework/TestTextEntry.h" #include #include #include "nux_automated_test_framework.h" class TestTextEntry: public ProgramTemplate { public: TestTextEntry(const char* program_name, int window_width, int window_height, int program_life_span); ~TestTextEntry(); virtual void UserInterfaceSetup(); void ResetEvents(); nux::TestTextEntry* text_entry_; }; TestTextEntry::TestTextEntry(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) , text_entry_(NULL) { ResetEvents(); } TestTextEntry::~TestTextEntry() { } void TestTextEntry::ResetEvents() { if (text_entry_) text_entry_->ResetEvents(); } void TestTextEntry::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); text_entry_ = new nux::TestTextEntry(NUX_TRACKER_LOCATION); text_entry_->SetFontSize(76); main_layout->AddView(text_entry_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->SetSpaceBetweenChildren(10); main_layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } TestTextEntry* test_textentry = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (test_textentry->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1300); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); test.TestReportMsg(test_textentry->text_entry_, "TextEntry created"); test_textentry->ResetEvents(); test.ViewSendMouseMotionToCenter(test_textentry->text_entry_); test.TestReportMsg(test_textentry->text_entry_->HasKeyFocus() == false, "Focus test"); test.TestReportMsg(test_textentry->text_entry_->IsInTextInputMode() == false, "Text input mode test"); test.ViewSendMouseClick(0, 1); test.TestReportMsg(test_textentry->text_entry_->HasKeyFocus() == true, "Focus test"); test.TestReportMsg(test_textentry->text_entry_->IsInTextInputMode() == false, "Text input mode test"); // Type "Nux" // The cursor is at the end of the line // Simulate CTRL+A to select the entire text // Simulate DELETE key to delete the text { test.ViewSendString("Nux"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Nux", "Typed \"Nux\""); test.TestReportMsg(test_textentry->text_entry_->IsInTextInputMode() == true, "Text input mode test"); test.ViewSendCtrlA(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetTextSelection() == "Nux", "Selection is \"Nux\""); test.ViewSendDelete(); nux::SleepForMilliseconds(500); test.TestReportMsg(test_textentry->text_entry_->GetText() == "", "TextEntry is empty"); } if (test.WhenDoneTerminateProgram()) { wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); test_textentry = new TestTextEntry("Text Entry", 600, 200, 10000); test_textentry->Startup(); test_textentry->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(NULL, &TestingThread, test_textentry->GetWindowThread()); test_thread->Start(test_textentry); test_textentry->Run(); delete test_thread; delete test_textentry; return 0; } nux-4.0.6+14.04.20140409/tests/gtest-nux-gesturebroker.cpp0000644000015301777760000001251312321344237023424 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include "Nux/GestureBroker.h" #include "FakeGestureEvent.h" using namespace nux; namespace { class SimpleTarget : public nux::GestureTarget { public: SimpleTarget(int id) : id(id) {} virtual ~SimpleTarget() {} virtual GestureDeliveryRequest GestureEvent(const nux::GestureEvent &/* event */) { return GestureDeliveryRequest::NONE; } void Die() { died.emit(*this); } int id; }; class SimpleGestureBroker : public nux::GestureBroker { public: virtual ~SimpleGestureBroker() {} std::vector targets_to_be_found; private: std::vector virtual FindGestureTargets(const nux::GestureEvent &/* event */) { return targets_to_be_found; } }; } class GestureBrokerTest : public ::testing::Test { public: GestureBrokerTest() { } SimpleGestureBroker gesture_broker; nux::FakeGestureEvent fake_event; }; TEST_F(GestureBrokerTest, RejectGestureIfTargetBecomesUnavailable) { std::shared_ptr target (new SimpleTarget (0)); nux::TouchPoint touch (0, 1.0f, 1.0f); gesture_broker.targets_to_be_found.push_back (target); g_gesture_acceptance[0] = 0; fake_event.type = nux::EVENT_GESTURE_BEGIN; fake_event.gesture_id = 0; fake_event.gesture_classes = nux::TOUCH_GESTURE; fake_event.timestamp = 0; fake_event.touches.clear(); fake_event.touches.push_back(touch); fake_event.is_construction_finished = false; gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent()); ASSERT_EQ (0, g_gesture_acceptance[0]); /* This target is now unavailable */ target->Die(); /* Reject the gesture */ EXPECT_EQ (-1, g_gesture_acceptance[0]); } /* Let's simulate a situation where a user lays 4 fingers over a trackpad. 5 different gesture candidates will be generated out of this physical action. if touch ids are 0,1,2 and 3, the following gestures will be generated: {0,1,2}, {0,1,3}, {0,2,3}, {1,2,3} and {0,1,2,3} The gesture canditates with the most fingers must prevail and the others must be rejected. */ TEST_F(GestureBrokerTest, GestureWithMostTouchesTakesPrecedence) { nux::TouchPoint all_touches[4]; all_touches[0].id = 0; all_touches[0].x = all_touches[0].y = 1.0f; all_touches[1].id = 1; all_touches[1].x = all_touches[0].y = 2.0f; all_touches[2].id = 2; all_touches[2].x = all_touches[0].y = 3.0f; all_touches[3].id = 3; all_touches[3].x = all_touches[0].y = 4.0f; gesture_broker.targets_to_be_found.push_back( ShPtGestureTarget(new SimpleTarget(0))); for (int i = 0; i < 5; ++i) g_gesture_acceptance[i] = 0; // begin gesture 0 with touches {0,1,2} fake_event.type = nux::EVENT_GESTURE_BEGIN; fake_event.gesture_id = 0; fake_event.gesture_classes = nux::TOUCH_GESTURE; fake_event.timestamp = 0; fake_event.touches.clear(); fake_event.touches.push_back(all_touches[0]); fake_event.touches.push_back(all_touches[1]); fake_event.touches.push_back(all_touches[2]); fake_event.is_construction_finished = false; gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent()); // begin gesture 1 with touches {0,1,3} fake_event.gesture_id = 1; fake_event.touches.clear(); fake_event.touches.push_back(all_touches[0]); fake_event.touches.push_back(all_touches[1]); fake_event.touches.push_back(all_touches[3]); gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent()); // begin gesture 2 with touches {0,2,3} fake_event.gesture_id = 2; fake_event.touches.clear(); fake_event.touches.push_back(all_touches[0]); fake_event.touches.push_back(all_touches[2]); fake_event.touches.push_back(all_touches[3]); gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent()); // begin gesture 3 with touches {1,2,3} fake_event.gesture_id = 3; fake_event.touches.clear(); fake_event.touches.push_back(all_touches[1]); fake_event.touches.push_back(all_touches[2]); fake_event.touches.push_back(all_touches[3]); gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent()); // begin gesture 4 with touches {0,1,2,3} fake_event.gesture_id = 4; fake_event.touches.clear(); fake_event.touches.push_back(all_touches[0]); fake_event.touches.push_back(all_touches[1]); fake_event.touches.push_back(all_touches[2]); fake_event.touches.push_back(all_touches[3]); gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent()); ASSERT_EQ(-1, g_gesture_acceptance[0]); ASSERT_EQ(-1, g_gesture_acceptance[1]); ASSERT_EQ(-1, g_gesture_acceptance[2]); ASSERT_EQ(-1, g_gesture_acceptance[3]); ASSERT_EQ(0, g_gesture_acceptance[4]); } nux-4.0.6+14.04.20140409/tests/nux_automated_test_framework.h0000644000015301777760000001171012321344237024241 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include #include #ifndef NUX_AUTOMATED_TEST_FRAMEWORK_H #define NUX_AUTOMATED_TEST_FRAMEWORK_H class NuxAutomatedTestFramework { public: NuxAutomatedTestFramework(nux::WindowThread *window_thread); virtual ~NuxAutomatedTestFramework(); //! Returns true if composition keys are supported by the server bool CompositionKeysSupported(); //! Warn the developer composition keys are not supported void WarnCompositionKeysNotSupported(); //! Initialize the testing framework. void Startup(); //! Simulate a mouse click event on a view. /*! Move the mouse to the middle of the view (if it isn't there already) and perform a click event. */ void ViewSendMouseClick(nux::View *view, int button); //! Simulate a mouse double click event on a view. /*! Move the mouse to the middle of the view (if it isn't there already) and perform a double click event. */ void ViewSendMouseDoubleClick(nux::View *view, int button); //! Simulate a mouse down event on a view. void ViewSendMouseDown(nux::View *view, int button); //! Simulate a mouse up event on a view. void ViewSendMouseUp(nux::View *view, int button); //! Simulate a drag event on a view from (x0, y0) to (x1, y1). void ViewSendMouseDrag(nux::View *view, int button, int x0, int y0, int x1, int y1); //! Simulate mouse motion to (x, y). void ViewSendMouseMotionTo(nux::View *view, int x, int y); //! Simulate mouse motion to the center of a view. void ViewSendMouseMotionToCenter(nux::View *view); //! Simulate mouse motion to the top left corner of a view. void ViewSendMouseMotionToTopLeft(nux::View *view); //! Simulate mouse motion to the top right corner of a view. void ViewSendMouseMotionToTopRight(nux::View *view); //! Simulate mouse motion to the bottom left corner of a view. void ViewSendMouseMotionToBottomLeft(nux::View *view); //! Simulate mouse motion to the bottom right corner of a view. void ViewSendMouseMotionToBottomRight(nux::View *view); //! Simulate a key event. void ViewSendChar(const char c); //! Simulate a succession of key events. void ViewSendString(const std::string &str); //! Simulate a key combo. void ViewSendKeyCombo(KeySym modsym0, KeySym modsym1, KeySym modsym2, const char c); //! Simulate Ctrl+a. void ViewSendCtrlA(); //! Simulate Delete key. void ViewSendDelete(); //! Simulate Backspace key. void ViewSendBackspace(); //! Simulate Escape key. void ViewSendEscape(); //! Simulate Tab key. void ViewSendTab(); //! Simulate Return key. void ViewSendReturn(); //! Simulate Left arrow key. void ViewSendLeft(); //! Simulate Right arrow key. void ViewSendRight(); //! Simulate Up arrow key. void ViewSendUp(); //! Simulate Down arrow key. void ViewSendDown(); //! Simulate composition keys. void ViewSendCompositionKeys(const std::string &str); //! Simulate 1-4 key presses. void ViewSendKeys(const std::string &str); void ViewSendIBusToggle(); //! Put the mouse pointer anywhere on the display. void PutMouseAt(int x, int y); //! Simulate a mouse event. void SendFakeMouseEvent(int mouse_button_index, bool pressed); //! Simulate a key event. void SendFakeKeyEvent(KeySym keysym, KeySym modsym); //! Simulate a mouse motion event. void SendFakeMouseMotionEvent(int x, int y, int ms_delay); /*! Set the test thread to terminae the program when testing is over. */ void SetTerminateProgramWhenDone(bool terminate); /*! Return true if the test thread is allowed to terminate the program after testing is over. */ bool WhenDoneTerminateProgram(); /*! Print a report message to the console. */ void TestReportMsg(bool b, const char* msg); private: void WindowConfigSignal(int x, int y, int width, int height); bool ready_to_start_; Display* display_; nux::WindowThread *window_thread_; int window_x_; int window_y_; int window_width_; int window_height_; bool terminate_when_test_over_; bool composition_keys_supported_; static int mouse_motion_time_span; // in milliseconds static int mouse_click_time_span; // in milliseconds static int minimum_sleep_time; // in milliseconds static int safety_border_inside_view; // in pixels }; #endif // NUX_AUTOMATED_TEST_FRAMEWORK_H nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-properties.cpp0000644000015301777760000006044112321344237023611 0ustar pbusernogroup00000000000000#include "NuxCore/Property.h" #include #include #include #include #include #include "Helpers.h" using namespace testing; namespace nt = nux::testing; namespace { template T to_and_from_string(T const& value) { std::string temp = nux::type::PropertyTrait::to_string(value); std::pair result = nux::type::PropertyTrait::from_string(temp); if (!result.second) { throw std::runtime_error("Failed to convert."); } return result.first; } enum TestEnum { FirstValue, MiddleValue, LastValue, }; struct TestClass { int value; }; TEST(TestTypeTraits, TestSerialization) { EXPECT_EQ("hello", nux::type::PropertyTrait::to_string("hello")); EXPECT_EQ("42", nux::type::PropertyTrait::to_string(42)); EXPECT_EQ("42", nux::type::PropertyTrait::to_string(42)); EXPECT_EQ("true", nux::type::PropertyTrait::to_string(true)); EXPECT_EQ("false", nux::type::PropertyTrait::to_string(false)); EXPECT_EQ("0", nux::type::PropertyTrait::to_string(0)); EXPECT_EQ("25.5", nux::type::PropertyTrait::to_string(25.5)); EXPECT_EQ("1", nux::type::PropertyTrait::to_string(MiddleValue)); } TEST(TestTypeTraits, TestDeserialization) { std::pair sr = nux::type::PropertyTrait::from_string("hello"); EXPECT_EQ("hello", sr.first); EXPECT_TRUE(sr.second); std::pair int_result = nux::type::PropertyTrait::from_string("42"); EXPECT_EQ(42, int_result.first); EXPECT_TRUE(int_result.second); int_result = nux::type::PropertyTrait::from_string("OMG!"); EXPECT_EQ(0, int_result.first); EXPECT_FALSE(int_result.second); std::pair unsigned_result = nux::type::PropertyTrait::from_string("42"); EXPECT_EQ(42, unsigned_result.first); EXPECT_TRUE(unsigned_result.second); unsigned_result = nux::type::PropertyTrait::from_string("OMG!"); EXPECT_EQ(0, unsigned_result.first); EXPECT_FALSE(unsigned_result.second); std::pair bool_result = nux::type::PropertyTrait::from_string("true"); EXPECT_TRUE(bool_result.first); EXPECT_TRUE(bool_result.second); bool_result = nux::type::PropertyTrait::from_string("false"); EXPECT_FALSE(bool_result.first); EXPECT_TRUE(bool_result.second); bool_result = nux::type::PropertyTrait::from_string("what?"); EXPECT_FALSE(bool_result.first); EXPECT_FALSE(bool_result.second); std::pair double_result = nux::type::PropertyTrait::from_string("25.5"); EXPECT_EQ(25.5, double_result.first); EXPECT_TRUE(double_result.second); double_result = nux::type::PropertyTrait::from_string("2e6"); EXPECT_EQ(2000000.0, double_result.first); EXPECT_TRUE(double_result.second); double_result = nux::type::PropertyTrait::from_string("what?"); EXPECT_EQ(0, double_result.first); EXPECT_FALSE(double_result.second); std::pair enum_result = nux::type::PropertyTrait::from_string("0"); EXPECT_EQ(FirstValue, enum_result.first); EXPECT_TRUE(enum_result.second); // This is tested to show behaviour even though it is undesirable (as there // isn't an enum value for 42). enum_result = nux::type::PropertyTrait::from_string("42"); EXPECT_EQ(42, enum_result.first); EXPECT_TRUE(enum_result.second); } TEST(TestTypeTraits, TestConversionHolds) { std::string string_value("Hello World!"); EXPECT_EQ(string_value, to_and_from_string(string_value)); double double_value = 34.345; EXPECT_EQ(double_value, to_and_from_string(double_value)); } TEST(TestProperty, TestDefaultConstructor) { nux::Property string_prop; // Need either an assignment or static cast to check the operator VALUE_TYPE // due to google-mock's template matching. std::string value = string_prop; EXPECT_THAT(value, Eq("")); EXPECT_THAT(string_prop.Get(), Eq("")); EXPECT_THAT(string_prop(), Eq("")); } TEST(TestProperty, TestValueExplicitConstructor) { nux::Property string_prop("Hello world!"); // Need either an assignment or static cast to check the operator VALUE_TYPE // due to google-mock's template matching. std::string value = string_prop; EXPECT_THAT(value, Eq("Hello world!")); EXPECT_THAT(string_prop.Get(), Eq("Hello world!")); EXPECT_THAT(string_prop(), Eq("Hello world!")); } TEST(TestProperty, TestAssignment) { nux::Property string_prop; // Need either an assignment or static cast to check the operator VALUE_TYPE // due to google-mock's template matching. string_prop = "Assignment operator"; std::string value = string_prop; EXPECT_THAT(value, Eq("Assignment operator")); EXPECT_THAT(string_prop.Get(), Eq("Assignment operator")); EXPECT_THAT(string_prop(), Eq("Assignment operator")); string_prop.Set("Set method"); value = string_prop; EXPECT_THAT(value, Eq("Set method")); EXPECT_THAT(string_prop.Get(), Eq("Set method")); EXPECT_THAT(string_prop(), Eq("Set method")); string_prop("Function call assignment"); value = string_prop; EXPECT_THAT(value, Eq("Function call assignment")); EXPECT_THAT(string_prop.Get(), Eq("Function call assignment")); EXPECT_THAT(string_prop(), Eq("Function call assignment")); } TEST(TestProperty, TestChanged) { nux::Property string_prop; nt::ChangeRecorder recorder; string_prop.changed.connect(recorder.listener()); string_prop = "Hello world" ; EXPECT_THAT(1, Eq(recorder.size())); EXPECT_THAT("Hello world", Eq(recorder.last())); // No notification if not changed. string_prop = std::string("Hello world"); EXPECT_THAT(1, Eq(recorder.size())); } TEST(TestProperty, TestEnableAndDisableNotifications) { nux::Property string_prop; nt::ChangeRecorder recorder; string_prop.changed.connect(recorder.listener()); string_prop.DisableNotifications(); string_prop = "Hello world" ; EXPECT_THAT(0, Eq(recorder.size())); string_prop.EnableNotifications(); // No notification if not changed. string_prop = "Hello world" ; EXPECT_THAT(0, Eq(recorder.size())); string_prop = "New value" ; EXPECT_THAT(1, Eq(recorder.size())); EXPECT_THAT("New value", Eq(recorder.last())); } bool string_prefix(std::string& target, std::string const& value) { bool changed = false; std::string prefixed("prefix-" + value); if (target != prefixed) { target = prefixed; changed = true; } return changed; } TEST(TestProperty, TestSetterConstructor) { nux::Property string_prop("", sigc::ptr_fun(&string_prefix)); string_prop = "foo"; // Need either an assignment or static cast to check the operator VALUE_TYPE // due to google-mock's template matching. std::string value = string_prop; EXPECT_THAT(value, Eq("prefix-foo")); EXPECT_THAT(string_prop.Get(), Eq("prefix-foo")); EXPECT_THAT(string_prop(), Eq("prefix-foo")); } class FloatClamp { public: FloatClamp(float min, float max) : min_(min), max_(max) { } bool Set(float& target, float const& value) { bool changed = false; float new_val = std::min(max_, std::max(min_, value)); if (target != new_val) { target = new_val; changed = true; } return changed; } private: float min_; float max_; }; TEST(TestProperty, TestCustomSetterFunction) { nux::Property float_prop; FloatClamp clamp(0, 1); float_prop.SetSetterFunction(sigc::mem_fun(&clamp, &FloatClamp::Set)); nt::ChangeRecorder recorder; float_prop.changed.connect(recorder.listener()); // Since the default value for a float is zero, and we clamp at zero, // setting to a negative value will result in setting to zero, which will // not signal a changed event. float_prop = -2; EXPECT_THAT(float_prop(), Eq(0)); EXPECT_THAT(0, Eq(recorder.size())); float_prop = 0.5; EXPECT_THAT(float_prop(), Eq(0.5)); EXPECT_THAT(1, Eq(recorder.size())); EXPECT_THAT(0.5, Eq(recorder.last())); float_prop = 4; EXPECT_THAT(float_prop(), Eq(1)); EXPECT_THAT(2, Eq(recorder.size())); EXPECT_THAT(1, Eq(recorder.last())); } TEST(TestProperty, TestCustomSetterFunctionLambda) { nux::Property float_prop; FloatClamp clamp(0, 1); float_prop.SetSetterFunction([&clamp] (float &target, float const& value) { return clamp.Set(target, value); }); nt::ChangeRecorder recorder; float_prop.changed.connect(recorder.listener()); // Since the default value for a float is zero, and we clamp at zero, // setting to a negative value will result in setting to zero, which will // not signal a changed event. float_prop = -2; EXPECT_THAT(float_prop(), Eq(0)); EXPECT_THAT(0, Eq(recorder.size())); float_prop = 0.5; EXPECT_THAT(float_prop(), Eq(0.5)); EXPECT_THAT(1, Eq(recorder.size())); EXPECT_THAT(0.5, Eq(recorder.last())); float_prop = 4; EXPECT_THAT(float_prop(), Eq(1)); EXPECT_THAT(2, Eq(recorder.size())); EXPECT_THAT(1, Eq(recorder.last())); } TEST(TestProperty, TestIntOperators) { nux::Property int_prop(42); EXPECT_TRUE(int_prop == 42); EXPECT_TRUE(42 == int_prop); EXPECT_FALSE(int_prop != 42); EXPECT_FALSE(42 != int_prop); EXPECT_FALSE(int_prop == 5); EXPECT_FALSE(5 == int_prop); EXPECT_TRUE(int_prop != 5); EXPECT_TRUE(5 != int_prop); EXPECT_FALSE(int_prop < 5); EXPECT_FALSE(int_prop <= 5); EXPECT_TRUE(int_prop > 5); EXPECT_TRUE(int_prop >= 5); EXPECT_TRUE(5 < int_prop); EXPECT_TRUE(5 <= int_prop); EXPECT_FALSE(5 > int_prop); EXPECT_FALSE(5 >= int_prop); nux::Property int_prop2(42); EXPECT_TRUE(int_prop2 == int_prop); EXPECT_FALSE(int_prop2 != int_prop); int_prop2 = 5; EXPECT_FALSE(int_prop2 == int_prop); EXPECT_TRUE(int_prop2 != int_prop); EXPECT_FALSE(int_prop < int_prop2); EXPECT_FALSE(int_prop <= int_prop2); EXPECT_TRUE(int_prop > int_prop2); EXPECT_TRUE(int_prop >= int_prop2); } // Only testing strings and ints, to show that the template classes work with // both primitive types and classes. TEST(TestProperty, TestStringOperators) { std::string value("Hello"); nux::Property str_prop(value); EXPECT_TRUE(str_prop == "Hello"); EXPECT_TRUE("Hello" == str_prop); EXPECT_FALSE(str_prop != "Hello"); EXPECT_FALSE("Hello" != str_prop); EXPECT_TRUE(str_prop == value); EXPECT_TRUE(value == str_prop); EXPECT_FALSE(str_prop != value); EXPECT_FALSE(value != str_prop); EXPECT_FALSE(str_prop == "World"); EXPECT_FALSE("World" == str_prop); EXPECT_TRUE(str_prop != "World"); EXPECT_TRUE("World" != str_prop); EXPECT_FALSE(str_prop < "Aardvark"); EXPECT_FALSE(str_prop <= "Aardvark"); EXPECT_TRUE(str_prop > "Aardvark"); EXPECT_TRUE(str_prop >= "Aardvark"); EXPECT_TRUE("Aardvark" < str_prop); EXPECT_TRUE("Aardvark" <= str_prop); EXPECT_FALSE("Aardvark" > str_prop); EXPECT_FALSE("Aardvark" >= str_prop); nux::Property str_prop2(value); EXPECT_TRUE(str_prop2 == str_prop); EXPECT_FALSE(str_prop2 != str_prop); str_prop2 = "Aardvark"; EXPECT_FALSE(str_prop2 == str_prop); EXPECT_TRUE(str_prop2 != str_prop); EXPECT_FALSE(str_prop < str_prop2); EXPECT_FALSE(str_prop <= str_prop2); EXPECT_TRUE(str_prop > str_prop2); EXPECT_TRUE(str_prop >= str_prop2); } TEST(TestROProperty, TestDefaultConstructor) { nux::ROProperty int_prop; int value = int_prop; EXPECT_THAT(value, Eq(0)); EXPECT_THAT(int_prop(), Eq(0)); EXPECT_THAT(int_prop.Get(), Eq(0)); nux::ROProperty string_prop; std::string svalue = string_prop; EXPECT_THAT(svalue, Eq("")); EXPECT_THAT(string_prop(), Eq("")); EXPECT_THAT(string_prop.Get(), Eq("")); } int simple_int_result() { return 42; } TEST(TestROProperty, TestGetterConstructor) { nux::ROProperty int_prop(sigc::ptr_fun(&simple_int_result)); int value = int_prop; EXPECT_THAT(value, Eq(42)); EXPECT_THAT(int_prop(), Eq(42)); EXPECT_THAT(int_prop.Get(), Eq(42)); } class Incrementer { public: Incrementer() : value_(0) {} int value() { return ++value_; } private: int value_; }; TEST(TestROProperty, TestSetGetter) { nux::ROProperty int_prop; Incrementer incrementer; int_prop.SetGetterFunction(sigc::mem_fun(&incrementer, &Incrementer::value)); int value = int_prop; EXPECT_THAT(value, Eq(1)); EXPECT_THAT(int_prop(), Eq(2)); EXPECT_THAT(int_prop.Get(), Eq(3)); } #if __cplusplus >= 201100L || defined (__GXX_EXPERIMENTAL_CXX0X__) TEST(TestROProperty, TestSetGetterLambda) { nux::ROProperty int_prop; int_prop.SetGetterFunction([] { static int value = 0; return ++value; }); int value = int_prop; EXPECT_THAT(value, Eq(1)); EXPECT_THAT(int_prop(), Eq(2)); EXPECT_THAT(int_prop.Get(), Eq(3)); } #endif TEST(TestROProperty, TestChangedEvent) { // RO Properties have a changed event, but it is up to the continer of the // property to emit the events as nothing is done automatically. nux::ROProperty int_prop; nt::ChangeRecorder recorder; int_prop.changed.connect(recorder.listener()); int_prop.EmitChanged(42); EXPECT_THAT(1, Eq(recorder.size())); EXPECT_THAT(42, Eq(recorder.last())); } // A simple class that just has a reader functon. template class ROPropHolder { public: ROPropHolder(VALUE_TYPE const& initial) : prop(sigc::mem_fun(this, &ROPropHolder::get_prop)) , prop_(initial) {} nux::ROProperty prop; VALUE_TYPE get_prop() const { return prop_; } VALUE_TYPE prop_; }; TEST(TestROProperty, TestIntOperators) { ROPropHolder int_prop(42); EXPECT_TRUE(int_prop.prop == 42); EXPECT_TRUE(42 == int_prop.prop); EXPECT_FALSE(int_prop.prop != 42); EXPECT_FALSE(42 != int_prop.prop); EXPECT_FALSE(int_prop.prop == 5); EXPECT_FALSE(5 == int_prop.prop); EXPECT_TRUE(int_prop.prop != 5); EXPECT_TRUE(5 != int_prop.prop); EXPECT_FALSE(int_prop.prop < 5); EXPECT_FALSE(int_prop.prop <= 5); EXPECT_TRUE(int_prop.prop > 5); EXPECT_TRUE(int_prop.prop >= 5); EXPECT_TRUE(5 < int_prop.prop); EXPECT_TRUE(5 <= int_prop.prop); EXPECT_FALSE(5 > int_prop.prop); EXPECT_FALSE(5 >= int_prop.prop); ROPropHolder int_prop2(42); EXPECT_TRUE(int_prop2.prop == int_prop.prop); EXPECT_FALSE(int_prop2.prop != int_prop.prop); int_prop2.prop_ = 5; EXPECT_FALSE(int_prop2.prop == int_prop.prop); EXPECT_TRUE(int_prop2.prop != int_prop.prop); EXPECT_FALSE(int_prop.prop < int_prop2.prop); EXPECT_FALSE(int_prop.prop <= int_prop2.prop); EXPECT_TRUE(int_prop.prop > int_prop2.prop); EXPECT_TRUE(int_prop.prop >= int_prop2.prop); } // Only testing strings and ints, to show that the template classes work with // both primitive types and classes. TEST(TestROProperty, TestStringOperators) { std::string value("Hello"); ROPropHolder str_prop(value); EXPECT_TRUE(str_prop.prop == "Hello"); EXPECT_TRUE("Hello" == str_prop.prop); EXPECT_FALSE(str_prop.prop != "Hello"); EXPECT_FALSE("Hello" != str_prop.prop); EXPECT_TRUE(str_prop.prop == value); EXPECT_TRUE(value == str_prop.prop); EXPECT_FALSE(str_prop.prop != value); EXPECT_FALSE(value != str_prop.prop); EXPECT_FALSE(str_prop.prop == "World"); EXPECT_FALSE("World" == str_prop.prop); EXPECT_TRUE(str_prop.prop != "World"); EXPECT_TRUE("World" != str_prop.prop); EXPECT_FALSE(str_prop.prop < "Aardvark"); EXPECT_FALSE(str_prop.prop <= "Aardvark"); EXPECT_TRUE(str_prop.prop > "Aardvark"); EXPECT_TRUE(str_prop.prop >= "Aardvark"); EXPECT_TRUE("Aardvark" < str_prop.prop); EXPECT_TRUE("Aardvark" <= str_prop.prop); EXPECT_FALSE("Aardvark" > str_prop.prop); EXPECT_FALSE("Aardvark" >= str_prop.prop); ROPropHolder str_prop2(value); EXPECT_TRUE(str_prop2.prop == str_prop.prop); EXPECT_FALSE(str_prop2.prop != str_prop.prop); str_prop2.prop_ = "Aardvark"; EXPECT_FALSE(str_prop2.prop == str_prop.prop); EXPECT_TRUE(str_prop2.prop != str_prop.prop); EXPECT_FALSE(str_prop.prop < str_prop2.prop); EXPECT_FALSE(str_prop.prop <= str_prop2.prop); EXPECT_TRUE(str_prop.prop > str_prop2.prop); EXPECT_TRUE(str_prop.prop >= str_prop2.prop); } TEST(TestRWProperty, TestDefaultConstructor) { nux::RWProperty int_prop; nt::ChangeRecorder recorder; int_prop.changed.connect(recorder.listener()); int_prop = 42; int value = int_prop; EXPECT_THAT(value, Eq(0)); EXPECT_THAT(int_prop(), Eq(0)); EXPECT_THAT(int_prop.Get(), Eq(0)); EXPECT_THAT(recorder.size(), Eq(0)); } bool is_even(int const& value) { return value % 2 == 0; } TEST(TestRWProperty, TestFunctionConstructor) { // This is a somewhat convoluted example. The setter emits if the value is // even, but the value being emitted is controlled by the incrementer. Incrementer incrementer; nux::RWProperty int_prop(sigc::mem_fun(&incrementer, &Incrementer::value), sigc::ptr_fun(&is_even)); nt::ChangeRecorder recorder; int_prop.changed.connect(recorder.listener()); int_prop = 42; EXPECT_THAT(recorder.size(), Eq(1)); EXPECT_THAT(recorder.last(), Eq(1)); // Catch the return value of the assignment. The getter is called. int assign_result = int_prop = 13; EXPECT_THAT(recorder.size(), Eq(1)); EXPECT_THAT(assign_result, Eq(2)); // each access increments the value. int value = int_prop; EXPECT_THAT(value, Eq(3)); EXPECT_THAT(int_prop(), Eq(4)); EXPECT_THAT(int_prop.Get(), Eq(5)); } // This bit would normally be in the header file. class HiddenImpl { public: HiddenImpl(); nux::RWProperty name; private: class Impl; boost::scoped_ptr pimpl; }; // This bit is in the implementation file. class HiddenImpl::Impl { public: bool set_name(std::string const& name) { bool changed = false; std::string new_name("Impl::" + name); if (name_ != new_name) { name_ = new_name; changed = true; } return changed; } std::string get_name() const { return name_; } private: std::string name_; }; HiddenImpl::HiddenImpl() : pimpl(new Impl()) { name.SetSetterFunction(sigc::mem_fun(pimpl.get(), &HiddenImpl::Impl::set_name)); name.SetGetterFunction(sigc::mem_fun(pimpl.get(), &HiddenImpl::Impl::get_name)); } TEST(TestRWProperty, TestPimplClassExample) { HiddenImpl hidden; nt::ChangeRecorder recorder; hidden.name.changed.connect(recorder.listener()); hidden.name = "NewName"; EXPECT_THAT(recorder.size(), Eq(1)); EXPECT_THAT(recorder.last(), Eq("Impl::NewName")); // Since the name is updated before comparison, no event emitted. hidden.name = "NewName"; EXPECT_THAT(recorder.size(), Eq(1)); std::string value = hidden.name; EXPECT_THAT(value, Eq("Impl::NewName")); EXPECT_THAT(hidden.name(), Eq("Impl::NewName")); EXPECT_THAT(hidden.name.Get(), Eq("Impl::NewName")); } // A simple class that just has a reader and writer functon. template class RWPropHolder { public: RWPropHolder(VALUE_TYPE const& initial) : prop(sigc::mem_fun(this, &RWPropHolder::get_prop), sigc::mem_fun(this, &RWPropHolder::set_prop)) , prop_(initial) {} nux::RWProperty prop; private: VALUE_TYPE get_prop() const { return prop_; } bool set_prop(VALUE_TYPE const& prop) { prop_ = prop; return true; } VALUE_TYPE prop_; }; TEST(TestRWProperty, TestIntOperators) { RWPropHolder int_prop(42); EXPECT_TRUE(int_prop.prop == 42); EXPECT_TRUE(42 == int_prop.prop); EXPECT_FALSE(int_prop.prop != 42); EXPECT_FALSE(42 != int_prop.prop); EXPECT_FALSE(int_prop.prop == 5); EXPECT_FALSE(5 == int_prop.prop); EXPECT_TRUE(int_prop.prop != 5); EXPECT_TRUE(5 != int_prop.prop); EXPECT_FALSE(int_prop.prop < 5); EXPECT_FALSE(int_prop.prop <= 5); EXPECT_TRUE(int_prop.prop > 5); EXPECT_TRUE(int_prop.prop >= 5); EXPECT_TRUE(5 < int_prop.prop); EXPECT_TRUE(5 <= int_prop.prop); EXPECT_FALSE(5 > int_prop.prop); EXPECT_FALSE(5 >= int_prop.prop); RWPropHolder int_prop2(42); EXPECT_TRUE(int_prop2.prop == int_prop.prop); EXPECT_FALSE(int_prop2.prop != int_prop.prop); int_prop2.prop = 5; EXPECT_FALSE(int_prop2.prop == int_prop.prop); EXPECT_TRUE(int_prop2.prop != int_prop.prop); EXPECT_FALSE(int_prop.prop < int_prop2.prop); EXPECT_FALSE(int_prop.prop <= int_prop2.prop); EXPECT_TRUE(int_prop.prop > int_prop2.prop); EXPECT_TRUE(int_prop.prop >= int_prop2.prop); } // Only testing strings and ints, to show that the template classes work with // both primitive types and classes. TEST(TestRWProperty, TestStringOperators) { std::string value("Hello"); RWPropHolder str_prop(value); EXPECT_TRUE(str_prop.prop == "Hello"); EXPECT_TRUE("Hello" == str_prop.prop); EXPECT_FALSE(str_prop.prop != "Hello"); EXPECT_FALSE("Hello" != str_prop.prop); EXPECT_TRUE(str_prop.prop == value); EXPECT_TRUE(value == str_prop.prop); EXPECT_FALSE(str_prop.prop != value); EXPECT_FALSE(value != str_prop.prop); EXPECT_FALSE(str_prop.prop == "World"); EXPECT_FALSE("World" == str_prop.prop); EXPECT_TRUE(str_prop.prop != "World"); EXPECT_TRUE("World" != str_prop.prop); EXPECT_FALSE(str_prop.prop < "Aardvark"); EXPECT_FALSE(str_prop.prop <= "Aardvark"); EXPECT_TRUE(str_prop.prop > "Aardvark"); EXPECT_TRUE(str_prop.prop >= "Aardvark"); EXPECT_TRUE("Aardvark" < str_prop.prop); EXPECT_TRUE("Aardvark" <= str_prop.prop); EXPECT_FALSE("Aardvark" > str_prop.prop); EXPECT_FALSE("Aardvark" >= str_prop.prop); RWPropHolder str_prop2(value); EXPECT_TRUE(str_prop2.prop == str_prop.prop); EXPECT_FALSE(str_prop2.prop != str_prop.prop); str_prop2.prop = "Aardvark"; EXPECT_FALSE(str_prop2.prop == str_prop.prop); EXPECT_TRUE(str_prop2.prop != str_prop.prop); EXPECT_FALSE(str_prop.prop < str_prop2.prop); EXPECT_FALSE(str_prop.prop <= str_prop2.prop); EXPECT_TRUE(str_prop.prop > str_prop2.prop); EXPECT_TRUE(str_prop.prop >= str_prop2.prop); } struct TestProperties : nux::Introspectable { TestProperties() : name(this, "name") , index(this, "index") {} nux::SerializableProperty name; nux::SerializableProperty index; }; TEST(TestIntrospectableProperty, TestSimplePropertyAccess) { TestProperties props; nt::ChangeRecorder recorder; props.name.changed.connect(recorder.listener()); EXPECT_EQ("", props.name()); EXPECT_EQ(0, props.index()); props.name = "Testing"; props.index = 5; EXPECT_EQ("Testing", props.name()); props.name("New Value"); EXPECT_EQ("New Value", props.name()); props.name.Set("Another"); EXPECT_EQ("Another", props.name()); EXPECT_EQ(3, recorder.size()); EXPECT_EQ("Testing", recorder.changed_values[0]); EXPECT_EQ("New Value", recorder.changed_values[1]); EXPECT_EQ("Another", recorder.changed_values[2]); } TEST(TestIntrospectableProperty, TestPropertyAccessByName) { TestProperties props; nt::ChangeRecorder name_recorder; nt::ChangeRecorder index_recorder; props.name.changed.connect(name_recorder.listener()); props.index.changed.connect(index_recorder.listener()); props.name = "Testing"; props.index = 5; EXPECT_EQ("Testing", props.GetProperty("name")); EXPECT_EQ("5", props.GetProperty("index")); EXPECT_EQ(5, props.GetProperty("index")); bool assigned = props.SetProperty("name", "New value"); EXPECT_TRUE(assigned); EXPECT_EQ("New value", props.name()); EXPECT_EQ("New value", props.GetProperty("name")); // A little dangreous, but legal. EXPECT_EQ(0, props.GetProperty("name")); assigned = props.SetProperty("name", 42); EXPECT_TRUE(assigned); EXPECT_EQ("42", props.name()); EXPECT_EQ("42", props.GetProperty("name")); // A little dangreous, but legal. EXPECT_EQ(42, props.GetProperty("name")); assigned = props.SetProperty("index", 42); EXPECT_TRUE(assigned); EXPECT_EQ(42, props.index()); EXPECT_EQ("42", props.GetProperty("index")); EXPECT_EQ(42, props.GetProperty("index")); assigned = props.SetProperty("index", "hello"); EXPECT_FALSE(assigned); EXPECT_EQ(42, props.index()); EXPECT_EQ("42", props.GetProperty("index")); EXPECT_EQ(42, props.GetProperty("index")); // Gettin a non-existant property returns a default constructed instance. std::string surname = props.GetProperty("surname"); EXPECT_EQ("", surname); int foo = props.GetProperty("foo"); EXPECT_EQ(0, foo); assigned = props.SetProperty("non-existant", "hello"); EXPECT_FALSE(assigned); } } nux-4.0.6+14.04.20140409/tests/xim-test-commands.txt0000644000015301777760000000262512321344237022216 0ustar pbusernogroup00000000000000// // Copyright 2010 Inalogic Inc. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // version 3 along with this program. If not, see // // // Author by: Brandon Schaefer // 0 is the name of the IM // 1 is any key sequences you need to enter to get the IM // in the correct state while testing // 2 is text that will get inputed to the IM. The input is what you // would normally type to get your desired CJK string // 3 is the expect result that the IM should turn your input into // 4 is when we know the test is over and to close the current IM // This test GCIN with chewing 0 gcin 1 ctrl+space 1 ctrl+alt+[ 2 w91o3g4 1 enter 1 ctrl+space 3 北市 4 halt // This test Fcitx with google pinyin 0 fcitx 1 ctrl+space 2 dianshi ji1 3 耟椒晃 4 halt // This test Hime with anthy 0 hime 1 ctrl+space 1 ctrl+alt+= 2 shisutemu 1 enter 1 ctrl+space 3 しすてむ 4 halt nux-4.0.6+14.04.20140409/tests/test-timeline.cpp0000644000015301777760000000521312321344237021367 0ustar pbusernogroup00000000000000/* * Copyright (C) 2010 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by Gordon Allott * */ #include #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/Button.h" static void test_timeline (void); void test_timeline_create_suite (void) { #define TESTDOMAIN "/Timeline/" g_test_add_func (TESTDOMAIN"/Timeline", test_timeline); } class TimelineTestClass { public: nux::Button *button; nux::Timeline *timeline_1; TimelineTestClass () { has_got_new_frame = false; } void OnNewFrame (unsigned long msecs) { has_got_new_frame = true; } void OnCompleted () { nux::GetGraphicsThread ()->NuxMainLoopQuit (); } void Init (nux::Layout *layout) { } bool has_got_new_frame; }; void ThreadWidgetInit(nux::NThread* thread, void* InitData) { TimelineTestClass *self = (TimelineTestClass*) InitData; nux::VLayout* MainVLayout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION); MainVLayout->SetContentDistribution(nux::eStackCenter); self->Init (MainVLayout); nux::GetGraphicsThread()->SetLayout(MainVLayout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); } static void test_timeline (void) { TimelineTestClass *test_class = new TimelineTestClass (); nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Timeline Test"), 400, 300, 0, ThreadWidgetInit, test_class); nux::Timeline *timeline = new nux::Timeline (1000, "My Timeline", NUX_TRACKER_LOCATION); timeline->Looping = false; timeline->NewFrame.connect (sigc::mem_fun (test_class, &TimelineTestClass::OnNewFrame)); timeline->Completed.connect (sigc::mem_fun (test_class, &TimelineTestClass::OnCompleted)); gint64 micro_secs = g_get_real_time(); unsigned long current_time = micro_secs / 1000; wt->AddTimeline (timeline); wt->Run(NULL); micro_secs = g_get_real_time(); g_assert(micro_secs / 1000 - current_time > 1000); g_assert (test_class->has_got_new_frame); delete test_class; delete wt; } nux-4.0.6+14.04.20140409/tests/gtest-nux-geisadapter.cpp0000644000015301777760000001605712321344237023040 0ustar pbusernogroup00000000000000#include #include #include "geis_mock.h" #include class GeisAdapterTest : public ::testing::Test { public: GeisAdapterTest() { adapter_emitted_init_complete = false; } void AddGestureClass(Geis geis, GeisGestureClass gesture_class) { GeisEvent event = new struct _GeisEvent; event->type = GEIS_EVENT_CLASS_AVAILABLE; event->attributes.AddPointer(GEIS_EVENT_ATTRIBUTE_CLASS, gesture_class); geis->pending_events.push_back(event); } void AddDevice(Geis geis, GeisDevice device) { GeisEvent event = new struct _GeisEvent; event->type = GEIS_EVENT_DEVICE_AVAILABLE; event->attributes.AddPointer(GEIS_EVENT_ATTRIBUTE_DEVICE, device); geis->pending_events.push_back(event); } void FinishInitialization(Geis geis) { GeisEvent event = new struct _GeisEvent; event->type = GEIS_EVENT_INIT_COMPLETE; geis->pending_events.push_back(event); } void StoreNuxGestureEvent(nux::GestureEvent &gesture_event) { gesture_events.push_back(gesture_event); } void MarkInitCompleteAsEmitted() { adapter_emitted_init_complete = true; } std::list gesture_events; bool adapter_emitted_init_complete; }; /* Send a GEIS_EVENT_INIT_COMPLETE and check if GeisAdapter emits init_complete and IsInitComplete() returns a correct value. */ TEST_F(GeisAdapterTest, SignalsInitComplete) { nux::GeisAdapter geis_adapter; Geis geis = geis_adapter.GetGeisInstance(); ASSERT_FALSE(geis_adapter.IsInitComplete()); geis_adapter.init_complete.connect(sigc::mem_fun(this, &GeisAdapterTest::MarkInitCompleteAsEmitted)); FinishInitialization(geis); geis_adapter.ProcessGeisEvents(); ASSERT_TRUE(adapter_emitted_init_complete); ASSERT_TRUE(geis_adapter.IsInitComplete()); } /* First send some necessary initialization events. One to define a multi-touch device, another defining a gesture class and one that tells that the initialization has completed. After that send a well formed GEIS_EVENT_GESTURE_BEGIN and check if GeisAdapter emits a corresponding nux::GestureEvent. */ TEST_F(GeisAdapterTest, EmitsWellFormedNuxGestureEvent) { nux::GeisAdapter geis_adapter; Geis geis = geis_adapter.GetGeisInstance(); struct _GeisGestureClass drag_class; drag_class.id = 12; drag_class.name = GEIS_GESTURE_DRAG; AddGestureClass(geis, &drag_class); struct _GeisDevice device; device.id = 7; device.attributes.AddBoolean(GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH, true); AddDevice(geis, &device); FinishInitialization(geis); struct _GeisFrame frame; frame.id = 321; frame.class_ids.insert(drag_class.id); frame.attributes.AddInteger(GEIS_GESTURE_ATTRIBUTE_DEVICE_ID, device.id); frame.attributes.AddFloat(GEIS_GESTURE_ATTRIBUTE_FOCUS_X, 87.3f); frame.attributes.AddFloat(GEIS_GESTURE_ATTRIBUTE_FOCUS_Y, 123.4f); struct _GeisGroup group; group.vector.push_back(&frame); struct _GeisGroupSet group_set; group_set.vector.push_back(&group); struct _GeisTouch touch; touch.id = 0; touch.attributes.AddFloat(GEIS_TOUCH_ATTRIBUTE_ID, 123); touch.attributes.AddFloat(GEIS_TOUCH_ATTRIBUTE_X, 777.7f); touch.attributes.AddFloat(GEIS_TOUCH_ATTRIBUTE_Y, 888.8f); struct _GeisTouchSet touch_set; touch_set.vector.push_back(&touch); GeisEvent event = new struct _GeisEvent; event->type = GEIS_EVENT_GESTURE_BEGIN; event->attributes.AddPointer(GEIS_EVENT_ATTRIBUTE_GROUPSET, &group_set); event->attributes.AddPointer(GEIS_EVENT_ATTRIBUTE_TOUCHSET, &touch_set); event->attributes.AddBoolean(GEIS_EVENT_ATTRIBUTE_CONSTRUCTION_FINISHED, true); geis->pending_events.push_back(event); geis_adapter.event_ready.connect(sigc::mem_fun(this, &GeisAdapterTest::StoreNuxGestureEvent)); geis_adapter.ProcessGeisEvents(); ASSERT_EQ(1, gesture_events.size()); const nux::GestureEvent &gesture_event = gesture_events.front(); ASSERT_EQ(nux::EVENT_GESTURE_BEGIN, gesture_event.type); ASSERT_EQ(frame.id, gesture_event.GetGestureId()); ASSERT_EQ(device.GetBoolean(GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH), gesture_event.IsDirectTouch()); ASSERT_FLOAT_EQ(frame.GetFloat(GEIS_GESTURE_ATTRIBUTE_FOCUS_X), gesture_event.GetFocus().x); ASSERT_FLOAT_EQ(frame.GetFloat(GEIS_GESTURE_ATTRIBUTE_FOCUS_Y), gesture_event.GetFocus().y); ASSERT_EQ(touch_set.vector.size(), gesture_event.GetTouches().size()); for (size_t i = 0; i < gesture_event.GetTouches().size(); ++i) { ASSERT_FLOAT_EQ(touch_set.vector[i]->GetInteger(GEIS_TOUCH_ATTRIBUTE_ID), gesture_event.GetTouches()[i].id); ASSERT_FLOAT_EQ(touch_set.vector[i]->GetFloat(GEIS_TOUCH_ATTRIBUTE_X), gesture_event.GetTouches()[i].x); ASSERT_FLOAT_EQ(touch_set.vector[i]->GetFloat(GEIS_TOUCH_ATTRIBUTE_Y), gesture_event.GetTouches()[i].y); } } /* Checks that when a Tap Update GeisEvent is received, GeisAdpater generates two events from it: A Tap Begin and a Tap End. */ TEST_F(GeisAdapterTest, SplitTapUpdateIntoTapBeginAndTapEnd) { nux::GeisAdapter geis_adapter; Geis geis = geis_adapter.GetGeisInstance(); struct _GeisGestureClass tap_class; tap_class.id = 12; tap_class.name = GEIS_GESTURE_TAP; AddGestureClass(geis, &tap_class); struct _GeisDevice device; device.id = 7; device.attributes.AddBoolean(GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH, true); AddDevice(geis, &device); FinishInitialization(geis); struct _GeisFrame frame; frame.id = 321; frame.class_ids.insert(tap_class.id); frame.attributes.AddInteger(GEIS_GESTURE_ATTRIBUTE_DEVICE_ID, device.id); frame.attributes.AddFloat(GEIS_GESTURE_ATTRIBUTE_FOCUS_X, 87.3f); frame.attributes.AddFloat(GEIS_GESTURE_ATTRIBUTE_FOCUS_Y, 123.4f); struct _GeisGroup group; group.vector.push_back(&frame); struct _GeisGroupSet group_set; group_set.vector.push_back(&group); struct _GeisTouch touch; touch.id = 0; touch.attributes.AddFloat(GEIS_TOUCH_ATTRIBUTE_ID, 123); touch.attributes.AddFloat(GEIS_TOUCH_ATTRIBUTE_X, 777.7f); touch.attributes.AddFloat(GEIS_TOUCH_ATTRIBUTE_Y, 888.8f); struct _GeisTouchSet touch_set; touch_set.vector.push_back(&touch); GeisEvent event = new struct _GeisEvent; event->type = GEIS_EVENT_GESTURE_UPDATE; event->attributes.AddPointer(GEIS_EVENT_ATTRIBUTE_GROUPSET, &group_set); event->attributes.AddPointer(GEIS_EVENT_ATTRIBUTE_TOUCHSET, &touch_set); event->attributes.AddBoolean(GEIS_EVENT_ATTRIBUTE_CONSTRUCTION_FINISHED, false); geis->pending_events.push_back(event); geis_adapter.event_ready.connect(sigc::mem_fun(this, &GeisAdapterTest::StoreNuxGestureEvent)); geis_adapter.ProcessGeisEvents(); ASSERT_EQ(2, gesture_events.size()); ASSERT_EQ(nux::EVENT_GESTURE_BEGIN, gesture_events.front().type); ASSERT_EQ(nux::TAP_GESTURE, gesture_events.front().GetGestureClasses()); ASSERT_TRUE(gesture_events.front().IsConstructionFinished()); ASSERT_EQ(nux::EVENT_GESTURE_END, gesture_events.back().type); ASSERT_EQ(nux::TAP_GESTURE, gesture_events.back().GetGestureClasses()); ASSERT_TRUE(gesture_events.back().IsConstructionFinished()); } nux-4.0.6+14.04.20140409/tests/xtest-scrollbar.cpp0000644000015301777760000000776512321344237021752 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" #include "test-scrollview.h" class ScrollBarTest: public ProgramTemplate { public: ScrollBarTest(const char* program_name, int window_width, int window_height, int program_life_span); ~ScrollBarTest(); virtual void UserInterfaceSetup(); nux::VLayout* layout_; TestScrollView* scroll_view_; nux::VLayout* in_layout_; nux::TestView* test_view_; }; ScrollBarTest::ScrollBarTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { } ScrollBarTest::~ScrollBarTest() { } void ScrollBarTest::UserInterfaceSetup() { layout_ = new nux::VLayout(NUX_TRACKER_LOCATION); layout_->SetPadding(20, 20); scroll_view_ = new TestScrollView(); layout_->AddView(scroll_view_); in_layout_ = new nux::VLayout(NUX_TRACKER_LOCATION); scroll_view_->SetLayout(in_layout_); test_view_ = new nux::TestView(); test_view_->SetMinimumHeight(1000); in_layout_->AddView(test_view_); static_cast(window_thread_)->SetLayout(layout_); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } ScrollBarTest* scrollbar_test; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (scrollbar_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); test.TestReportMsg(scrollbar_test->scroll_view_, "TestScrollView created"); scrollbar_test->scroll_view_->ResetEvents(); test.ViewSendMouseMotionToCenter(scrollbar_test->scroll_view_); test.ViewSendMouseClick(scrollbar_test->scroll_view_, 4); nux::SleepForMilliseconds(1000); test.TestReportMsg(scrollbar_test->scroll_view_->registered_scroll_, "Scroll on the center of the scrollview"); scrollbar_test->scroll_view_->ResetEvents(); test.ViewSendMouseMotionToCenter(scrollbar_test->scroll_view_->GetVScrollbar()); test.ViewSendMouseClick(scrollbar_test->scroll_view_->GetVScrollbar(), 4); nux::SleepForMilliseconds(1000); test.TestReportMsg(scrollbar_test->scroll_view_->registered_scroll_, "Scroll on the scrollbar"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); scrollbar_test = new ScrollBarTest("Scrollbar Test", 500, 400, 13000); scrollbar_test->Startup(); scrollbar_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(scrollbar_test->GetWindowThread(), &TestingThread, scrollbar_test->GetWindowThread()); test_thread->Start(scrollbar_test); scrollbar_test->Run(); delete test_thread; delete scrollbar_test; return 0; } nux-4.0.6+14.04.20140409/tests/gtest-nuxgraphics-texture.cpp0000644000015301777760000000613212321344237023762 0ustar pbusernogroup00000000000000#include #include #include #include "Nux/Nux.h" #include "Nux/HLayout.h" #include "NuxGraphics/NuxGraphics.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "Nux/CairoWrapper.h" using namespace testing; using namespace nux; namespace { const char *FALLBACK_ENV = "NUX_FALLBACK_TEXTURE"; class TestTextures : public ::testing::Test { public: virtual void SetUp() { g_unsetenv(FALLBACK_ENV); nux::NuxInitialize(0); wnd_thread.reset(nux::CreateNuxWindow("nux::TestTextures", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL)); } void EnableFallbackMode() { g_setenv(FALLBACK_ENV, "TRUE", TRUE); } std::unique_ptr wnd_thread; }; TEST_F(TestTextures, TestTextureSizes) { int max_size = GetGraphicsDisplay()->GetGpuDevice()->GetGpuInfo().GetMaxTextureSize(); int size = max_size/4; nux::ObjectPtr texture; while (size <= max_size * 4) { BitmapFormat bitmap_format = BITFMT_B8G8R8A8; NBitmapData* bitmap = new NTextureData (bitmap_format, 10, size, 1); texture.Adopt(GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture()); GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(texture.GetPointer()); texture->Update(bitmap, true); delete bitmap; size*=2; } } TEST_F(TestTextures, TestCreateTexture2DFromIDAssignemnt) { GLuint texid; glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); nux::ObjectPtr foreign_texture_as_nux_texture (nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID( texid, 1, 1, 0, nux::BITFMT_B8G8R8A8)); EXPECT_EQ(texid, foreign_texture_as_nux_texture->GetOpenGLID()); glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &texid); } TEST_F(TestTextures, FallbackTexture2DFromFile) { ASSERT_THAT(CreateTexture2DFromFile(nullptr, -1, false), IsNull()); EnableFallbackMode(); ASSERT_THAT(CreateTexture2DFromFile(nullptr, -1, false), NotNull()); } TEST_F(TestTextures, FallbackTexture2DFromPixbuf) { ASSERT_THAT(CreateTexture2DFromPixbuf(nullptr, false), IsNull()); EnableFallbackMode(); ASSERT_THAT(CreateTexture2DFromPixbuf(nullptr, false), NotNull()); } TEST_F(TestTextures, FallbackTextureFromPixbuf) { ASSERT_THAT(CreateTextureFromPixbuf(nullptr), IsNull()); EnableFallbackMode(); ASSERT_THAT(CreateTextureFromPixbuf(nullptr), NotNull()); } TEST_F(TestTextures, FallbackTextureFromFile) { ASSERT_THAT(CreateTextureFromFile(nullptr), IsNull()); EnableFallbackMode(); ASSERT_THAT(CreateTextureFromFile(nullptr), NotNull()); } TEST_F(TestTextures, FallbackTextureFromBitmapData) { ASSERT_THAT(CreateTextureFromBitmapData(nullptr), IsNull()); EnableFallbackMode(); ASSERT_THAT(CreateTextureFromBitmapData(nullptr), NotNull()); } TEST_F(TestTextures, FallbackTextureLoadFromFile) { ASSERT_THAT(LoadTextureFromFile(std::string()), IsNull()); EnableFallbackMode(); ASSERT_THAT(LoadTextureFromFile(std::string()), NotNull()); } } nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-main.cpp0000644000015301777760000000050212321344237022331 0ustar pbusernogroup00000000000000#include #include #include "NuxCore/NuxCore.h" int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); #if G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION) <= GLIB_VERSION_2_34 g_type_init(); #endif nux::NuxCoreInitialize(0); return RUN_ALL_TESTS(); } nux-4.0.6+14.04.20140409/tests/geis_mock.cpp0000644000015301777760000002405312321344237020547 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #include #include "geis_mock.h" #include #include #include #include //#define DEBUG_PRINT printf("%s mock called!\n", __func__); #define DEBUG_PRINT /******** GeisAttributes helper class *********/ GeisAttr GeisAttributes::GetByName(GeisString name) { for (size_t i = 0; i < vector.size(); ++i) { GeisAttr attr = vector[i].get(); if (attr->name.compare(name) == 0) return attr; } return nullptr; } GeisAttr GeisAttributes::GetByIndex(GeisSize index) { if (vector.size() > index) { return vector[index].get(); } else { return nullptr; } } GeisSize GeisAttributes::Count() { return vector.size(); } void GeisAttributes::AddBoolean(const char *name, GeisBoolean value) { std::unique_ptr attr(new struct _GeisAttr); attr->type = GEIS_ATTR_TYPE_BOOLEAN; attr->name = name; attr->b = value; vector.push_back(std::move(attr)); } void GeisAttributes::AddFloat(const char *name, GeisFloat value) { std::unique_ptr attr(new struct _GeisAttr); attr->type = GEIS_ATTR_TYPE_FLOAT; attr->name = name; attr->f = value; vector.push_back(std::move(attr)); } void GeisAttributes::AddInteger(const char *name, GeisInteger value) { std::unique_ptr attr(new struct _GeisAttr); attr->type = GEIS_ATTR_TYPE_INTEGER; attr->name = name; attr->i = value; vector.push_back(std::move(attr)); } void GeisAttributes::AddPointer(const char *name, void *value) { std::unique_ptr attr(new struct _GeisAttr); attr->type = GEIS_ATTR_TYPE_POINTER; attr->name = name; attr->p = value; vector.push_back(std::move(attr)); } /******* Geis *******/ Geis geis_new(GeisString /* init_arg_name */, ...) { DEBUG_PRINT Geis geis = new struct _Geis; geis->fd = eventfd(0, EFD_NONBLOCK); return geis; } GeisStatus geis_delete(Geis geis) { DEBUG_PRINT close(geis->fd); delete geis; return GEIS_STATUS_SUCCESS; } GeisStatus geis_get_configuration(Geis geis, GeisString configuration_item_name, void *configuration_item_value) { DEBUG_PRINT if (strcmp(configuration_item_name, GEIS_CONFIGURATION_FD) == 0) { int *fd = static_cast(configuration_item_value); *fd = geis->fd; return GEIS_STATUS_SUCCESS; } else { return GEIS_STATUS_NOT_SUPPORTED; } } GeisStatus geis_dispatch_events(Geis /* geis */) { DEBUG_PRINT return GEIS_STATUS_SUCCESS; } GeisStatus geis_next_event(Geis geis, GeisEvent *event) { DEBUG_PRINT if (geis->pending_events.size() > 0) { *event = geis->pending_events.front(); geis->pending_events.pop_front(); if (geis->pending_events.size() > 0) return GEIS_STATUS_CONTINUE; else return GEIS_STATUS_SUCCESS; } else { *event = nullptr; return GEIS_STATUS_EMPTY; } } GeisStatus geis_gesture_accept(Geis /* geis */, GeisGroup /* group */, GeisGestureId /* gesture_id */) { DEBUG_PRINT return GEIS_STATUS_SUCCESS; } GeisStatus geis_gesture_reject(Geis /* geis */, GeisGroup /* group */, GeisGestureId /* gesture_id */) { DEBUG_PRINT return GEIS_STATUS_SUCCESS; } /******* Attr *******/ GeisString geis_attr_name(GeisAttr attr) { DEBUG_PRINT return attr->name.c_str(); } GeisAttrType geis_attr_type(GeisAttr attr) { DEBUG_PRINT return attr->type; } GeisBoolean geis_attr_value_to_boolean(GeisAttr attr) { DEBUG_PRINT return attr->b; } GeisFloat geis_attr_value_to_float(GeisAttr attr) { DEBUG_PRINT return attr->f; } GeisInteger geis_attr_value_to_integer(GeisAttr attr) { DEBUG_PRINT return attr->i; } GeisPointer geis_attr_value_to_pointer(GeisAttr attr) { DEBUG_PRINT return attr->p; } GeisString geis_attr_value_to_string(GeisAttr attr) { DEBUG_PRINT return attr->s.c_str(); } /*********** Event **************/ void geis_event_delete(GeisEvent event) { DEBUG_PRINT delete event; } GeisEventType geis_event_type(GeisEvent event) { DEBUG_PRINT return event->type; } GeisSize geis_event_attr_count(GeisEvent event) { DEBUG_PRINT return event->attributes.Count(); } GeisAttr geis_event_attr(GeisEvent event, GeisSize index) { DEBUG_PRINT return event->attributes.GetByIndex(index); } GeisAttr geis_event_attr_by_name(GeisEvent event, GeisString attr_name) { DEBUG_PRINT return event->attributes.GetByName(attr_name); } /******** Gesture Class ***********/ void geis_gesture_class_ref(GeisGestureClass /* gesture_class */) { DEBUG_PRINT } void geis_gesture_class_unref(GeisGestureClass /* gesture_class */) { DEBUG_PRINT } GeisString geis_gesture_class_name(GeisGestureClass gesture_class) { DEBUG_PRINT return const_cast(gesture_class->name.c_str()); } GeisInteger geis_gesture_class_id(GeisGestureClass gesture_class) { DEBUG_PRINT return gesture_class->id; } GeisSize geis_gesture_class_attr_count(GeisGestureClass gesture_class) { DEBUG_PRINT return gesture_class->attributes.Count(); } GeisAttr geis_gesture_class_attr(GeisGestureClass gesture_class, int index) { DEBUG_PRINT return gesture_class->attributes.GetByIndex(index); } /********* Device ***********/ GeisInteger geis_device_id(GeisDevice device) { DEBUG_PRINT return device->id; } GeisAttr geis_device_attr_by_name(GeisDevice device, GeisString attr_name) { DEBUG_PRINT return device->attributes.GetByName(attr_name); } /********** Group Set **********/ GeisSize geis_groupset_group_count(GeisGroupSet groupset) { DEBUG_PRINT return groupset->vector.size(); } GeisGroup geis_groupset_group(GeisGroupSet groupset, GeisSize index) { DEBUG_PRINT return groupset->vector[index]; } /****** Group ******/ GeisSize geis_group_frame_count(GeisGroup group) { DEBUG_PRINT return group->vector.size(); } GeisFrame geis_group_frame(GeisGroup group, GeisSize index) { DEBUG_PRINT return group->vector[index]; } /***** Touch Set *****/ GeisSize geis_touchset_touch_count(GeisTouchSet touchset) { DEBUG_PRINT return touchset->vector.size(); } GeisTouch geis_touchset_touch(GeisTouchSet touchset, GeisSize index) { DEBUG_PRINT return touchset->vector[index]; } /***** Touch ******/ GeisTouchId geis_touch_id(GeisTouch touch) { DEBUG_PRINT return touch->id; } GeisSize geis_touch_attr_count(GeisTouch touch) { DEBUG_PRINT return touch->attributes.Count(); } GeisAttr geis_touch_attr(GeisTouch touch, GeisSize index) { DEBUG_PRINT return touch->attributes.GetByIndex(index); } GeisAttr geis_touch_attr_by_name(GeisTouch touch, GeisString name) { DEBUG_PRINT return touch->attributes.GetByName(name); } /***** Frame *****/ GeisGestureId geis_frame_id(GeisFrame frame) { DEBUG_PRINT return frame->id; } GeisBoolean geis_frame_is_class(GeisFrame frame, GeisGestureClass gesture_class) { DEBUG_PRINT std::set::iterator it = frame->class_ids.find(gesture_class->id); if (it == frame->class_ids.end()) return GEIS_FALSE; else return GEIS_TRUE; } GeisSize geis_frame_attr_count(GeisFrame frame) { DEBUG_PRINT return frame->attributes.Count(); } GeisAttr geis_frame_attr(GeisFrame frame, GeisSize index) { DEBUG_PRINT return frame->attributes.GetByIndex(index); } GeisAttr geis_frame_attr_by_name(GeisFrame frame, GeisString name) { DEBUG_PRINT return frame->attributes.GetByName(name); } /***** Subscription *****/ GeisSubscription geis_subscription_new(Geis /* geis */, GeisString /* name */, GeisSubscriptionFlags /* flags */) { DEBUG_PRINT return new struct _GeisSubscription; } GeisStatus geis_subscription_delete(GeisSubscription subscription) { DEBUG_PRINT for (auto filter : subscription->filters) { delete filter; } delete subscription; return GEIS_STATUS_SUCCESS; } GeisStatus geis_subscription_activate(GeisSubscription /* subscription */) { DEBUG_PRINT return GEIS_STATUS_SUCCESS; } GeisStatus geis_subscription_deactivate(GeisSubscription /* subscription */) { DEBUG_PRINT return GEIS_STATUS_SUCCESS; } GeisString geis_subscription_name(GeisSubscription subscription) { DEBUG_PRINT return const_cast(subscription->name.c_str()); } GeisInteger geis_subscription_id(GeisSubscription subscription) { DEBUG_PRINT return subscription->id; } GeisStatus geis_subscription_add_filter(GeisSubscription subscription, GeisFilter filter) { DEBUG_PRINT subscription->filters.push_back(filter); return GEIS_STATUS_SUCCESS; } GeisFilter geis_subscription_filter_by_name(GeisSubscription /* sub */, GeisString /* name */) { DEBUG_PRINT return nullptr; } GeisStatus geis_subscription_remove_filter(GeisSubscription subscription, GeisFilter filter) { DEBUG_PRINT std::vector::iterator it = subscription->filters.begin(); while (it != subscription->filters.end()) { if (filter == *it) { subscription->filters.erase(it); return GEIS_STATUS_SUCCESS; } ++it; } return GEIS_STATUS_BAD_ARGUMENT; } nux-4.0.6+14.04.20140409/tests/gtest-nux-emmetrics.cpp0000644000015301777760000000735412321344237022540 0ustar pbusernogroup00000000000000#include #include #include "Nux/Nux.h" #include "Nux/EMMetrics.h" namespace { TEST(TestMetrics, TestCreate) { // Test fallback (no display) of constructor, DPI of 96.0 will be used nux::EMMetrics* metrics5 = new nux::EMMetrics(NULL, 0, 5.0); nux::EMMetrics* metrics10 = new nux::EMMetrics(NULL, 0, 10.0); nux::EMMetrics* metrics15 = new nux::EMMetrics(NULL, 0, 15.0); nux::EMMetrics* metrics20 = new nux::EMMetrics(NULL, 0, 20.0); // Test conversion from pixel to EM (testing fallback-case) 5-point font EXPECT_EQ(metrics5->Pixel2EM(30), 4.5); EXPECT_EQ(metrics5->Pixel2EM(25), 3.75); EXPECT_EQ(metrics5->Pixel2EM(20), 3.0); EXPECT_EQ(metrics5->Pixel2EM(15), 2.25); EXPECT_EQ(metrics5->Pixel2EM(10), 1.5); EXPECT_EQ(metrics5->Pixel2EM(5), 0.75); EXPECT_EQ(metrics5->Pixel2EM(0), 0.0); // Test conversion from EM to pixel (testing fallback-case) 5-point font EXPECT_EQ(metrics5->EM2Pixel(4.5), 30); EXPECT_EQ(metrics5->EM2Pixel(3.75), 25); EXPECT_EQ(metrics5->EM2Pixel(3.0), 20); EXPECT_EQ(metrics5->EM2Pixel(2.25), 15); EXPECT_EQ(metrics5->EM2Pixel(1.5), 10); EXPECT_EQ(metrics5->EM2Pixel(0.75), 5); EXPECT_EQ(metrics5->EM2Pixel(0.0), 0); // Test conversion from pixel to EM (testing fallback-case) 10-point font EXPECT_EQ(metrics10->Pixel2EM(30), 2.25); EXPECT_EQ(metrics10->Pixel2EM(25), 1.875); EXPECT_EQ(metrics10->Pixel2EM(20), 1.5); EXPECT_EQ(metrics10->Pixel2EM(15), 1.125); EXPECT_EQ(metrics10->Pixel2EM(10), 0.75); EXPECT_EQ(metrics10->Pixel2EM(5), 0.375); EXPECT_EQ(metrics10->Pixel2EM(0), 0.0); // Test conversion from EM to pixel (testing fallback-case) 10-point font EXPECT_EQ(metrics10->EM2Pixel(2.25), 30); EXPECT_EQ(metrics10->EM2Pixel(1.875), 25); EXPECT_EQ(metrics10->EM2Pixel(1.5), 20); EXPECT_EQ(metrics10->EM2Pixel(1.125), 15); EXPECT_EQ(metrics10->EM2Pixel(0.75), 10); EXPECT_EQ(metrics10->EM2Pixel(0.375), 5); EXPECT_EQ(metrics10->EM2Pixel(0.0), 0); // Test conversion from pixel to EM (testing fallback-case) 15-point font EXPECT_EQ(metrics15->Pixel2EM(30), 1.5); EXPECT_EQ(metrics15->Pixel2EM(25), 1.25); EXPECT_EQ(metrics15->Pixel2EM(20), 1.0); EXPECT_EQ(metrics15->Pixel2EM(15), 0.75); EXPECT_EQ(metrics15->Pixel2EM(10), 0.5); EXPECT_EQ(metrics15->Pixel2EM(5), 0.25); EXPECT_EQ(metrics15->Pixel2EM(0), 0.0); // Test conversion from EM to pixel (testing fallback-case) 15-point font EXPECT_EQ(metrics15->EM2Pixel(1.5), 30); EXPECT_EQ(metrics15->EM2Pixel(1.25), 25); EXPECT_EQ(metrics15->EM2Pixel(1.0), 20); EXPECT_EQ(metrics15->EM2Pixel(0.75), 15); EXPECT_EQ(metrics15->EM2Pixel(0.5), 10); EXPECT_EQ(metrics15->EM2Pixel(0.25), 5); EXPECT_EQ(metrics15->EM2Pixel(0.0), 0); // Test conversion from pixel to EM (testing fallback-case) 20-point font EXPECT_EQ(metrics20->Pixel2EM(30), 1.125); EXPECT_EQ(metrics20->Pixel2EM(25), 0.9375); EXPECT_EQ(metrics20->Pixel2EM(20), 0.75); EXPECT_EQ(metrics20->Pixel2EM(15), 0.5625); EXPECT_EQ(metrics20->Pixel2EM(10), 0.375); EXPECT_EQ(metrics20->Pixel2EM(5), 0.1875); EXPECT_EQ(metrics20->Pixel2EM(0), 0.0); // Test conversion from EM to pixel (testing fallback-case) 20-point font EXPECT_EQ(metrics20->EM2Pixel(1.125), 30); EXPECT_EQ(metrics20->EM2Pixel(0.9375), 25); EXPECT_EQ(metrics20->EM2Pixel(0.75), 20); EXPECT_EQ(metrics20->EM2Pixel(0.5625), 15); EXPECT_EQ(metrics20->EM2Pixel(0.375), 10); EXPECT_EQ(metrics20->EM2Pixel(0.1875), 5); EXPECT_EQ(metrics20->EM2Pixel(0.0), 0); delete metrics5; delete metrics10; delete metrics15; delete metrics20; } } // unnamed namespace nux-4.0.6+14.04.20140409/tests/geis_mock.h0000644000015301777760000000534712321344237020221 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #ifndef GEIS_MOCK_H #define GEIS_MOCK_H #include #include #include #include #include /* helper class */ class GeisAttributes { public: GeisAttr GetByName(GeisString name); GeisAttr GetByIndex(GeisSize index); GeisSize Count(); void AddBoolean(const char *name, GeisBoolean value); void AddFloat(const char *name, GeisFloat value); void AddInteger(const char *name, GeisInteger value); void AddPointer(const char *name, void *value); std::vector< std::unique_ptr > vector; }; struct _GeisAttr { GeisAttrType type; std::string name; GeisBoolean b; GeisFloat f; GeisInteger i; std::string s; void* p; }; struct GeisStructWithAttributes { GeisAttributes attributes; bool GetBoolean(const char *name) { return attributes.GetByName(name)->b; } float GetFloat(const char *name) { return attributes.GetByName(name)->f; } int GetInteger(const char *name) { return attributes.GetByName(name)->i; } std::string GetString(const char *name) { return attributes.GetByName(name)->s; } void* GetPointer(const char *name) { return attributes.GetByName(name)->p; } }; struct _Geis { int fd; std::list pending_events; }; struct _GeisGestureClass : GeisStructWithAttributes { int id; std::string name; }; struct _GeisEvent : GeisStructWithAttributes { GeisEventType type; }; struct _GeisDevice : GeisStructWithAttributes { int id; }; struct _GeisGroup { int id; std::vector vector; }; struct _GeisGroupSet { std::vector vector; }; struct _GeisTouch : GeisStructWithAttributes { int id; }; struct _GeisTouchSet { std::vector vector; }; struct _GeisFrame : GeisStructWithAttributes { int id; std::set class_ids; }; struct _GeisSubscription { int id; std::string name; std::vector filters; }; struct _GeisFilter { int foo; }; #endif nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-object.cpp0000644000015301777760000001350512321344237022662 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include #include "NuxCore/NuxCore.h" #include "NuxCore/Object.h" #include "NuxCore/ObjectPtr.h" using namespace testing; namespace { const int ARRAY_SIZE = 1000; class OwnedObject: public nux::Object { public: OwnedObject(NUX_FILE_LINE_PROTO) : nux::Object(true, NUX_FILE_LINE_PARAM) { } ~OwnedObject() {} int array[ARRAY_SIZE]; }; class ChildOwnedObject: public OwnedObject { public: ChildOwnedObject(NUX_FILE_LINE_PROTO) : OwnedObject(NUX_FILE_LINE_PARAM) { } ~ChildOwnedObject() {} int array [ARRAY_SIZE]; }; class UnOwnedObject: public nux::Object { public: UnOwnedObject(NUX_FILE_LINE_PROTO) : nux::Object(false, NUX_FILE_LINE_PARAM) { } ~UnOwnedObject() {} int array [ARRAY_SIZE]; }; class ChildUnOwnedObject: public UnOwnedObject { public: ChildUnOwnedObject(NUX_FILE_LINE_PROTO) : UnOwnedObject (NUX_FILE_LINE_PARAM) { } ~ChildUnOwnedObject () {} int array [ARRAY_SIZE]; }; TEST(TestObject, TestObject) { OwnedObject* a = new OwnedObject(NUX_TRACKER_LOCATION); OwnedObject b(NUX_TRACKER_LOCATION); EXPECT_THAT(a, NotNull()); EXPECT_TRUE(a->IsHeapAllocated()); EXPECT_FALSE(b.IsHeapAllocated()); EXPECT_THAT(a->GetObjectSize(), Ge(ARRAY_SIZE)); a->UnReference(); } TEST(TestObject, TestObjectReference) { OwnedObject *a = new OwnedObject (NUX_TRACKER_LOCATION); // ref count = 1, owned UnOwnedObject *b = new UnOwnedObject (NUX_TRACKER_LOCATION); // ref count = 1, unowned EXPECT_THAT(a->GetReferenceCount(), Eq(1)); EXPECT_THAT(b->GetReferenceCount(), Eq(1)); EXPECT_FALSE(b->OwnsTheReference()); a->Reference (); // ref count = 2 a->Reference (); // ref count = 3 b->Reference (); // ref count = 1, owned EXPECT_THAT(a->GetReferenceCount(), Eq(3)); EXPECT_THAT(b->GetReferenceCount(), Eq(1)); EXPECT_TRUE(b->OwnsTheReference()); EXPECT_FALSE(a->UnReference()); EXPECT_THAT(a->GetReferenceCount(), Eq(2)); EXPECT_FALSE(a->UnReference()); EXPECT_THAT(a->GetReferenceCount(), Eq(1)); EXPECT_TRUE(a->UnReference()); // object destroyed EXPECT_TRUE(b->UnReference()); // object destroyed } TEST(TestObject, TestObjectPtr) { OwnedObject* a = new OwnedObject(NUX_TRACKER_LOCATION); // ref count = 1, owned nux::ObjectPtr object_ptr(a); // ref count = 2 EXPECT_THAT(a->GetReferenceCount(), Eq(2)); EXPECT_FALSE(a->UnReference()); // ref count = 1 EXPECT_THAT(a->GetReferenceCount(), Eq(1)); object_ptr.Release(); } TEST(TestObject, TestObjectPtrAdopt) { OwnedObject* a = new OwnedObject(NUX_TRACKER_LOCATION); // ref count = 1, owned nux::ObjectPtr object_ptr; object_ptr.Adopt(a); EXPECT_THAT(a->GetReferenceCount(), Eq(1)); } TEST(TestObject, TestObjectPtrGetPointer) { OwnedObject* a = new OwnedObject(NUX_TRACKER_LOCATION); // ref count = 1, owned nux::ObjectPtr object_ptr; object_ptr.Adopt(a); EXPECT_THAT(object_ptr.GetPointer(), Eq(a)); // Const too nux::ObjectPtr const& object_ptr_ref = object_ptr; EXPECT_THAT(object_ptr_ref.GetPointer(), Eq(a)); } TEST(TestObject, TestObjectPtr1) { ChildOwnedObject* c = new ChildOwnedObject(NUX_TRACKER_LOCATION); // ref count = 1, owned nux::ObjectPtr object_ptr0(c); // ref count = 2 EXPECT_THAT(c->GetReferenceCount(), Eq(2)); nux::ObjectPtr object_ptr1(object_ptr0); // ref count = 3 EXPECT_THAT(c->GetReferenceCount(), Eq(3)); EXPECT_FALSE(c->UnReference()); // ref count = 2 object_ptr1.Release(); EXPECT_THAT(c->GetReferenceCount(), Eq(1)); object_ptr0.Release (); } TEST(TestObject, TestObjectPtr2) { ChildOwnedObject *c = new ChildOwnedObject(NUX_TRACKER_LOCATION); nux::ObjectPtr obj_ptr(c); nux::ObjectWeakPtr weak_ptr(obj_ptr); EXPECT_THAT(c->GetReferenceCount(), Eq(2)); EXPECT_FALSE(c->UnReference()); EXPECT_THAT(c->GetReferenceCount(), Eq(1)); // Clearing the smart pointer deletes the object. EXPECT_TRUE(obj_ptr.Release()); EXPECT_FALSE(weak_ptr.IsValid()); EXPECT_TRUE(weak_ptr.IsNull()); EXPECT_FALSE(weak_ptr()); } bool g_signal_called = false; void on_destroyed_cb (nux::Object * /* obj */) { g_signal_called = true; } TEST(TestObject, TestObjectSignal) { nux::Object *obj = new nux::Object (); obj->OnDestroyed.connect(sigc::ptr_fun(on_destroyed_cb)); EXPECT_FALSE(g_signal_called); obj->UnReference (); EXPECT_TRUE(g_signal_called); } TEST(TestObject, TestObjectAdoptUnOwned) { UnOwnedObject* obj = new UnOwnedObject(NUX_TRACKER_LOCATION); EXPECT_THAT(obj->OwnsTheReference(), Eq(false)); nux::ObjectPtr obj_smart_ptr; obj_smart_ptr.Adopt(obj); EXPECT_THAT(obj->GetReferenceCount(), Eq(1)); EXPECT_THAT(obj->ObjectPtrCount(), Eq(1)); EXPECT_THAT(obj->OwnsTheReference(), Eq(true)); } TEST(TestObject, TestObjectAdoptOwned) { OwnedObject* obj = new OwnedObject(NUX_TRACKER_LOCATION); EXPECT_THAT(obj->OwnsTheReference(), Eq(true)); nux::ObjectPtr obj_smart_ptr; obj_smart_ptr.Adopt(obj); EXPECT_THAT(obj->GetReferenceCount(), Eq(1)); EXPECT_THAT(obj->ObjectPtrCount(), Eq(1)); } } nux-4.0.6+14.04.20140409/tests/Readme.txt0000644000015301777760000000405612321344237020042 0ustar pbusernogroup00000000000000 Automated Tests --------------- Since the instruction for the simulated events are comming from a separate thread, the tests are very sensible to timing and can generate false negatives. For this reason, in some location of the code, there are sleeping periodes that have been added to allow time for events to be processed and for results to be generated. All test must be over in 20 seconds or less. Note on the Test: When using the nux::TestView class, a small white square at the top left corner of the TestView area indicate that the view has keyboard focus. Description of tests: --------------------- graphics_display_states: Test the graphics display states after it has been created. empty_window: Display an empty window and close it after 3 seconds. xtest-button: Using XTest, love the mouse around the boundaries of a button view and simulate click and drag mouse events. The program close itself after a delay. xtest-mouse-events: Test the following mouse events: - mouse down - mouse up - mouse click - mouse double-click - mouse drag - mouse enter - mouse leave - mouse move xtest-mouse-buttons: Make sure that only physical mouse button 1, 2 and 3 generate mouse-down and mouse-up events. The artificial button event 4 and 5 should not generate mouse-down or mouse-up events. xtest-hgrid-key-navigation Make sure that the key navigation works well in a GridHLayout. xtest-hlayout-key-navigation Make sure that the key naviagation works well in a HLayout. xtest-vlayout-key-navigation Make sure that the key navigation works well in a VLayout. xtest-focus-on-mouse-down Make sure that AcceptKeyNavFocusOnMouseDown works well. xtest-focus-on-mouse-enter Make sure that AcceptKeyNavFocusOnMouseEnter works well. xtest-keynav-direction Test key navigation. Especially test the direction a key nav is coming from when the view is getting the focus. xtest-text-entry Simulate various operations on the text entry xtest-text-entry-logic Test the state of TextEntry::text_input_mode_ before and after some text is typed in. nux-4.0.6+14.04.20140409/tests/gtest-nux-inputmethodibus.cpp0000644000015301777760000000572212321344237023770 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Marco Trevisan * */ #include #include "Nux/Nux.h" #include "Nux/InputMethodIBus.h" using namespace nux; class MockIBusIMEContext : public IBusIMEContext { public: static std::vector ParseIBusHotkeys(const gchar** keybindings) { return IBusIMEContext::ParseIBusHotkeys(keybindings); } }; namespace { TEST(TestIBusIMEContext, ParseNullHotkeys) { auto hotkeys = MockIBusIMEContext::ParseIBusHotkeys(nullptr); EXPECT_TRUE(hotkeys.empty()); } TEST(TestIBusIMEContext, ParseInvalidHotkeys) { const gchar* invalid_code[] = {"Alt+InvalidCode", nullptr }; auto hotkeys = MockIBusIMEContext::ParseIBusHotkeys(invalid_code); EXPECT_TRUE(hotkeys.empty()); const gchar* missing_key[] = {"Alt+Control", nullptr }; hotkeys = MockIBusIMEContext::ParseIBusHotkeys(missing_key); EXPECT_TRUE(hotkeys.empty()); } TEST(TestIBusIMEContext, ParseHotkeys) { const gchar* keybindings[] = {"Control+space", "Zenkaku_Hankaku", "Alt+Kanji", "Alt+grave", "Hangul", "Alt+Release+Alt_R", "Alt+Control+Release+Shift_L", nullptr}; auto hotkeys = MockIBusIMEContext::ParseIBusHotkeys(keybindings); ASSERT_EQ(hotkeys.size(), 7); auto event = hotkeys[0]; EXPECT_EQ(event.type, NUX_KEYDOWN); EXPECT_EQ(event.key_modifiers, KEY_MODIFIER_CTRL); EXPECT_EQ(event.x11_keysym, XK_space); event = hotkeys[1]; EXPECT_EQ(event.type, NUX_KEYDOWN); EXPECT_EQ(event.key_modifiers, 0); EXPECT_EQ(event.x11_keysym, XK_Zenkaku_Hankaku); event = hotkeys[2]; EXPECT_EQ(event.type, NUX_KEYDOWN); EXPECT_EQ(event.key_modifiers, KEY_MODIFIER_ALT); EXPECT_EQ(event.x11_keysym, XK_Kanji); event = hotkeys[3]; EXPECT_EQ(event.type, NUX_KEYDOWN); EXPECT_EQ(event.key_modifiers, KEY_MODIFIER_ALT); EXPECT_EQ(event.x11_keysym, XK_grave); event = hotkeys[4]; EXPECT_EQ(event.type, NUX_KEYDOWN); EXPECT_EQ(event.key_modifiers, 0); EXPECT_EQ(event.x11_keysym, XK_Hangul); event = hotkeys[5]; EXPECT_EQ(event.type, NUX_KEYUP); EXPECT_EQ(event.key_modifiers, KEY_MODIFIER_ALT); EXPECT_EQ(event.x11_keysym, XK_Alt_R); event = hotkeys[6]; EXPECT_EQ(event.type, NUX_KEYUP); EXPECT_EQ(event.key_modifiers, (KEY_MODIFIER_ALT | KEY_MODIFIER_CTRL)); EXPECT_EQ(event.x11_keysym, XK_Shift_L); } } nux-4.0.6+14.04.20140409/tests/xtest-text-entry-deadkeys.cpp0000644000015301777760000003440712321344237023672 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/TextEntry.h" #include "Nux/InputMethodIBus.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" class TextTextEntry: public ProgramTemplate { public: TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span); ~TextTextEntry(); virtual void UserInterfaceSetup(); void TextEntryClick(nux::TextEntry* text_entry); void ResetEvents(); nux::TextEntry* text_entry_; bool clicked_; }; TextTextEntry::TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { ResetEvents(); text_entry_ = NULL; } TextTextEntry::~TextTextEntry() { } void TextTextEntry::ResetEvents() { clicked_ = false; } void TextTextEntry::TextEntryClick(nux::TextEntry* text_entry) { if (text_entry_ == text_entry) { clicked_ = true; } } void TextTextEntry::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); text_entry_ = new nux::TextEntry("", NUX_TRACKER_LOCATION); text_entry_->SetFontSize(76); main_layout->AddView(text_entry_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->SetSpaceBetweenChildren(10); main_layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } TextTextEntry* test_textentry = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (test_textentry->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1300); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); test.TestReportMsg(test_textentry->text_entry_, "TextEntry created"); test_textentry->ResetEvents(); test.ViewSendMouseMotionToCenter(test_textentry->text_entry_); test.ViewSendMouseClick(0, 1); if (test.CompositionKeysSupported()) { test.ViewSendCompositionKeys("`o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ò", "ò"); test.ViewSendCompositionKeys("~o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõ", "òõ"); test.ViewSendCompositionKeys("^o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô", "òõô"); test.ViewSendCompositionKeys("c="); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€", "òõô€"); test.ViewSendCompositionKeys("oc"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€©", "òõô€©"); test.ViewSendCompositionKeys("\"w"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€©ẅ", "òõô€©ẅ"); test.ViewSendCompositionKeys("'S"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€©ẅŚ", "òõô€©ẅŚ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //exclamdown # INVERTED EXCLAMATION MARK test.ViewSendCompositionKeys("!!"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¡", "¡"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //CENT SIGN test.ViewSendCompositionKeys("|c"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¢", "¢"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //POUND SIGN test.ViewSendCompositionKeys("-L"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "£", "£"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //currency # CURRENCY SIGN test.ViewSendCompositionKeys("xo"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¤", "¤"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //yen # YEN SIGN test.ViewSendCompositionKeys("Y="); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¥", "¥"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //FEMININE ORDINAL INDICATOR test.ViewSendCompositionKeys("^_a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ª", "ª"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //guillemotleft # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK test.ViewSendCompositionKeys("<<"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "«", "«"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //SUPERSCRIPT THREE test.ViewSendCompositionKeys("^3"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "³", "³"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //MIDDLE DOT test.ViewSendCompositionKeys(".."); test.TestReportMsg(test_textentry->text_entry_->GetText() == "·", "·"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //cedilla # CEDILLA test.ViewSendCompositionKeys(", "); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¸", "¸"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //VULGAR FRACTION THREE QUARTERS test.ViewSendCompositionKeys("34"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¾", "¾"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //questiondown # INVERTED QUESTION MARK test.ViewSendCompositionKeys("??"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¿", "¿"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH GRAVE test.ViewSendCompositionKeys("`A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "À", "À"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH ACUTE test.ViewSendCompositionKeys("'A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Á", "Á"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH CIRCUMFLEX test.ViewSendCompositionKeys("^A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Â", "Â"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH TILDE test.ViewSendCompositionKeys("~A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ã", "Ã"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH DIAERESIS test.ViewSendCompositionKeys("\"A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ä", "Ä"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH RING ABOVE test.ViewSendCompositionKeys("oA"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Å", "Å"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //AE # LATIN CAPITAL LETTER AE test.ViewSendCompositionKeys("AE"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Æ", "Æ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //ssharp # LATIN SMALL LETTER SHARP S test.ViewSendCompositionKeys("ss"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ß", "ß"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH GRAVE test.ViewSendCompositionKeys("`a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "à", "à"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH ACUTE test.ViewSendCompositionKeys("'a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "á", "á"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH CIRCUMFLEX test.ViewSendCompositionKeys("^a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "â", "â"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH TILDE test.ViewSendCompositionKeys("~a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ã", "ã"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH DIAERESIS test.ViewSendCompositionKeys("\"a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ä", "ä"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH RING ABOVE test.ViewSendCompositionKeys("oa"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "å", "å"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //ae # LATIN SMALL LETTER AE test.ViewSendCompositionKeys("ae"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "æ", "æ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //DIVISION SIGN test.ViewSendCompositionKeys("-:"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "÷", "÷"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH OGONEK test.ViewSendCompositionKeys(";A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ą", "Ą"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH OGONEK test.ViewSendCompositionKeys(";a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ą", "ą"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH CARON test.ViewSendCompositionKeys("cA"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ǎ", "Ǎ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //EN DASH test.ViewSendCompositionKeys("--."); test.TestReportMsg(test_textentry->text_entry_->GetText() == "–", "–"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //RIGHT SINGLE QUOTATION MARK test.ViewSendCompositionKeys(">'"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "’", "’"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //LEFT DOUBLE QUOTATION MARK test.ViewSendCompositionKeys("<\""); test.TestReportMsg(test_textentry->text_entry_->GetText() == "“", "“"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //RIGHT DOUBLE QUOTATION MARK test.ViewSendCompositionKeys("\">"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "”", "”"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //DOUBLE LOW-9 QUOTATION MARK test.ViewSendCompositionKeys("\","); test.TestReportMsg(test_textentry->text_entry_->GetText() == "„", "„"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //PER MILLE SIGN test.ViewSendCompositionKeys("%o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "‰", "‰"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //SINGLE RIGHT-POINTING ANGLE QUOTATION MARK test.ViewSendCompositionKeys(".>"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "›", "›"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //EuroSign # EURO SIGN test.ViewSendCompositionKeys("=E"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "€", "€"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //REVERSED DOUBLE PRIME QUOTATION MARK test.ViewSendCompositionKeys("\"\\"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "〝", "〝"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); } else { test.WarnCompositionKeysNotSupported(); } if (test.WhenDoneTerminateProgram()) { wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); test_textentry = new TextTextEntry("Text Entry: Composition Characters", 600, 200, 40000); test_textentry->Startup(); test_textentry->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(NULL, &TestingThread, test_textentry->GetWindowThread()); test_thread->Start(test_textentry); test_textentry->Run(); delete test_thread; delete test_textentry; return 0; } nux-4.0.6+14.04.20140409/tests/xtest-text-entry-xim.cpp0000644000015301777760000002401212321344237022665 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Brandon Schaefer * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/TextEntry.h" #include "Nux/InputMethodIBus.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" #include #include #include #include #include class TextTextEntry: public ProgramTemplate { public: TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span); ~TextTextEntry(); virtual void UserInterfaceSetup(); void TextEntryClick(nux::TextEntry* text_entry); void OnActivated(); void OnCursorMoved(int); void ResetEvents(); nux::TextEntry* text_entry_; bool clicked_; bool activated_; bool cursor_moved_; }; TextTextEntry::TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) , clicked_(false) , activated_(false) , cursor_moved_(false) { ResetEvents(); text_entry_ = NULL; } TextTextEntry::~TextTextEntry() { } void TextTextEntry::ResetEvents() { clicked_ = false; activated_ = false; cursor_moved_ = false; } void TextTextEntry::TextEntryClick(nux::TextEntry* text_entry) { if (text_entry_ == text_entry) { clicked_ = true; } } void TextTextEntry::OnActivated() { activated_ = true; } void TextTextEntry::OnCursorMoved(int position) { cursor_moved_ = true; } void TextTextEntry::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); text_entry_ = new nux::TextEntry("", NUX_TRACKER_LOCATION); text_entry_->activated.connect(sigc::mem_fun(this, &TextTextEntry::OnActivated)); text_entry_->cursor_moved.connect(sigc::mem_fun(this, &TextTextEntry::OnCursorMoved)); text_entry_->SetFontSize(76); main_layout->AddView(text_entry_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->SetSpaceBetweenChildren(10); main_layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } TextTextEntry* test_textentry = NULL; // Returns dynamic memory, delete me! char* ReadInCommands(const char* path) { char* raw_file = NULL; long size; std::ifstream file(path, std::ios::in|std::ios::ate); if (file.is_open()) { size = file.tellg(); raw_file = new char[size+1]; file.seekg (0, std::ios::beg); file.read(raw_file, size); file.close(); } return raw_file; } void TokenizeCommands(char* raw_cmds, std::queue& token_queue) { int i = 0; int size = strlen(raw_cmds); while (i < size) { if (raw_cmds[i] == '/' && raw_cmds[i+1] == '/') { while (raw_cmds[i] != '\n' && i < size) { i++; } i++; } else if (raw_cmds[i] >= '0' && raw_cmds[i] <= '9') { std::string num = ""; while (raw_cmds[i] != ' ' && i < size) { num += raw_cmds[i]; i++; } token_queue.push(num); while (raw_cmds[i] == ' ') {i++;} std::string cmd = ""; while (raw_cmds[i] != '\n' && raw_cmds[i] != '\0' && i < size) { cmd += raw_cmds[i]; i++; } token_queue.push(cmd); } else { i++; } } } void KillInputMethod(const char* im_name) { FILE* f_ptr; char pgrep[128] = "pgrep "; char pid[128]; char* last = NULL; int cur_pid = 0; strcat(pgrep, im_name); if ((f_ptr = popen(pgrep, "r")) == NULL) return; while(fgets(pid, 128, f_ptr) != NULL) { cur_pid = strtol(pid, &last, 10); if (*last == '\0' || *last == '\n') { // Make sure it's dead kill(cur_pid, SIGKILL); kill(cur_pid, SIGSTOP); } } pclose(f_ptr); } void KillCurrentInputMethod() { const char* xmodifier; xmodifier = getenv("XMODIFIERS"); if (!xmodifier) return; KillInputMethod(strchr(xmodifier, '=')+1); } /* 0 - Name of Input method 1 - what keys we should press 2 - what to type 3 - what to expect 4 - we are done with this IM CFG (If someone complains that we need to check the input) **Note I cheated with Key, Letter and CJK...can be filled in S -> 0 L | 1 K | 2 L | 3 C | 4 K -> K+K | L -> LL | C -> CC | example: 0 fcitx 1 ctrl+space 2 ninhao Abstract Syntax IM = 0 KeyStrokes= 1 | 1 | 1 | 1 Input = 2 Expect = 3 Halt = 4 halt 0 -> popen(im_name) 1 -> RunKeyStrokes(keys) 2 -> TypeInput(input) 3 -> CheckInput(cjk) 4 -> pclose(im_name) */ std::vector& GetSplitEnvPath() { static std::vector split_path; if (split_path.empty()) { std::string tmp; size_t colon_ptr = 0, start_ptr = 0; const std::string env_path(getenv("PATH")); if (!env_path.empty()) { // Splits the env path var up on (":") while (colon_ptr != std::string::npos) { colon_ptr = env_path.find(":", start_ptr); tmp = env_path.substr(start_ptr, (colon_ptr-start_ptr)); start_ptr = colon_ptr+1; split_path.push_back(tmp); } } } return split_path; } bool CheckIMExist(const char* im_name) { std::vector split_path = GetSplitEnvPath(); std::string command("ls "); char buf [128]; FILE* path = NULL; for (unsigned int i = 0; i < split_path.size(); i++) { if ((path = popen((command + split_path[i]).c_str(),"r")) == NULL) return false; while (fgets(buf, 128, path) != NULL) { if (strstr(buf, im_name)) return true; } } return false; } FILE* OpenIM(const char* im_name) { FILE* open_file = NULL; if (CheckIMExist(im_name)) { open_file = popen(im_name,"r"); nux::SleepForMilliseconds(500); } return open_file; } bool CheckInput(const std::string cjk, NuxAutomatedTestFramework* test) { std::string message("Test is: " + cjk); test->TestReportMsg(test_textentry->text_entry_->GetText() == cjk, message.c_str()); test->ViewSendCtrlA(); nux::SleepForMilliseconds(500); test->ViewSendDelete(); nux::SleepForMilliseconds(500); return true; } std::string next_token (std::queue& tokens) { std::string next_token; if (!tokens.empty()) { next_token = tokens.front(); tokens.pop(); } return next_token; } bool RunCommands(std::queue& tokens, NuxAutomatedTestFramework* test) { std::string next_cmd; std::string im_name; std::string cur_cmd = next_token(tokens); FILE* start_im = NULL; while (!tokens.empty()) { next_cmd = next_token(tokens); if (cur_cmd == "0") { if ((start_im = OpenIM(next_cmd.c_str())) != NULL) { im_name = next_cmd.c_str(); nux::SleepForMilliseconds(500); } else { fprintf(stderr, "Command not found: %s\n", next_cmd.c_str()); // Skip the test while (cur_cmd != "4") { cur_cmd = next_token(tokens); } next_cmd = next_token(tokens); } } else if (cur_cmd == "1") { test->ViewSendKeys(next_cmd); } else if (cur_cmd == "2") { test->ViewSendString(next_cmd); } else if (cur_cmd == "3") { CheckInput(next_cmd, test); } else if (cur_cmd == "4") { KillInputMethod(im_name.c_str()); pclose(start_im); } else { fprintf(stderr, "Error - Incorrect command: %s\n", cur_cmd.c_str()); return false; } nux::SleepForMilliseconds(500); cur_cmd = next_token(tokens); } return true; } void TestingThread(nux::NThread* thread, void* user_data) { while (test_textentry->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1300); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); test.TestReportMsg(test_textentry->text_entry_, "TextEntry created"); test_textentry->ResetEvents(); test.ViewSendMouseMotionToCenter(test_textentry->text_entry_); test.ViewSendMouseClick(0,1); std::queue tokens; char* raw_commands; // Just kills what should be the current IM (if there is one) KillCurrentInputMethod(); raw_commands = ReadInCommands("xim-test-commands.txt"); if (raw_commands) { TokenizeCommands(raw_commands, tokens); delete raw_commands; RunCommands(tokens, &test); } if (test.WhenDoneTerminateProgram()) { wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main(int argc, char** argv) { int xstatus = XInitThreads(); nuxAssertMsg(xstatus > 0, "XInitThreads has failed"); test_textentry = new TextTextEntry("Text Entry", 600, 200, 40000); test_textentry->Startup(); test_textentry->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(NULL, &TestingThread, test_textentry->GetWindowThread()); test_thread->Start(test_textentry); test_textentry->Run(); delete test_thread; delete test_textentry; return 0; } nux-4.0.6+14.04.20140409/tests/test-system.cpp0000644000015301777760000000513112321344237021104 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/Button.h" //static void TestMainWindow(void); //static void TestMainWindowStatus(void); //static void TestMainWindowSize(void); void TestSystemSuite (void) { #define TESTDOMAIN "/System/" // g_test_add_func (TESTDOMAIN"/TestMainWindow", TestMainWindow); // g_test_add_func (TESTDOMAIN"/TestMainWindowStatus", TestMainWindowStatus); // g_test_add_func (TESTDOMAIN"/TestMainWindowSize", TestMainWindowSize); } /* static void TestMainWindow (void) { // Warning: on windows the window can not be physically smaller than ~120x100 nux::WindowThread* wt = nux::CreateGUIThread(TEXT("TestMainWindow"), 120, 100, 0, 0, 0); g_assert (wt != 0); g_assert (nux::GetGraphicsThread () == wt); delete wt; } static void TestMainWindowStatus (void) { // Warning: on windows the window can not be physically smaller than ~120x100 nux::WindowThread* wt = nux::CreateGUIThread(TEXT("TestMainWindowStatus"), 120, 100, 0, 0, 0); g_assert (wt != 0); g_assert (nux::GetGraphicsThread () == wt); //g_assert (nux::GetWindow ().IsWindowVisible () == false); //nux::GetWindow ().ShowWindow (); //g_assert (nux::GetWindow ().IsWindowVisible () == true); //nux::GetWindow ().HideWindow (); //g_assert (nux::GetWindow ().IsWindowVisible () == false); delete wt; } static void TestMainWindowSize (void) { // Warning: on windows the window can not be physically smaller than ~120x100 nux::WindowThread* wt = nux::CreateGUIThread(TEXT("TestMainWindowSize"), 120, 100, 0, 0, 0); nux::GetWindow ().ShowWindow (); g_assert (wt != 0); g_assert (nux::GetGraphicsThread () == wt); g_assert (nux::GetWindow ().GetWindowWidth () == 120); g_assert (nux::GetWindow ().GetWindowHeight () == 100); delete wt; }*/ nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-color.cpp0000644000015301777760000002472212321344237022535 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include #include "NuxCore/Color.h" using namespace testing; static const float epsilon = 0.005f; namespace { TEST(TestColor, TestColorConstructor0) { nux::Color c; EXPECT_EQ(c.red, 0.0f); EXPECT_EQ(c.green, 0.0f); EXPECT_EQ(c.blue, 0.0f); EXPECT_EQ(c.alpha, 1.0); EXPECT_EQ(c.IsPremultiplied(), false); } TEST(TestColor, TestColorConstructor1) { // testing float inputs nux::Color c0(0.1f, 0.2f, 0.3f); EXPECT_EQ(c0.red, 0.1f); EXPECT_EQ(c0.green, 0.2f); EXPECT_EQ(c0.blue, 0.3f); EXPECT_EQ(c0.alpha, 1.0f); EXPECT_EQ(c0.IsPremultiplied(), false); // testing float inputs nux::Color c1(0.1f, 0.2f, 0.3f, 0.4f); EXPECT_EQ(c1.red, 0.1f); EXPECT_EQ(c1.green, 0.2f); EXPECT_EQ(c1.blue, 0.3f); EXPECT_EQ(c1.alpha, 0.4f); EXPECT_EQ(c1.IsPremultiplied(), false); // testing double inputs nux::Color c2(0.1, 0.2, 0.3, 0.4); EXPECT_EQ(c2.red, 0.1f); EXPECT_EQ(c2.green, 0.2f); EXPECT_EQ(c2.blue, 0.3f); EXPECT_EQ(c2.alpha, 0.4f); EXPECT_EQ(c2.IsPremultiplied(), false); } TEST(TestColor, TestColorConstructor2) { nux::Color c0(255, 255, 255); EXPECT_EQ(c0.red, 1.0f); EXPECT_EQ(c0.green, 1.0f); EXPECT_EQ(c0.blue, 1.0f); EXPECT_EQ(c0.alpha, 1.0f); EXPECT_EQ(c0.IsPremultiplied(), false); nux::Color c1(10, 128, 192); EXPECT_EQ(c1.red, 10/255.0f); EXPECT_EQ(c1.green, 128/255.0f); EXPECT_EQ(c1.blue, 192/255.0f); EXPECT_EQ(c1.alpha, 1.0f); EXPECT_EQ(c1.IsPremultiplied(), false); } TEST(TestColor, TestColorConstructor3) { nux::Color c0((255<<24)|(255<<16)|(255<<8)|255); EXPECT_EQ(c0.red, 1.0f); EXPECT_EQ(c0.green, 1.0f); EXPECT_EQ(c0.blue, 1.0f); EXPECT_EQ(c0.alpha, 1.0f); EXPECT_EQ(c0.IsPremultiplied(), false); // A R G B nux::Color c1((128<<24)|(192<<16)|(128<<8)|10); EXPECT_EQ(c1.red, 192/255.0f); EXPECT_EQ(c1.green, 128/255.0f); EXPECT_EQ(c1.blue, 10/255.0f); EXPECT_EQ(c1.alpha, 128/255.0f); EXPECT_EQ(c1.IsPremultiplied(), false); } TEST(TestColor, TestColorConstructorHex) { nux::Color c0("#abc"); EXPECT_EQ(c0.red, 0xaa / 255.0f); EXPECT_EQ(c0.green, 0xbb / 255.0f); EXPECT_EQ(c0.blue, 0xcc / 255.0f); EXPECT_EQ(c0.alpha, 1.0f); EXPECT_EQ(c0.IsPremultiplied(), false); nux::Color c1("#abcd"); EXPECT_EQ(c1.red, 0xaa / 255.0f); EXPECT_EQ(c1.green, 0xbb / 255.0f); EXPECT_EQ(c1.blue, 0xcc / 255.0f); EXPECT_EQ(c1.alpha, 0xdd / 255.0f); EXPECT_EQ(c1.IsPremultiplied(), false); nux::Color c2("#aabbcc"); EXPECT_EQ(c2.red, 0xaa / 255.0f); EXPECT_EQ(c2.green, 0xbb / 255.0f); EXPECT_EQ(c2.blue, 0xcc / 255.0f); EXPECT_EQ(c2.alpha, 1.0f); EXPECT_EQ(c2.IsPremultiplied(), false); nux::Color c3("#aabbccdd"); EXPECT_EQ(c3.red, 0xaa / 255.0f); EXPECT_EQ(c3.green, 0xbb / 255.0f); EXPECT_EQ(c3.blue, 0xcc / 255.0f); EXPECT_EQ(c3.alpha, 0xdd / 255.0f); EXPECT_EQ(c3.IsPremultiplied(), false); nux::Color c4("abcdef"); EXPECT_EQ(c4.red, 0xab / 255.0f ); EXPECT_EQ(c4.green, 0xcd / 255.0f); EXPECT_EQ(c4.blue, 0xef / 255.0f); EXPECT_EQ(c4.alpha, 1.0f); EXPECT_EQ(c4.IsPremultiplied(), false); } TEST(TestColor, TestColorConstructorHexInvalid) { nux::Color c0(""); EXPECT_EQ(c0.red, 0.0f); EXPECT_EQ(c0.green, 0.0f); EXPECT_EQ(c0.blue, 0.0f); EXPECT_EQ(c0.alpha, 1.0f); EXPECT_EQ(c0.IsPremultiplied(), false); nux::Color c1("#abcdeG"); EXPECT_EQ(c0.red, 0.0f); EXPECT_EQ(c0.green, 0.0f); EXPECT_EQ(c0.blue, 0.0f); EXPECT_EQ(c0.alpha, 1.0f); EXPECT_EQ(c1.IsPremultiplied(), false); } TEST(TestColor, TestColorPremultiplied0) { nux::Color c0(0.81f, 0.24f, 0.53f, 0.79f); EXPECT_EQ(c0.red, 0.81f); EXPECT_EQ(c0.green, 0.24f); EXPECT_EQ(c0.blue, 0.53f); EXPECT_EQ(c0.alpha, 0.79f); EXPECT_EQ(c0.IsPremultiplied(), false); nux::Color c1 = c0.GetPremultiplied(); EXPECT_EQ(c1.red, 0.81f * 0.79f); EXPECT_EQ(c1.green, 0.24f * 0.79f); EXPECT_EQ(c1.blue, 0.53f * 0.79f); EXPECT_EQ(c1.alpha, 0.79f); EXPECT_EQ(c1.IsPremultiplied(), true); EXPECT_EQ(c0.IsPremultiplied(), false); } TEST(TestColor, TestColorRGBToHSV0) { nux::color::RedGreenBlue rgb(255/255.0f, 128/255.0f, 169/255.0f); nux::color::HueSaturationValue hsv(rgb); EXPECT_NEAR(hsv.hue, 341/360.0f, epsilon); EXPECT_NEAR(hsv.saturation, 50/100.0f, epsilon); EXPECT_NEAR(hsv.value, 100/100.0f, epsilon); } TEST(TestColor, TestColorHSVToRGB0) { nux::color::HueSaturationValue hsv(341/360.0f, 50/100.0f, 100/100.0f); nux::color::RedGreenBlue rgb(hsv); EXPECT_NEAR(rgb.red, 255/255.0f, epsilon); EXPECT_NEAR(rgb.green, 128/255.0f, epsilon); EXPECT_NEAR(rgb.blue, 169/255.0f, epsilon); } TEST(TestColor, TestColorRGBToHSV1) { nux::color::RedGreenBlue rgb(65/255.0f, 28/255.0f, 6/255.0f); nux::color::HueSaturationValue hsv(rgb); EXPECT_NEAR(hsv.hue, 22/360.0f, epsilon); EXPECT_NEAR(hsv.saturation, 91/100.0f, epsilon); EXPECT_NEAR(hsv.value, 25/100.0f, epsilon); } TEST(TestColor, TestColorHSVToRGB1) { nux::color::HueSaturationValue hsv(22/360.0f, 91/100.0f, 25/100.0f); nux::color::RedGreenBlue rgb(hsv); EXPECT_NEAR(rgb.red, 65/255.0f, epsilon); EXPECT_NEAR(rgb.green, 28/255.0f, epsilon); EXPECT_NEAR(rgb.blue, 6/255.0f, epsilon); } TEST(TestColor, TestColorRGBToHSV2) { nux::color::RedGreenBlue rgb(90/255.0f, 65/255.0f, 158/255.0f); nux::color::HueSaturationValue hsv(rgb); EXPECT_NEAR(hsv.hue, 256/360.0f, epsilon); EXPECT_NEAR(hsv.saturation, 59/100.0f, epsilon); EXPECT_NEAR(hsv.value, 62/100.0f, epsilon); } TEST(TestColor, TestColorHSVToRGB2) { nux::color::HueSaturationValue hsv(256/360.0f, 59/100.0f, 62/100.0f); nux::color::RedGreenBlue rgb(hsv); EXPECT_NEAR(rgb.red, 90/255.0f, epsilon); EXPECT_NEAR(rgb.green, 65/255.0f, epsilon); EXPECT_NEAR(rgb.blue, 158/255.0f, epsilon); } TEST(TestColor, TestColorRGBToHLS0) { nux::color::RedGreenBlue rgb(127/255.0f, 0/255.0f, 255/255.0f); nux::color::HueLightnessSaturation hls(rgb); EXPECT_NEAR(hls.hue, 270/360.0f, epsilon); EXPECT_NEAR(hls.lightness, 50/100.0f, epsilon); EXPECT_NEAR(hls.saturation, 100/100.0f, epsilon); } TEST(TestColor, TestColorHLSToRGB0) { nux::color::HueLightnessSaturation hls(270/360.0f, 50/100.0f, 100/100.0f); nux::color::RedGreenBlue rgb(hls); EXPECT_NEAR(rgb.red, 127/255.0f, epsilon); EXPECT_NEAR(rgb.green, 0/255.0f, epsilon); EXPECT_NEAR(rgb.blue, 255/255.0f, epsilon); } TEST(TestColor, TestColorRGBToHLS1) { nux::color::RedGreenBlue rgb(50/255.0f, 84/255.0f, 13/255.0f); nux::color::HueLightnessSaturation hls(rgb); EXPECT_NEAR(hls.hue, 89/360.0f, epsilon); EXPECT_NEAR(hls.lightness, 19/100.0f, epsilon); EXPECT_NEAR(hls.saturation, 73/100.0f, epsilon); } TEST(TestColor, TestColorHLSToRGB1) { nux::color::HueLightnessSaturation hls(89/360.0f, 19/100.0f, 73/100.0f); nux::color::RedGreenBlue rgb(hls); EXPECT_NEAR(rgb.red, 50/255.0f, epsilon); EXPECT_NEAR(rgb.green, 84/255.0f, epsilon); EXPECT_NEAR(rgb.blue, 13/255.0f, epsilon); } TEST(TestColor, TestColorRGBToHLS2) { nux::color::RedGreenBlue rgb(201/255.0f, 200/255.0f, 239/255.0f); nux::color::HueLightnessSaturation hls(rgb); EXPECT_NEAR(hls.hue, 242/360.0f, epsilon); EXPECT_NEAR(hls.lightness, 86/100.0f, epsilon); EXPECT_NEAR(hls.saturation, 55/100.0f, epsilon); } TEST(TestColor, TestColorHLSToRGB2) { nux::color::HueLightnessSaturation hls(242/360.0f, 86/100.0f, 55/100.0f); nux::color::RedGreenBlue rgb(hls); EXPECT_NEAR(rgb.red, 201/255.0f, epsilon); EXPECT_NEAR(rgb.green, 200/255.0f, epsilon); EXPECT_NEAR(rgb.blue, 239/255.0f, epsilon); } TEST(TestColor, TestSubtraction) { nux::Color start = nux::Color(1.0f, 0.0f, 0.0f); nux::Color finish = nux::Color(0.0f, 0.5f, 0.0f); nux::Color difference = finish - start; EXPECT_THAT(difference.red, FloatEq(-1)); EXPECT_THAT(difference.green, FloatEq(0.5)); EXPECT_THAT(difference.blue, FloatEq(0)); EXPECT_THAT(difference.alpha, FloatEq(0)); } TEST(TestColor, TestColorToRGB) { nux::Color color = nux::Color(0.3f, 0.8f, 0.1f, 0.5f); nux::color::RedGreenBlue rgb = color; EXPECT_EQ(rgb.red, color.red); EXPECT_EQ(rgb.green, color.green); EXPECT_EQ(rgb.blue, color.blue); } TEST(TestColor, TestRandomColor) { float rmin = 1.0f; float rmax = 0.0f; float gmin = 1.0f; float gmax = 0.0f; float bmin = 1.0f; float bmax = 0.0f; for (int i = 0; i < 100; ++i) { nux::Color c = nux::color::RandomColor(); EXPECT_EQ(1.0f, c.alpha); rmin = std::min(rmin, c.red); rmax = std::max(rmax, c.red); gmin = std::min(gmin, c.green); gmax = std::max(gmax, c.green); bmin = std::min(bmin, c.blue); bmax = std::max(bmax, c.blue); } // Ultra unlikely that we create 100 identical values in a row. // The universe will end long before this happens. EXPECT_NE(rmin, rmax); EXPECT_NE(gmin, gmax); EXPECT_NE(bmin, bmax); // Values must have changed from the initial settings EXPECT_NE(1.0f, rmin); EXPECT_NE(0.0f, rmax); EXPECT_NE(1.0f, gmin); EXPECT_NE(0.0f, gmax); EXPECT_NE(1.0f, bmin); EXPECT_NE(0.0f, bmax); } } nux-4.0.6+14.04.20140409/tests/test-nux.cpp0000644000015301777760000000254712321344237020402 0ustar pbusernogroup00000000000000/* * Copyright (C) 2010 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by Gordon Allott * */ #include #include #include #include #include void TestCanvasSuite(); void TestSystemSuite(); void test_timeline_create_suite (); gint main (gint argc, gchar *argv[]) { #if G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION) <= GLIB_VERSION_2_34 g_type_init(); #endif g_test_init (&argc, &argv, NULL); nux::NuxInitialize(0); // Do not print Nux log messages to the console. GLogDevice.Disable (); /* First the Nux specific tests */ TestSystemSuite(); // TODO: fix the test // TestCanvasSuite(); /* Please keep this alphabetically ordered */ //test_timeline_create_suite (); return g_test_run (); } nux-4.0.6+14.04.20140409/tests/gtest-nux-globals.h0000644000015301777760000000022012321344237021621 0ustar pbusernogroup00000000000000#ifndef GTEST_NUX_GLOBALS_H #define GTEST_NUX_GLOBALS_H #include extern gint64 g_fake_monotonic_time; #endif // GTEST_NUX_GLOBALS_H nux-4.0.6+14.04.20140409/tests/xtest-keynav-directions.cpp0000644000015301777760000001451612321344237023415 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" class KeyNavDirectionTest: public ProgramTemplate { public: KeyNavDirectionTest(const char *program_name, int window_width, int window_height, int program_life_span); ~KeyNavDirectionTest(); virtual void UserInterfaceSetup(); nux::TestView* view0_; nux::TestView* view1_; nux::TestView* view2_; nux::TestView* view3_; }; KeyNavDirectionTest::KeyNavDirectionTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) , view0_(NULL) , view1_(NULL) , view2_(NULL) , view3_(NULL) { } KeyNavDirectionTest::~KeyNavDirectionTest() { } void KeyNavDirectionTest::UserInterfaceSetup() { nux::HLayout* main_layout = new nux::HLayout(NUX_TRACKER_LOCATION); main_layout->SetSpaceBetweenChildren(10); main_layout->SetPadding(10, 10); nux::VLayout* layout0 = new nux::VLayout(NUX_TRACKER_LOCATION); nux::VLayout* layout1 = new nux::VLayout(NUX_TRACKER_LOCATION); layout0->SetSpaceBetweenChildren(10); layout1->SetSpaceBetweenChildren(10); view0_ = new nux::TestView(NUX_TRACKER_LOCATION); view0_->can_focus_ = true; view0_->SetAcceptKeyNavFocusOnMouseDown(true); layout0->AddView(view0_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); view1_ = new nux::TestView(NUX_TRACKER_LOCATION); view1_->can_focus_ = true; view1_->SetAcceptKeyNavFocusOnMouseDown(true); layout0->AddView(view1_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); view2_ = new nux::TestView(NUX_TRACKER_LOCATION); view2_->can_focus_ = true; view2_->SetAcceptKeyNavFocusOnMouseDown(true); layout1->AddView(view2_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); view3_ = new nux::TestView(NUX_TRACKER_LOCATION); view3_->can_focus_ = true; view3_->SetAcceptKeyNavFocusOnMouseDown(true); layout1->AddView(view3_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->AddLayout(layout0, 1); main_layout->AddLayout(layout1, 1); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } KeyNavDirectionTest* keynav_direction_test = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (keynav_direction_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread *wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); // Move mouse to center of view0_ test.ViewSendMouseMotionToCenter(keynav_direction_test->view0_); // Mouse down/up on view0_ test.ViewSendMouseClick(keynav_direction_test->view0_, 1); nux::SleepForMilliseconds(500); test.SendFakeKeyEvent(XK_Down, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(keynav_direction_test->view1_->has_focus_ && (keynav_direction_test->view1_->key_nav_direction_ == nux::KEY_NAV_DOWN), "View1 received key nav from top"); test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(keynav_direction_test->view0_->has_focus_ && (keynav_direction_test->view0_->key_nav_direction_ == nux::KEY_NAV_UP), "View0 received key nav from bottom"); test.SendFakeKeyEvent(XK_Right, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(keynav_direction_test->view2_->has_focus_ && (keynav_direction_test->view0_->key_nav_direction_ == nux::KEY_NAV_RIGHT), "View2 received key nav from left"); test.SendFakeKeyEvent(XK_Down, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(keynav_direction_test->view3_->has_focus_ && (keynav_direction_test->view3_->key_nav_direction_ == nux::KEY_NAV_DOWN), "View3 received key nav from top"); test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(keynav_direction_test->view2_->has_focus_ && (keynav_direction_test->view2_->key_nav_direction_ == nux::KEY_NAV_UP), "View2 received key nav from bottom"); test.SendFakeKeyEvent(XK_Left, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(keynav_direction_test->view0_->has_focus_ && (keynav_direction_test->view0_->key_nav_direction_ == nux::KEY_NAV_LEFT), "View0 received key nav from right"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); keynav_direction_test = new KeyNavDirectionTest("Automated: KeyNav Directions", 300, 300, 15000); keynav_direction_test->Startup(); keynav_direction_test->UserInterfaceSetup(); nux::SystemThread *test_thread = nux::CreateSystemThread(keynav_direction_test->GetWindowThread(), &TestingThread, keynav_direction_test->GetWindowThread()); test_thread->Start(keynav_direction_test); keynav_direction_test->Run(); delete test_thread; delete keynav_direction_test; return 0; } nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-rolling-file-appender.cpp0000644000015301777760000001114612321344237025572 0ustar pbusernogroup00000000000000#include #include #include #include #include #include #include #include "NuxCore/RollingFileAppender.h" #include "Helpers.h" namespace bf = boost::filesystem; using namespace nux::logging; using namespace nux::testing; using namespace testing; namespace { /** * Due to the asynchronous manner in which the rolling file appender writes * the data to disk, it is incredibly hard to test in a simple unit test as * the underlying file on the file system isn't created synchronously, nor is * the output written synchronously. * * A files_rolled event exists on the RollingFileAppender so we can at least * wait for that signal and check the underlying files on the file system at * that stage. This does mean that we aren't testing the smaller chunks of * how it works, but more only the complete system, which I guess has to be * good enough for this case. */ const std::string TEST_ROOT("/tmp/nux-test-cases"); class TestRollingFileAppender : public ::testing::Test { protected: virtual void SetUp() { // Make sure that the tests start with nothing there. bf::remove_all(TEST_ROOT); } virtual void TearDown() { // Delete the unity test directory bf::remove_all(TEST_ROOT); } bool WaitForRoll(RollingFileAppender& appender, unsigned timeout = 5) { TestCallback rolled; TestCallback timed_out; g_timeout_add_seconds(timeout, &TestCallback::glib_callback, &timed_out); appender.files_rolled.connect(rolled.sigc_callback()); while (!rolled.happened && !timed_out.happened) { PumpGObjectMainLoop(); } return rolled.happened; } }; TEST_F(TestRollingFileAppender, NoTestRoot) { // The test root should not exist. EXPECT_FALSE(bf::exists(TEST_ROOT)); } TEST_F(TestRollingFileAppender, TestLogFileRollsAtFlush) { std::string logfile = TEST_ROOT + "/nux.log"; unsigned max_log_size = 20; // roll every 20 characters RollingFileAppender output(logfile, 5, max_log_size); output << "Testing the rolling of the logfile" << std::endl; WaitForRoll(output); output << "Long line greater than max_log_size" << std::endl; WaitForRoll(output); // Since the log files are rolled on flush, if the last thing written out // takes the filesize greater than the max_log_size, the log files are // rolled and the current file being appended to is now empty. EXPECT_THAT(ReadFile(logfile + ".1"), Eq("Long line greater than max_log_size\n")); EXPECT_THAT(ReadFile(logfile + ".2"), Eq("Testing the rolling of the logfile\n")); } TEST_F(TestRollingFileAppender, TestExistingLogFileMoved) { std::string logfile = TEST_ROOT + "/nux.log"; { bf::create_directories(bf::path(logfile).parent_path()); std::ofstream output(logfile); output << "Existing file."; } EXPECT_TRUE(bf::exists(logfile)); RollingFileAppender output(logfile); EXPECT_THAT(ReadFile(logfile + ".1"), Eq("Existing file.")); } TEST_F(TestRollingFileAppender, TestDeletingOld) { std::string logfile = TEST_ROOT + "/nux.log"; // Two backups, size 20 bytes. RollingFileAppender output(logfile, 2, 20); // Due to the asynchronous manner in which the output is sent to the // underlying file, we explicitly wait for the roll here. Otherwise we may // just send all the logging lines to one file then it would roll. output << "Oldest line should be deleted." << std::endl; WaitForRoll(output); output << "This line will be in the last backup." << std::endl; WaitForRoll(output); output << "This is backup number 1." << std::endl; WaitForRoll(output); EXPECT_THAT(ReadFile(logfile + ".1"), Eq("This is backup number 1.\n")); EXPECT_THAT(ReadFile(logfile + ".2"), Eq("This line will be in the last backup.\n")); EXPECT_FALSE(bf::exists(logfile + ".3")); } TEST_F(TestRollingFileAppender, TestFullPathNeeded) { EXPECT_THROW(RollingFileAppender("nux.log"), std::runtime_error); EXPECT_THROW(RollingFileAppender("relative/nux.log"), std::runtime_error); } TEST_F(TestRollingFileAppender, TestFileNeeded) { // For some obscure reason, EXPECT_THROW won't accept: // RollingFileAppender(logfile) // as its first arg. std::string directory_path = TEST_ROOT + "/somedir"; bf::create_directories(directory_path); EXPECT_THROW(RollingFileAppender appender(directory_path), std::runtime_error); std::string symlink_path = TEST_ROOT + "/somelink"; bf::create_symlink(directory_path, symlink_path); EXPECT_THROW(RollingFileAppender appender(symlink_path), std::runtime_error); } } // anon namespace nux-4.0.6+14.04.20140409/tests/xtest-hgrid-key-navigation.cpp0000644000015301777760000001517412321344237024000 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/GridHLayout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" // 0 1 2 3 // 4 5 6 7 // 8 9 10 class HGridKeyNavigationTest: public ProgramTemplate { public: HGridKeyNavigationTest(const char* program_name, int window_width, int window_height, int program_life_span); ~HGridKeyNavigationTest(); virtual void UserInterfaceSetup(); nux::TestView* CreateTile(); void AddTile(nux::TestView* tile); nux::VLayout* vlayout_; nux::GridHLayout* grid_layout_; nux::TestView* tiles_[11]; nux::TestView* bottom_view_; }; HGridKeyNavigationTest::HGridKeyNavigationTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { } HGridKeyNavigationTest::~HGridKeyNavigationTest() { } nux::TestView* HGridKeyNavigationTest::CreateTile() { nux::TestView* tile = new nux::TestView(); return tile; } void HGridKeyNavigationTest::AddTile(nux::TestView* tile) { grid_layout_->AddView(tile, 1); } void HGridKeyNavigationTest::UserInterfaceSetup() { vlayout_ = new nux::VLayout(NUX_TRACKER_LOCATION); grid_layout_ = new nux::GridHLayout(NUX_TRACKER_LOCATION); grid_layout_->ForceChildrenSize(true); grid_layout_->SetChildrenSize(100, 100); grid_layout_->EnablePartialVisibility(false); grid_layout_->SetPadding(20, 20); grid_layout_->SetSpaceBetweenChildren(10, 10); vlayout_->AddLayout(grid_layout_); for (int i=0; i<11; ++i) { tiles_[i] = CreateTile(); AddTile(tiles_[i]); } bottom_view_ = CreateTile(); vlayout_->AddView(bottom_view_); nux::GetWindowCompositor().SetKeyFocusArea(bottom_view_); static_cast(window_thread_)->SetLayout(vlayout_); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } HGridKeyNavigationTest* key_navigation_test = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (key_navigation_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); test.TestReportMsg(key_navigation_test->grid_layout_, "TestView created"); test.TestReportMsg(key_navigation_test->bottom_view_->has_focus_, "bottom_view has key focus"); // Up key, must focus (last row, first column) item test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->tiles_[8]->has_focus_, "KEY_NAV_UP test"); key_navigation_test->bottom_view_->can_focus_ = false; for (int i = 0; i < 2; ++i) test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); // Rigth key for (int i=0; i<3; ++i) { test.SendFakeKeyEvent(XK_Right, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(!key_navigation_test->tiles_[i]->has_focus_, "Right: key focus out"); test.TestReportMsg(key_navigation_test->tiles_[i+1]->has_focus_, "Right: key focus in"); } // Another right key, should do nothing test.SendFakeKeyEvent(XK_Right, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->tiles_[3]->has_focus_, "Right key, last element"); // Left key for (int i=3; i>0; --i) { test.SendFakeKeyEvent(XK_Left, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(!key_navigation_test->tiles_[i]->has_focus_, "Left: key focus out"); test.TestReportMsg(key_navigation_test->tiles_[i-1]->has_focus_, "Left: key focus in"); } // Another left key, should do nothing test.SendFakeKeyEvent(XK_Left, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->tiles_[0]->has_focus_, "Left key, fist element"); // Down key for (int i=0; i<2; ++i) { test.SendFakeKeyEvent(XK_Down, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(!key_navigation_test->tiles_[4*i]->has_focus_, "Down: key focus out"); test.TestReportMsg(key_navigation_test->tiles_[4*(i+1)]->has_focus_, "Down: key focus in"); } // Another down key, should do nothing test.SendFakeKeyEvent(XK_Down, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->tiles_[8]->has_focus_, "Down key, last row"); // Up key for (int i=2; i>0; --i) { test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(!key_navigation_test->tiles_[4*i]->has_focus_, "Up: key focus out"); test.TestReportMsg(key_navigation_test->tiles_[4*(i-1)]->has_focus_, "Up: key focus in"); } // Another up key, should do nothing test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->tiles_[0]->has_focus_, "Up key, first row"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); key_navigation_test = new HGridKeyNavigationTest("Key navigation Test", 500, 400, 20000); key_navigation_test->Startup(); key_navigation_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(key_navigation_test->GetWindowThread(), &TestingThread, key_navigation_test->GetWindowThread()); test_thread->Start(key_navigation_test); key_navigation_test->Run(); delete test_thread; delete key_navigation_test; return 0; } nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-colorprivate.cpp0000644000015301777760000000505212321344237024123 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "NuxCore/ColorPrivate.h" using namespace nux::color; #include using namespace testing; namespace { TEST(TestColorPrivate, TestIsValidHex) { EXPECT_TRUE(IsValidHex("#abcdef")); EXPECT_TRUE(IsValidHex("abcdef")); EXPECT_TRUE(IsValidHex("#ABCDEF")); EXPECT_TRUE(IsValidHex("ABCDEF")); EXPECT_FALSE(IsValidHex("")); EXPECT_FALSE(IsValidHex("#")); EXPECT_FALSE(IsValidHex("#abcde")); EXPECT_FALSE(IsValidHex("#abcdefa")); EXPECT_FALSE(IsValidHex("abcde")); EXPECT_FALSE(IsValidHex("abcdefa")); EXPECT_FALSE(IsValidHex("#abcdeg")); } TEST(TestColorPrivate, TestHexToInt) { EXPECT_EQ(HexToInt("ab"), 0xab); EXPECT_EQ(HexToInt("AB"), 0xab); EXPECT_EQ(HexToInt("01"), 0x01); EXPECT_EQ(HexToInt("0a"), 0x0a); } TEST(TestColorPrivate, TestHexToRGBA) { float r, g, b, a; EXPECT_FALSE(HexToRGBA("", r, g, b, a)); EXPECT_FALSE(HexToRGBA("#ubuntu", r, g, b, a)); EXPECT_TRUE(HexToRGBA("#abc", r, g, b, a)); EXPECT_EQ(r, 0xaa / 255.0f); EXPECT_EQ(g, 0xbb / 255.0f); EXPECT_EQ(b, 0xcc / 255.0f); EXPECT_EQ(a, 1.0f); r = g = b = a = 0; EXPECT_TRUE(HexToRGBA("#abcd", r, g, b, a)); EXPECT_EQ(r, 0xaa / 255.0f); EXPECT_EQ(g, 0xbb / 255.0f); EXPECT_EQ(b, 0xcc / 255.0f); EXPECT_EQ(a, 0xdd / 255.0f); r = g = b = a = 0; EXPECT_TRUE(HexToRGBA("#abcdef", r, g, b, a)); EXPECT_EQ(r, 0xab / 255.0f); EXPECT_EQ(g, 0xcd / 255.0f); EXPECT_EQ(b, 0xef / 255.0f); EXPECT_EQ(a, 1.0f); r = g = b = a = 0; EXPECT_TRUE(HexToRGBA("#abcdefdd", r, g, b, a)); EXPECT_EQ(r, 0xab / 255.0f); EXPECT_EQ(g, 0xcd / 255.0f); EXPECT_EQ(b, 0xef / 255.0f); EXPECT_EQ(a, 0xdd / 255.0f); r = g = b = a = 0; EXPECT_TRUE(HexToRGBA("abcdef", r, g, b, a)); EXPECT_EQ(r, 0xab / 255.0f); EXPECT_EQ(g, 0xcd / 255.0f); EXPECT_EQ(b, 0xef / 255.0f); } } nux-4.0.6+14.04.20140409/tests/gtest-nux-statictext.cpp0000644000015301777760000000237712321344237022744 0ustar pbusernogroup00000000000000#include #include #include #include #include #include #include "Nux/Nux.h" #include "Nux/StaticText.h" using namespace testing; namespace { TEST(TestStaticText, TestCreate) { nux::NuxInitialize(0); nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL); nux::StaticText *statictext = new nux::StaticText(""); EXPECT_EQ(statictext->GetText(), std::string("")); // Test the default color. Should be white. EXPECT_EQ(statictext->GetTextColor(), nux::color::White); // Test random color. nux::Color random_color = nux::color::RandomColor(); statictext->SetTextColor(random_color); EXPECT_EQ(statictext->GetTextColor(), random_color); // Test default font. Should be "Ubuntu". EXPECT_EQ(statictext->GetFontName(), std::string("Ubuntu")); // Test random font. statictext->SetFontName("Courrier"); EXPECT_EQ(statictext->GetFontName(), std::string("Courrier")); // Test default font point size; EXPECT_EQ(statictext->GetTextPointSize(), 10); statictext->SetTextPointSize(20); EXPECT_EQ(statictext->GetTextPointSize(), 20); statictext->UnReference(); delete wnd_thread; } } nux-4.0.6+14.04.20140409/tests/gtest-nux-velocitycalculator.cpp0000644000015301777760000000513612321344237024454 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include #include "gtest-nux-globals.h" using namespace nux; TEST(VelocityCalculator, SimpleSamples) { VelocityCalculator vel_calc; g_fake_monotonic_time = 10 * 1000; vel_calc.ProcessMovement(20); g_fake_monotonic_time = 20 * 1000; vel_calc.ProcessMovement(20); g_fake_monotonic_time = 30 * 1000; vel_calc.ProcessMovement(20); float velocity = vel_calc.CalculateVelocity(); ASSERT_FLOAT_EQ(2.0f, velocity); } TEST(VelocityCalculator, NoSamples) { VelocityCalculator vel_calc; float velocity = vel_calc.CalculateVelocity(); ASSERT_FLOAT_EQ(0.0f, velocity); } TEST(VelocityCalculator, OverflowSamples) { VelocityCalculator vel_calc; for (int i = 0; i < 1000; ++i) { g_fake_monotonic_time += 10 * 1000; vel_calc.ProcessMovement(20); } /* overwrite all existing samples with faster ones */ for (int i = 0; i < VelocityCalculator::MAX_SAMPLES; ++i) { g_fake_monotonic_time += 10 * 1000; vel_calc.ProcessMovement(40); } float velocity = vel_calc.CalculateVelocity(); /* check that the calculated velocity correspond to the latest, faster, samples */ ASSERT_FLOAT_EQ(4.0f, velocity); } TEST(VelocityCalculator, Average) { VelocityCalculator vel_calc; g_fake_monotonic_time = 10 * 1000; vel_calc.ProcessMovement(20); g_fake_monotonic_time = 20 * 1000; vel_calc.ProcessMovement(20); /* the last sample is an erratic one and would yield a big velocity if considered isolatedly */ g_fake_monotonic_time = 30 * 1000; vel_calc.ProcessMovement(100); float velocity = vel_calc.CalculateVelocity(); /* calculated velocity is lower than the one from the last sample */ ASSERT_TRUE(velocity < 9.0f); /* but it's higher the the slow samples */ ASSERT_TRUE(velocity > 2.5f); } nux-4.0.6+14.04.20140409/tests/gtest-nux-view.cpp0000644000015301777760000000427512321344237021521 0ustar pbusernogroup00000000000000#include #include #include #include #include #include #include "Nux/Nux.h" #include "Nux/HLayout.h" #include "Nux/StaticText.h" #include "Nux/ProgramFramework/TestView.h" using namespace testing; namespace { TEST(TestView, TestViewEnable) { nux::NuxInitialize(0); nux::WindowThread *wnd_thread = nux::CreateNuxWindow("View Test", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL); nux::TestView* test_view = new nux::TestView(""); test_view->EnableView(); EXPECT_TRUE(test_view->IsViewEnabled()); test_view->DisableView(); EXPECT_FALSE(test_view->IsViewEnabled()); test_view->UnReference(); delete wnd_thread; } TEST(TestView, TestQueueDraw) { nux::NuxInitialize(0); nux::WindowThread *wnd_thread = nux::CreateNuxWindow("View Test", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL); nux::TestView* main_view = new nux::TestView(""); nux::HLayout* hlayout = new nux::HLayout(""); main_view->SetLayout(hlayout); nux::TestView* test_view1 = new nux::TestView(""); hlayout->AddView(test_view1); nux::TestView* test_view2 = new nux::TestView(""); hlayout->AddView(test_view2); nux::TestView* test_view3 = new nux::TestView(""); hlayout->AddView(test_view3); hlayout->ComputeContentSize(); EXPECT_EQ(main_view->calls_to_queue_draw_, 0); EXPECT_EQ(test_view1->calls_to_queue_draw_, 0); EXPECT_EQ(test_view2->calls_to_queue_draw_, 0); EXPECT_EQ(test_view3->calls_to_queue_draw_, 0); main_view->QueueDraw(); EXPECT_EQ(main_view->calls_to_queue_draw_, 1); EXPECT_EQ(test_view1->calls_to_queue_draw_, 1); EXPECT_EQ(test_view2->calls_to_queue_draw_, 1); EXPECT_EQ(test_view3->calls_to_queue_draw_, 1); int old_size = wnd_thread->GetDrawList().size(); main_view->QueueDraw(); test_view2->QueueDraw(); int new_size = wnd_thread->GetDrawList().size(); EXPECT_EQ(old_size, new_size); // LP: #1014610 EXPECT_EQ(main_view->calls_to_queue_draw_, 2); EXPECT_EQ(test_view1->calls_to_queue_draw_, 1); EXPECT_EQ(test_view2->calls_to_queue_draw_, 2); EXPECT_EQ(test_view3->calls_to_queue_draw_, 1); main_view->UnReference(); delete wnd_thread; } } nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-logger.cpp0000644000015301777760000003067712321344237022704 0ustar pbusernogroup00000000000000#include "NuxCore/Logger.h" #include "NuxCore/LoggerPrivate.h" #include "NuxCore/LoggingWriter.h" #include "Helpers.h" #include #include #include namespace nt = nux::testing; using namespace nux::logging; using namespace testing; namespace { TEST(TestLogger, TestSimpleConstruction) { Logger logger(""); EXPECT_EQ(logger.module(), ""); EXPECT_TRUE(logger.IsErrorEnabled()); EXPECT_TRUE(logger.IsWarningEnabled()); EXPECT_FALSE(logger.IsInfoEnabled()); EXPECT_FALSE(logger.IsDebugEnabled()); } TEST(TestLogger, TestModuleName) { Logger logger("nux.logging"); EXPECT_EQ(logger.module(), "nux.logging"); } TEST(TestLogger, TestSetLevel) { Logger logger("testing"); EXPECT_EQ(logger.GetLogLevel(), Level::NotSpecified); EXPECT_EQ(logger.GetEffectiveLogLevel(), Level::Warning); EXPECT_TRUE(logger.IsErrorEnabled()); EXPECT_TRUE(logger.IsWarningEnabled()); EXPECT_FALSE(logger.IsInfoEnabled()); EXPECT_FALSE(logger.IsDebugEnabled()); logger.SetLogLevel(Level::Debug); EXPECT_EQ(logger.GetLogLevel(), Level::Debug); EXPECT_EQ(logger.GetEffectiveLogLevel(), Level::Debug); EXPECT_TRUE(logger.IsErrorEnabled()); EXPECT_TRUE(logger.IsWarningEnabled()); EXPECT_TRUE(logger.IsInfoEnabled()); EXPECT_TRUE(logger.IsDebugEnabled()); logger.SetLogLevel(Level::Info); EXPECT_EQ(logger.GetLogLevel(), Level::Info); EXPECT_EQ(logger.GetEffectiveLogLevel(), Level::Info); EXPECT_TRUE(logger.IsErrorEnabled()); EXPECT_TRUE(logger.IsWarningEnabled()); EXPECT_TRUE(logger.IsInfoEnabled()); EXPECT_FALSE(logger.IsDebugEnabled()); logger.SetLogLevel(Level::Warning); EXPECT_EQ(logger.GetLogLevel(), Level::Warning); EXPECT_EQ(logger.GetEffectiveLogLevel(), Level::Warning); EXPECT_TRUE(logger.IsErrorEnabled()); EXPECT_TRUE(logger.IsWarningEnabled()); EXPECT_FALSE(logger.IsInfoEnabled()); EXPECT_FALSE(logger.IsDebugEnabled()); logger.SetLogLevel(Level::Error); EXPECT_EQ(logger.GetLogLevel(), Level::Error); EXPECT_EQ(logger.GetEffectiveLogLevel(), Level::Error); EXPECT_TRUE(logger.IsErrorEnabled()); EXPECT_FALSE(logger.IsWarningEnabled()); EXPECT_FALSE(logger.IsInfoEnabled()); EXPECT_FALSE(logger.IsDebugEnabled()); logger.SetLogLevel(Level::NotSpecified); EXPECT_EQ(logger.GetLogLevel(), Level::NotSpecified); EXPECT_EQ(logger.GetEffectiveLogLevel(), Level::Warning); } TEST(TestLogger, TestLevelsSharedForSameModule) { Logger logger1("testing.module"); Logger logger2("testing.module"); logger1.SetLogLevel(Level::Info); EXPECT_TRUE(logger1.IsInfoEnabled()); EXPECT_TRUE(logger2.IsInfoEnabled()); } TEST(TestLogger, TestModuleLowered) { Logger logger1("TESTING.MODULE"); Logger logger2("Testing"); EXPECT_THAT(logger1.module(), Eq("testing.module")); EXPECT_THAT(logger2.module(), Eq("testing")); } TEST(TestLogger, TestLevelsInherited) { Logger root(""); Logger first("first"); Logger second("first.second"); root.SetLogLevel(Level::Error); EXPECT_EQ(root.GetLogLevel(), Level::Error); EXPECT_EQ(root.GetEffectiveLogLevel(), Level::Error); EXPECT_EQ(first.GetLogLevel(), Level::NotSpecified); EXPECT_EQ(first.GetEffectiveLogLevel(), Level::Error); EXPECT_EQ(second.GetLogLevel(), Level::NotSpecified); EXPECT_EQ(second.GetEffectiveLogLevel(), Level::Error); first.SetLogLevel(Level::Debug); EXPECT_EQ(root.GetLogLevel(), Level::Error); EXPECT_EQ(root.GetEffectiveLogLevel(), Level::Error); EXPECT_EQ(first.GetLogLevel(), Level::Debug); EXPECT_EQ(first.GetEffectiveLogLevel(), Level::Debug); EXPECT_EQ(second.GetLogLevel(), Level::NotSpecified); EXPECT_EQ(second.GetEffectiveLogLevel(), Level::Debug); second.SetLogLevel(Level::Info); EXPECT_EQ(root.GetLogLevel(), Level::Error); EXPECT_EQ(root.GetEffectiveLogLevel(), Level::Error); EXPECT_EQ(first.GetLogLevel(), Level::Debug); EXPECT_EQ(first.GetEffectiveLogLevel(), Level::Debug); EXPECT_EQ(second.GetLogLevel(), Level::Info); EXPECT_EQ(second.GetEffectiveLogLevel(), Level::Info); first.SetLogLevel(Level::NotSpecified); EXPECT_EQ(root.GetLogLevel(), Level::Error); EXPECT_EQ(root.GetEffectiveLogLevel(), Level::Error); EXPECT_EQ(first.GetLogLevel(), Level::NotSpecified); EXPECT_EQ(first.GetEffectiveLogLevel(), Level::Error); EXPECT_EQ(second.GetLogLevel(), Level::Info); EXPECT_EQ(second.GetEffectiveLogLevel(), Level::Info); } class UseTimezone { public: UseTimezone(std::string const& tz) { char* old_tz = ::getenv("TZ"); if (old_tz) { // std::strings don't like beeing assigned NULL old_tz_ = old_tz; } ::setenv("TZ", tz.c_str(), true); ::tzset(); } ~UseTimezone() { if (old_tz_.empty()) { ::unsetenv("TZ"); } else { ::setenv("TZ", old_tz_.c_str(), true); } ::tzset(); } private: std::string old_tz_; }; TEST(TestLoggingWriter, TestWriteMessage) { nt::CaptureLogOutput log_output; // set a known timezone UseTimezone timezone(":Antarctica/Vostok"); // This time is known to be: 2010-09-10 12:34:45 (UTC+12) std::time_t when = 1284078885; Writer::Instance().WriteMessage(Level::Error, "test.module", "testfile.cpp", 1234, when, "my message"); std::string result = log_output.GetOutput(); // Vostok is UTC+6 EXPECT_THAT(result, Eq("ERROR 2010-09-10 06:34:45 test.module testfile.cpp:1234 my message\n")); } TEST(TestLogStream, TestSimpleConstruction) { // First test is to make sure a LogStream can be constructed and destructed. LogStream test(Level::Debug, "module", "filename", 42); } TEST(TestLogStream, TestOutput) { nt::CaptureLogOutput log_output; LogStream test(Level::Debug, "module", "filename", 42); test << "testing message" << std::flush; std::string result = log_output.GetOutput(); EXPECT_THAT(result, StartsWith("DEBUG")); EXPECT_THAT(result, HasSubstr("module filename:42")); EXPECT_THAT(result, EndsWith("testing message\n")); } TEST(TestLogStream, TestShortenedFilename) { // Filenames only show the last path segment. nt::CaptureLogOutput log_output; LogStream test(Level::Debug, "module", "/some/absolute/filename", 42); test << "testing message" << std::flush; std::string result = log_output.GetOutput(); EXPECT_THAT(result, HasSubstr("module filename:42")); } TEST(TestLogStream, TestTemporary) { // First test is to make sure a LogStream can be constructed and destructed. nt::CaptureLogOutput log_output; LogStream(Level::Debug, "module", "filename", 42).stream() << "testing message"; std::string result = log_output.GetOutput(); EXPECT_THAT(result, StartsWith("DEBUG")); EXPECT_THAT(result, HasSubstr(" module filename:42")); EXPECT_THAT(result, EndsWith("testing message\n")); } TEST(TestLogStream, TestDebugMacro) { // First test is to make sure a LogStream can be constructed and destructed. nt::CaptureLogOutput log_output; int counter = 0; Logger logger("test.module"); LOG_DEBUG(logger) << ++counter << "Not output, as not debug."; logger.SetLogLevel(Level::Debug); LOG_DEBUG(logger) << ++counter << " Is output now."; std::string result = log_output.GetOutput(); EXPECT_THAT(result, StartsWith("DEBUG")); EXPECT_THAT(result, HasSubstr(" test.module gtest-nuxcore-logger.cpp")); EXPECT_THAT(result, EndsWith("1 Is output now.\n")); // Also only one line. EXPECT_THAT(counter, Eq(1)); } TEST(TestLogStream, TestBlockTracer) { nt::CaptureLogOutput log_output; Logger logger("test"); logger.SetLogLevel(Level::Debug); { BlockTracer tracer(logger, Level::Debug, "func_name", "file_name", 42); } std::string result = log_output.GetOutput(); EXPECT_THAT(result, MatchesRegex("DEBUG .+ test file_name:42 \\+func_name\n" "DEBUG .+ test file_name:42 -func_name\n")); } TEST(TestLogHelpers, TestGetLoggingLevel) { EXPECT_THAT(get_logging_level("trace"), Eq(Level::Trace)); EXPECT_THAT(get_logging_level("TrAce"), Eq(Level::Trace)); EXPECT_THAT(get_logging_level("TRACE"), Eq(Level::Trace)); EXPECT_THAT(get_logging_level("debug"), Eq(Level::Debug)); EXPECT_THAT(get_logging_level("DEBUG"), Eq(Level::Debug)); EXPECT_THAT(get_logging_level("info"), Eq(Level::Info)); EXPECT_THAT(get_logging_level("INFO"), Eq(Level::Info)); EXPECT_THAT(get_logging_level("warn"), Eq(Level::Warning)); EXPECT_THAT(get_logging_level("WARN"), Eq(Level::Warning)); EXPECT_THAT(get_logging_level("warning"), Eq(Level::Warning)); EXPECT_THAT(get_logging_level("WARNING"), Eq(Level::Warning)); EXPECT_THAT(get_logging_level("error"), Eq(Level::Error)); EXPECT_THAT(get_logging_level("ERROR"), Eq(Level::Error)); // Unknown levels result in WARNING EXPECT_THAT(get_logging_level("critical"), Eq(Level::Warning)); EXPECT_THAT(get_logging_level("not_specified"), Eq(Level::Warning)); EXPECT_THAT(get_logging_level("other"), Eq(Level::Warning)); } TEST(TestLogHelpers, TestResetLogging) { // First set root and another. Logger("").SetLogLevel(Level::Debug); Logger("test.module").SetLogLevel(Level::Info); reset_logging(); std::string levels = dump_logging_levels(); EXPECT_THAT(levels, Eq(" WARNING")); } TEST(TestLogHelpers, TestHasModule) { LoggerModules& modules = LoggerModules::Instance(); EXPECT_FALSE(modules.HasModule("test.module.non.existent")); Logger("test.module.non.existent"); EXPECT_TRUE(modules.HasModule("test.module.non.existent")); } DECLARE_LOGGER(file_level_logger, "test.module.file.level"); TEST(TestStaticFileFunction, TestLoggerConstruction) { LoggerModules& modules = LoggerModules::Instance(); EXPECT_FALSE(modules.HasModule("test.module.file.level")); // Call the function file_level_logger(); EXPECT_TRUE(modules.HasModule("test.module.file.level")); } TEST(TestLoggerMacros, TestPassingObject) { nt::CaptureLogOutput log_output; configure_logging("test.module=trace"); Logger local("test.module"); LOG_TRACE(local) << "trace log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("TRACE .+ trace log\n")); LOG_DEBUG(local) << "debug log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("DEBUG .+ debug log\n")); LOG_INFO(local) << "info log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("INFO .+ info log\n")); LOG_WARN(local) << "warn log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("WARN .+ warn log\n")); LOG_ERROR(local) << "error log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("ERROR .+ error log\n")); } DECLARE_LOGGER(test_logger, "test.module"); TEST(TestLoggerMacros, TestPassingFunction) { nt::CaptureLogOutput log_output; configure_logging("test.module=trace"); LoggerFunc the_func = test_logger; LOG_TRACE(test_logger) << "trace log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("TRACE .+ trace log\n")); LOG_DEBUG(test_logger) << "debug log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("DEBUG .+ debug log\n")); LOG_INFO(test_logger) << "info log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("INFO .+ info log\n")); LOG_WARN(test_logger) << "warn log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("WARN .+ warn log\n")); LOG_ERROR(test_logger) << "error log"; EXPECT_THAT(log_output.GetOutput(), MatchesRegex("ERROR .+ error log\n")); } TEST(TestLogHelpers, TestConfigureLoggingNull) { reset_logging(); Logger("").SetLogLevel(Level::Debug); Logger("test.module").SetLogLevel(Level::Info); // Configure passed a null pointer does nothing. configure_logging(NULL); std::string levels = dump_logging_levels(); EXPECT_THAT(levels, Eq(" DEBUG\n" "test.module INFO")); } TEST(TestLogHelpers, TestConfigureLoggingRoot) { reset_logging(); configure_logging("=debug"); std::string levels = dump_logging_levels(); EXPECT_THAT(levels, Eq(" DEBUG")); } TEST(TestLogHelpers, TestConfigureLoggingSingleModule) { reset_logging(); configure_logging("test.module=debug"); std::string levels = dump_logging_levels(); EXPECT_THAT(levels, Eq(" WARNING\n" "test.module DEBUG")); } TEST(TestLogHelpers, TestConfigureLoggingMultipleModules) { reset_logging(); configure_logging("module=info;sub.module=debug;other.module=warning"); std::string levels = dump_logging_levels(); EXPECT_THAT(levels, Eq(" WARNING\n" "module INFO\n" "other.module WARNING\n" "sub.module DEBUG")); } } // anon namespace nux-4.0.6+14.04.20140409/tests/gtest-nuxgraphics-graphic-display.cpp0000644000015301777760000000205412321344237025341 0ustar pbusernogroup00000000000000#include #include #include #include "Nux/Nux.h" #include "NuxGraphics/GraphicsDisplay.h" using namespace testing; using namespace nux; namespace { struct TestGraphicsDisplay : Test { TestGraphicsDisplay() : graphic_display_(nullptr) {} virtual void SetUp() { nux::NuxInitialize(0); wnd_thread.reset(nux::CreateNuxWindow("nux::TestGraphicsDisplay", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL)); graphic_display_ = nux::GetGraphicsDisplay(); ASSERT_NE(graphic_display_, nullptr); } std::unique_ptr wnd_thread; GraphicsDisplay* graphic_display_; }; #if defined(USE_X11) TEST_F(TestGraphicsDisplay, X11TimestampOnButtonPress) { XEvent xevent; xevent.type = ButtonPress; xevent.xany.display = graphic_display_->GetX11Display(); xevent.xbutton.time = g_random_int(); graphic_display_->ProcessXEvent(xevent, true); auto event_time = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp; EXPECT_EQ(xevent.xbutton.time, event_time); } #endif }nux-4.0.6+14.04.20140409/tests/gtest-nux-cairo-wrapper.cpp0000644000015301777760000001137212321344237023316 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller #include #include "Nux/CairoWrapper.h" #include #include #include typedef void (*TestFunc)(void); nux::TimerFunctor* g_timer = NULL; nux::TimerHandle g_handler = NULL; void callback_one (nux::Geometry const& geom, cairo_t* cr) { if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) return; cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_scale (cr, 1.0, 1.0); cairo_set_source_rgba (cr, 1.0, 0.5, 0.25, 1.0); cairo_rectangle (cr, 5.0, 5.0, (double) geom.width - 10.0, (double) geom.height - 10.0); cairo_fill (cr); } void callback_two (nux::Geometry const& geom, cairo_t* cr) { if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) return; cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_scale (cr, 1.0, 1.0); cairo_set_source_rgba (cr, 0.25, 0.5, 1.0, 1.0); cairo_rectangle (cr, 2.0, 2.0, (double) geom.width - 4.0, (double) geom.height - 4.0); cairo_fill (cr); } void terminate (void* data) { nux::WindowThread* thread = NUX_STATIC_CAST (nux::WindowThread*, data); thread->ExitMainLoop(); } void init (nux::NThread* /* thread */, void* data) { TestFunc func = (TestFunc) data; (func) (); g_timer = new nux::TimerFunctor (); g_timer->tick.connect (sigc::ptr_fun (&terminate)); g_handler = nux::GetTimer().AddOneShotTimer (100, g_timer, nux::GetWindowThread ()); } void run_test (TestFunc func) { nux::WindowThread* wt = NULL; wt = nux::CreateGUIThread (TEXT ("Canvas Test"), 400, 400, 0, &init, (void*) func); wt->Run (NULL); delete wt; delete g_timer; g_timer = NULL; } void test_construction () { nux::Geometry geom_one = {0, 0, 100, 100}; nux::Geometry geom_two = {0, 0, 200, 200}; nux::CairoWrapper wrapper (geom_one, sigc::ptr_fun (callback_one)); EXPECT_FALSE (wrapper.Invalidate (geom_one)); EXPECT_TRUE (wrapper.Invalidate (geom_two)); } void test_invalidate () { nux::Geometry geom_one = {0, 0, 100, 100}; nux::Geometry geom_two = {0, 0, 150, 75}; nux::CairoWrapper wrapper (geom_one, sigc::ptr_fun (callback_one)); EXPECT_FALSE (wrapper.Invalidate (geom_one)); EXPECT_TRUE (wrapper.Invalidate (geom_two)); } void test_get_cairo_surface () { nux::Geometry geom = {0, 0, 100, 100}; nux::CairoWrapper wrapper (geom, sigc::ptr_fun (callback_one)); cairo_surface_t* surf = wrapper.GetCairoSurface (); EXPECT_FALSE (surf == NULL); } void test_get_cairo_context () { nux::Geometry geom = {0, 0, 100, 100}; nux::CairoWrapper wrapper (geom, sigc::ptr_fun (callback_one)); EXPECT_TRUE (wrapper.GetCairoContext ()); } void test_dump_to_file () { nux::Geometry geom = {0, 0, 100, 100}; nux::CairoWrapper wrapper (geom, sigc::ptr_fun (callback_one)); EXPECT_TRUE (wrapper.DumpToFile ("/tmp/dump.png")); } void test_get_texture () { nux::Geometry geom = {0, 0, 100, 100}; nux::CairoWrapper wrapper (geom, sigc::ptr_fun (callback_one)); EXPECT_TRUE (wrapper.GetTexture ()); } void test_get_bitmap () { nux::Geometry geom = {0, 0, 100, 100}; nux::CairoWrapper wrapper (geom, sigc::ptr_fun (callback_one)); EXPECT_TRUE (wrapper.GetBitmap ()); } namespace { TEST (DISABLED_TestCairoWrapper, TestConstruction) { run_test (test_construction); } TEST (DISABLED_TestCairoWrapper, TestInvalidate) { run_test (test_invalidate); } TEST (DISABLED_TestCairoWrapper, TestGetCairoSurface) { run_test (test_get_cairo_surface); } TEST (DISABLED_TestCairoWrapper, TestGetCairoContext) { run_test (test_get_cairo_context); } TEST (DISABLED_TestCairoWrapper, TestDumpToFile) { run_test (test_dump_to_file); } TEST (DISABLED_TestCairoWrapper, TestGetTexture) { run_test (test_get_texture); } TEST (DISABLED_TestCairoWrapper, TestGetBitmap) { run_test (test_get_bitmap); } } nux-4.0.6+14.04.20140409/tests/gtest-nux-main.cpp0000644000015301777760000000130612321344237021463 0ustar pbusernogroup00000000000000#include #include #include "Nux/Nux.h" #ifdef NUX_GESTURES_SUPPORT #include "NuxGraphics/GestureEvent.h" #include "FakeGestureEvent.h" std::map g_gesture_acceptance; void nux::GestureEvent::Accept() { g_gesture_acceptance[gesture_id_] = g_gesture_acceptance[gesture_id_] + 1; } void nux::GestureEvent::Reject() { g_gesture_acceptance[gesture_id_] = g_gesture_acceptance[gesture_id_] - 1; } #endif // NUX_GESTURES_SUPPORT int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); #if G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION) <= GLIB_VERSION_2_34 g_type_init(); #endif nux::NuxInitialize(0); return RUN_ALL_TESTS(); } nux-4.0.6+14.04.20140409/tests/gtest-nux-textentry.cpp0000644000015301777760000004133112321344237022607 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 along with this program. If not, see * * * Authored by: Marco Trevisan * */ #include "gtest-nux-utils.h" #include #include "Nux/Nux.h" #include "Nux/TextEntry.h" #include "Nux/HLayout.h" #if defined(NUX_OS_LINUX) #include "Nux/InputMethodIBus.h" #include "Nux/TextEntryComposeSeqs.h" #endif using namespace testing; using namespace nux; namespace { class MockTextEntry : public TextEntry { public: MockTextEntry() : TextEntry("") {} bool InspectKeyEvent(Event const& event) { return TextEntry::InspectKeyEvent(event); } bool GetSelectionBounds(int* start, int* end) const { return TextEntry::GetSelectionBounds(start, end); } int GetCursor() const { return cursor_; } void SetCursor(int cursor) { TextEntry::SetCursor(cursor); } bool InCompositionMode() const { return TextEntry::IsInCompositionMode(); } bool HandleComposition(unsigned long keysym) { return TextEntry::HandleComposition(keysym); } void ClearText() { TextEntry::DeleteText(0, std::numeric_limits::max()); ASSERT_TRUE(GetText().empty()); } enum class CompositionResult { NO_MATCH, PARTIAL, MATCH }; CompositionResult GetCompositionForList(std::vector const& input, std::string& composition) { return static_cast(TextEntry::GetCompositionForList(input, composition)); } CompositionResult GetCompositionForString(std::string const& input, std::string& composition) { std::vector input_vec; #if defined(NUX_OS_LINUX) input_vec.push_back(XK_Multi_key); for (auto c : input) { input_vec.push_back(c); } #endif return GetCompositionForList(input_vec, composition); } nux::IBusIMEContext* ime() const { #if defined(NUX_OS_LINUX) return ime_; #else return nullptr; #endif } MOCK_METHOD0(CutClipboard, void()); MOCK_METHOD0(CopyClipboard, void()); MOCK_METHOD0(PasteClipboard, void()); #if defined(NUX_OS_LINUX) MOCK_METHOD0(PastePrimaryClipboard, void()); #endif }; class TestEvent : public Event { public: TestEvent(KeyModifier keymod, unsigned long keysym, EventType type = NUX_KEYDOWN) { Init(keysym, type); key_modifiers = keymod; } TestEvent(unsigned long keysym, EventType type = NUX_KEYDOWN) { Init(keysym, type); } void Init(unsigned long keysym, EventType etype) { type = etype; #if defined(NUX_OS_LINUX) x11_keysym = keysym; g_unichar_to_utf8(x11_keysym, text); #elif defined(NUX_OS_WINDOWS) win32_keysym = keysym; #endif } }; class TestTextEntry : public Test { public: virtual void SetUp() { wnd_thread.reset(CreateNuxWindow("Nux Window", 300, 200, WINDOWSTYLE_NORMAL, nullptr, false, NULL, NULL)); text_entry = new MockTextEntry(); HLayout* layout = new HLayout(); layout->AddView(text_entry); wnd_thread->SetLayout(layout); GetWindowCompositor().SetKeyFocusArea(text_entry); } void WaitEvent() { if (text_entry->im_running()) Utils::WaitForTimeoutMSec(20); } void SendEvent(Event& event) { GetWindowCompositor().ProcessEvent(event); WaitEvent(); } std::unique_ptr wnd_thread; MockTextEntry* text_entry; }; TEST_F(TestTextEntry, TestSetText) { EXPECT_EQ(text_entry->IsInTextInputMode(), false); text_entry->SetText("Nux"); EXPECT_EQ(text_entry->GetText() == std::string("Nux"), true); EXPECT_EQ(text_entry->IsInTextInputMode(), true); } TEST_F(TestTextEntry, TestEnterText) { EXPECT_EQ(text_entry->IsInTextInputMode(), false); text_entry->EnterText("Nux"); EXPECT_EQ(text_entry->GetText() == std::string("Nux"), true); EXPECT_EQ(text_entry->IsInTextInputMode(), true); } TEST_F(TestTextEntry, TestDeleteText) { EXPECT_EQ(text_entry->IsInTextInputMode(), false); text_entry->EnterText("Nux"); EXPECT_EQ(text_entry->GetText() == std::string("Nux"), true); EXPECT_EQ(text_entry->IsInTextInputMode(), true); GetWindowCompositor().SetKeyFocusArea(nullptr); GetWindowCompositor().SetKeyFocusArea(text_entry); EXPECT_EQ(text_entry->IsInTextInputMode(), false); text_entry->DeleteText(0, 3); EXPECT_EQ(text_entry->GetText() == std::string(""), true); EXPECT_EQ(text_entry->IsInTextInputMode(), true); } #if defined(NUX_OS_LINUX) TEST_F(TestTextEntry, AltLinuxKeybindings) { for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym) { TestEvent event(KEY_MODIFIER_ALT, keysym); if (text_entry->ime()->IsHotkeyEvent(event.type, event.GetKeySym(), event.key_modifiers)) EXPECT_TRUE(text_entry->InspectKeyEvent(event)); else EXPECT_FALSE(text_entry->InspectKeyEvent(event)); } } TEST_F(TestTextEntry, SuperLinuxKeybindings) { for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym) { TestEvent event(KEY_MODIFIER_SUPER, keysym); if (text_entry->ime()->IsHotkeyEvent(event.type, event.GetKeySym(), event.key_modifiers)) EXPECT_TRUE(text_entry->InspectKeyEvent(event)); else EXPECT_FALSE(text_entry->InspectKeyEvent(event)); } } #endif TEST_F(TestTextEntry, InvalidKeys) { std::vector invalid_chars = {"", "", "", "", "", "", "", "", "", "", "", "", ""}; for (auto c : invalid_chars) { unsigned int keysym = g_utf8_get_char(c.c_str()); text_entry->ClearText(); text_entry->key_down.emit(NUX_KEYDOWN, keysym, 0, c.c_str(), 1); WaitEvent(); EXPECT_EQ(text_entry->GetText(), ""); } } TEST_F(TestTextEntry, CopyCtrlC) { EXPECT_CALL(*text_entry, CopyClipboard()); TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_c); SendEvent(event); } TEST_F(TestTextEntry, CopyCtrlIns) { EXPECT_CALL(*text_entry, CopyClipboard()); TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_INSERT); SendEvent(event); } TEST_F(TestTextEntry, PasteCtrlV) { EXPECT_CALL(*text_entry, PasteClipboard()); TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_v); SendEvent(event); } TEST_F(TestTextEntry, PasteShiftIns) { EXPECT_CALL(*text_entry, PasteClipboard()); TestEvent event(KEY_MODIFIER_SHIFT, NUX_VK_INSERT); SendEvent(event); } #if defined(NUX_OS_LINUX) TEST_F(TestTextEntry, PastePrimaryClipboard) { EXPECT_CALL(*text_entry, PastePrimaryClipboard()); text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON2_DOWN, 0); EXPECT_CALL(*text_entry, PastePrimaryClipboard()).Times(0); text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON1_DOWN, 0); EXPECT_CALL(*text_entry, PastePrimaryClipboard()).Times(0); text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON3_DOWN, 0); } #endif TEST_F(TestTextEntry, CutCtrlX) { EXPECT_CALL(*text_entry, CutClipboard()); TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_x); SendEvent(event); } TEST_F(TestTextEntry, CutShiftDel) { EXPECT_CALL(*text_entry, CutClipboard()); TestEvent event(KEY_MODIFIER_SHIFT, NUX_VK_DELETE); SendEvent(event); } TEST_F(TestTextEntry, CtrlA) { TestEvent selectall(KEY_MODIFIER_CTRL, NUX_VK_a); int start, end; const std::string test_str("Nux"); text_entry->EnterText(test_str.c_str()); EXPECT_FALSE(text_entry->GetSelectionBounds(&start, &end)); ASSERT_EQ(start, end); ASSERT_EQ(start, test_str.length()); SendEvent(selectall); EXPECT_TRUE(text_entry->GetSelectionBounds(&start, &end)); EXPECT_EQ(start, 0); EXPECT_EQ(end, test_str.length()); } TEST_F(TestTextEntry, MoveKeys) { const std::string test_str("Nux"); text_entry->EnterText(test_str.c_str()); ASSERT_EQ(text_entry->GetCursor(), test_str.length()); text_entry->SetCursor(0); ASSERT_EQ(text_entry->GetCursor(), 0); TestEvent right(NUX_VK_RIGHT); SendEvent(right); EXPECT_EQ(text_entry->GetCursor(), 1); TestEvent end(NUX_VK_END); SendEvent(end); EXPECT_EQ(text_entry->GetCursor(), test_str.length()); TestEvent left(NUX_VK_LEFT); SendEvent(left); EXPECT_EQ(text_entry->GetCursor(), 2); TestEvent home(NUX_VK_HOME); SendEvent(home); EXPECT_EQ(text_entry->GetCursor(), 0); } TEST_F(TestTextEntry, CtrlMoveKeys) { const std::string test_str("Nux Text Entry"); text_entry->EnterText(test_str.c_str()); ASSERT_EQ(text_entry->GetCursor(), test_str.length()); text_entry->SetCursor(0); ASSERT_EQ(text_entry->GetCursor(), 0); TestEvent right(KEY_MODIFIER_CTRL, NUX_VK_RIGHT); SendEvent(right); EXPECT_EQ(text_entry->GetCursor(), 3); TestEvent left(KEY_MODIFIER_CTRL, NUX_VK_LEFT); SendEvent(left); EXPECT_EQ(text_entry->GetCursor(), 0); TestEvent end(KEY_MODIFIER_CTRL, NUX_VK_END); SendEvent(end); EXPECT_EQ(text_entry->GetCursor(), test_str.length()); TestEvent home(KEY_MODIFIER_CTRL, NUX_VK_HOME); SendEvent(home); EXPECT_EQ(text_entry->GetCursor(), 0); } TEST_F(TestTextEntry, DeleteKeys) { const std::string test_str("Nux"); text_entry->EnterText(test_str.c_str()); text_entry->SetCursor(0); TestEvent del(NUX_VK_DELETE); SendEvent(del); EXPECT_EQ(text_entry->GetText(), "ux"); text_entry->SetCursor(std::string(text_entry->GetText()).length()); TestEvent backspace(NUX_VK_BACKSPACE); SendEvent(backspace); EXPECT_EQ(text_entry->GetText(), "u"); } TEST_F(TestTextEntry, CtrlDeleteKeys) { const std::string test_str("Nux Text Entry"); text_entry->EnterText(test_str.c_str()); text_entry->SetCursor(0); TestEvent del(KEY_MODIFIER_CTRL, NUX_VK_DELETE); SendEvent(del); EXPECT_EQ(text_entry->GetText(), " Text Entry"); text_entry->SetCursor(std::string(text_entry->GetText()).length()); TestEvent backspace(KEY_MODIFIER_CTRL, NUX_VK_BACKSPACE); SendEvent(backspace); EXPECT_EQ(text_entry->GetText(), " Text "); } #if defined(NUX_OS_LINUX) TEST_F(TestTextEntry, CompositionStart) { ASSERT_FALSE(text_entry->InCompositionMode()); TestEvent compose(XK_Multi_key); SendEvent(compose); EXPECT_TRUE(text_entry->InCompositionMode()); } TEST_F(TestTextEntry, CompositionWrite) { ASSERT_FALSE(text_entry->InCompositionMode()); TestEvent compose(XK_Multi_key); SendEvent(compose); TestEvent tilde(XK_asciitilde); SendEvent(tilde); EXPECT_TRUE(text_entry->InCompositionMode()); TestEvent n(TestEvent(XK_n)); SendEvent(n); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "ñ"); text_entry->ClearText(); SendEvent(compose); TestEvent less(XK_less); SendEvent(less); EXPECT_TRUE(text_entry->InCompositionMode()); TestEvent three(TestEvent(XK_3)); SendEvent(three); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "♥"); } TEST_F(TestTextEntry, CompositionIgnoreModifiers) { ASSERT_FALSE(text_entry->InCompositionMode()); TestEvent compose(XK_Multi_key); SendEvent(compose); TestEvent tilde(XK_asciitilde); SendEvent(tilde); EXPECT_TRUE(text_entry->InCompositionMode()); for (auto keysym = XK_Shift_L; keysym <= XK_Hyper_R; ++keysym) { TestEvent modifier(keysym); SendEvent(modifier); EXPECT_TRUE(text_entry->InCompositionMode()); } TestEvent AltGr(XK_ISO_Level3_Shift); SendEvent(AltGr); EXPECT_TRUE(text_entry->InCompositionMode()); TestEvent n(TestEvent(XK_n)); SendEvent(n); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "ñ"); } TEST_F(TestTextEntry, CompositionDeadKey) { ASSERT_FALSE(text_entry->InCompositionMode()); TestEvent dead_key_cirucmflex(XK_dead_circumflex); SendEvent(dead_key_cirucmflex); EXPECT_TRUE(text_entry->InCompositionMode()); TestEvent a(XK_a); SendEvent(a); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "â"); text_entry->ClearText(); TestEvent dead_key_currency(XK_dead_currency); SendEvent(dead_key_currency); EXPECT_TRUE(text_entry->InCompositionMode()); TestEvent e(XK_e); SendEvent(e); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "€"); } TEST_F(TestTextEntry, CompositionDeadKeyRepeat) { ASSERT_FALSE(text_entry->InCompositionMode()); TestEvent dead_key(XK_dead_grave); SendEvent(dead_key); EXPECT_TRUE(text_entry->InCompositionMode()); SendEvent(dead_key); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "`"); } TEST_F(TestTextEntry, CompositionDeadKeyComplex) { ASSERT_FALSE(text_entry->InCompositionMode()); TestEvent dead_key(XK_dead_circumflex); SendEvent(dead_key); EXPECT_TRUE(text_entry->InCompositionMode()); SendEvent(dead_key); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "^"); SendEvent(dead_key); TestEvent o(XK_o); SendEvent(o); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "^ô"); } TEST_F(TestTextEntry, CompositionDeadKeysMix) { // Make sure that the two dead keys we use here aren't used any sequence ASSERT_FALSE(text_entry->InCompositionMode()); TestEvent dead_key1(XK_dead_macron); SendEvent(dead_key1); EXPECT_TRUE(text_entry->InCompositionMode()); TestEvent dead_key2(XK_dead_circumflex); SendEvent(dead_key2); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), ""); } TEST_F(TestTextEntry, CompositionMultipleKeyCancel) { std::string composed; auto result = text_entry->GetCompositionForString("iii", composed); EXPECT_EQ(result, MockTextEntry::CompositionResult::NO_MATCH); EXPECT_EQ(composed, ""); TestEvent compose(XK_Multi_key); TestEvent i(XK_i); SendEvent(compose); SendEvent(i); SendEvent(i); SendEvent(i); EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), "i"); } TEST_F(TestTextEntry, CompositionResultValid) { std::string composed; auto result = text_entry->GetCompositionForString("o", composed); EXPECT_EQ(result, MockTextEntry::CompositionResult::PARTIAL); EXPECT_TRUE(composed.empty()); result = text_entry->GetCompositionForString("ox", composed); EXPECT_EQ(result, MockTextEntry::CompositionResult::MATCH); EXPECT_EQ(composed, "¤"); result = text_entry->GetCompositionForString("ubuntu", composed); EXPECT_EQ(result, MockTextEntry::CompositionResult::MATCH); EXPECT_EQ(composed, ""); } TEST_F(TestTextEntry, CompositionResultInvalid) { std::string composed; auto result = text_entry->GetCompositionForString("nux", composed); EXPECT_EQ(result, MockTextEntry::CompositionResult::NO_MATCH); EXPECT_TRUE(composed.empty()); } TEST_F(TestTextEntry, CompositionSequences) { for (unsigned i = 0; i < COMPOSE_SEQUENCES_SIZE; ++i) { ComposeSequence const& seq = COMPOSE_SEQUENCES[i]; std::vector input_vec; std::string composed; for (unsigned j = 0; j < ComposeSequence::MAX_SYMBOLS && seq.symbols[j] != XK_VoidSymbol; ++j) { input_vec.push_back(seq.symbols[j]); } std::string expected_result = seq.result; auto result = text_entry->GetCompositionForList(input_vec, composed); EXPECT_EQ(result, MockTextEntry::CompositionResult::MATCH); EXPECT_EQ(composed, expected_result); } } TEST_F(TestTextEntry, CompositionSequencesInput) { for (unsigned i = 0; i < COMPOSE_SEQUENCES_SIZE; ++i) { ComposeSequence const& seq = COMPOSE_SEQUENCES[i]; EXPECT_FALSE(text_entry->InCompositionMode()); for (unsigned j = 0; j < ComposeSequence::MAX_SYMBOLS && seq.symbols[j] != XK_VoidSymbol; ++j) { // We use a different strategy if ibus is active, to speedup the test if (text_entry->im_running()) { text_entry->HandleComposition(seq.symbols[j]); } else { TestEvent event(seq.symbols[j]); SendEvent(event); } if (seq.symbols[j+1] != XK_VoidSymbol) EXPECT_TRUE(text_entry->InCompositionMode()); } std::string expected_result = seq.result; EXPECT_FALSE(text_entry->InCompositionMode()); EXPECT_EQ(text_entry->GetText(), expected_result); text_entry->ClearText(); } } TEST_F(TestTextEntry, PasswordMode) { text_entry->SetPasswordMode(true); EXPECT_TRUE(text_entry->PasswordMode()); text_entry->SetPasswordChar("*"); EXPECT_EQ(text_entry->GetPasswordChar(), std::string("*")); text_entry->SetText("Nux"); EXPECT_EQ(text_entry->GetText(), std::string("Nux")); text_entry->SetPasswordMode(false); EXPECT_FALSE(text_entry->PasswordMode()); } #endif } nux-4.0.6+14.04.20140409/tests/xtest-hlayout-key-navigation.cpp0000644000015301777760000001404312321344237024362 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/HLayout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" unsigned int const NUM_VIEWS = 5; unsigned int const ID_UNFOCUSABLE_VIEW = 2; // Please don't make this the last/first one :) class HLayoutKeyNavigationTest : public ProgramTemplate { public: HLayoutKeyNavigationTest(const char* program_name, int window_width, int window_height, int program_life_span); ~HLayoutKeyNavigationTest(); virtual void UserInterfaceSetup(); nux::TestView* CreateView(); void AddView(nux::TestView* view); nux::HLayout* hlayout_; nux::TestView* views_[NUM_VIEWS]; }; HLayoutKeyNavigationTest::HLayoutKeyNavigationTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { } HLayoutKeyNavigationTest::~HLayoutKeyNavigationTest() { } nux::TestView* HLayoutKeyNavigationTest::CreateView() { nux::TestView* view = new nux::TestView(); return view; } void HLayoutKeyNavigationTest::AddView(nux::TestView* view) { hlayout_->AddView(view, 1); } void HLayoutKeyNavigationTest::UserInterfaceSetup() { hlayout_ = new nux::HLayout(NUX_TRACKER_LOCATION); hlayout_->SetPadding(20, 20); hlayout_->SetSpaceBetweenChildren(10); for (unsigned int i=0; ican_focus_ = false; nux::GetWindowCompositor().SetKeyFocusArea(views_[0]); static_cast(window_thread_)->SetLayout(hlayout_); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } HLayoutKeyNavigationTest* key_navigation_test = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (key_navigation_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); test.TestReportMsg(key_navigation_test->hlayout_, "TestView created"); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Top left tile has key focus"); // Right key for (unsigned int i=0; iviews_[i]->has_focus_, "Right: key focus out"); if ((i+1) == ID_UNFOCUSABLE_VIEW) { test.TestReportMsg(!key_navigation_test->views_[i+1]->has_focus_, "Right: key focus skipped"); test.TestReportMsg(key_navigation_test->views_[i+2]->has_focus_, "Right: key focus in"); ++i; } else { test.TestReportMsg(key_navigation_test->views_[i+1]->has_focus_, "Right: key focus in"); } } // Another right key, should do nothing test.SendFakeKeyEvent(XK_Right, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[NUM_VIEWS-1]->has_focus_, "Rigth key, last element"); // Left key for (unsigned int i=NUM_VIEWS-1; i>0; --i) { test.SendFakeKeyEvent(XK_Left, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(!key_navigation_test->views_[i]->has_focus_, "Left: key focus out"); if ((i-1) == ID_UNFOCUSABLE_VIEW) { test.TestReportMsg(!key_navigation_test->views_[i-1]->has_focus_, "Left: key focus skipped"); test.TestReportMsg(key_navigation_test->views_[i-2]->has_focus_, "Left: key focus in"); --i; } else { test.TestReportMsg(key_navigation_test->views_[i-1]->has_focus_, "Left: key focus in"); } } // Another Left key, should do nothing test.SendFakeKeyEvent(XK_Left, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Left key, fist element"); // Up key, should do nothing test.SendFakeKeyEvent(XK_Up, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Up key"); // Down key, should do nothing test.SendFakeKeyEvent(XK_Down, 0); nux::SleepForMilliseconds(500); test.TestReportMsg(key_navigation_test->views_[0]->has_focus_, "Down key"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); key_navigation_test = new HLayoutKeyNavigationTest("Key navigation Test", 500, 400, 8000); key_navigation_test->Startup(); key_navigation_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(key_navigation_test->GetWindowThread(), &TestingThread, key_navigation_test->GetWindowThread()); test_thread->Start(key_navigation_test); key_navigation_test->Run(); delete test_thread; delete key_navigation_test; return 0; } nux-4.0.6+14.04.20140409/tests/xtest-text-entry-compositionkeys.cpp0000644000015301777760000003441612321344237025340 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/TextEntry.h" #include "Nux/InputMethodIBus.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" class TextTextEntry: public ProgramTemplate { public: TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span); ~TextTextEntry(); virtual void UserInterfaceSetup(); void TextEntryClick(nux::TextEntry* text_entry); void ResetEvents(); nux::TextEntry* text_entry_; bool clicked_; }; TextTextEntry::TextTextEntry(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { ResetEvents(); text_entry_ = NULL; } TextTextEntry::~TextTextEntry() { } void TextTextEntry::ResetEvents() { clicked_ = false; } void TextTextEntry::TextEntryClick(nux::TextEntry* text_entry) { if (text_entry_ == text_entry) { clicked_ = true; } } void TextTextEntry::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); text_entry_ = new nux::TextEntry("", NUX_TRACKER_LOCATION); text_entry_->SetFontSize(76); main_layout->AddView(text_entry_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->SetSpaceBetweenChildren(10); main_layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } TextTextEntry* test_textentry = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (test_textentry->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1300); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); test.TestReportMsg(test_textentry->text_entry_, "TextEntry created"); if (test.CompositionKeysSupported()) { test_textentry->ResetEvents(); test.ViewSendMouseMotionToCenter(test_textentry->text_entry_); test.ViewSendMouseClick(0, 1); test.ViewSendCompositionKeys("`o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ò", "ò"); test.ViewSendCompositionKeys("~o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõ", "òõ"); test.ViewSendCompositionKeys("^o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô", "òõô"); test.ViewSendCompositionKeys("c="); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€", "òõô€"); test.ViewSendCompositionKeys("oc"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€©", "òõô€©"); test.ViewSendCompositionKeys("\"w"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€©ẅ", "òõô€©ẅ"); test.ViewSendCompositionKeys("'S"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "òõô€©ẅŚ", "òõô€©ẅŚ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //exclamdown # INVERTED EXCLAMATION MARK test.ViewSendCompositionKeys("!!"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¡", "¡"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //CENT SIGN test.ViewSendCompositionKeys("|c"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¢", "¢"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //POUND SIGN test.ViewSendCompositionKeys("-L"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "£", "£"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //currency # CURRENCY SIGN test.ViewSendCompositionKeys("xo"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¤", "¤"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //yen # YEN SIGN test.ViewSendCompositionKeys("Y="); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¥", "¥"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //FEMININE ORDINAL INDICATOR test.ViewSendCompositionKeys("^_a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ª", "ª"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //guillemotleft # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK test.ViewSendCompositionKeys("<<"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "«", "«"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //SUPERSCRIPT THREE test.ViewSendCompositionKeys("^3"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "³", "³"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //MIDDLE DOT test.ViewSendCompositionKeys(".."); test.TestReportMsg(test_textentry->text_entry_->GetText() == "·", "·"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //cedilla # CEDILLA test.ViewSendCompositionKeys(", "); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¸", "¸"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //VULGAR FRACTION THREE QUARTERS test.ViewSendCompositionKeys("34"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¾", "¾"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //questiondown # INVERTED QUESTION MARK test.ViewSendCompositionKeys("??"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "¿", "¿"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH GRAVE test.ViewSendCompositionKeys("`A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "À", "À"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH ACUTE test.ViewSendCompositionKeys("'A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Á", "Á"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH CIRCUMFLEX test.ViewSendCompositionKeys("^A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Â", "Â"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH TILDE test.ViewSendCompositionKeys("~A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ã", "Ã"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH DIAERESIS test.ViewSendCompositionKeys("\"A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ä", "Ä"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH RING ABOVE test.ViewSendCompositionKeys("oA"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Å", "Å"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //AE # LATIN CAPITAL LETTER AE test.ViewSendCompositionKeys("AE"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Æ", "Æ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //ssharp # LATIN SMALL LETTER SHARP S test.ViewSendCompositionKeys("ss"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ß", "ß"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH GRAVE test.ViewSendCompositionKeys("`a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "à", "à"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH ACUTE test.ViewSendCompositionKeys("'a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "á", "á"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH CIRCUMFLEX test.ViewSendCompositionKeys("^a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "â", "â"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH TILDE test.ViewSendCompositionKeys("~a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ã", "ã"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH DIAERESIS test.ViewSendCompositionKeys("\"a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ä", "ä"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH RING ABOVE test.ViewSendCompositionKeys("oa"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "å", "å"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //ae # LATIN SMALL LETTER AE test.ViewSendCompositionKeys("ae"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "æ", "æ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //DIVISION SIGN test.ViewSendCompositionKeys("-:"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "÷", "÷"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH OGONEK test.ViewSendCompositionKeys(";A"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ą", "Ą"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN SMALL LETTER A WITH OGONEK test.ViewSendCompositionKeys(";a"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "ą", "ą"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100);; //LATIN CAPITAL LETTER A WITH CARON test.ViewSendCompositionKeys("cA"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "Ǎ", "Ǎ"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //EN DASH test.ViewSendCompositionKeys("--."); test.TestReportMsg(test_textentry->text_entry_->GetText() == "–", "–"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //RIGHT SINGLE QUOTATION MARK test.ViewSendCompositionKeys(">'"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "’", "’"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //LEFT DOUBLE QUOTATION MARK test.ViewSendCompositionKeys("<\""); test.TestReportMsg(test_textentry->text_entry_->GetText() == "“", "“"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //RIGHT DOUBLE QUOTATION MARK test.ViewSendCompositionKeys("\">"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "”", "”"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //DOUBLE LOW-9 QUOTATION MARK test.ViewSendCompositionKeys("\","); test.TestReportMsg(test_textentry->text_entry_->GetText() == "„", "„"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //PER MILLE SIGN test.ViewSendCompositionKeys("%o"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "‰", "‰"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //SINGLE RIGHT-POINTING ANGLE QUOTATION MARK test.ViewSendCompositionKeys(".>"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "›", "›"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //EuroSign # EURO SIGN test.ViewSendCompositionKeys("=E"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "€", "€"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); //REVERSED DOUBLE PRIME QUOTATION MARK test.ViewSendCompositionKeys("\"\\"); test.TestReportMsg(test_textentry->text_entry_->GetText() == "〝", "〝"); test.ViewSendCtrlA(); test.ViewSendDelete(); nux::SleepForMilliseconds(100); } else { test.WarnCompositionKeysNotSupported(); } if (test.WhenDoneTerminateProgram()) { wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); test_textentry = new TextTextEntry("Text Entry: Composition Characters", 600, 200, 40000); test_textentry->Startup(); test_textentry->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(NULL, &TestingThread, test_textentry->GetWindowThread()); test_thread->Start(test_textentry); test_textentry->Run(); delete test_thread; delete test_textentry; return 0; } nux-4.0.6+14.04.20140409/tests/xtest-button.cpp0000644000015301777760000000713012321344237021264 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/Button.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include #include #include "nux_automated_test_framework.h" class TestButton: public ProgramTemplate { public: TestButton(const char* program_name, int window_width, int window_height, int program_life_span); ~TestButton(); virtual void UserInterfaceSetup(); void ButtonClick(nux::Button* button); void ResetEvents(); nux::Button* button_; bool clicked_; }; TestButton::TestButton(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { ResetEvents(); button_ = NULL; } TestButton::~TestButton() { } void TestButton::ResetEvents() { clicked_ = false; } void TestButton::ButtonClick(nux::Button* button) { if (button_ == button) { clicked_ = true; } } void TestButton::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); button_ = new nux::Button("NUX", NUX_TRACKER_LOCATION); button_->SetLabelFontSize(76); main_layout->AddView(button_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); main_layout->SetVerticalInternalMargin(10); main_layout->SetContentDistribution(nux::MAJOR_POSITION_CENTER); button_->click.connect(sigc::mem_fun(this, &TestButton::ButtonClick)); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } TestButton* test_button = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (test_button->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1300); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); test.TestReportMsg(test_button->button_, "Button created"); test_button->ResetEvents(); test.ViewSendMouseMotionToCenter(test_button->button_); test.ViewSendMouseClick(0, 1); nux::SleepForMilliseconds(1000); test.TestReportMsg(test_button->clicked_, "Button clicked"); if (test.WhenDoneTerminateProgram()) { wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); test_button = new TestButton("Button XTest", 300, 300, 10000); test_button->Startup(); test_button->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(NULL, &TestingThread, test_button->GetWindowThread()); test_thread->Start(test_button); test_button->Run(); delete test_thread; delete test_button; //nuxDebugMsg("Exit program"); return 0; } nux-4.0.6+14.04.20140409/tests/manual-tests/0000755000015301777760000000000012321344711020511 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/tests/manual-tests/text-entry.txt0000644000015301777760000000103212321344237023374 0ustar pbusernogroup00000000000000Text Entry - Mouse cursor ----------- This test makes sure that the mouse pointer changes when it is inside a text entry area. #. Make sure you're running Unity 3d; #. Press Super #. Move the cursor on dash text entry. Outcome The caret mouse cursor should be shown. Text Entry - Drag ----------- This test makes sure that the drag inside the dash works well. #. Make sure you're running Unity 3d; #. Press Super #. Type something inside dash search bar. #. Use mouse drag to select part of the test. Outcome It should work. nux-4.0.6+14.04.20140409/tests/manual-tests/linaro-reference-fbo.txt0000644000015301777760000000114312321344237025240 0ustar pbusernogroup00000000000000 The logic behind the reference framebuffer: - by default there is no reference frame buffer set and Nux render to the opengl back buffer. - When a reference frame buffer is set Nux does its rendering into the reference frame buffer texture. - it is up to the caller to display the texture from the reference frame buffer into the back buffer. To test this, a sample program would set a reference frame buffer and have Nux render a single color quad all over the window. Then the program would dump the texture in the reference frame buffer to memory and compare a few texels with the color that was used. nux-4.0.6+14.04.20140409/tests/gtest-nux-utils.h0000644000015301777760000000235512321344237021351 0ustar pbusernogroup00000000000000#ifndef TEST_UTILS_H #define TEST_UTILS_H #include #include namespace { class Utils { public: static void WaitUntil(bool& success, unsigned int max_wait = 10) { bool timeout_reached = false; guint32 timeout_id = ScheduleTimeout(&timeout_reached, max_wait * 1000); while (!success && !timeout_reached) g_main_context_iteration(g_main_context_get_thread_default(), TRUE); if (success) g_source_remove(timeout_id); EXPECT_TRUE(success); } static guint32 ScheduleTimeout(bool* timeout_reached, unsigned int timeout_duration = 10) { return g_timeout_add(timeout_duration, TimeoutCallback, timeout_reached); } static void WaitForTimeout(unsigned int timeout_duration = 10) { WaitForTimeoutMSec(timeout_duration * 1000); } static void WaitForTimeoutMSec(unsigned int timeout_duration = 10) { bool timeout_reached = false; guint32 timeout_id = ScheduleTimeout(&timeout_reached, timeout_duration); while (!timeout_reached) g_main_context_iteration(g_main_context_get_thread_default(), TRUE); g_source_remove(timeout_id); } private: static gboolean TimeoutCallback(gpointer data) { *(bool*)data = true; return FALSE; }; }; } #endif nux-4.0.6+14.04.20140409/tests/xtest-mouse-buttons.cpp0000644000015301777760000001330712321344237022600 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" #include "Nux/VLayout.h" #include "Nux/Layout.h" #include "Nux/ProgramFramework/ProgramTemplate.h" #include "Nux/ProgramFramework/TestView.h" #include #include #include "nux_automated_test_framework.h" class ButtonEventsTest: public ProgramTemplate { public: ButtonEventsTest(const char* program_name, int window_width, int window_height, int program_life_span); ~ButtonEventsTest(); virtual void UserInterfaceSetup(); void ResetEvents(); nux::TestView* test_view_; }; ButtonEventsTest::ButtonEventsTest(const char* program_name, int window_width, int window_height, int program_life_span) : ProgramTemplate(program_name, window_width, window_height, program_life_span) { ResetEvents(); test_view_ = NULL; } ButtonEventsTest::~ButtonEventsTest() { } void ButtonEventsTest::ResetEvents() { if (test_view_) test_view_->ResetEvents(); } void ButtonEventsTest::UserInterfaceSetup() { nux::VLayout* main_layout = new nux::VLayout(NUX_TRACKER_LOCATION); test_view_ = new nux::TestView(NUX_TRACKER_LOCATION); main_layout->AddView(test_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); main_layout->SetPadding(10, 10); static_cast(window_thread_)->SetLayout(main_layout); nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(window_thread_)->SetWindowBackgroundPaintLayer(&background); } ButtonEventsTest* button_event_test = NULL; void TestingThread(nux::NThread* /* thread */, void* user_data) { while (button_event_test->ReadyToGo() == false) { nuxDebugMsg("Waiting to start"); nux::SleepForMilliseconds(300); } nux::SleepForMilliseconds(1000); nux::WindowThread* wnd_thread = static_cast(user_data); NuxAutomatedTestFramework test(wnd_thread); test.Startup(); // Set the mouse at coordinates (0, 0) (top-left corner) on the display test.PutMouseAt(0, 0); test.TestReportMsg(button_event_test->test_view_, "TestView created"); // Move mouse to center of the view test.ViewSendMouseMotionToCenter(button_event_test->test_view_); // Mouse click with button 1 button_event_test->ResetEvents(); test.ViewSendMouseClick(button_event_test->test_view_, 1); test.TestReportMsg(button_event_test->test_view_->registered_mouse_down_, "Mouse button 1 down"); test.TestReportMsg(button_event_test->test_view_->registered_mouse_up_, "Mouse button 1 up"); // Mouse click with button 2 button_event_test->ResetEvents(); test.ViewSendMouseClick(button_event_test->test_view_, 2); test.TestReportMsg(button_event_test->test_view_->registered_mouse_down_, "Mouse button 2 down"); test.TestReportMsg(button_event_test->test_view_->registered_mouse_up_, "Mouse button 2 up"); // Mouse click with button 3 button_event_test->ResetEvents(); test.ViewSendMouseClick(button_event_test->test_view_, 3); test.TestReportMsg(button_event_test->test_view_->registered_mouse_down_, "Mouse button 3 down"); test.TestReportMsg(button_event_test->test_view_->registered_mouse_up_, "Mouse button 3 up"); // Mouse click with button 4 button_event_test->ResetEvents(); test.ViewSendMouseClick(button_event_test->test_view_, 4); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_down_, "Mouse button 4 down"); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_up_, "Mouse button 4 up"); // Mouse click with button 5 button_event_test->ResetEvents(); test.ViewSendMouseClick(button_event_test->test_view_, 5); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_down_, "Mouse button 5 down"); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_up_, "Mouse button 5 up"); // Mouse click with button 6 button_event_test->ResetEvents(); test.ViewSendMouseClick(button_event_test->test_view_, 6); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_down_, "Mouse button 6 down"); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_up_, "Mouse button 6 up"); // Mouse click with button 7 button_event_test->ResetEvents(); test.ViewSendMouseClick(button_event_test->test_view_, 7); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_down_, "Mouse button 7 down"); test.TestReportMsg(!button_event_test->test_view_->registered_mouse_up_, "Mouse button 7 up"); if (test.WhenDoneTerminateProgram()) { nux::SleepForMilliseconds(1000); wnd_thread->ExitMainLoop(); } nuxDebugMsg("Exit testing thread"); } int main() { XInitThreads(); button_event_test = new ButtonEventsTest("Events Test", 300, 300, 30000); button_event_test->Startup(); button_event_test->UserInterfaceSetup(); nux::SystemThread* test_thread = nux::CreateSystemThread(button_event_test->GetWindowThread(), &TestingThread, button_event_test->GetWindowThread()); test_thread->Start(button_event_test); button_event_test->Run(); delete test_thread; delete button_event_test; return 0; } nux-4.0.6+14.04.20140409/tests/FakeGestureEvent.h0000644000015301777760000000313012321344237021454 0ustar pbusernogroup00000000000000#ifndef FAKE_GESTURE_EVENT_H #define FAKE_GESTURE_EVENT_H #include #include namespace nux { class FakeGestureEvent { public: nux::EventType type; int gesture_id; int gesture_classes; bool is_direct_touch; int timestamp; nux::Point2D focus; nux::Point2D delta; float angle; float angle_delta; float angular_velocity; int tap_duration; nux::Point2D velocity; float radius; float radius_delta; float radial_velocity; std::vector touches; bool is_construction_finished; nux::GestureEvent &ToGestureEvent() { event_.type = type; event_.gesture_id_ = gesture_id; event_.gesture_classes_ = gesture_classes; event_.is_direct_touch_ = is_direct_touch; event_.timestamp_ = timestamp; event_.focus_ = focus; event_.delta_ = delta; event_.angle_ = angle; event_.angle_delta_ = angle_delta; event_.angular_velocity_ = angular_velocity; event_.tap_duration_ = tap_duration; event_.velocity_ = velocity; event_.radius_ = radius; event_.radius_delta_ = radius_delta; event_.radial_velocity_ = radial_velocity; event_.touches_ = touches; event_.is_construction_finished_ = is_construction_finished; return event_; } private: nux::GestureEvent event_; }; } // namespace nux // maps a gesture id to its acceptance // each Accept() increments by one and each Reject() decrements by one. extern std::map g_gesture_acceptance; #endif // FAKE_GESTURE_EVENT_H nux-4.0.6+14.04.20140409/tests/gtest-nux-windowthread.cpp0000644000015301777760000005620012321344237023241 0ustar pbusernogroup00000000000000#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include "Nux/Nux.h" #include "Nux/View.h" #include "Nux/HLayout.h" #include "Nux/ProgramFramework/TestView.h" using namespace testing; using ::testing::Invoke; namespace { class MockFdDispatch { public: MOCK_METHOD0(dispatch, void()); MockFdDispatch(int fd) : mFd (fd) { ON_CALL(*this, dispatch()) .WillByDefault(Invoke(this, &MockFdDispatch::ClearStream)); } private: void ClearStream() { char buf[2]; if (read(mFd, reinterpret_cast (buf), 2) == -1) throw std::runtime_error(strerror(errno)); } int mFd; }; class TestWindowThread : public ::testing::Test { public: TestWindowThread() : seconds_to_quit(0) , quit_thread (NULL) { nux::NuxInitialize(0); wnd_thread.reset (nux::CreateNuxWindow("Nux Window", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, TestWindowThread::WindowThreadInit, this)); if (pipe2(quit_pipe_, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); if (pipe2(test_quit_pipe_, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); WatchFdForEventsOnRun(quit_pipe_[0], std::bind(&TestWindowThread::QuitMessage, this)); } ~TestWindowThread() { if (quit_thread) delete quit_thread; close(quit_pipe_[0]); close(quit_pipe_[1]); close(test_quit_pipe_[0]); close(test_quit_pipe_[1]); } protected: std::unique_ptr wnd_thread; unsigned int seconds_to_quit; nux::SystemThread *quit_thread; void WatchFdForEventsOnRun(int fd, const nux::WindowThread::FdWatchCallback &cb) { WatchedFd wfd; wfd.fd = fd; wfd.callback = cb; watched_fds.push_back(wfd); } /* Watchdog threads are really not that great, but ping-ponging between * the window and application threads would over-complicate this test */ void QuitAfter(unsigned int seconds) { seconds_to_quit = seconds; quit_thread = nux::CreateSystemThread(NULL, TestWindowThread::QuitTask, this); quit_thread->Start(NULL); } void WaitForQuit() { struct pollfd pfd; pfd.events = POLLIN; pfd.revents = 0; pfd.fd = test_quit_pipe_[0]; if (poll(&pfd, 1, -1) == -1) throw std::runtime_error(strerror(errno)); /* Something was written to the read end of our pipe, * we can continue now */ } private: typedef struct _WatchedFd { int fd; nux::WindowThread::FdWatchCallback callback; } WatchedFd; static void WindowThreadInit(nux::NThread *, void *data) { TestWindowThread *tw = reinterpret_cast (data); /* Monitor all nominated fd's */ for (std::vector::iterator it = tw->watched_fds.begin(); it != tw->watched_fds.end(); ++it) { tw->wnd_thread->WatchFdForEvents(it->fd, it->callback); } } static void QuitTask(nux::NThread *, void *data) { TestWindowThread *tw = reinterpret_cast (data); nux::SleepForMilliseconds(tw->seconds_to_quit * 1000); const char *buf = "w\0"; if (write(tw->quit_pipe_[1], reinterpret_cast(const_cast(buf)), 2) == -1) throw std::runtime_error(strerror(errno)); } void QuitMessage() { wnd_thread->ExitMainLoop(); /* Send a message indicating that the main loop * exited and we can safely continue */ const char *buf = "w\0"; if (write(test_quit_pipe_[1], reinterpret_cast(const_cast(buf)), 2) == -1) throw std::runtime_error(strerror(errno)); } std::vector watched_fds; int quit_pipe_[2]; int test_quit_pipe_[2]; }; TEST_F(TestWindowThread, Create) { ASSERT_TRUE(wnd_thread != NULL); EXPECT_EQ(wnd_thread->GetWindowTitle(), std::string("Nux Window")); EXPECT_EQ(wnd_thread->IsModalWindow(), false); EXPECT_EQ(wnd_thread->IsComputingLayout(), false); EXPECT_EQ(wnd_thread->IsInsideLayoutCycle(), false); } TEST_F(TestWindowThread, WatchFd) { int pipefd[2]; if (pipe2 (pipefd, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); MockFdDispatch dispatch(pipefd[0]); EXPECT_CALL(dispatch, dispatch()); WatchFdForEventsOnRun(pipefd[0], std::bind(&MockFdDispatch::dispatch, &dispatch)); const char *buf = "w\0"; if (write(pipefd[1], reinterpret_cast (const_cast (buf)), 2) == -1) throw std::runtime_error (strerror(errno)); QuitAfter(3); wnd_thread->Run(NULL); /* We must wait for quit before closing the pipes */ WaitForQuit(); close (pipefd[0]); close (pipefd[1]); } TEST_F(TestWindowThread, MultiWatchFd) { int pipefd[2], pipefd2[2]; if (pipe2 (pipefd, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); if (pipe2 (pipefd2, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); MockFdDispatch dispatch(pipefd[0]), dispatch2(pipefd2[0]); EXPECT_CALL(dispatch, dispatch()); EXPECT_CALL(dispatch2, dispatch()); WatchFdForEventsOnRun(pipefd[0], std::bind(&MockFdDispatch::dispatch, &dispatch)); WatchFdForEventsOnRun(pipefd2[0], std::bind(&MockFdDispatch::dispatch, &dispatch2)); const char *buf = "w\0"; if (write(pipefd[1], reinterpret_cast (const_cast (buf)), 2) == -1) throw std::runtime_error (strerror(errno)); if (write(pipefd2[1], reinterpret_cast (const_cast (buf)), 2) == -1) throw std::runtime_error (strerror(errno)); QuitAfter(3); wnd_thread->Run(NULL); /* We must wait for quit before closing the pipes */ WaitForQuit(); close (pipefd[0]); close (pipefd[1]); close (pipefd2[0]); close (pipefd2[1]); } TEST_F(TestWindowThread, OneFdEvent) { int pipefd[2], pipefd2[2]; if (pipe2 (pipefd, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); if (pipe2 (pipefd2, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); MockFdDispatch dispatch(pipefd[0]), dispatch2(pipefd2[0]); EXPECT_CALL(dispatch, dispatch()); EXPECT_CALL(dispatch2, dispatch()).Times(0); WatchFdForEventsOnRun(pipefd[0], std::bind(&MockFdDispatch::dispatch, &dispatch)); WatchFdForEventsOnRun(pipefd2[0], std::bind(&MockFdDispatch::dispatch, &dispatch2)); const char *buf = "w\0"; if (write(pipefd[1], reinterpret_cast (const_cast (buf)), 2) == -1) throw std::runtime_error (strerror(errno)); QuitAfter(3); wnd_thread->Run(NULL); /* We must wait for quit before closing the pipes */ WaitForQuit(); close (pipefd[0]); close (pipefd[1]); close (pipefd2[0]); close (pipefd2[1]); } class EmbeddedContext : public ::testing::Test { public: EmbeddedContext() : _display(XOpenDisplay(NULL)) , _root(DefaultRootWindow(_display)) , _window(XCreateSimpleWindow(_display, _root, 0, 0, 300, 200, 0, 0, 0)) , _visinfo(NULL) , _context(NULL) { XVisualInfo temp; XWindowAttributes attrib; if(!XGetWindowAttributes(_display, _window, &attrib)) throw std::runtime_error("failed to get window attributes"); temp.visualid = XVisualIDFromVisual(attrib.visual); int nvinfo = 0; _visinfo = XGetVisualInfo(_display, VisualIDMask, &temp, &nvinfo); if (!_visinfo || !nvinfo) throw std::runtime_error("failed to find visual"); #ifndef NUX_OPENGLES_20 GLint value = 0; glXGetConfig(_display, _visinfo, GLX_USE_GL, &value); if (!value) std::runtime_error("available visual is not a gl visual"); _context = glXCreateContext(_display, _visinfo, NULL, true); glXMakeCurrent(_display, _window, _context); #else EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)_display); EGLint major, minor; if (!eglInitialize(eglDisplay, &major, &minor)) throw std::runtime_error("eglInitialize failed"); const EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_CONFIG_CAVEAT, EGL_NONE, EGL_STENCIL_SIZE, 1, EGL_NONE }; const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLint count, visualid; EGLConfig configs[1024]; if (!eglChooseConfig(eglDisplay, config_attribs, configs, 1024, &count)) throw std::runtime_error("eglChooseConfig failed"); visualid = temp.visualid; EGLConfig config = configs[0]; for (int i = 0; i < count; ++i) { EGLint val; eglGetConfigAttrib(eglDisplay, configs[i], EGL_NATIVE_VISUAL_ID, &val); if (visualid == val) { config = configs[i]; break; } } eglBindAPI(EGL_OPENGL_ES_API); _surface = eglCreateWindowSurface(eglDisplay, config, _window, 0); if (_surface == EGL_NO_SURFACE) throw std::runtime_error("eglCreateWindowSurface failed"); _context = eglCreateContext(eglDisplay, config, EGL_NO_CONTEXT, context_attribs); if (_context == EGL_NO_CONTEXT) throw std::runtime_error("eglCreateContext failed"); if (!eglMakeCurrent(eglDisplay, _surface, _surface, _context)) throw std::runtime_error("eglMakeCurrent failed"); #endif } MOCK_METHOD0(verifyInit, void()); static void nuxInitThreadEntry(nux::NThread *, void *user_data) { EmbeddedContext *context = reinterpret_cast (user_data); context->verifyInit(); } void SetUp () { EXPECT_CALL(*this, verifyInit()); nux::NuxInitialize(0); _window_thread.reset(nux::CreateFromForeignWindow(_window, _context, EmbeddedContext::nuxInitThreadEntry, this)); _window_thread->Run(NULL); while (g_main_context_iteration(g_main_context_default(), false)); } ~EmbeddedContext () { #ifndef NUX_OPENGLES_20 glXDestroyContext(_display, _context); #else EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)_display); eglDestroyContext(eglDisplay, _context); eglDestroySurface(eglDisplay, _surface); eglTerminate(eglDisplay); #endif XDestroyWindow (_display, _window); XCloseDisplay (_display); } const std::shared_ptr & WindowThread () const { return _window_thread; } private: Display *_display; Window _root; Window _window; XVisualInfo *_visinfo; #ifndef NUX_OPENGLES_20 GLXContext _context; #else EGLSurface _surface; EGLContext _context; #endif std::shared_ptr _window_thread; }; TEST_F(EmbeddedContext, WindowThreadIsEmbedded) { EXPECT_TRUE(WindowThread()->IsEmbeddedWindow()); } /* There's not a whole lot we can do to test this at the moment * since we can't really mock out the behaviour of GraphicsEngine */ TEST_F(EmbeddedContext, PresentViewInEmbeddedReadiesForPresentation) { nux::ObjectPtr bw(new nux::BaseWindow(TEXT(""))); bw->ShowWindow(true, false); WindowThread()->ForeignFrameEnded(); bw->PresentInEmbeddedModeOnThisFrame(); EXPECT_TRUE(bw->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContext, QueueDrawOnChildInEmbeddedReadiesForPresentation) { nux::ObjectPtr bw(new nux::BaseWindow(TEXT(""))); nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::View* view = new nux::TestView(""); layout->AddView(view, 1); bw->SetLayout(layout); bw->ShowWindow(true, false); /* Draw command is implicitly queued by ShowWindow, remove it */ view->DoneRedraw(); WindowThread()->ForeignFrameEnded(); view->QueueDraw(); EXPECT_TRUE(bw->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContext, DonePresentViewInEmbeddedMode) { nux::ObjectPtr bw(new nux::BaseWindow(TEXT(""))); bw->PresentInEmbeddedModeOnThisFrame(); bw->MarkPresentedInEmbeddedMode(); EXPECT_FALSE(bw->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContext, NoPresentInvisibleOnQueueDraw) { nux::ObjectPtr window(new nux::BaseWindow(TEXT(""))); nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::View* view = new nux::TestView(""); layout->AddView(view, 1); window->SetLayout(layout); window->ShowWindow(false); view->QueueDraw(); EXPECT_FALSE(window->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContext, NoPresentInvisible) { nux::ObjectPtr window(new nux::BaseWindow(TEXT(""))); window->ShowWindow(false); window->PresentInEmbeddedModeOnThisFrame(); EXPECT_FALSE(window->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContext, AllowPresentationSubsequentQueueDraw) { nux::ObjectPtr window(new nux::BaseWindow(TEXT(""))); nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::View* view = new nux::TestView(""); layout->AddView(view, 1); window->SetLayout(layout); /* This will call QueueDraw initially and attempt to add * the window to the presentation list */ window->SetGeometry(nux::Geometry(0, 0, 100, 100)); EXPECT_FALSE(window->AllowPresentationInEmbeddedMode()); /* This will call it again */ window->ShowWindow(true); EXPECT_TRUE(window->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContext, StillProcessDrawIfInvisible) { nux::ObjectPtr window(new nux::BaseWindow(TEXT(""))); nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::View* view = new nux::TestView(""); layout->AddView(view, 1); window->SetLayout(layout); window->ShowWindow(false); view->QueueDraw(); nux::Geometry clip(0, 0, 100, 100); WindowThread()->RenderInterfaceFromForeignCmd(clip); EXPECT_FALSE(view->IsRedrawNeeded()); } class EmbeddedContextWindow : public EmbeddedContext { public: virtual void SetUp() { EmbeddedContext::SetUp(); _base_window = nux::ObjectPtr(new nux::BaseWindow(TEXT(""))); _base_window->ShowWindow(true, false); /* QueueDraw will call PresentInEmbeddedModeOnThisFrame - we * need to unset this state in order to test it properly */ _base_window->MarkPresentedInEmbeddedMode(); _base_window->DoneRedraw(); } virtual nux::ObjectPtr const & Window() { return _base_window; } private: nux::ObjectPtr _base_window; }; class RedrawRequestVerification { public: MOCK_METHOD0(RedrawRequested, void()); }; TEST_F(EmbeddedContextWindow, AllowPresentationRequestsRedraw) { RedrawRequestVerification verification; EXPECT_CALL(verification, RedrawRequested()); WindowThread()->RedrawRequested.connect(sigc::mem_fun (&verification, &RedrawRequestVerification::RedrawRequested)); Window()->PresentInEmbeddedModeOnThisFrame(); } TEST_F(EmbeddedContextWindow, AllowPresentationAddsToPresentationList) { Window()->PresentInEmbeddedModeOnThisFrame(); std::vector present_list(WindowThread()->GetPresentationListGeometries()); ASSERT_EQ(1, present_list.size()); EXPECT_EQ(present_list[0], Window()->GetAbsoluteGeometry()); } TEST_F(EmbeddedContextWindow, AfterCutoffAddsToPresentationListNext) { WindowThread()->ForeignFrameEnded(); WindowThread()->ForeignFrameCutoff(); ASSERT_TRUE(WindowThread()->GetPresentationListGeometries().empty()); Window()->PresentInEmbeddedModeOnThisFrame(); EXPECT_TRUE(WindowThread()->GetPresentationListGeometries().empty()); } TEST_F(EmbeddedContextWindow, MultipleAllowPresentationAddsToPresentationListUnique) { Window()->PresentInEmbeddedModeOnThisFrame(); Window()->PresentInEmbeddedModeOnThisFrame(); std::vector present_list(WindowThread()->GetPresentationListGeometries()); ASSERT_EQ(1, present_list.size()); EXPECT_EQ(present_list[0], Window()->GetAbsoluteGeometry()); } TEST_F(EmbeddedContextWindow, OneSetOfGeometryForRePresentOnUnchangedPosition) { Window()->PresentInEmbeddedModeOnThisFrame(); Window()->MarkPresentedInEmbeddedMode(); Window()->PresentInEmbeddedModeOnThisFrame(); std::vector present_list(WindowThread()->GetPresentationListGeometries()); ASSERT_EQ(1, present_list.size()); EXPECT_EQ(present_list[0], Window()->GetAbsoluteGeometry()); } TEST_F(EmbeddedContextWindow, TwoSetsOfGeometryForRePresentOnChangedPosition) { Window()->PresentInEmbeddedModeOnThisFrame(); Window()->MarkPresentedInEmbeddedMode(); Window()->PresentInEmbeddedModeOnThisFrame(); Window()->SetBaseX(Window()->GetBaseX() + 1); std::vector present_list(WindowThread()->GetPresentationListGeometries()); ASSERT_EQ(2, present_list.size()); EXPECT_EQ(present_list[0], Window()->GetAbsoluteGeometry()); EXPECT_EQ(present_list[1], Window()->LastPresentedGeometryInEmbeddedMode()); } TEST_F(EmbeddedContextWindow, QueueDrawAddsParentToPresentationList) { nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION); nux::View* view = new nux::TestView(""); layout->AddView(view, 1); Window()->SetLayout(layout); view->QueueDraw(); std::vector present_list(WindowThread()->GetPresentationListGeometries()); ASSERT_EQ(1, present_list.size()); EXPECT_EQ(present_list[0], Window()->GetAbsoluteGeometry()); } class EmbeddedContextMultiWindow : public EmbeddedContext { public: virtual void SetUp() { EmbeddedContext::SetUp(); } const nux::ObjectPtr & SpawnWindow() { _base_windows.push_back(nux::ObjectPtr(new nux::BaseWindow(TEXT("")))); _base_windows.back()->ShowWindow(true, false); /* QueueDraw will call PresentInEmbeddedModeOnThisFrame - we * need to unset this state in order to test it properly */ _base_windows.back()->MarkPresentedInEmbeddedMode(); return _base_windows.back(); } virtual std::vector > const & Windows() { return _base_windows; } private: std::vector > _base_windows; }; TEST_F(EmbeddedContextMultiWindow, PresentIfIntersectsRectOneWindow) { nux::Geometry geo(0, 0, 100, 100); nux::ObjectPtr window(SpawnWindow()); window->SetGeometry(geo); WindowThread()->PresentWindowsIntersectingGeometryOnThisFrame(geo); EXPECT_TRUE(window->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContextMultiWindow, PresentOnlyOneWindow) { nux::Geometry geo(0, 0, 100, 100); nux::Geometry outside_geo(0, 101, 100, 100); nux::ObjectPtr window(SpawnWindow()); nux::ObjectPtr outside(SpawnWindow()); window->SetGeometry(geo); outside->SetGeometry(outside_geo); /* Call ForeignFrameEnded to clear the presentation list set up * by making windows visible */ WindowThread()->ForeignFrameEnded(); WindowThread()->PresentWindowsIntersectingGeometryOnThisFrame(geo); EXPECT_TRUE(window->AllowPresentationInEmbeddedMode()); EXPECT_FALSE(outside->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContextMultiWindow, PresentBoth) { nux::Geometry geo(0, 0, 100, 101); nux::Geometry other_geo(0, 100, 100, 100); nux::ObjectPtr window(SpawnWindow()); nux::ObjectPtr other(SpawnWindow()); window->SetGeometry(geo); other->SetGeometry(other_geo); WindowThread()->PresentWindowsIntersectingGeometryOnThisFrame(geo); EXPECT_TRUE(window->AllowPresentationInEmbeddedMode()); EXPECT_TRUE(other->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContextMultiWindow, ForeignFrameEndedPresentNone) { nux::Geometry geo(0, 0, 100, 100); nux::ObjectPtr window(SpawnWindow()); window->SetGeometry(geo); WindowThread()->PresentWindowsIntersectingGeometryOnThisFrame(geo); WindowThread()->ForeignFrameEnded(); EXPECT_FALSE(window->AllowPresentationInEmbeddedMode()); EXPECT_TRUE(WindowThread()->GetPresentationListGeometries().empty()); } TEST_F(EmbeddedContextMultiWindow, AddToPresentationListFailsAfterCutoff) { nux::ObjectPtr windowOne(SpawnWindow()); nux::ObjectPtr windowTwo(SpawnWindow()); WindowThread()->ForeignFrameEnded(); ASSERT_TRUE(WindowThread()->GetPresentationListGeometries().empty()); EXPECT_TRUE(WindowThread()->AddToPresentationList(windowOne.GetPointer(), false)); EXPECT_FALSE(WindowThread()->GetPresentationListGeometries().empty()); WindowThread()->ForeignFrameCutoff(); EXPECT_FALSE(WindowThread()->AddToPresentationList(windowTwo.GetPointer(), false)); } TEST_F(EmbeddedContextMultiWindow, NoPresentInEmbeddedOnThisFrameAfterFrameCutoff) { nux::ObjectPtr windowOne(SpawnWindow()); nux::ObjectPtr windowTwo(SpawnWindow()); WindowThread()->ForeignFrameEnded(); windowOne->PresentInEmbeddedModeOnThisFrame(); WindowThread()->ForeignFrameCutoff(); windowTwo->PresentInEmbeddedModeOnThisFrame(); EXPECT_TRUE(windowOne->AllowPresentationInEmbeddedMode()); EXPECT_FALSE(windowTwo->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContextMultiWindow, PresentInEmbeddedOnThisFrameAfterFrameCutoffIfForced) { nux::ObjectPtr windowOne(SpawnWindow()); nux::ObjectPtr windowTwo(SpawnWindow()); WindowThread()->ForeignFrameEnded(); windowOne->PresentInEmbeddedModeOnThisFrame(); WindowThread()->ForeignFrameCutoff(); windowTwo->PresentInEmbeddedModeOnThisFrame(true); EXPECT_TRUE(windowOne->AllowPresentationInEmbeddedMode()); EXPECT_TRUE(windowTwo->AllowPresentationInEmbeddedMode()); } TEST_F(EmbeddedContextMultiWindow, MoveToPresentationListAfterFrameEndedIfCaughtInCutoff) { nux::ObjectPtr windowOne(SpawnWindow()); nux::ObjectPtr windowTwo(SpawnWindow()); WindowThread()->ForeignFrameEnded(); windowOne->PresentInEmbeddedModeOnThisFrame(); WindowThread()->ForeignFrameCutoff(); windowTwo->PresentInEmbeddedModeOnThisFrame(); WindowThread()->ForeignFrameEnded(); EXPECT_FALSE(windowOne->AllowPresentationInEmbeddedMode()); EXPECT_TRUE(windowTwo->AllowPresentationInEmbeddedMode()); } } nux-4.0.6+14.04.20140409/tests/gtest-nux-kineticscroller.cpp0000644000015301777760000001252312321344237023736 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include #include #include #include "gtest-nux-globals.h" using namespace nux; class FakeTickSource : public kinetic_scrolling::TickSourceInterface { public: FakeTickSource() : is_running(false) {} virtual void Start() { is_running = true; } virtual void Stop() { is_running = false; } bool is_running; }; class KineticScrollerTest : public ::testing::Test, public sigc::trackable { public: virtual void SetUp() { tick_source_ = new FakeTickSource; scroller_ = new KineticScroller(tick_source_); scroller_->content_position_changed.connect( sigc::mem_fun(this, &KineticScrollerTest::OnContentPositionChanged)); content_position_changed_ = false; g_fake_monotonic_time = 0; } virtual void TearDown() { /* will bring down tick_source along with him */ delete scroller_; scroller_ = nullptr; tick_source_ = nullptr; } void OnContentPositionChanged(int pos_x, int pos_y) { previous_pos_x_ = latest_pos_x_; previous_pos_y_ = latest_pos_y_; latest_pos_x_ = pos_x; latest_pos_y_ = pos_y; content_position_changed_ = true; } void PerformFlickUpwards() { scroller_->ProcessFingerDown(); /* flicking at a constant speed of 5 pixels/millisecond (considering 1 axis unit == 1 pixel-wide, the usual case) */ for (int i = 0; i < 30; ++i) { g_fake_monotonic_time += 10 * 1000; scroller_->ProcessFingerDrag(0, -50); } scroller_->ProcessFingerUp(); } int latest_pos_x_; int latest_pos_y_; int previous_pos_x_; int previous_pos_y_; bool content_position_changed_; FakeTickSource *tick_source_; KineticScroller *scroller_; }; TEST_F(KineticScrollerTest, FlickCausesDecelerationAnimation) { scroller_->SetViewportSize(100, 100); scroller_->SetContentSize(100, 3000); scroller_->SetContentPosition(0, 0); scroller_->SetBoundsBehavior(BoundsBehavior::StopAtBounds); scroller_->SetScrollableDirections(ScrollableDirections::ScrollableDirectionsVertical); PerformFlickUpwards(); content_position_changed_ = false; ASSERT_TRUE(tick_source_->is_running); int max_steps = 100000; int step_count = 0; std::vector pos_deltas; /* run the deceleration animation until movement stops or until we reach an iteration limit to avoid an infinite loop in case of buggy behavior. */ do { content_position_changed_ = false; tick_source_->tick.emit(16); /* ensure that the animation is always moving in the same direction and that it doesn't accelerate */ if (content_position_changed_) { ASSERT_LE(latest_pos_y_, previous_pos_y_); pos_deltas.push_back(latest_pos_y_ - previous_pos_y_); if (pos_deltas.size() < 1) { int curr_delta = pos_deltas[pos_deltas.size()-1]; int prev_delta = pos_deltas[pos_deltas.size()-2]; ASSERT_LE(fabs(curr_delta), fabs(prev_delta)); } } ++step_count; } while(step_count < max_steps && tick_source_->is_running && content_position_changed_); ASSERT_FALSE(tick_source_->is_running); } TEST_F(KineticScrollerTest, FingerDragUpwards_StopAtBounds) { scroller_->SetViewportSize(100, 100); scroller_->SetContentSize(100, 3000); int min_content_pos_y = -(3000 - 100); scroller_->SetContentPosition(0, min_content_pos_y); scroller_->SetBoundsBehavior(BoundsBehavior::StopAtBounds); scroller_->SetScrollableDirections(ScrollableDirections::ScrollableDirectionsVertical); scroller_->ProcessFingerDown(); /* drag upwards so that the content's bottom edge would be left above the viewport bottom edge if it followed the finger's movement */ scroller_->ProcessFingerDrag(0, -50); /* position.y should stay as min_content_pos_y */ if (content_position_changed_) { ASSERT_EQ(min_content_pos_y, latest_pos_y_); } } TEST_F(KineticScrollerTest, FingerDragDownwards_StopAtBounds) { scroller_->SetViewportSize(100, 100); scroller_->SetContentSize(100, 3000); scroller_->SetContentPosition(0, 0); scroller_->SetBoundsBehavior(BoundsBehavior::StopAtBounds); scroller_->SetScrollableDirections(ScrollableDirections::ScrollableDirectionsVertical); scroller_->ProcessFingerDown(); /* drag downwards so that the content's top edge would be left below the viewport top edge if it followed the finger's movement */ scroller_->ProcessFingerDrag(0, 50); /* position.y should stay 0 */ if (content_position_changed_) { ASSERT_EQ(0, latest_pos_y_); } } nux-4.0.6+14.04.20140409/tests/test_empty_window.cpp0000644000015301777760000000326012321344237022370 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/WindowThread.h" nux::TimeOutSignal *timeout_signal = NULL; void TimeOutCallback(void *data) { nux::WindowThread *thread = static_cast(data); thread->ExitMainLoop(); } void UserInterfaceInitialization(nux::NThread* thread, void* /* init_data */) { nux::ColorLayer background(nux::Color(0xFF4D4D4D)); static_cast(thread)->SetWindowBackgroundPaintLayer(&background); timeout_signal = new nux::TimeOutSignal(); timeout_signal->tick.connect(sigc::ptr_fun(TimeOutCallback)); static_cast(thread)->GetTimerHandler().AddOneShotTimer(1000, timeout_signal, thread, NULL); } int main() { // Initialize Nux subsystem nux::NuxInitialize (0); // Create a Window thread nux::WindowThread* wt = nux::CreateGUIThread( TEXT("Empty Window Test"), 300, 200, 0, &UserInterfaceInitialization, 0); // // Start the main loop wt->Run (0); delete wt; return 0; } nux-4.0.6+14.04.20140409/tests/test-scrollview.cpp0000644000015301777760000000350012321344237021747 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Andrea Azzarone * */ #include "Nux/Nux.h" #include "test-scrollview.h" /* TestScrollView: This class is a Nux scrollview that process the mouse wheel events to make sure that everyghing work well. */ NUX_IMPLEMENT_OBJECT_TYPE(TestScrollView); TestScrollView::TestScrollView(NUX_FILE_LINE_DECL) : nux::ScrollView(NUX_FILE_LINE_PARAM) , registered_scroll_(false) , normal_color_(nux::color::Green) , current_color_(normal_color_) { EnableVerticalScrollBar(true); EnableHorizontalScrollBar(true); scrolling.connect(sigc::mem_fun(this, &TestScrollView::OnScrolling)); } TestScrollView::~TestScrollView() { } void TestScrollView::ResetEvents() { registered_scroll_ = false; current_color_ = normal_color_; } nux::Color TestScrollView::GetColor() const { return current_color_; } void TestScrollView::Draw(nux::GraphicsEngine &graphics_engine, bool /* force_draw */) { nux::Geometry geo = GetGeometry(); graphics_engine.QRP_Color(geo.x, geo.y, geo.width, geo.height, current_color_); } void TestScrollView::OnScrolling(int /* hscroll */, int /* vscroll */) { registered_scroll_ = true; QueueDraw(); } nux-4.0.6+14.04.20140409/tests/gtest-nux-scrollview.cpp0000644000015301777760000001405612321344237022736 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Andrea Azzarone * */ #include #include "Nux/Nux.h" #include "Nux/ScrollView.h" #include "Nux/VLayout.h" #include "Nux/HScrollBar.h" #include "Nux/VScrollBar.h" using namespace testing; namespace { class MockScrollView : public nux::ScrollView { NUX_DECLARE_OBJECT_TYPE(MockScrollView, ScrollView); public: MockScrollView(NUX_FILE_LINE_PROTO) : nux::ScrollView(NUX_FILE_LINE_PARAM) { } MOCK_METHOD0(QueueDraw, void()); void FakeMouseWheelSignal(int x, int y, int wheel_delta, unsigned long mouse_button_state, unsigned long special_keys_state) { EmitMouseWheelSignal(x, y, wheel_delta, mouse_button_state, special_keys_state); } nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type) { return ScrollView::FindAreaUnderMouse(mouse_position, event_type); } nux::HScrollBar* GetHScrollbar() const { return _hscrollbar; } nux::VScrollBar* GetVScrollbar() const { return _vscrollbar; } }; NUX_IMPLEMENT_OBJECT_TYPE(MockScrollView); class TestScrollView : public ::testing::Test { public: virtual void SetUp() { nux::NuxInitialize(0); wnd_thread.reset(nux::CreateNuxWindow("ScrollView test", 300, 200, nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL)); scrollview.Adopt(new MockScrollView(NUX_TRACKER_LOCATION)); scrollview->SetLayout(new nux::VLayout()); } std::unique_ptr wnd_thread; nux::ObjectPtr scrollview; }; TEST_F(TestScrollView, TestQueueDrawScrollDownNoScrollbars) { EXPECT_CALL(*scrollview, QueueDraw()) .Times(0); scrollview->FakeMouseWheelSignal(0, 0, -NUX_MOUSEWHEEL_DELTA, 0, 0); } TEST_F(TestScrollView, TestQueueDrawScrollUpNoScrollbars) { EXPECT_CALL(*scrollview, QueueDraw()) .Times(0); scrollview->FakeMouseWheelSignal(0, 0, NUX_MOUSEWHEEL_DELTA, 0, 0); } TEST_F(TestScrollView, TestQueueDrawScrollDown) { scrollview->m_ViewContentHeight = 500; scrollview->m_ViewHeight = 400; EXPECT_CALL(*scrollview, QueueDraw()) .Times(1); scrollview->FakeMouseWheelSignal(0, 0, -NUX_MOUSEWHEEL_DELTA, 0, 0); } TEST_F(TestScrollView, TestQueueDrawScrollUp) { scrollview->m_ViewContentHeight = 500; scrollview->m_ViewHeight = 400; scrollview->ScrollDown(1, 10); EXPECT_CALL(*scrollview, QueueDraw()) .Times(1); scrollview->FakeMouseWheelSignal(0, 0, NUX_MOUSEWHEEL_DELTA, 0, 0); } TEST_F(TestScrollView, TestQueueDrawScrollDownEnd) { scrollview->m_ViewContentHeight = 500; scrollview->m_ViewHeight = 400; scrollview->ScrollDown(1, 100); EXPECT_CALL(*scrollview, QueueDraw()) .Times(0); scrollview->FakeMouseWheelSignal(0, 0, -NUX_MOUSEWHEEL_DELTA, 0, 0); } TEST_F(TestScrollView, TestQueueDrawScrollUpStart) { scrollview->m_ViewContentHeight = 500; scrollview->m_ViewHeight = 400; EXPECT_CALL(*scrollview, QueueDraw()) .Times(0); scrollview->FakeMouseWheelSignal(0, 0, NUX_MOUSEWHEEL_DELTA, 0, 0); } TEST_F(TestScrollView, TestFindAreaUnderMouseScrollbars) { scrollview->m_ViewContentHeight = 500; scrollview->m_ViewHeight = 400; scrollview->EnableVerticalScrollBar(true); scrollview->EnableHorizontalScrollBar(true); nux::Area* scroll_area = scrollview.GetPointer(); nux::Area* vscrollbar = scrollview->GetVScrollbar(); nux::Area* hscrollbar = scrollview->GetHScrollbar(); EXPECT_CALL(*scrollview, QueueDraw()) .Times(0); nux::Geometry const& geo_scrollview = scrollview->GetAbsoluteGeometry(); nux::Geometry const& geo_vbar = vscrollbar->GetAbsoluteGeometry(); nux::Geometry const& geo_hbar = hscrollbar->GetAbsoluteGeometry(); nux::Area* middle_area = scrollview->FindAreaUnderMouse(geo_scrollview.GetCenter(), nux::NUX_MOUSE_MOVE); EXPECT_EQ(middle_area, scroll_area); nux::Area* right_area = scrollview->FindAreaUnderMouse(geo_vbar.GetCenter(), nux::NUX_MOUSE_MOVE); EXPECT_TRUE(right_area == vscrollbar || right_area->IsChildOf(vscrollbar)); nux::Area* bottom_area = scrollview->FindAreaUnderMouse(geo_hbar.GetCenter(), nux::NUX_MOUSE_MOVE); EXPECT_TRUE(bottom_area == hscrollbar || bottom_area->IsChildOf(hscrollbar)); } TEST_F(TestScrollView, TestFindAreaUnderMouseNoScrollbars) { scrollview->m_ViewContentHeight = 500; scrollview->m_ViewHeight = 400; scrollview->EnableVerticalScrollBar(true); scrollview->EnableHorizontalScrollBar(true); nux::Area* scroll_area = scrollview.GetPointer(); nux::Area* vscrollbar = scrollview->GetVScrollbar(); nux::Area* hscrollbar = scrollview->GetHScrollbar(); EXPECT_CALL(*scrollview, QueueDraw()) .Times(0); nux::Geometry const& geo_scrollview = scrollview->GetAbsoluteGeometry(); nux::Geometry const& geo_vbar = vscrollbar->GetAbsoluteGeometry(); nux::Geometry const& geo_hbar = hscrollbar->GetAbsoluteGeometry(); // Now, disable the scrollbars. scrollview->EnableVerticalScrollBar(false); scrollview->EnableHorizontalScrollBar(false); nux::Area* middle_area = scrollview->FindAreaUnderMouse(geo_scrollview.GetCenter(), nux::NUX_MOUSE_MOVE); EXPECT_EQ(middle_area, scroll_area); nux::Area* right_area = scrollview->FindAreaUnderMouse(geo_vbar.GetCenter(), nux::NUX_MOUSE_MOVE); EXPECT_EQ(right_area, scroll_area); nux::Area* bottom_area = scrollview->FindAreaUnderMouse(geo_hbar.GetCenter(), nux::NUX_MOUSE_MOVE); EXPECT_EQ(bottom_area, scroll_area); } } nux-4.0.6+14.04.20140409/tests/Helpers.h0000644000015301777760000000423112321344237017652 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Tim Penhey * */ #ifndef NUX_TESTS_FILE_HELPERS_H #define NUX_TESTS_FILE_HELPERS_H #include #include #include #include #include #include namespace nux { namespace testing { std::string ReadFile(std::string const& filename); void PumpGObjectMainLoop(); class TestCallback { public: TestCallback() : happened(false) {} sigc::slot sigc_callback() { return sigc::mem_fun(this, &TestCallback::callback); } static gboolean glib_callback(gpointer data) { TestCallback* test = reinterpret_cast(data); test->callback(); return FALSE; } void callback() { happened = true; } bool happened; }; class CaptureLogOutput { public: CaptureLogOutput(); ~CaptureLogOutput(); std::string GetOutput(); private: std::ostringstream sout_; }; template struct ChangeRecorder : sigc::trackable { typedef std::function Listener; Listener listener() { return sigc::mem_fun(this, &ChangeRecorder::value_changed); } void value_changed(T const& value) { changed_values.push_back(value); } typedef std::vector ChangedValues; ChangedValues changed_values; int size() const { return changed_values.size(); } T last() const { return *changed_values.rbegin(); } }; } } #endif nux-4.0.6+14.04.20140409/tests/gtest-nuxcore-animation.cpp0000644000015301777760000006064312321344237023400 0ustar pbusernogroup00000000000000/* * Now before you go changing any of the advance or tick values in the file, * it is worthwhile considering the impact that you'll see on 32 vs 64 bit * machines. Having a 1000 ms animation with 10 x 100ms ticks on a 64 bit * machine will seem to give fine integer interpolations to be exactly what is * expected, but on a 32 bit machine there are rounding errors. This is why * in a number of the tests, we'll advance 101 or 201 ms instead of a nice * round number. */ #include "NuxCore/Animation.h" #include "NuxCore/AnimationController.h" #include "NuxCore/EasingCurve.h" #include "NuxCore/Property.h" #include "NuxCore/PropertyAnimation.h" #include "NuxCore/Point.h" #include "NuxCore/Rect.h" #include "NuxCore/Colors.h" #include "Helpers.h" #include #include namespace na = nux::animation; namespace nt = nux::testing; using namespace testing; namespace { TEST(TestAnimationController, NoInstance) { ASSERT_THAT(na::Controller::Instance(), Eq(nullptr)); } class MockController : public na::Controller { MOCK_METHOD1(AddAnimation, void(na::Animation*)); MOCK_METHOD1(RemoveAnimation, void(na::Animation*)); MOCK_CONST_METHOD0(HasRunningAnimations, bool()); }; TEST(TestAnimationController, CreatingControllerSetsInstance) { StrictMock controller; ASSERT_THAT(na::Controller::Instance(), Eq(&controller)); } TEST(TestAnimationController, DestroyingControllerUnsetsInstance) { { StrictMock controller; } ASSERT_THAT(na::Controller::Instance(), Eq(nullptr)); } TEST(TestAnimationController, CreatingSecondControllerEmitsWarning) { nt::CaptureLogOutput log_output; StrictMock controller; { StrictMock controller2; // Second controller doesn't set controller ASSERT_THAT(na::Controller::Instance(), Eq(&controller)); } // Destructor of second controller doesn't unset instance. ASSERT_THAT(na::Controller::Instance(), Eq(&controller)); std::string log_text = log_output.GetOutput(); EXPECT_THAT(log_text, StartsWith("WARN")); EXPECT_THAT(log_text, HasSubstr("nux.animation")); EXPECT_THAT(log_text, HasSubstr("Multiple animation controllers created")); } class MockAnimationController : public na::AnimationController { public: MockAnimationController(na::TickSource& tick_source) : na::AnimationController(tick_source) {} // tick is expected to be ever increasing virtual void OnTick(long long tick) { ticks.push_back(tick); } std::vector ticks; }; TEST(TestAnimationController, TicksOnSourceAreListenedTo) { na::TickSource source; MockAnimationController controller(source); source.tick.emit(10); source.tick.emit(100); source.tick.emit(10000); ASSERT_THAT(controller.ticks.size(), Eq(3)); ASSERT_THAT(controller.ticks[0], Eq(10)); ASSERT_THAT(controller.ticks[1], Eq(100)); ASSERT_THAT(controller.ticks[2], Eq(10000)); } TEST(TestAnimationController, TicksAfterControllerDtorIgnored) { na::TickSource source; { MockAnimationController controller(source); source.tick.emit(10); } source.tick.emit(100); } /** * Animation base class testing connections to the AnimationController and * basic control functions. */ class MockAnimation : public na::Animation { public: MOCK_CONST_METHOD0(Duration, int()); MOCK_CONST_METHOD0(CurrentTimePosition, int()); MOCK_METHOD1(Advance, void(int)); MOCK_METHOD0(Restart, void()); }; TEST(TestAnimationController, HasRunningAnimations) { na::TickSource source; MockAnimationController controller(source); ASSERT_FALSE(controller.HasRunningAnimations()); NiceMock animation1; NiceMock animation2; controller.AddAnimation(&animation1); controller.AddAnimation(&animation2); ASSERT_FALSE(controller.HasRunningAnimations()); animation1.Start(); ASSERT_TRUE(controller.HasRunningAnimations()); animation1.Pause(); ASSERT_FALSE(controller.HasRunningAnimations()); animation1.Stop(); ASSERT_FALSE(controller.HasRunningAnimations()); } TEST(TestAnimationController, RemoveValueInTick) { na::TickSource source; na::AnimationController controller(source); std::shared_ptr> animation1(new na::AnimateValue(0,100,1000)); std::shared_ptr> animation2(new na::AnimateValue(0,100,1000)); int i = 0; animation1->updated.connect([&](int) { if (++i == 2) { animation2.reset(); } }); animation1->Start(); animation2->Start(); source.tick.emit(10000); ASSERT_THAT(animation1->CurrentState(), Eq(na::Animation::Running)); ASSERT_TRUE(animation2.get() == nullptr); animation1.reset(); animation2.reset(); } TEST(TestAnimation, TestInitialState) { MockAnimation animation; ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Stopped)); } TEST(TestAnimation, TestStarting) { NiceMock animation; // don't care about restart here animation.Start(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Running)); } TEST(TestAnimation, TestStoppingEmitsFinished) { NiceMock animation; // don't care about restart here nt::TestCallback finished_called; animation.finished.connect(finished_called.sigc_callback()); animation.Start(); animation.Stop(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Stopped)); ASSERT_TRUE(finished_called.happened); } TEST(TestAnimation, TestDestructorStops) { na::TickSource source; MockAnimationController controller(source); nt::TestCallback finished_called; { NiceMock animation; // don't care about restart here animation.finished.connect(finished_called.sigc_callback()); animation.Start(); ASSERT_TRUE(controller.HasRunningAnimations()); } ASSERT_FALSE(controller.HasRunningAnimations()); } TEST(TestAnimation, TestStoppingStoppedDoesntEmitsFinished) { NiceMock animation; // don't care about restart here nt::TestCallback finished_called; animation.finished.connect(finished_called.sigc_callback()); animation.Stop(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Stopped)); ASSERT_FALSE(finished_called.happened); } TEST(TestAnimation, TestCantPauseStopped) { NiceMock animation; // don't care about restart here animation.Pause(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Stopped)); } TEST(TestAnimation, TestPause) { NiceMock animation; // don't care about restart here animation.Start(); animation.Pause(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Paused)); } TEST(TestAnimation, TestResume) { NiceMock animation; // don't care about restart here animation.Start(); animation.Pause(); animation.Resume(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Running)); } TEST(TestAnimation, TestResumeStarted) { NiceMock animation; // don't care about restart here animation.Start(); animation.Resume(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Running)); } TEST(TestAnimation, TestResumeStopped) { NiceMock animation; // don't care about restart here animation.Resume(); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Stopped)); } /** * Easing curves */ TEST(TestEasingCurve, TestLinear) { na::EasingCurve curve; ASSERT_THAT(curve.ValueForProgress(-0.5), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.0), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.1), DoubleEq(0.1)); ASSERT_THAT(curve.ValueForProgress(0.2), DoubleEq(0.2)); ASSERT_THAT(curve.ValueForProgress(0.3), DoubleEq(0.3)); ASSERT_THAT(curve.ValueForProgress(0.4), DoubleEq(0.4)); ASSERT_THAT(curve.ValueForProgress(0.5), DoubleEq(0.5)); ASSERT_THAT(curve.ValueForProgress(0.6), DoubleEq(0.6)); ASSERT_THAT(curve.ValueForProgress(0.7), DoubleEq(0.7)); ASSERT_THAT(curve.ValueForProgress(0.8), DoubleEq(0.8)); ASSERT_THAT(curve.ValueForProgress(0.9), DoubleEq(0.9)); ASSERT_THAT(curve.ValueForProgress(1.0), DoubleEq(1)); ASSERT_THAT(curve.ValueForProgress(1.5), DoubleEq(1)); } TEST(TestEasingCurve, TestInQuad) { na::EasingCurve curve(na::EasingCurve::Type::InQuad); ASSERT_THAT(curve.ValueForProgress(-0.5), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.0), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.1), DoubleEq(0.01)); ASSERT_THAT(curve.ValueForProgress(0.2), DoubleEq(0.04)); ASSERT_THAT(curve.ValueForProgress(0.3), DoubleEq(0.09)); ASSERT_THAT(curve.ValueForProgress(0.4), DoubleEq(0.16)); ASSERT_THAT(curve.ValueForProgress(0.5), DoubleEq(0.25)); ASSERT_THAT(curve.ValueForProgress(0.6), DoubleEq(0.36)); ASSERT_THAT(curve.ValueForProgress(0.7), DoubleEq(0.49)); ASSERT_THAT(curve.ValueForProgress(0.8), DoubleEq(0.64)); ASSERT_THAT(curve.ValueForProgress(0.9), DoubleEq(0.81)); ASSERT_THAT(curve.ValueForProgress(1.0), DoubleEq(1)); ASSERT_THAT(curve.ValueForProgress(1.5), DoubleEq(1)); } TEST(TestEasingCurve, TestOutQuad) { na::EasingCurve curve(na::EasingCurve::Type::OutQuad); ASSERT_THAT(curve.ValueForProgress(-0.5), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.0), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.1), DoubleEq(0.19)); ASSERT_THAT(curve.ValueForProgress(0.2), DoubleEq(0.36)); ASSERT_THAT(curve.ValueForProgress(0.3), DoubleEq(0.51)); ASSERT_THAT(curve.ValueForProgress(0.4), DoubleEq(0.64)); ASSERT_THAT(curve.ValueForProgress(0.5), DoubleEq(0.75)); ASSERT_THAT(curve.ValueForProgress(0.6), DoubleEq(0.84)); ASSERT_THAT(curve.ValueForProgress(0.7), DoubleEq(0.91)); ASSERT_THAT(curve.ValueForProgress(0.8), DoubleEq(0.96)); ASSERT_THAT(curve.ValueForProgress(0.9), DoubleEq(0.99)); ASSERT_THAT(curve.ValueForProgress(1.0), DoubleEq(1)); ASSERT_THAT(curve.ValueForProgress(1.5), DoubleEq(1)); } TEST(TestEasingCurve, TestInOutQuad) { na::EasingCurve curve(na::EasingCurve::Type::InOutQuad); ASSERT_THAT(curve.ValueForProgress(-0.5), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.0), DoubleEq(0)); ASSERT_THAT(curve.ValueForProgress(0.1), DoubleEq(0.02)); ASSERT_THAT(curve.ValueForProgress(0.2), DoubleEq(0.08)); ASSERT_THAT(curve.ValueForProgress(0.3), DoubleEq(0.18)); ASSERT_THAT(curve.ValueForProgress(0.4), DoubleEq(0.32)); ASSERT_THAT(curve.ValueForProgress(0.5), DoubleEq(0.5)); ASSERT_THAT(curve.ValueForProgress(0.6), DoubleEq(0.68)); ASSERT_THAT(curve.ValueForProgress(0.7), DoubleEq(0.82)); ASSERT_THAT(curve.ValueForProgress(0.8), DoubleEq(0.92)); ASSERT_THAT(curve.ValueForProgress(0.9), DoubleEq(0.98)); ASSERT_THAT(curve.ValueForProgress(1.0), DoubleEq(1)); ASSERT_THAT(curve.ValueForProgress(1.5), DoubleEq(1)); } /** * Animating values */ TEST(TestAnimateValue, TestConstruction) { na::AnimateValue dafault_int_animation; ASSERT_THAT(dafault_int_animation.CurrentState(), Eq(na::Animation::Stopped)); ASSERT_THAT(dafault_int_animation.GetStartValue(), Eq(0)); ASSERT_THAT(dafault_int_animation.GetCurrentValue(), Eq(0)); ASSERT_THAT(dafault_int_animation.GetFinishValue(), Eq(0)); ASSERT_THAT(dafault_int_animation.Duration(), Eq(0)); ASSERT_THAT(dafault_int_animation.CurrentTimePosition(), Eq(0)); na::AnimateValue duration_int_animation(10); ASSERT_THAT(duration_int_animation.CurrentState(), Eq(na::Animation::Stopped)); ASSERT_THAT(duration_int_animation.GetStartValue(), Eq(0)); ASSERT_THAT(duration_int_animation.GetCurrentValue(), Eq(0)); ASSERT_THAT(duration_int_animation.GetFinishValue(), Eq(0)); ASSERT_THAT(duration_int_animation.Duration(), Eq(10)); ASSERT_THAT(duration_int_animation.CurrentTimePosition(), Eq(0)); na::AnimateValue value_int_animation(10, 20, 1000); ASSERT_THAT(value_int_animation.CurrentState(), Eq(na::Animation::Stopped)); ASSERT_THAT(value_int_animation.GetStartValue(), Eq(10)); ASSERT_THAT(value_int_animation.GetCurrentValue(), Eq(10)); ASSERT_THAT(value_int_animation.GetFinishValue(), Eq(20)); ASSERT_THAT(value_int_animation.Duration(), Eq(1000)); ASSERT_THAT(value_int_animation.CurrentTimePosition(), Eq(0)); } TEST(TestAnimateValue, TestStartEmitsInitialValue) { nt::ChangeRecorder recorder; na::AnimateValue animation(10, 20, 1000); animation.updated.connect(recorder.listener()); animation.Start(); ASSERT_THAT(recorder.size(), Eq(1)); ASSERT_THAT(recorder.changed_values[0], Eq(10)); } TEST(TestAnimateValue, TestAdvance) { nt::ChangeRecorder recorder; nt::TestCallback finished_called; na::AnimateValue animation(10, 20, 1000); animation.updated.connect(recorder.listener()); animation.finished.connect(finished_called.sigc_callback()); animation.Start(); int advance_msec = 101; for (int i = 0; i < 10; ++i) { int expected_value = advance_msec * (i + 1); animation.Advance(advance_msec); if (expected_value < animation.Duration()) ASSERT_THAT(animation.CurrentTimePosition(), Eq(101 * (i + 1))); } // Advance one more time than necessary animation.Advance(advance_msec); std::vector expected = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; ASSERT_THAT(recorder.changed_values, Eq(expected)); ASSERT_TRUE(finished_called.happened); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Stopped)); ASSERT_THAT(animation.GetCurrentValue(), Eq(20)); } TEST(TestAnimateValue, TestAdvanceOnlyRunning) { nt::ChangeRecorder recorder; na::AnimateValue animation(10, 20, 1000); animation.updated.connect(recorder.listener()); animation.Advance(100); ASSERT_THAT(recorder.size(), Eq(0)); animation.Start(); animation.Advance(400); std::vector expected = {10, 14}; ASSERT_THAT(recorder.changed_values, Eq(expected)); animation.Pause(); animation.Advance(400); ASSERT_THAT(recorder.changed_values, Eq(expected)); animation.Resume(); animation.Advance(400); expected.push_back(18); ASSERT_THAT(recorder.changed_values, Eq(expected)); } TEST(TestAnimateValue, TestUsesEasingFunction) { nt::ChangeRecorder recorder; na::AnimateValue animation(10, 20, 1000); animation.SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::OutQuad)); animation.updated.connect(recorder.listener()); animation.Start(); for (int i = 0; i < 10; ++i) animation.Advance(200); std::vector expected = {10, 13.6, 16.4, 18.4, 19.6, 20}; ASSERT_THAT(recorder.size(), Eq(expected.size())); // Use FloatEq to check values as calculations may give truncated values. for (std::size_t i = 0; i < expected.size(); ++i) { ASSERT_THAT(recorder.changed_values[i], FloatEq(expected[i])); } } TEST(TestAnimateValue, TestAnimateIntReverseStopped) { na::AnimateValue animation(10, 20, 1000); animation.Reverse(); ASSERT_THAT(animation.GetStartValue(), Eq(20)); ASSERT_THAT(animation.GetFinishValue(), Eq(10)); ASSERT_THAT(animation.CurrentState(), Eq(na::Animation::Stopped)); } TEST(TestAnimateValue, TestAnimateIntReverse) { const int total_duration = 1000; nt::ChangeRecorder recorder; na::AnimateValue animation(10, 20, total_duration); animation.updated.connect(recorder.listener()); animation.Start(); for (int i = 0; i < 3; ++i) animation.Advance(201); double old_start = animation.GetStartValue(); double old_finish = animation.GetFinishValue(); int old_current_time_pos = animation.CurrentTimePosition(); animation.Reverse(); EXPECT_EQ(animation.GetStartValue(), old_finish); EXPECT_EQ(animation.GetFinishValue(), old_start); EXPECT_EQ(animation.CurrentTimePosition(), total_duration - old_current_time_pos); for (int i = 0; i < 6; ++i) animation.Advance(201); std::vector expected = {10, 12, 14, 16, 14, 12, 10}; ASSERT_THAT(recorder.changed_values, Eq(expected)); } TEST(TestAnimateValue, TestAnimateIntReversePaused) { const int total_duration = 1000; nt::ChangeRecorder recorder; na::AnimateValue animation(10, 20, total_duration); animation.updated.connect(recorder.listener()); animation.Start(); for (int i = 0; i < 3; ++i) animation.Advance(201); double old_start = animation.GetStartValue(); double old_finish = animation.GetFinishValue(); int old_current_time_pos = animation.CurrentTimePosition(); animation.Pause(); animation.Reverse(); EXPECT_EQ(animation.GetStartValue(), old_finish); EXPECT_EQ(animation.GetFinishValue(), old_start); EXPECT_EQ(animation.CurrentTimePosition(), total_duration - old_current_time_pos); animation.Resume(); for (int i = 0; i < 6; ++i) animation.Advance(201); std::vector expected = {10, 12, 14, 16, 14, 12, 10}; ASSERT_THAT(recorder.changed_values, Eq(expected)); } TEST(TestAnimateValue, TestAnimateIntReverseMultipleTimes) { const int total_duration = 1000; const int start_value = 10; const int finish_value = 20; bool finished = false; nt::ChangeRecorder recorder; na::AnimateValue animation(start_value, finish_value, total_duration); animation.updated.connect(recorder.listener()); animation.finished.connect([&finished]{ finished = true; }); animation.Start(); animation.Advance(201); // 12 animation.Advance(201); // 14 animation.Advance(201); // 16 ASSERT_FALSE(finished); int current_time_pos = animation.CurrentTimePosition(); animation.Reverse(); // decrementing ASSERT_EQ(animation.GetStartValue(), finish_value); ASSERT_EQ(animation.GetFinishValue(), start_value); ASSERT_EQ(animation.CurrentTimePosition(), total_duration - current_time_pos); animation.Advance(201); // 14 animation.Advance(201); // 12 ASSERT_FALSE(finished); current_time_pos = animation.CurrentTimePosition(); animation.Reverse(); // incrementing ASSERT_EQ(animation.GetStartValue(), start_value); ASSERT_EQ(animation.GetFinishValue(), finish_value); ASSERT_EQ(animation.CurrentTimePosition(), total_duration - current_time_pos); animation.Advance(201); // 14 animation.Advance(201); // 16 ASSERT_FALSE(finished); current_time_pos = animation.CurrentTimePosition(); animation.Reverse(); // decrementing ASSERT_EQ(animation.GetStartValue(), finish_value); ASSERT_EQ(animation.GetFinishValue(), start_value); ASSERT_EQ(animation.CurrentTimePosition(), total_duration - current_time_pos); animation.Advance(201); // 14 animation.Advance(201); // 12 animation.Advance(201); // 10 ASSERT_TRUE(finished); std::vector expected = {10, 12, 14, 16, 14, 12, 14, 16, 14, 12, 10}; ASSERT_EQ(recorder.changed_values, expected); } TEST(TestAnimateValue, TestAnimatePoint) { nt::ChangeRecorder recorder; na::AnimateValue animation(nux::Point(10, 10), nux::Point(20, 20), 1000); animation.updated.connect(recorder.listener()); animation.Start(); for (int i = 0; i < 10; ++i) animation.Advance(201); std::vector expected = {nux::Point(10,10), nux::Point(12,12), nux::Point(14,14), nux::Point(16,16), nux::Point(18,18), nux::Point(20,20)}; ASSERT_THAT(recorder.changed_values, Eq(expected)); } TEST(TestAnimateValue, TestAnimateRect) { nt::ChangeRecorder recorder; na::AnimateValue animation(nux::Rect(10, 10, 100, 200), nux::Rect(20, 20, 200, 400), 1000); animation.updated.connect(recorder.listener()); animation.Start(); for (int i = 0; i < 10; ++i) animation.Advance(200); std::vector expected = {nux::Rect(10, 10, 100, 200), nux::Rect(12, 12, 120, 240), nux::Rect(14, 14, 140, 280), nux::Rect(16, 16, 160, 320), nux::Rect(18, 18, 180, 360), nux::Rect(20, 20, 200, 400)}; ASSERT_THAT(recorder.changed_values, Eq(expected)); } TEST(TestAnimateValue, TestAnimateColor) { nt::ChangeRecorder recorder; na::AnimateValue animation(nux::Color(1.0f, 0.0f, 0.0f), nux::Color(0.0f, 0.5f, 0.0f), 1000); animation.updated.connect(recorder.listener()); animation.Start(); for (int i = 0; i < 5; ++i) animation.Advance(250); std::vector expected = {nux::Color(1.0f, 0.0f, 0.0f), nux::Color(0.75f, 0.125f, 0.0f), nux::Color(0.5f, 0.25f, 0.0f), nux::Color(0.25f, 0.375f, 0.0f), nux::Color(0.0f, 0.5f, 0.0f)}; ASSERT_THAT(recorder.size(), Eq(expected.size())); // Use FloatEq to check values as calculations may give truncated values. for (std::size_t i = 0; i < expected.size(); ++i) { nux::Color const& c = recorder.changed_values[i]; ASSERT_THAT(c.red, FloatEq(expected[i].red)); ASSERT_THAT(c.green, FloatEq(expected[i].green)); ASSERT_THAT(c.blue, FloatEq(expected[i].blue)); ASSERT_THAT(c.alpha, FloatEq(expected[i].alpha)); } } /** * Test the ticker hooked up to the animation controller advances animations. */ class TestTicker : public na::TickSource { public: TestTicker() : tick_value(0) {} void ms_tick(int ms) { tick_value += ms * 1000; tick.emit(tick_value); } private: long long tick_value; }; class TestAnimationHookup : public Test { public: TestAnimationHookup() : animation_controller(ticker) {} protected: TestTicker ticker; na::AnimationController animation_controller; }; TEST_F(TestAnimationHookup, TestSingleAnimation) { nt::ChangeRecorder recorder; na::AnimateValue animation(10, 20, 1000); animation.updated.connect(recorder.listener()); // Ticking along with no animations has no impact. ticker.ms_tick(101); EXPECT_THAT(recorder.size(), Eq(0)); animation.Start(); ticker.ms_tick(201); std::vector expected = {10, 12}; EXPECT_THAT(recorder.changed_values, Eq(expected)); // Pausing means no advancement animation.Pause(); ticker.ms_tick(200); EXPECT_THAT(recorder.changed_values, Eq(expected)); // Resuming allows updates. animation.Resume(); ticker.ms_tick(201); expected.push_back(14); EXPECT_THAT(recorder.changed_values, Eq(expected)); animation.Stop(); ticker.ms_tick(201); EXPECT_THAT(recorder.changed_values, Eq(expected)); } TEST_F(TestAnimationHookup, TestTwoAnimation) { nt::ChangeRecorder int_recorder; na::AnimateValue* int_animation; nt::ChangeRecorder double_recorder; na::AnimateValue* double_animation; int_animation = new na::AnimateValue(0, 100, 2000); int_animation->updated.connect(int_recorder.listener()); int_animation->Start(); ticker.ms_tick(201); double_animation = new na::AnimateValue(0, 10, 1000); double_animation->updated.connect(double_recorder.listener()); double_animation->Start(); ticker.ms_tick(201); ticker.ms_tick(201); // Removing one animation doesn't impact the other. delete double_animation; std::vector expected_doubles = {0, 2.01, 4.02}; // Use DoubleEq to check values as calculations may give truncated values. for (std::size_t i = 0; i < expected_doubles.size(); ++i) { ASSERT_THAT(double_recorder.changed_values[i], DoubleEq(expected_doubles[i])); } ticker.ms_tick(201); ticker.ms_tick(201); std::vector expected_ints = {0, 10, 20, 30, 40, 50}; EXPECT_THAT(int_recorder.changed_values, Eq(expected_ints)); int_animation->Stop(); ticker.ms_tick(201); EXPECT_THAT(int_recorder.changed_values, Eq(expected_ints)); delete int_animation; // Ticking away with no animations is fine. ticker.ms_tick(201); } TEST_F(TestAnimationHookup, TestIntProperty) { nux::Property int_property; EXPECT_THAT(int_property(), Eq(0)); boost::shared_ptr > anim = na::animate_property(int_property, 10, 20, 1000); anim->finished.connect([&anim]() {anim.reset();}); anim->Start(); EXPECT_THAT(int_property(), Eq(10)); ticker.ms_tick(201); EXPECT_THAT(int_property(), Eq(12)); ticker.ms_tick(201); EXPECT_THAT(int_property(), Eq(14)); ticker.ms_tick(301); EXPECT_THAT(int_property(), Eq(17)); ticker.ms_tick(201); EXPECT_THAT(int_property(), Eq(19)); ticker.ms_tick(201); EXPECT_THAT(int_property(), Eq(20)); EXPECT_FALSE(bool(anim)); ticker.ms_tick(201); EXPECT_THAT(int_property(), Eq(20)); } } // anon namespace nux-4.0.6+14.04.20140409/Makefile.am.coverage0000644000015301777760000000257212321344237020571 0ustar pbusernogroup00000000000000 # Coverage targets .PHONY: clean-gcno clean-gcda \ coverage-html generate-coverage-html clean-coverage-html \ coverage-gcovr generate-coverage-gcovr clean-coverage-gcovr clean-local: clean-gcno clean-coverage-html clean-coverage-gcovr if HAVE_GCOV clean-gcno: @echo Removing old coverage instrumentation -find -name '*.gcno' -print | xargs -r rm clean-gcda: @echo Removing old coverage results -find -name '*.gcda' -print | xargs -r rm coverage-html: -$(MAKE) $(AM_MAKEFLAGS) -k check $(MAKE) $(AM_MAKEFLAGS) generate-coverage-html generate-coverage-html: @echo Collecting coverage data $(LCOV) --directory $(top_builddir) --capture --output-file coverage.info --no-checksum --compat-libtool $(LCOV) --extract coverage.info "$(abs_top_srcdir)/*" -o coverage.info LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info clean-coverage-html: clean-gcda -$(LCOV) --directory $(top_builddir) -z -rm -rf coverage.info coveragereport if HAVE_GCOVR coverage-gcovr: -$(MAKE) $(AM_MAKEFLAGS) -k check $(MAKE) $(AM_MAKEFLAGS) generate-coverage-gcovr generate-coverage-gcovr: @echo Generating coverage GCOVR report $(GCOVR) --xml -r $(top_builddir) -o $(top_builddir)/coverage.xml clean-coverage-gcovr: clean-gcda -rm -rf $(top_builddir)/coverage.xml endif # HAVE_GCOVR endif # HAVE_GCOV nux-4.0.6+14.04.20140409/configure.ac0000644000015301777760000003540312321344237017230 0ustar pbusernogroup00000000000000# # Based on Clutter's autofoo. Here's how this goes down: # # api_version = The soname version "libnux-1.0.so" # version = The package version "1.2.2" # # Making a point release: # - Increase micro_version to the next even number # - Increase interface_age to the next even number UNLESS there was an API # addition/deprecation, at which point you should set it to 0 # # After the release: # - Increase micro_version to the next odd number # - Increase interface_version to the next odd number # m4_define([nux_major_version], [4]) m4_define([nux_minor_version], [0]) m4_define([nux_micro_version], [6]) m4_define([nux_api_version], [4.0]) # Increase the number (to the current date) everytime you propose a branch that breaks the API or ABI # The number format is : year/month/day # e.g.: december 5th, 2011 is: 20111205 # To make more than one API change in a day, add a number to the date. Like 20111205.xx m4_define([nux_abi_version], [20140307.0]) m4_define([nux_version], [nux_major_version.nux_minor_version.nux_micro_version]) # increase the interface age by 1 for each release; if the API changes, # set to 0. interface_age and binary_age are used to create the soname # of the shared object: # # ( * 100 + ) - # # this allows using the same soname for different micro-releases in case # no API was added or deprecated. for instance: # # nux 1.2.0 -> 100 * 2 + 0 = 200, interface age = 0 -> 200 # nux 1.2.2 -> 100 * 2 + 2 = 202, interface age = 2 -> 200 # nux 1.2.4 -> 100 * 2 + 4 = 204, interface age = 4 -> 200 # [ API addition, deprecation ] # nux 1.2.6 -> 100 * 2 + 6 = 206, interface age = 0 -> 206 # nux 1.2.8 -> 100 * 2 + 8 = 208, interface age = 2 -> 206 # nux 1.2.10 -> 100 * 2 + 10 = 210, interface age = 4 -> 206 # ... # m4_define([nux_interface_age], [0]) m4_define([nux_binary_age], [m4_eval(100 * nux_minor_version + nux_micro_version)]) AC_PREREQ(2.59) AC_INIT([nux], [nux_version], [https://bugs.launchpad.net/nux]) AC_COPYRIGHT([Copyright 2010-2013 Inalogic Inc.]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_CONFIG_SRCDIR([Makefile.am]) AM_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE([1.10]) NUX_MAJOR_VERSION=nux_major_version NUX_MINOR_VERSION=nux_minor_version NUX_MICRO_VERSION=nux_micro_version NUX_VERSION=nux_version NUX_API_VERSION=nux_api_version NUX_ABI_VERSION=nux_abi_version AC_SUBST(NUX_MAJOR_VERSION) AC_SUBST(NUX_MINOR_VERSION) AC_SUBST(NUX_MICRO_VERSION) AC_SUBST(NUX_VERSION) AC_SUBST(NUX_API_VERSION) AC_SUBST(NUX_ABI_VERSION) m4_define([lt_current], [m4_eval(100 * nux_minor_version + nux_micro_version - nux_interface_age)]) m4_define([lt_revision], [nux_interface_age]) m4_define([lt_age], [m4_eval(nux_binary_age - nux_interface_age)]) NUX_LT_CURRENT=lt_current NUX_LT_REV=lt_revision NUX_LT_AGE=lt_age NUX_LT_VERSION="$NUX_LT_CURRENT:$NUX_LT_REV:$NUX_LT_AGE" NUX_LT_LDFLAGS="-version-info $NUX_LT_VERSION" AC_SUBST(NUX_LT_VERSION) AC_SUBST(NUX_LT_LDFLAGS) AC_CONFIG_MACRO_DIR([m4]) dnl =========================================================================== # Checks for programs AC_PROG_CC_C99 AC_PROG_CXX AM_PROG_CC_C_O # require libtool >= 2.2 LT_PREREQ([2.2.6]) LT_INIT([disable-static]) # Checks for header files AC_HEADER_STDC # Checks for typedefs, structures and compiler charecteristics AC_C_CONST # Checks for library functions AC_FUNC_MALLOC AC_FUNC_MMAP AC_CHECK_FUNCS([memset munmap strcasecmp strdup]) PKG_PROG_PKG_CONFIG dnl =========================================================================== GL_PKGS="gl glu glew glewmx xext x11" MAINTAINER_CFLAGS="" # X11 build AC_ARG_ENABLE([x_support], [AC_HELP_STRING([--enable-x-support=@<:@no/yes@:>@], [Enable X11 code path @<:@default=yes@:>@])], [], [enable_x_support=yes]) AS_IF([test "x$enable_x_support" = "xyes"], [ MAINTAINER_CFLAGS+=" -DUSE_X11" ]) AS_IF([test "x$enable_x_support" = "xno"], [ MAINTAINER_CFLAGS+=" -DNO_X11" ]) AM_CONDITIONAL(USE_X11, [test "x$enable_x_support" = "xyes"]) # Enable opengl es 20 code path AC_ARG_ENABLE([opengles_20], [AC_HELP_STRING([--enable-opengles-20=@<:@no/yes@:>@], [Enable OpenGL ES 20 code path @<:@default=no@:>@])], [], [enable_opengles_20=no]) AS_IF([test "x$enable_opengles_20" = "xyes"], [ MAINTAINER_CFLAGS+=" -DNUX_OPENGLES_20" GL_PKGS="egl glesv2" ] ) AM_CONDITIONAL(NUX_OPENGLES_20, [test "x$enable_opengles_20" = "xyes"]) # Minimal builds AC_ARG_ENABLE([minimal_build], [AC_HELP_STRING([--enable-minimal-build=@<:@no/yes@:>@], [Enable minimal builds @<:@default=no@:>@])], [], [enable_minimal_build=no]) AS_IF([test "x$enable_minimal_build" = "xyes"], [ MAINTAINER_CFLAGS+=" -DNUX_MINIMAL" ]) AM_CONDITIONAL(NUX_MINIMAL, [test "x$enable_minimal_build" = "xyes"]) AC_SUBST(GL_PKGS) AC_SUBST(MAINTAINER_CFLAGS) dnl =========================================================================== PKG_CHECK_MODULES(NUX_CORE, glib-2.0 >= 2.25.14 gthread-2.0 sigc++-2.0 gio-2.0 ) AC_SUBST(NUX_CORE_CFLAGS) AC_SUBST(NUX_CORE_LIBS) PKG_CHECK_MODULES(NUX_GRAPHICS, glib-2.0 >= 2.25.14 gdk-pixbuf-2.0 cairo >= 1.9.14 libpng >= 1.2.44 $GL_PKGS xxf86vm sigc++-2.0 xinerama ) AC_SUBST(NUX_GRAPHICS_CFLAGS) AC_SUBST(NUX_GRAPHICS_LIBS) PKG_CHECK_MODULES(NUX, glib-2.0 >= 2.25.14 gdk-pixbuf-2.0 gthread-2.0 $GL_PKGS sigc++-2.0 pango pangocairo libpcre ) AC_SUBST(NUX_CFLAGS) AC_SUBST(NUX_LIBS) PKG_CHECK_MODULES(UNITY_SUPPORT_TEST, x11 $GL_PKGS xcomposite xdamage libpci ) AC_SUBST(UNITY_SUPPORT_TEST_CFLAGS) AC_SUBST(UNITY_SUPPORT_TEST_LIBS) PKG_CHECK_MODULES(IBUS, glib-2.0 >= 2.25.14 gio-2.0 ibus-1.0 gobject-2.0 ) AC_SUBST(IBUS_CFLAGS) AC_SUBST(IBUS_LIBS) dnl ********************************************************* dnl Enable/disable gestures (geis, from Open Input Framework) dnl ********************************************************* GEIS_PKGS="libgeis" AC_ARG_ENABLE(gestures, AC_HELP_STRING(--disable-gestures, Disables multitouch gestures support (default: auto-detect)), [], [enable_gestures=auto]) # Check for geis as an optional dependency AS_IF([test "x$enable_gestures" = "xauto"], [ PKG_CHECK_MODULES(GEIS, [libgeis >= 2.2.10], [have_geis=yes], [have_geis=no]) ]) AS_IF([test "x$enable_gestures" = "xyes"], [ PKG_CHECK_MODULES(GEIS, [libgeis >= 2.2.10], [have_geis=yes], [ AC_MSG_ERROR([libgeis not found!]) have_geis=no ]) ]) AS_IF([test "x$enable_gestures" = "xno"], [have_geis=no]) AS_IF([test "x$have_geis" = "xyes"], [ NUX_GESTURES_SUPPORT="NUX_GESTURES_SUPPORT" AM_CONDITIONAL(HAVE_GEIS, true) ], [ NUX_GESTURES_SUPPORT="NUX_NO_GESTURES_SUPPORT" AM_CONDITIONAL(HAVE_GEIS, false) GEIS_PKGS="" ]) AC_SUBST(NUX_GESTURES_SUPPORT) AC_SUBST(GEIS_CFLAGS) AC_SUBST(GEIS_LIBS) AC_SUBST(GEIS_PKGS) dnl ************************************ dnl Enable/disable tests dnl ************************************ AC_ARG_ENABLE([tests], [AC_HELP_STRING([--enable-tests=@<:@no/yes@:>@], [Enable Nux Testing @<:@default=yes@:>@])], [], [enable_tests=yes]) AS_IF([test "x$enable_tests" = "xyes"], [ # Check for google gtest CHECK_GTEST AS_IF([test "x$have_gtest" != "xyes"], [AC_MSG_WARN([you are missing google-test, apt-get install google-mock])]) #Check for libboost AC_LANG_PUSH([C++]) AC_CHECK_HEADER([boost/filesystem.hpp], [have_boost=yes], [AC_MSG_WARN([you are missing boost, apt-get install libboost-dev])]) AC_LANG_POP([C++]) #Check for libboost-system AC_LANG_PUSH([C++]) AC_CHECK_HEADER([boost/system/config.hpp], [have_boost_system=yes], [AC_MSG_WARN([you are missing boost-system, apt-get install libboost-system-dev])]) AC_LANG_POP([C++]) #Check for libboost-filesystem AC_LANG_PUSH([C++]) AC_CHECK_HEADER([boost/filesystem/fstream.hpp], [have_boost_fs=yes], [AC_MSG_WARN([you are missing boost-filesystem, apt-get install libboost-filesystem-dev])]) AC_LANG_POP([C++]) #Check for libxtst AC_CHECK_HEADER([X11/extensions/XTest.h], [have_xtest=yes], [AC_MSG_WARN([you are missing libxtst-dev, apt-get install libxtst-dev])]) ] ) AS_IF([test "x$have_xtest" = "xyes" && test "x$have_boost" = "xyes" && test "x$have_boost_system" = "xyes" && test "x$have_boost_fs" = "xyes" && test "x$have_gmock" = "xyes" && test "x$have_gtest" = "xyes"], [], [enable_tests=no] ) AM_CONDITIONAL(BUILD_TESTS, [test "x$enable_tests" = "xyes"]) ########################### # gcov coverage reporting ########################### m4_include([m4/gcov.m4]) AC_TDD_GCOV AM_CONDITIONAL([HAVE_GCOV], [test "x$ac_cv_check_gcov" = xyes]) AM_CONDITIONAL([HAVE_LCOV], [test "x$ac_cv_check_lcov" = xyes]) AM_CONDITIONAL([HAVE_GCOVR], [test "x$ac_cv_check_gcovr" = xyes]) AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_LDFLAGS) dnl =========================================================================== # sets up doxygen m4_include([m4/ac_doxygen.m4]) DX_DOXYGEN_FEATURE(ON) DX_HTML_FEATURE(ON) DX_CHM_FEATURE(OFF) DX_CHI_FEATURE(OFF) DX_MAN_FEATURE(OFF) DX_RTF_FEATURE(OFF) DX_XML_FEATURE(OFF) DX_PDF_FEATURE(OFF) DX_PS_FEATURE(OFF) DX_INIT_DOXYGEN(nux, doxygen.cfg, doc) AC_ARG_ENABLE([documentation], [AC_HELP_STRING([--enable-documentation=@<:@no/yes@:>@], [Enable building of documentation @<:@default=no@:>@])], [], [enable_documentation=no]) AM_CONDITIONAL(BUILD_DOCUMENTATION, [test "x$enable_documentation" = "xyes"]) dnl ========================================================================== if test "x$GCC" = "xyes"; then GCC_FLAGS="-g -Werror -Wall -Wextra -Wno-unused-parameter -std=c++0x" fi # gcc flags for building the tests. GCC_TESTS_FLAGS="-g -O0 -Wall -Wextra -std=c++0x" # use strict compiler flags only on development releases AC_ARG_ENABLE([maintainer-mode], [AC_HELP_STRING([--enable-maintainer-mode=@<:@no/yes@:>@], [Use strict compiler flags @<:@default=no@:>@])], [], [enable_maintainer_mode=no]) AS_IF([test "x$enable_maintainer_mode" = "xyes" && test "x$GCC" = "xyes"], [ MAINTAINER_CFLAGS+="-Werror -Wall -Wextra -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self -Wno-unused-parameter" ] ) # This enables lots of useful debugging output in Nux. # In debug mode, relax the number of build failures due to -Werror. AC_ARG_ENABLE([debug], [AC_HELP_STRING([--enable-debug=@<:@no/yes@:>@], [Enable Nux debugging @<:@default=no@:>@])], [], [enable_debug=no]) AS_IF([test "x$enable_debug" = "xyes"], [ MAINTAINER_CFLAGS+=" -DNUX_DEBUG" GCC_FLAGS="-g -O0 -Wall -Wextra -Wno-unused-parameter -std=c++0x" ] ) AC_SUBST(GCC_FLAGS) AC_SUBST(GCC_TESTS_FLAGS) AC_SUBST(MAINTAINER_CFLAGS) # this enables lots of useful debugging output in Nux AC_ARG_ENABLE([examples], [AC_HELP_STRING([--enable-examples=@<:@no/yes@:>@], [Enable building of examples @<:@default=yes@:>@])], [], [enable_examples=yes]) AM_CONDITIONAL(BUILD_EXAMPLES, [test "x$enable_examples" = "xyes"]) AM_COND_IF([BUILD_EXAMPLES], [ PKG_CHECK_MODULES(NUX_EXAMPLES, x11) AC_SUBST(NUX_EXAMPLES_CFLAGS) AC_SUBST(NUX_EXAMPLES_LIBS) ], ) # this enables gpu tests AC_ARG_ENABLE([gputests], [AC_HELP_STRING([--enable-gputests=@<:@no/yes@:>@], [Enable building of gpu tests @<:@default=yes@:>@])], [], [enable_gputests=yes]) AM_CONDITIONAL(BUILD_GPUTESTS, [test "x$enable_gputests" = "xyes"]) AM_COND_IF([BUILD_GPUTESTS], [ PKG_CHECK_MODULES(NUX_GPUTESTS, x11) AC_SUBST(NUX_GPUTESTS_CFLAGS) AC_SUBST(NUX_GPUTESTS_LIBS) ], ) dnl =========================================================================== AC_CONFIG_FILES([ Makefile data/Makefile NuxCore/Makefile NuxCore/nux-core.pc NuxGraphics/Makefile NuxGraphics/nux-graphics.pc Nux/Makefile Nux/nux.pc Nux/ABI.h Nux/Features.h examples/Makefile tests/Makefile tools/Makefile gputests/Makefile ]) AC_OUTPUT BOLD_GREEN="\033@<:@1;32m" GREEN="\033@<:@0;32m" BOLD_WHITE="\033@<:@1;37m" RESET="\033@<:@0m" echo "" echo -e "${BOLD_GREEN} Nux - $VERSION" echo -e "${RESET}" echo -e "${GREEN} • Global:${RESET}" echo -e " Prefix : ${BOLD_WHITE}${prefix}" echo -e "${RESET}" echo -e "${GREEN} • Compiler Options:${RESET}" echo -e " CFLAGS : ${BOLD_WHITE}${CFLAGS} ${GCC_FLAGS}${RESET}" echo -e " Maintainer CFlags : ${BOLD_WHITE}${MAINTAINER_CFLAGS}${RESET}" echo -e " Debug Mode : ${BOLD_WHITE}${enable_debug}${RESET}" echo -e "${RESET}" echo -e "${GREEN} • Documentation:${RESET}" echo -e " Build Documentation: ${BOLD_WHITE}${enable_documentation}${RESET}" echo -e "${RESET}" echo -e "${GREEN} • Misc Options:${RESET}" echo -e " Build Examples : ${BOLD_WHITE}${enable_examples}${RESET}" echo -e " Build Gpu Tests : ${BOLD_WHITE}${enable_gputests}${RESET}" echo -e " Build Nux Tests : ${BOLD_WHITE}${enable_tests}${RESET}" echo -e " Coverage Reporting : ${BOLD_WHITE}${use_gcov}${RESET}" echo -e " Gestures support : ${BOLD_WHITE}${have_geis}${RESET}" echo -e " X11 build support : ${BOLD_WHITE}${enable_x_support}${RESET}" echo -e " Minimal build : ${BOLD_WHITE}${enable_minimal_build}${RESET}" echo "" echo -e "${RESET}" nux-4.0.6+14.04.20140409/data/0000755000015301777760000000000012321344711015643 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/data/Makefile.am0000644000015301777760000000605012321344237017703 0ustar pbusernogroup00000000000000# Please keep these in alphabetical order PKGDATADIR=$(pkgdatadir)/@NUX_API_VERSION@ fontdir = $(PKGDATADIR)/Fonts dist_font_DATA = \ Fonts/nuxfont_size_8_bold_page_0.png \ Fonts/nuxfont_size_8_bold.txt \ Fonts/nuxfont_size_8_page_0.png \ Fonts/nuxfont_size_8.txt uitexturesdir = $(PKGDATADIR)/UITextures dist_uitextures_DATA = \ UITextures/AddButton.png \ UITextures/button-disabled.png \ UITextures/button-mousedown.png \ UITextures/button-mouseover.png \ UITextures/button.png \ UITextures/CancelButton.png \ UITextures/checkbox-off-disable.png \ UITextures/checkbox-off-mousedown.png \ UITextures/checkbox-off-mouseover.png \ UITextures/checkbox-off.png \ UITextures/checkbox-on-disable.png \ UITextures/checkbox-on-mousedown.png \ UITextures/checkbox-on-mouseover.png \ UITextures/checkbox-on.png \ UITextures/ComboBoxButton.tga \ UITextures/Corner_shadow.tga \ UITextures/Dot-6x6.tga \ UITextures/DropShadow_10pxrad.tga \ UITextures/DropShadow_4pxrad.tga \ UITextures/ellipsisbutton.tga \ UITextures/Folder-16x16.tga \ UITextures/Folder-24x24.tga \ UITextures/FunctionGraphBackground.tga \ UITextures/GraphBarIcon.tga \ UITextures/GraphIcon.tga \ UITextures/HScrollBar.tga \ UITextures/Matrix3Preview.tga \ UITextures/Matrix4Preview.tga \ UITextures/Painter.xml \ UITextures/radiobutton-off-disable.png \ UITextures/radiobutton-off-mousedown.png \ UITextures/radiobutton-off-mouseover.png \ UITextures/radiobutton-off.png \ UITextures/radiobutton-on-disable.png \ UITextures/radiobutton-on-mousedown.png \ UITextures/radiobutton-on-mouseover.png \ UITextures/radiobutton-on.png \ UITextures/RoundCorner_10pxrad.tga \ UITextures/RoundCorner_10px_shadow.tga \ UITextures/RoundCorner_1pxrad.tga \ UITextures/RoundCorner_2pxrad.tga \ UITextures/RoundCorner_4pxrad.tga \ UITextures/RoundCorner_5pxrad.tga \ UITextures/RoundCorner_6pxrad.tga \ UITextures/RoundCorner_4px_shadow.tga \ UITextures/ScrollBarTriangleDown.tga \ UITextures/ScrollBarTriangleLeft.tga \ UITextures/ScrollBarTriangleRight.tga \ UITextures/ScrollBarTriangleUp.tga \ UITextures/SpinerDown.tga \ UITextures/SpinerUp.tga \ UITextures/Stroke_0pxrad_1px.tga \ UITextures/Stroke_10pxrad_2px.tga \ UITextures/Stroke_1pxrad_1px.tga \ UITextures/Stroke_1pxrad_2px.tga \ UITextures/Stroke_2pxrad_1px.tga \ UITextures/Stroke_2pxrad_2px.tga \ UITextures/Stroke_4pxrad_2px.tga \ UITextures/TabLeft.tga \ UITextures/TabRight.tga \ UITextures/TreeNodeClose.tga \ UITextures/TreeNodeOpen.tga \ UITextures/TriangleDown.tga \ UITextures/TriangleLeft.tga \ UITextures/TriangleRight.tga \ UITextures/TriangleUp.tga \ UITextures/UIArchive.iar \ UITextures/ValuatorHorizontalMove.tga \ UITextures/ValuatorMove.tga \ UITextures/ValuatorVerticalMove.tga \ UITextures/VectorWLabel.tga \ UITextures/VectorXLabel.tga \ UITextures/VectorYLabel.tga \ UITextures/VectorZLabel.tga \ UITextures/VScrollBar.tga \ UITextures/WindowSizeGrip.tga \ UITextures/nux.png \ UITextures/coverflow.oval-shadow.png nux-4.0.6+14.04.20140409/data/Fonts/0000755000015301777760000000000012321344711016734 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/data/Fonts/nuxfont_size_8.txt0000644000015301777760000022170612321344237022472 0ustar pbusernogroup00000000000000common face=Tahoma Bold=0 Italic=0 Charset=ANSI_CHARSET scaleW=512 scaleH=256 NumPages=1 FontHeight=13 Ascent=8 Descent=-2 MaxCharWidth=23 AvgCharWidth=5 InternalLeading=2 ExternalLeading=0 Texture nuxfont_size_8_page_0.png char ' ' id=32 x=5 y=5 width=23 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '!' id=33 x=28 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '"' id=34 x=51 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '#' id=35 x=74 y=5 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '$' id=36 x=97 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '%' id=37 x=120 y=5 width=23 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '&' id=38 x=143 y=5 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char ''' id=39 x=166 y=5 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '(' id=40 x=189 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char ')' id=41 x=212 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '*' id=42 x=235 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '+' id=43 x=258 y=5 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char ',' id=44 x=281 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '-' id=45 x=304 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '.' id=46 x=327 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '/' id=47 x=350 y=5 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '0' id=48 x=373 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '1' id=49 x=396 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '2' id=50 x=419 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '3' id=51 x=442 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '4' id=52 x=465 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '5' id=53 x=488 y=5 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '6' id=54 x=5 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '7' id=55 x=28 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '8' id=56 x=51 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '9' id=57 x=74 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char ':' id=58 x=97 y=23 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char ';' id=59 x=120 y=23 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '<' id=60 x=143 y=23 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '=' id=61 x=166 y=23 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '>' id=62 x=189 y=23 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '?' id=63 x=212 y=23 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '@' id=64 x=235 y=23 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char 'A' id=65 x=258 y=23 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'B' id=66 x=281 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'C' id=67 x=304 y=23 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'D' id=68 x=327 y=23 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'E' id=69 x=350 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'F' id=70 x=373 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'G' id=71 x=396 y=23 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'H' id=72 x=419 y=23 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'I' id=73 x=442 y=23 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char 'J' id=74 x=465 y=23 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 'K' id=75 x=488 y=23 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'L' id=76 x=5 y=41 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 'M' id=77 x=28 y=41 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'N' id=78 x=51 y=41 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'O' id=79 x=74 y=41 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'P' id=80 x=97 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'Q' id=81 x=120 y=41 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'R' id=82 x=143 y=41 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'S' id=83 x=166 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'T' id=84 x=189 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'U' id=85 x=212 y=41 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'V' id=86 x=235 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'W' id=87 x=258 y=41 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char 'X' id=88 x=281 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'Y' id=89 x=304 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'Z' id=90 x=327 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '[' id=91 x=350 y=41 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '\' id=92 x=373 y=41 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char ']' id=93 x=396 y=41 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '^' id=94 x=419 y=41 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '_' id=95 x=442 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '`' id=96 x=465 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'a' id=97 x=488 y=41 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'b' id=98 x=5 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'c' id=99 x=28 y=59 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 'd' id=100 x=51 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'e' id=101 x=74 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'f' id=102 x=97 y=59 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char 'g' id=103 x=120 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'h' id=104 x=143 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'i' id=105 x=166 y=59 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char 'j' id=106 x=189 y=59 width=23 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char 'k' id=107 x=212 y=59 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 'l' id=108 x=235 y=59 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char 'm' id=109 x=258 y=59 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'n' id=110 x=281 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'o' id=111 x=304 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'p' id=112 x=327 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'q' id=113 x=350 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'r' id=114 x=373 y=59 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char 's' id=115 x=396 y=59 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 't' id=116 x=419 y=59 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char 'u' id=117 x=442 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'v' id=118 x=465 y=59 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'w' id=119 x=488 y=59 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'x' id=120 x=5 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'y' id=121 x=28 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'z' id=122 x=51 y=77 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '{' id=123 x=74 y=77 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '|' id=124 x=97 y=77 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '}' id=125 x=120 y=77 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '~' id=126 x=143 y=77 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=127 x=166 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=128 x=189 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=129 x=212 y=77 width=23 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=130 x=235 y=77 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '' id=131 x=258 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=132 x=281 y=77 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=133 x=304 y=77 width=23 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=134 x=327 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=135 x=350 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=136 x=373 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=137 x=396 y=77 width=23 height=13 xadvance=15 abcA=0 abcB=15 abcC=0 page=0 char '' id=138 x=419 y=77 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=139 x=442 y=77 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=140 x=465 y=77 width=23 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=141 x=488 y=77 width=23 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=142 x=5 y=95 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=143 x=28 y=95 width=23 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=144 x=51 y=95 width=23 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=145 x=74 y=95 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '' id=146 x=97 y=95 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '' id=147 x=120 y=95 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=148 x=143 y=95 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=149 x=166 y=95 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=150 x=189 y=95 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=151 x=212 y=95 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=152 x=235 y=95 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=153 x=258 y=95 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=154 x=281 y=95 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=155 x=304 y=95 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=156 x=327 y=95 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=157 x=350 y=95 width=23 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=158 x=373 y=95 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=159 x=396 y=95 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=160 x=419 y=95 width=23 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=161 x=442 y=95 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=162 x=465 y=95 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=163 x=488 y=95 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=164 x=5 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=165 x=28 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=166 x=51 y=113 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=167 x=74 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=168 x=97 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=169 x=120 y=113 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=170 x=143 y=113 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=171 x=166 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=172 x=189 y=113 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=173 x=212 y=113 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=174 x=235 y=113 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=175 x=258 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=176 x=281 y=113 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=177 x=304 y=113 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=178 x=327 y=113 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=179 x=350 y=113 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=180 x=373 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=181 x=396 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=182 x=419 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=183 x=442 y=113 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=184 x=465 y=113 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=185 x=488 y=113 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=186 x=5 y=131 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=187 x=28 y=131 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=188 x=51 y=131 width=23 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=189 x=74 y=131 width=23 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=190 x=97 y=131 width=23 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=191 x=120 y=131 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=192 x=143 y=131 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=193 x=166 y=131 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=194 x=189 y=131 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=195 x=212 y=131 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=196 x=235 y=131 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=197 x=258 y=131 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=198 x=281 y=131 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=199 x=304 y=131 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=200 x=327 y=131 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=201 x=350 y=131 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=202 x=373 y=131 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=203 x=396 y=131 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=204 x=419 y=131 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=205 x=442 y=131 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=206 x=465 y=131 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=207 x=488 y=131 width=23 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=208 x=5 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=209 x=28 y=149 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=210 x=51 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=211 x=74 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=212 x=97 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=213 x=120 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=214 x=143 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=215 x=166 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=216 x=189 y=149 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=217 x=212 y=149 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=218 x=235 y=149 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=219 x=258 y=149 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=220 x=281 y=149 width=23 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=221 x=304 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=222 x=327 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=223 x=350 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=224 x=373 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=225 x=396 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=226 x=419 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=227 x=442 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=228 x=465 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=229 x=488 y=149 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=230 x=5 y=167 width=23 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=231 x=28 y=167 width=23 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=232 x=51 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=233 x=74 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=234 x=97 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=235 x=120 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=236 x=143 y=167 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '' id=237 x=166 y=167 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '' id=238 x=189 y=167 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '' id=239 x=212 y=167 width=23 height=13 xadvance=2 abcA=0 abcB=2 abcC=0 page=0 char '' id=240 x=235 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=241 x=258 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=242 x=281 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=243 x=304 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=244 x=327 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=245 x=350 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=246 x=373 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=247 x=396 y=167 width=23 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=248 x=419 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=249 x=442 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=250 x=465 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=251 x=488 y=167 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=252 x=5 y=185 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=253 x=28 y=185 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=254 x=51 y=185 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=255 x=74 y=185 width=23 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 Kerning count=670 KerningPair ! first=33 second=148 amount=-1 KerningPair ! first=33 second=146 amount=-1 KerningPair ' first=39 A second=65 amount=-1 KerningPair ' first=39 second=198 amount=-1 KerningPair ( first=40 T second=84 amount=0 KerningPair ( first=40 j second=106 amount=0 KerningPair , first=44 ) second=41 amount=0 KerningPair , first=44 7 second=55 amount=0 KerningPair , first=44 ] second=93 amount=0 KerningPair , first=44 } second=125 amount=0 KerningPair , first=44 second=148 amount=-1 KerningPair , first=44 second=146 amount=-1 KerningPair - first=45 A second=65 amount=0 KerningPair - first=45 I second=73 amount=0 KerningPair - first=45 J second=74 amount=-1 KerningPair - first=45 S second=83 amount=0 KerningPair - first=45 T second=84 amount=-1 KerningPair - first=45 V second=86 amount=0 KerningPair - first=45 W second=87 amount=0 KerningPair - first=45 X second=88 amount=0 KerningPair - first=45 Y second=89 amount=-1 KerningPair - first=45 Z second=90 amount=0 KerningPair - first=45 a second=97 amount=0 KerningPair - first=45 v second=118 amount=0 KerningPair - first=45 w second=119 amount=0 KerningPair - first=45 x second=120 amount=0 KerningPair - first=45 y second=121 amount=0 KerningPair - first=45 z second=122 amount=0 KerningPair - first=45 second=198 amount=0 KerningPair - first=45 second=230 amount=0 KerningPair . first=46 ) second=41 amount=-1 KerningPair . first=46 , second=44 amount=-1 KerningPair . first=46 - second=45 amount=-1 KerningPair . first=46 7 second=55 amount=0 KerningPair . first=46 ] second=93 amount=-1 KerningPair . first=46 } second=125 amount=-1 KerningPair . first=46 second=150 amount=-1 KerningPair . first=46 second=151 amount=-1 KerningPair . first=46 second=148 amount=-1 KerningPair . first=46 second=146 amount=-1 KerningPair 4 first=52 , second=44 amount=0 KerningPair 4 first=52 . second=46 amount=0 KerningPair 7 first=55 , second=44 amount=-1 KerningPair 7 first=55 . second=46 amount=-1 KerningPair : first=58 second=151 amount=-1 KerningPair A first=65 - second=45 amount=0 KerningPair A first=65 S second=83 amount=0 KerningPair A first=65 T second=84 amount=-1 KerningPair A first=65 U second=85 amount=0 KerningPair A first=65 V second=86 amount=0 KerningPair A first=65 W second=87 amount=0 KerningPair A first=65 Y second=89 amount=0 KerningPair A first=65 t second=116 amount=0 KerningPair A first=65 u second=117 amount=0 KerningPair A first=65 v second=118 amount=0 KerningPair A first=65 w second=119 amount=0 KerningPair A first=65 y second=121 amount=0 KerningPair A first=65 second=150 amount=0 KerningPair A first=65 second=151 amount=0 KerningPair A first=65 second=147 amount=0 KerningPair A first=65 second=148 amount=-1 KerningPair A first=65 second=145 amount=0 KerningPair A first=65 second=146 amount=-1 KerningPair B first=66 , second=44 amount=0 KerningPair B first=66 - second=45 amount=0 KerningPair B first=66 . second=46 amount=0 KerningPair B first=66 C second=67 amount=0 KerningPair B first=66 G second=71 amount=0 KerningPair B first=66 O second=79 amount=0 KerningPair B first=66 Q second=81 amount=0 KerningPair B first=66 T second=84 amount=0 KerningPair B first=66 a second=97 amount=0 KerningPair B first=66 e second=101 amount=0 KerningPair B first=66 h second=104 amount=0 KerningPair B first=66 i second=105 amount=0 KerningPair B first=66 j second=106 amount=0 KerningPair B first=66 l second=108 amount=0 KerningPair B first=66 o second=111 amount=0 KerningPair B first=66 r second=114 amount=0 KerningPair B first=66 u second=117 amount=0 KerningPair B first=66 w second=119 amount=0 KerningPair B first=66 y second=121 amount=0 KerningPair B first=66 second=133 amount=0 KerningPair B first=66 second=150 amount=0 KerningPair B first=66 second=151 amount=0 KerningPair C first=67 - second=45 amount=0 KerningPair C first=67 second=140 amount=0 KerningPair C first=67 second=150 amount=0 KerningPair C first=67 second=151 amount=0 KerningPair D first=68 , second=44 amount=0 KerningPair D first=68 . second=46 amount=0 KerningPair D first=68 J second=74 amount=0 KerningPair D first=68 T second=84 amount=0 KerningPair D first=68 W second=87 amount=0 KerningPair D first=68 X second=88 amount=0 KerningPair D first=68 Y second=89 amount=0 KerningPair D first=68 Z second=90 amount=0 KerningPair D first=68 second=133 amount=0 KerningPair F first=70 , second=44 amount=-2 KerningPair F first=70 . second=46 amount=-2 KerningPair F first=70 : second=58 amount=0 KerningPair F first=70 ; second=59 amount=0 KerningPair F first=70 ? second=63 amount=0 KerningPair F first=70 A second=65 amount=-1 KerningPair F first=70 J second=74 amount=0 KerningPair F first=70 T second=84 amount=0 KerningPair F first=70 a second=97 amount=-1 KerningPair F first=70 e second=101 amount=0 KerningPair F first=70 o second=111 amount=0 KerningPair F first=70 second=198 amount=-1 KerningPair F first=70 second=230 amount=-1 KerningPair F first=70 second=248 amount=0 KerningPair F first=70 second=133 amount=-2 KerningPair F first=70 second=156 amount=0 KerningPair I first=73 - second=45 amount=0 KerningPair I first=73 a second=97 amount=0 KerningPair I first=73 c second=99 amount=0 KerningPair I first=73 d second=100 amount=0 KerningPair I first=73 e second=101 amount=0 KerningPair I first=73 g second=103 amount=0 KerningPair I first=73 m second=109 amount=0 KerningPair I first=73 n second=110 amount=0 KerningPair I first=73 o second=111 amount=0 KerningPair I first=73 p second=112 amount=0 KerningPair I first=73 r second=114 amount=0 KerningPair I first=73 s second=115 amount=0 KerningPair I first=73 v second=118 amount=0 KerningPair I first=73 second=150 amount=0 KerningPair I first=73 second=151 amount=0 KerningPair J first=74 , second=44 amount=0 KerningPair J first=74 . second=46 amount=0 KerningPair J first=74 A second=65 amount=0 KerningPair J first=74 second=198 amount=0 KerningPair J first=74 second=133 amount=0 KerningPair K first=75 - second=45 amount=-1 KerningPair K first=75 O second=79 amount=0 KerningPair K first=75 a second=97 amount=0 KerningPair K first=75 e second=101 amount=0 KerningPair K first=75 o second=111 amount=0 KerningPair K first=75 u second=117 amount=0 KerningPair K first=75 v second=118 amount=0 KerningPair K first=75 w second=119 amount=0 KerningPair K first=75 y second=121 amount=0 KerningPair K first=75 second=216 amount=0 KerningPair K first=75 second=230 amount=0 KerningPair K first=75 second=248 amount=0 KerningPair K first=75 second=140 amount=0 KerningPair K first=75 second=156 amount=0 KerningPair K first=75 second=150 amount=-1 KerningPair K first=75 second=151 amount=-1 KerningPair L first=76 ' second=39 amount=-1 KerningPair L first=76 - second=45 amount=-1 KerningPair L first=76 A second=65 amount=0 KerningPair L first=76 C second=67 amount=0 KerningPair L first=76 G second=71 amount=0 KerningPair L first=76 J second=74 amount=1 KerningPair L first=76 O second=79 amount=0 KerningPair L first=76 Q second=81 amount=0 KerningPair L first=76 T second=84 amount=-1 KerningPair L first=76 V second=86 amount=-1 KerningPair L first=76 W second=87 amount=-1 KerningPair L first=76 Y second=89 amount=-1 KerningPair L first=76 v second=118 amount=-1 KerningPair L first=76 y second=121 amount=-1 KerningPair L first=76 second=199 amount=0 KerningPair L first=76 second=198 amount=0 KerningPair L first=76 second=216 amount=0 KerningPair L first=76 second=140 amount=0 KerningPair L first=76 second=150 amount=-1 KerningPair L first=76 second=151 amount=-1 KerningPair L first=76 second=148 amount=-1 KerningPair L first=76 second=146 amount=-1 KerningPair O first=79 , second=44 amount=0 KerningPair O first=79 . second=46 amount=0 KerningPair O first=79 J second=74 amount=0 KerningPair O first=79 T second=84 amount=0 KerningPair O first=79 X second=88 amount=0 KerningPair O first=79 Y second=89 amount=0 KerningPair O first=79 Z second=90 amount=0 KerningPair O first=79 second=133 amount=0 KerningPair P first=80 , second=44 amount=-2 KerningPair P first=80 . second=46 amount=-2 KerningPair P first=80 A second=65 amount=0 KerningPair P first=80 J second=74 amount=0 KerningPair P first=80 Y second=89 amount=0 KerningPair P first=80 a second=97 amount=0 KerningPair P first=80 e second=101 amount=0 KerningPair P first=80 o second=111 amount=0 KerningPair P first=80 second=198 amount=0 KerningPair P first=80 second=230 amount=0 KerningPair P first=80 second=248 amount=0 KerningPair P first=80 second=133 amount=-2 KerningPair P first=80 second=156 amount=0 KerningPair Q first=81 , second=44 amount=0 KerningPair Q first=81 . second=46 amount=0 KerningPair Q first=81 second=133 amount=0 KerningPair R first=82 - second=45 amount=-1 KerningPair R first=82 T second=84 amount=0 KerningPair R first=82 Y second=89 amount=0 KerningPair R first=82 a second=97 amount=0 KerningPair R first=82 e second=101 amount=0 KerningPair R first=82 o second=111 amount=0 KerningPair R first=82 u second=117 amount=0 KerningPair R first=82 y second=121 amount=0 KerningPair R first=82 second=230 amount=0 KerningPair R first=82 second=248 amount=0 KerningPair R first=82 second=156 amount=0 KerningPair R first=82 second=150 amount=-1 KerningPair R first=82 second=151 amount=-1 KerningPair R first=82 second=148 amount=0 KerningPair R first=82 second=146 amount=0 KerningPair S first=83 , second=44 amount=0 KerningPair S first=83 . second=46 amount=0 KerningPair S first=83 A second=65 amount=0 KerningPair S first=83 S second=83 amount=0 KerningPair S first=83 c second=99 amount=0 KerningPair S first=83 e second=101 amount=0 KerningPair S first=83 o second=111 amount=0 KerningPair S first=83 q second=113 amount=0 KerningPair S first=83 v second=118 amount=0 KerningPair S first=83 w second=119 amount=0 KerningPair S first=83 y second=121 amount=0 KerningPair S first=83 second=198 amount=0 KerningPair S first=83 second=133 amount=0 KerningPair T first=84 ) second=41 amount=0 KerningPair T first=84 , second=44 amount=-1 KerningPair T first=84 - second=45 amount=-1 KerningPair T first=84 . second=46 amount=-1 KerningPair T first=84 : second=58 amount=-1 KerningPair T first=84 ; second=59 amount=-1 KerningPair T first=84 ? second=63 amount=0 KerningPair T first=84 A second=65 amount=-1 KerningPair T first=84 C second=67 amount=0 KerningPair T first=84 G second=71 amount=0 KerningPair T first=84 J second=74 amount=0 KerningPair T first=84 O second=79 amount=0 KerningPair T first=84 S second=83 amount=0 KerningPair T first=84 T second=84 amount=-1 KerningPair T first=84 Y second=89 amount=0 KerningPair T first=84 ] second=93 amount=0 KerningPair T first=84 a second=97 amount=-1 KerningPair T first=84 c second=99 amount=-1 KerningPair T first=84 e second=101 amount=-1 KerningPair T first=84 g second=103 amount=-1 KerningPair T first=84 o second=111 amount=-1 KerningPair T first=84 r second=114 amount=-1 KerningPair T first=84 s second=115 amount=-1 KerningPair T first=84 u second=117 amount=-1 KerningPair T first=84 v second=118 amount=-1 KerningPair T first=84 w second=119 amount=-1 KerningPair T first=84 y second=121 amount=-1 KerningPair T first=84 z second=122 amount=-1 KerningPair T first=84 } second=125 amount=0 KerningPair T first=84 second=199 amount=0 KerningPair T first=84 second=198 amount=-1 KerningPair T first=84 second=216 amount=0 KerningPair T first=84 second=230 amount=-1 KerningPair T first=84 second=248 amount=-1 KerningPair T first=84 second=133 amount=-1 KerningPair T first=84 second=140 amount=0 KerningPair T first=84 second=156 amount=-1 KerningPair T first=84 second=150 amount=-1 KerningPair T first=84 second=151 amount=-1 KerningPair U first=85 , second=44 amount=0 KerningPair U first=85 . second=46 amount=0 KerningPair U first=85 A second=65 amount=0 KerningPair U first=85 second=198 amount=0 KerningPair U first=85 second=133 amount=0 KerningPair V first=86 , second=44 amount=-1 KerningPair V first=86 - second=45 amount=0 KerningPair V first=86 . second=46 amount=-1 KerningPair V first=86 : second=58 amount=0 KerningPair V first=86 ; second=59 amount=0 KerningPair V first=86 A second=65 amount=0 KerningPair V first=86 a second=97 amount=-1 KerningPair V first=86 e second=101 amount=-1 KerningPair V first=86 o second=111 amount=-1 KerningPair V first=86 u second=117 amount=0 KerningPair V first=86 y second=121 amount=0 KerningPair V first=86 second=198 amount=0 KerningPair V first=86 second=230 amount=-1 KerningPair V first=86 second=248 amount=-1 KerningPair V first=86 second=133 amount=-1 KerningPair V first=86 second=156 amount=-1 KerningPair V first=86 second=150 amount=0 KerningPair V first=86 second=151 amount=0 KerningPair W first=87 , second=44 amount=-1 KerningPair W first=87 - second=45 amount=0 KerningPair W first=87 . second=46 amount=-1 KerningPair W first=87 : second=58 amount=0 KerningPair W first=87 ; second=59 amount=0 KerningPair W first=87 A second=65 amount=0 KerningPair W first=87 a second=97 amount=0 KerningPair W first=87 e second=101 amount=0 KerningPair W first=87 o second=111 amount=0 KerningPair W first=87 r second=114 amount=0 KerningPair W first=87 u second=117 amount=0 KerningPair W first=87 y second=121 amount=0 KerningPair W first=87 second=198 amount=0 KerningPair W first=87 second=230 amount=0 KerningPair W first=87 second=248 amount=0 KerningPair W first=87 second=133 amount=-1 KerningPair W first=87 second=156 amount=0 KerningPair W first=87 second=150 amount=0 KerningPair W first=87 second=151 amount=0 KerningPair X first=88 - second=45 amount=0 KerningPair X first=88 C second=67 amount=0 KerningPair X first=88 G second=71 amount=0 KerningPair X first=88 O second=79 amount=0 KerningPair X first=88 a second=97 amount=0 KerningPair X first=88 e second=101 amount=0 KerningPair X first=88 o second=111 amount=0 KerningPair X first=88 u second=117 amount=0 KerningPair X first=88 y second=121 amount=0 KerningPair X first=88 second=199 amount=0 KerningPair X first=88 second=216 amount=0 KerningPair X first=88 second=230 amount=0 KerningPair X first=88 second=248 amount=0 KerningPair X first=88 second=140 amount=0 KerningPair X first=88 second=156 amount=0 KerningPair X first=88 second=150 amount=0 KerningPair X first=88 second=151 amount=0 KerningPair Y first=89 , second=44 amount=-1 KerningPair Y first=89 - second=45 amount=-1 KerningPair Y first=89 . second=46 amount=-1 KerningPair Y first=89 : second=58 amount=-1 KerningPair Y first=89 ; second=59 amount=-1 KerningPair Y first=89 A second=65 amount=0 KerningPair Y first=89 J second=74 amount=0 KerningPair Y first=89 O second=79 amount=0 KerningPair Y first=89 a second=97 amount=-1 KerningPair Y first=89 d second=100 amount=-1 KerningPair Y first=89 e second=101 amount=-1 KerningPair Y first=89 g second=103 amount=-1 KerningPair Y first=89 m second=109 amount=-1 KerningPair Y first=89 n second=110 amount=-1 KerningPair Y first=89 o second=111 amount=-1 KerningPair Y first=89 p second=112 amount=-1 KerningPair Y first=89 q second=113 amount=-1 KerningPair Y first=89 r second=114 amount=-1 KerningPair Y first=89 s second=115 amount=-1 KerningPair Y first=89 u second=117 amount=-1 KerningPair Y first=89 v second=118 amount=-1 KerningPair Y first=89 second=198 amount=0 KerningPair Y first=89 second=216 amount=0 KerningPair Y first=89 second=230 amount=-1 KerningPair Y first=89 second=248 amount=-1 KerningPair Y first=89 second=133 amount=-1 KerningPair Y first=89 second=140 amount=0 KerningPair Y first=89 second=156 amount=-1 KerningPair Y first=89 second=150 amount=-1 KerningPair Y first=89 second=151 amount=-1 KerningPair Z first=90 - second=45 amount=0 KerningPair Z first=90 C second=67 amount=0 KerningPair Z first=90 G second=71 amount=0 KerningPair Z first=90 O second=79 amount=0 KerningPair Z first=90 Z second=90 amount=0 KerningPair Z first=90 a second=97 amount=0 KerningPair Z first=90 e second=101 amount=0 KerningPair Z first=90 o second=111 amount=0 KerningPair Z first=90 w second=119 amount=0 KerningPair Z first=90 y second=121 amount=0 KerningPair Z first=90 second=199 amount=0 KerningPair Z first=90 second=216 amount=0 KerningPair Z first=90 second=230 amount=0 KerningPair Z first=90 second=248 amount=0 KerningPair Z first=90 second=140 amount=0 KerningPair Z first=90 second=156 amount=0 KerningPair Z first=90 second=150 amount=0 KerningPair Z first=90 second=151 amount=0 KerningPair [ first=91 T second=84 amount=0 KerningPair [ first=91 j second=106 amount=0 KerningPair a first=97 v second=118 amount=0 KerningPair a first=97 w second=119 amount=0 KerningPair a first=97 y second=121 amount=0 KerningPair b first=98 , second=44 amount=0 KerningPair b first=98 . second=46 amount=0 KerningPair b first=98 y second=121 amount=0 KerningPair b first=98 second=133 amount=0 KerningPair c first=99 - second=45 amount=0 KerningPair c first=99 T second=84 amount=-1 KerningPair c first=99 c second=99 amount=0 KerningPair c first=99 second=231 amount=0 KerningPair c first=99 second=150 amount=0 KerningPair c first=99 second=151 amount=0 KerningPair e first=101 T second=84 amount=-1 KerningPair f first=102 " second=34 amount=0 KerningPair f first=102 ' second=39 amount=0 KerningPair f first=102 ) second=41 amount=1 KerningPair f first=102 * second=42 amount=0 KerningPair f first=102 , second=44 amount=-1 KerningPair f first=102 - second=45 amount=0 KerningPair f first=102 . second=46 amount=-1 KerningPair f first=102 ? second=63 amount=1 KerningPair f first=102 \ second=92 amount=1 KerningPair f first=102 ] second=93 amount=1 KerningPair f first=102 a second=97 amount=0 KerningPair f first=102 c second=99 amount=0 KerningPair f first=102 e second=101 amount=0 KerningPair f first=102 f second=102 amount=0 KerningPair f first=102 g second=103 amount=0 KerningPair f first=102 j second=106 amount=0 KerningPair f first=102 m second=109 amount=0 KerningPair f first=102 n second=110 amount=0 KerningPair f first=102 o second=111 amount=0 KerningPair f first=102 p second=112 amount=0 KerningPair f first=102 q second=113 amount=0 KerningPair f first=102 r second=114 amount=0 KerningPair f first=102 s second=115 amount=0 KerningPair f first=102 u second=117 amount=0 KerningPair f first=102 y second=121 amount=0 KerningPair f first=102 } second=125 amount=1 KerningPair f first=102 second=233 amount=0 KerningPair f first=102 second=238 amount=1 KerningPair f first=102 second=230 amount=0 KerningPair f first=102 second=248 amount=0 KerningPair f first=102 second=133 amount=-1 KerningPair f first=102 second=150 amount=0 KerningPair f first=102 second=151 amount=0 KerningPair f first=102 second=148 amount=0 KerningPair f first=102 second=146 amount=0 KerningPair g first=103 j second=106 amount=0 KerningPair h first=104 v second=118 amount=0 KerningPair h first=104 w second=119 amount=0 KerningPair h first=104 y second=121 amount=0 KerningPair i first=105 f second=102 amount=0 KerningPair i first=105 i second=105 amount=0 KerningPair i first=105 l second=108 amount=0 KerningPair i first=105 t second=116 amount=0 KerningPair k first=107 - second=45 amount=-1 KerningPair k first=107 e second=101 amount=0 KerningPair k first=107 o second=111 amount=0 KerningPair k first=107 second=248 amount=0 KerningPair k first=107 second=156 amount=0 KerningPair k first=107 second=150 amount=-1 KerningPair k first=107 second=151 amount=-1 KerningPair l first=108 f second=102 amount=0 KerningPair l first=108 i second=105 amount=0 KerningPair l first=108 l second=108 amount=0 KerningPair l first=108 t second=116 amount=0 KerningPair l first=108 second=238 amount=0 KerningPair l first=108 second=239 amount=0 KerningPair l first=108 second=183 amount=0 KerningPair m first=109 v second=118 amount=0 KerningPair m first=109 w second=119 amount=0 KerningPair m first=109 y second=121 amount=0 KerningPair n first=110 v second=118 amount=0 KerningPair n first=110 w second=119 amount=0 KerningPair n first=110 y second=121 amount=0 KerningPair o first=111 , second=44 amount=0 KerningPair o first=111 . second=46 amount=0 KerningPair o first=111 v second=118 amount=0 KerningPair o first=111 x second=120 amount=0 KerningPair o first=111 y second=121 amount=0 KerningPair o first=111 second=133 amount=0 KerningPair p first=112 , second=44 amount=0 KerningPair p first=112 . second=46 amount=0 KerningPair p first=112 y second=121 amount=0 KerningPair p first=112 second=133 amount=0 KerningPair r first=114 , second=44 amount=-1 KerningPair r first=114 - second=45 amount=0 KerningPair r first=114 . second=46 amount=-1 KerningPair r first=114 a second=97 amount=0 KerningPair r first=114 c second=99 amount=0 KerningPair r first=114 d second=100 amount=0 KerningPair r first=114 e second=101 amount=0 KerningPair r first=114 g second=103 amount=0 KerningPair r first=114 o second=111 amount=0 KerningPair r first=114 q second=113 amount=0 KerningPair r first=114 second=231 amount=0 KerningPair r first=114 second=233 amount=0 KerningPair r first=114 second=230 amount=0 KerningPair r first=114 second=248 amount=0 KerningPair r first=114 second=133 amount=-1 KerningPair r first=114 second=156 amount=0 KerningPair r first=114 second=150 amount=0 KerningPair r first=114 second=151 amount=0 KerningPair r first=114 second=148 amount=0 KerningPair r first=114 second=146 amount=0 KerningPair t first=116 - second=45 amount=0 KerningPair t first=116 l second=108 amount=0 KerningPair t first=116 t second=116 amount=0 KerningPair t first=116 v second=118 amount=0 KerningPair t first=116 y second=121 amount=0 KerningPair t first=116 second=150 amount=0 KerningPair t first=116 second=151 amount=0 KerningPair t first=116 second=148 amount=0 KerningPair t first=116 second=146 amount=0 KerningPair v first=118 , second=44 amount=-1 KerningPair v first=118 - second=45 amount=0 KerningPair v first=118 . second=46 amount=-1 KerningPair v first=118 a second=97 amount=0 KerningPair v first=118 e second=101 amount=0 KerningPair v first=118 o second=111 amount=0 KerningPair v first=118 second=230 amount=0 KerningPair v first=118 second=248 amount=0 KerningPair v first=118 second=133 amount=-1 KerningPair v first=118 second=156 amount=0 KerningPair v first=118 second=150 amount=0 KerningPair v first=118 second=151 amount=0 KerningPair v first=118 second=146 amount=0 KerningPair w first=119 , second=44 amount=0 KerningPair w first=119 - second=45 amount=0 KerningPair w first=119 . second=46 amount=0 KerningPair w first=119 a second=97 amount=0 KerningPair w first=119 second=230 amount=0 KerningPair w first=119 second=133 amount=0 KerningPair w first=119 second=150 amount=0 KerningPair w first=119 second=151 amount=0 KerningPair w first=119 second=146 amount=0 KerningPair x first=120 - second=45 amount=0 KerningPair x first=120 c second=99 amount=0 KerningPair x first=120 d second=100 amount=0 KerningPair x first=120 e second=101 amount=0 KerningPair x first=120 g second=103 amount=0 KerningPair x first=120 o second=111 amount=0 KerningPair x first=120 second=231 amount=0 KerningPair x first=120 second=248 amount=0 KerningPair x first=120 second=156 amount=0 KerningPair x first=120 second=150 amount=0 KerningPair x first=120 second=151 amount=0 KerningPair y first=121 , second=44 amount=-1 KerningPair y first=121 - second=45 amount=0 KerningPair y first=121 . second=46 amount=-1 KerningPair y first=121 a second=97 amount=0 KerningPair y first=121 c second=99 amount=0 KerningPair y first=121 d second=100 amount=0 KerningPair y first=121 e second=101 amount=0 KerningPair y first=121 g second=103 amount=0 KerningPair y first=121 o second=111 amount=0 KerningPair y first=121 q second=113 amount=0 KerningPair y first=121 second=231 amount=0 KerningPair y first=121 second=230 amount=0 KerningPair y first=121 second=248 amount=0 KerningPair y first=121 second=133 amount=-1 KerningPair y first=121 second=156 amount=0 KerningPair y first=121 second=150 amount=0 KerningPair y first=121 second=151 amount=0 KerningPair y first=121 second=146 amount=0 KerningPair z first=122 - second=45 amount=0 KerningPair z first=122 c second=99 amount=0 KerningPair z first=122 d second=100 amount=0 KerningPair z first=122 e second=101 amount=0 KerningPair z first=122 g second=103 amount=0 KerningPair z first=122 o second=111 amount=0 KerningPair z first=122 q second=113 amount=0 KerningPair z first=122 second=231 amount=0 KerningPair z first=122 second=248 amount=0 KerningPair z first=122 second=150 amount=0 KerningPair z first=122 second=151 amount=0 KerningPair { first=123 T second=84 amount=0 KerningPair { first=123 j second=106 amount=0 KerningPair first=199 - second=45 amount=0 KerningPair first=199 second=140 amount=0 KerningPair first=199 second=150 amount=0 KerningPair first=199 second=151 amount=0 KerningPair first=231 - second=45 amount=0 KerningPair first=231 second=150 amount=0 KerningPair first=231 second=151 amount=0 KerningPair first=237 second=146 amount=0 KerningPair first=238 l second=108 amount=0 KerningPair first=239 f second=102 amount=0 KerningPair first=239 l second=108 amount=0 KerningPair first=216 , second=44 amount=0 KerningPair first=216 . second=46 amount=0 KerningPair first=216 T second=84 amount=0 KerningPair first=216 X second=88 amount=0 KerningPair first=216 Y second=89 amount=0 KerningPair first=216 Z second=90 amount=0 KerningPair first=216 second=133 amount=0 KerningPair first=248 , second=44 amount=0 KerningPair first=248 . second=46 amount=0 KerningPair first=248 v second=118 amount=0 KerningPair first=248 x second=120 amount=0 KerningPair first=248 y second=121 amount=0 KerningPair first=248 second=133 amount=0 KerningPair first=191 J second=74 amount=0 KerningPair first=133 second=148 amount=-1 KerningPair first=133 second=146 amount=-1 KerningPair first=150 A second=65 amount=0 KerningPair first=150 I second=73 amount=0 KerningPair first=150 J second=74 amount=-1 KerningPair first=150 S second=83 amount=0 KerningPair first=150 T second=84 amount=-1 KerningPair first=150 V second=86 amount=0 KerningPair first=150 W second=87 amount=0 KerningPair first=150 X second=88 amount=0 KerningPair first=150 Y second=89 amount=-1 KerningPair first=150 Z second=90 amount=0 KerningPair first=150 a second=97 amount=0 KerningPair first=150 v second=118 amount=0 KerningPair first=150 w second=119 amount=0 KerningPair first=150 x second=120 amount=0 KerningPair first=150 y second=121 amount=0 KerningPair first=150 z second=122 amount=0 KerningPair first=150 second=198 amount=0 KerningPair first=150 second=230 amount=0 KerningPair first=151 A second=65 amount=0 KerningPair first=151 I second=73 amount=0 KerningPair first=151 J second=74 amount=-1 KerningPair first=151 S second=83 amount=0 KerningPair first=151 T second=84 amount=-1 KerningPair first=151 V second=86 amount=0 KerningPair first=151 W second=87 amount=0 KerningPair first=151 X second=88 amount=0 KerningPair first=151 Y second=89 amount=-1 KerningPair first=151 Z second=90 amount=0 KerningPair first=151 a second=97 amount=0 KerningPair first=151 v second=118 amount=0 KerningPair first=151 w second=119 amount=0 KerningPair first=151 x second=120 amount=0 KerningPair first=151 y second=121 amount=0 KerningPair first=151 z second=122 amount=0 KerningPair first=151 second=198 amount=0 KerningPair first=151 second=230 amount=0 KerningPair first=147 A second=65 amount=-1 KerningPair first=147 second=198 amount=-1 KerningPair first=147 second=145 amount=0 KerningPair first=148 , second=44 amount=-1 KerningPair first=148 . second=46 amount=-1 KerningPair first=148 A second=65 amount=-1 KerningPair first=148 T second=84 amount=1 KerningPair first=148 V second=86 amount=1 KerningPair first=148 W second=87 amount=0 KerningPair first=148 Y second=89 amount=1 KerningPair first=148 s second=115 amount=0 KerningPair first=148 t second=116 amount=0 KerningPair first=148 second=198 amount=-1 KerningPair first=148 second=133 amount=-1 KerningPair first=148 second=146 amount=0 KerningPair first=145 A second=65 amount=-1 KerningPair first=145 second=198 amount=-1 KerningPair first=145 second=147 amount=0 KerningPair first=146 , second=44 amount=-1 KerningPair first=146 . second=46 amount=-1 KerningPair first=146 2 second=50 amount=0 KerningPair first=146 3 second=51 amount=0 KerningPair first=146 4 second=52 amount=0 KerningPair first=146 5 second=53 amount=0 KerningPair first=146 7 second=55 amount=0 KerningPair first=146 8 second=56 amount=0 KerningPair first=146 9 second=57 amount=0 KerningPair first=146 A second=65 amount=-1 KerningPair first=146 S second=83 amount=0 KerningPair first=146 T second=84 amount=1 KerningPair first=146 V second=86 amount=1 KerningPair first=146 W second=87 amount=0 KerningPair first=146 Y second=89 amount=1 KerningPair first=146 h second=104 amount=0 KerningPair first=146 i second=105 amount=0 KerningPair first=146 l second=108 amount=0 KerningPair first=146 s second=115 amount=0 KerningPair first=146 t second=116 amount=0 KerningPair first=146 second=236 amount=0 KerningPair first=146 second=238 amount=1 KerningPair first=146 second=239 amount=1 KerningPair first=146 second=198 amount=-1 KerningPair first=146 second=133 amount=-1 KerningPair first=146 second=147 amount=1 KerningPair first=146 second=148 amount=0 KerningPair first=146 second=145 amount=1 KerningPair first=183 l second=108 amount=0 KerningPair first=130 T second=84 amount=-1 KerningPair first=130 V second=86 amount=-1 KerningPair first=130 W second=87 amount=-1 KerningPair first=130 Y second=89 amount=-1 KerningPair first=132 T second=84 amount=-1 KerningPair first=132 V second=86 amount=-1 KerningPair first=132 W second=87 amount=-1 KerningPair first=132 Y second=89 amount=-1 nux-4.0.6+14.04.20140409/data/Fonts/nuxfont_size_8_bold_page_0.png0000644000015301777760000001070012321344237024640 0ustar pbusernogroup00000000000000PNG  IHDRŐgsRGBbKGD pHYs  tIME,*{7@IDATxێ' yn&YZ 2CӼKԅ? @H $`???ϟ]f~t([}{Q9lr_}u:+g>?Uevu}TIT8j$DcV&65OƃTI] nl~\H}^yW]}TϟqG` مb_ĶB3Z1LGP,+w f"y0&@3خ}R!-wѿb\ku}Xga1`2?|`{#$r۫H,n1J9oW>sp+AN=-EVU\-em6"уW8]3OIH $8= h9O>V)ngY>u^ŎxЧ#FֶVdjk(XyKw5휉omtVẗM.y[ڍ_'#fՇixt<Ն-WIqײl#Vnvd(q~Ty pv,\I{'c,0}rjY $@LY[O>^]ިOeޣ+ʚWgF}vieMǝrS,H,`5R' jjWawrU' |yOm(͙b ^!wψAܩs7 3߂nrgX:%AķtY:%xm,im$[1jAڌ~5 J&cޥct'w{`ԫE+'h~?VmQ 7ϧ3i  p@HUvK8u|@nY7pl >g'%ӹO6F'R2䩪eTUh7mu1-Hڪ0;mܷ[$)v:ӓܕ3:u+gFn撉/j  $R'}@Pܟf[d^ .`>0"xǿJ2 d ,ՇŃOWY]Ĝf;ea-P:7;QY,)ߪO fg M#,yKR?4͑swy낭fDJqy4Wg\%U苏΄ߗ;oKyt_UNusf0Ixש>Uu!;Kx?w_=sjʿ:\M'_/}LuYgi @H %ӏѳT%?Xng1\ʤsW$?vF2|@ՙdø $D]]ߜeӧ3V}݆W\T;ϪavڍhIZbco-0=R=vJ8=x)141v $X/oΞs{}`Pn>[:f՟4Iۻ\;wUƃ>INsIplbҿ;j6׾|sα]=Fg?y%|r-]կN{>?~ iHQ z0sXyz:LP(]AutK#-z:G> ],%~9HMQI]qx}Գ]kW:܀+$&+G9@L<}*۾̪t{?Da;aW` sՖ-ٶH&wy-@Dr{_ePr(F;m;:OulvΌr.E:? dWXU H'GS<; 7pui_za@ $awO:vxn(Vi?15W;ۏ=T8PΨ 6~f hF(G9#˹n;u1_&r9!r3i s&% @{~϶~r`~,(g_+MW;I`rܛ<$| zhX{X(~qH $h-|lHH*#UNe`\u~V(~Y+cMI8S?&׉qMj+ۯGS;>l,}B wx7ph&r]N:(W'ur.h̭<3ro;Psr\V)Ւ#ʏVy|1֭>HY@N' 0L:;\-wx{@)nyZ$uwAp$X&d?p @H $@H $@H $@H $@HU"IENDB`nux-4.0.6+14.04.20140409/data/Fonts/nuxfont_size_8_page_0.png0000644000015301777760000001025512321344237023645 0ustar pbusernogroup00000000000000PNG  IHDRŐgsRGBbKGD pHYs  tIME-+-IDATxێPe!0ȷnZ d2le~ @@@z߮OM]$FFG' Q׾Uv:k>R9Eo&M]wNĵtcQr=%uHַ{,Y޿Dv:IK/Nzqӗ~_Ӄo>y}ϟX;sMN}ޘj`N׻Uc~JO턦"M҉l믝W^=_p:9Ƅ:4qrF_ѕ 'N"|sw~w͕w\fv=1>iR|PQ7# X?n͞mY=^U}b+r3o}5st\}iV+oY,{9tk~\'u^]_jVq!z۽>8qK?pش>yt&T4wmdG2SuS]v?%opk6v|=4eD];Ng>*8ۭvK~ $uR_fw>Qjz6NNRЃHG)Xٻ?]=?Tű]wk FG?S0J7.m'\(o8WɎ5zdCu۪]=ou^nl;ۓ\ׇO׏4דD+Pۛk޾w hU`D ]X[۠8hfyk; px6j&;)XPp@0$lga@Ue'jS@Tc^:/}}GQ@d姏^8n;e?HMЀQG};1q0jjx{A^i)A{a1ЉvNS |*!DNC1Yvr@LDv<`ص_&zçNζsaBRh3'R`hC   ŒԷ_p৺vR\ C;~5"_tNh//JnQƩm廰u"pr'?Dɲek[_{r0鲭h+|:Ny%lu k|oV^ݶV7vIN< #Dh8ٱMwXdܪʊpJy]WN !hu[go>[su=ޱyˮ⚓+3ɧ#-m?nhb+=u3VߡSz),>yb{<}[rJ|9&9A%,nk]R:|͸˛gG:3bl!'N__t8L,֫*w~FzAha8qx7n;vssMjۧ ǐx띿v9(j~aY'MG/5@bf`~Ep`:V0yke}@>kZwj7?GVQq$9[u|\_V\,:Η7b_]$'59q5μ_8Z ݬQvz0kZ'd[^h<}/:!V3@`uyQ?O5v L +9 ZDGg`9@#5?Y%%|Nm:zu֏^G;'Nuuu @r:|33Yis/ל~ ?Ng`z}d-?>a{<+z6׵$Ln&]uqYOHkx֏^?˾ڢ<$}7مz2$V|!Cnl|+TUo,Lt<{2< #m&~mVmav?f0Z7_P@ġ#[]q}{y]7[Ot9't/9R?Rz*/So׆ *@~h^ 4@.K vNwݵյ@@řrSמ*wU]D}mݩ X^ '@瓪QZg0O^蔚 IkKsj ZTtns\3rl_B@r:yϻ1:ylXmҕ]SvE}'MٙGUA_z ZdaneזݵQtEFt٩]\đSغF-eז\==sKƒz麕]_vz;ʈvV|"MwV' id=62 x=291 y=23 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '?' id=63 x=317 y=23 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '@' id=64 x=343 y=23 width=26 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char 'A' id=65 x=369 y=23 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'B' id=66 x=395 y=23 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'C' id=67 x=421 y=23 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'D' id=68 x=447 y=23 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'E' id=69 x=473 y=23 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'F' id=70 x=5 y=41 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'G' id=71 x=31 y=41 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'H' id=72 x=57 y=41 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'I' id=73 x=83 y=41 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 'J' id=74 x=109 y=41 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'K' id=75 x=135 y=41 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'L' id=76 x=161 y=41 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'M' id=77 x=187 y=41 width=26 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char 'N' id=78 x=213 y=41 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'O' id=79 x=239 y=41 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'P' id=80 x=265 y=41 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'Q' id=81 x=291 y=41 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'R' id=82 x=317 y=41 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'S' id=83 x=343 y=41 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'T' id=84 x=369 y=41 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'U' id=85 x=395 y=41 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char 'V' id=86 x=421 y=41 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'W' id=87 x=447 y=41 width=26 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char 'X' id=88 x=473 y=41 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'Y' id=89 x=5 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'Z' id=90 x=31 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '[' id=91 x=57 y=59 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '\' id=92 x=83 y=59 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char ']' id=93 x=109 y=59 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '^' id=94 x=135 y=59 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '_' id=95 x=161 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '`' id=96 x=187 y=59 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'a' id=97 x=213 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'b' id=98 x=239 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'c' id=99 x=265 y=59 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 'd' id=100 x=291 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'e' id=101 x=317 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'f' id=102 x=343 y=59 width=26 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char 'g' id=103 x=369 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'h' id=104 x=395 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'i' id=105 x=421 y=59 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char 'j' id=106 x=447 y=59 width=26 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char 'k' id=107 x=473 y=59 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'l' id=108 x=5 y=77 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char 'm' id=109 x=31 y=77 width=26 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char 'n' id=110 x=57 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'o' id=111 x=83 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'p' id=112 x=109 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'q' id=113 x=135 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'r' id=114 x=161 y=77 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 's' id=115 x=187 y=77 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char 't' id=116 x=213 y=77 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char 'u' id=117 x=239 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'v' id=118 x=265 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'w' id=119 x=291 y=77 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char 'x' id=120 x=317 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'y' id=121 x=343 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char 'z' id=122 x=369 y=77 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '{' id=123 x=395 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '|' id=124 x=421 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '}' id=125 x=447 y=77 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '~' id=126 x=473 y=77 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=127 x=5 y=95 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=128 x=31 y=95 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=129 x=57 y=95 width=26 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=130 x=83 y=95 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=131 x=109 y=95 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=132 x=135 y=95 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=133 x=161 y=95 width=26 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=134 x=187 y=95 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=135 x=213 y=95 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=136 x=239 y=95 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=137 x=265 y=95 width=26 height=13 xadvance=18 abcA=0 abcB=18 abcC=0 page=0 char '' id=138 x=291 y=95 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=139 x=317 y=95 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=140 x=343 y=95 width=26 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=141 x=369 y=95 width=26 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=142 x=395 y=95 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=143 x=421 y=95 width=26 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=144 x=447 y=95 width=26 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=145 x=473 y=95 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=146 x=5 y=113 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=147 x=31 y=113 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=148 x=57 y=113 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=149 x=83 y=113 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=150 x=109 y=113 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=151 x=135 y=113 width=26 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=152 x=161 y=113 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=153 x=187 y=113 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=154 x=213 y=113 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=155 x=239 y=113 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=156 x=265 y=113 width=26 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=157 x=291 y=113 width=26 height=13 xadvance=0 abcA=0 abcB=0 abcC=0 page=0 char '' id=158 x=317 y=113 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=159 x=343 y=113 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=160 x=369 y=113 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=161 x=395 y=113 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=162 x=421 y=113 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=163 x=447 y=113 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=164 x=473 y=113 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=165 x=5 y=131 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=166 x=31 y=131 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=167 x=57 y=131 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=168 x=83 y=131 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=169 x=109 y=131 width=26 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=170 x=135 y=131 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=171 x=161 y=131 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=172 x=187 y=131 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=173 x=213 y=131 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=174 x=239 y=131 width=26 height=13 xadvance=10 abcA=0 abcB=10 abcC=0 page=0 char '' id=175 x=265 y=131 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=176 x=291 y=131 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=177 x=317 y=131 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=178 x=343 y=131 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=179 x=369 y=131 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=180 x=395 y=131 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=181 x=421 y=131 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=182 x=447 y=131 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=183 x=473 y=131 width=26 height=13 xadvance=4 abcA=0 abcB=4 abcC=0 page=0 char '' id=184 x=5 y=149 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=185 x=31 y=149 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=186 x=57 y=149 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=187 x=83 y=149 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=188 x=109 y=149 width=26 height=13 xadvance=12 abcA=0 abcB=12 abcC=0 page=0 char '' id=189 x=135 y=149 width=26 height=13 xadvance=12 abcA=0 abcB=12 abcC=0 page=0 char '' id=190 x=161 y=149 width=26 height=13 xadvance=12 abcA=0 abcB=12 abcC=0 page=0 char '' id=191 x=187 y=149 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=192 x=213 y=149 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=193 x=239 y=149 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=194 x=265 y=149 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=195 x=291 y=149 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=196 x=317 y=149 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=197 x=343 y=149 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=198 x=369 y=149 width=26 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=199 x=395 y=149 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=200 x=421 y=149 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=201 x=447 y=149 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=202 x=473 y=149 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=203 x=5 y=167 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=204 x=31 y=167 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=205 x=57 y=167 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=206 x=83 y=167 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=207 x=109 y=167 width=26 height=13 xadvance=5 abcA=0 abcB=5 abcC=0 page=0 char '' id=208 x=135 y=167 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=209 x=161 y=167 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=210 x=187 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=211 x=213 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=212 x=239 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=213 x=265 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=214 x=291 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=215 x=317 y=167 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=216 x=343 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=217 x=369 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=218 x=395 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=219 x=421 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=220 x=447 y=167 width=26 height=13 xadvance=8 abcA=0 abcB=8 abcC=0 page=0 char '' id=221 x=473 y=167 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=222 x=5 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=223 x=31 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=224 x=57 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=225 x=83 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=226 x=109 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=227 x=135 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=228 x=161 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=229 x=187 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=230 x=213 y=185 width=26 height=13 xadvance=11 abcA=0 abcB=11 abcC=0 page=0 char '' id=231 x=239 y=185 width=26 height=13 xadvance=6 abcA=0 abcB=6 abcC=0 page=0 char '' id=232 x=265 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=233 x=291 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=234 x=317 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=235 x=343 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=236 x=369 y=185 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=237 x=395 y=185 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=238 x=421 y=185 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=239 x=447 y=185 width=26 height=13 xadvance=3 abcA=0 abcB=3 abcC=0 page=0 char '' id=240 x=473 y=185 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=241 x=5 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=242 x=31 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=243 x=57 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=244 x=83 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=245 x=109 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=246 x=135 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=247 x=161 y=203 width=26 height=13 xadvance=9 abcA=0 abcB=9 abcC=0 page=0 char '' id=248 x=187 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=249 x=213 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=250 x=239 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=251 x=265 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=252 x=291 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=253 x=317 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=254 x=343 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 char '' id=255 x=369 y=203 width=26 height=13 xadvance=7 abcA=0 abcB=7 abcC=0 page=0 Kerning count=0 nux-4.0.6+14.04.20140409/data/UITextures/0000755000015301777760000000000012321344711017724 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/data/UITextures/CancelButton.png0000644000015301777760000000177712321344237023032 0ustar pbusernogroup00000000000000PNG  IHDR IDAT8MH\W;͌37d  !BFIAjTl"A]$Ub J!Bh*YM(.Z Iђ!DbpqtƯyۅ`Yl.{Ώ9KJ)'q[x&'S謯c#!e@CpggmE ?}TWN VJT[[ff~ɭ}? |Tuuݱ+WBR힥Xo{kw`ŋ/?voJFo/}b1Xl׷hīTjh? FVp~H&# C0VWYl!x"ˁG"0I81=$ǹ>q"O$؈*54 p O \: 0ǡ\9BW"48u3>iউp}=|@Ft,z7RdSSS< 4 (U{,HT D1G.ѨlmmȈXYY-ҥy~J#.,"c&4ͬJfIJӴIm8Bi^{{PMMMe?f >-IENDB`nux-4.0.6+14.04.20140409/data/UITextures/TriangleRight.tga0000644000015301777760000000054212321344237023170 0ustar pbusernogroup00000000000000  $$$j ZZZ0007iiimiiim0007ZZZ $$$jTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/ValuatorVerticalMove.tga0000644000015301777760000000046012321344237024542 0ustar pbusernogroup00000000000000  ~~~~~~~~~~~~~~~~~~~~TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/radiobutton-on-mouseover.png0000644000015301777760000000617612321344237025435 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڌKk;Lґ!E)0>(tW0 B@nĝ;7#ܹGEQ\Xh| 2 n21R#{*DWoj1FU̲yQDց;z뺛Ra$Gv{xYQD6Zvq-`>q?Vգ,w}oڶ}rg8?H4 6NF^F؜0J(l۶z"QT|󧝌7&K_nNP֟LbYJyy4e5LU'0 ɲ{ 璫~{Y|/b k xE^4h H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FTIDATxڌKJ`Fύ8h-"5"qE:| t$ Д:IŜw2AD 4gxTg;Ed oZx<8zLU_~DYjGz}Ӷu`0Apᱪ͋peYMf` a>yޡ8ieIEZ.=rmW R(*yE4RU"?iJ x3~+fۇ95JZmfp8|v'@$If^N>K-{Yr^TjF#?,>ju*_LG=<*rIENDB`nux-4.0.6+14.04.20140409/data/UITextures/RoundCorner_5pxrad.tga0000644000015301777760000000102312321344237024143 0ustar pbusernogroup00000000000000 @@ YYYYYYYYTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/radiobutton-off-mousedown.png0000644000015301777760000000621112321344237025555 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڌjQΟLdb2*Rt'/PA|‡Yꢏ .tH23d0?89DžOTJ"πh;'U]*("q FbE$U"r8FQtyʲZK_$\[UpEdx5 N~uݝ},"{䇈:p8|A@t]q08ƘJQ78hc<6"R}.0}4Hu7y^x`k_*URspgh`ZM4E\UwXm@lBgzIENDB`nux-4.0.6+14.04.20140409/data/UITextures/Matrix4Preview.tga0000644000015301777760000000213012321344237023312 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/checkbox-on-mousedown.png0000644000015301777760000000611512321344237024656 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FxIDATxڌjAe|bCVBim)_!I@*+T `Y/$|ba7a37ޯ;nO{jfs""I)R"Hpxэ hsнF Y}એs(:8oj\McvŏO ""R-[}Uae֌Ko;=:18GJ&6e$hy|鉣]O2GaSb Xt𠝑b#450ȭ1~>DލD^~gV/Y (/fv̪J1[bIB* `hnG< IENDB`nux-4.0.6+14.04.20140409/data/UITextures/checkbox-off-disable.png0000644000015301777760000000546712321344237024410 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FbIDATx˱ ѓPJafpe !d4^}o9 $t]a{sN'iP#~8sjac@P(~|IENDB`nux-4.0.6+14.04.20140409/data/UITextures/ellipsisbutton.tga0000644000015301777760000000134712321344237023511 0ustar pbusernogroup00000000000000  RRRMMM???777333777???NNNRRRRRREEE555444555GGGRRRRRRIII;;;<<<>>>???>>><<<777666JJJRRRQQQ;;;AAA@@@AAA@@@:::777:::QQQFFF???CCCBBB999GGG===DDDEEE@@@;;;AAA:::GGGEEE<<<>>>:::JJJIII???<< H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڌn`kJ\'rL!*ސ:J@!!l H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FLIDATxڌJpGM%P" / >oC, u vpi@kJkuI՜;刪2FD &eW Rv,NU}f"%#,3U}D[S"s—6`mIENDB`nux-4.0.6+14.04.20140409/data/UITextures/checkbox-on-disable.png0000644000015301777760000000574412321344237024250 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڌ=n0?X@0DxI` Y(9CKtYz$CBB@tiP#O_??lt:oex5Kz.REvK]B_8 qhE0 EQL j麎TUvC˲p])Zypfދ, PJQ5B6 I0 s8#RJ0dMiPJͯsui>,cǿ!R,@JIdY逴m=Q4 |g xO F hz.@IENDB`nux-4.0.6+14.04.20140409/data/UITextures/radiobutton-on-mousedown.png0000644000015301777760000000627412321344237025430 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڌMKTq?m.ՙ8Bf-!ѢEhբoч軄r&$4a$3̌?mF^gwDU9x}601\m`UU yPDgq/T* &NNNZ`3Ie^Ed6 qߋ.EA$zoTu2|lll~ddd}ǹM)mn j BKˏf~wcLUU%Mӝhð>O茳O+8Z'=ϫc,`""cp] PS_t `|_7,S Y \h|,1^(,t:i.:Z^ 1&OOɲ`nW5GUEdpZEQ47$I6%U=-I Q H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڔ1K@wM* Vn5-/Ap7Q&bABm*ޝ i1>8xܽ4&` &@8EG&H0V,;} k@!PUUzӻ4cR2m[^= W*f8&ܱ7JoJ5AP!}c\7:B'QډBT 2'x0zX" DIdސ(@%smU#IENDB`nux-4.0.6+14.04.20140409/data/UITextures/button-mouseover.png0000644000015301777760000000063212321344237023773 0ustar pbusernogroup00000000000000PNG  IHDR@@iq pHYs   cHRMz%u0`:o_F IDATx=J@G/ U0Xxk=G,uHؤl6hn`*~~ ~S͆%7#}Ӷm๮HӔ)ݎ,˶!8E:o>^I\Ŭ<@@@@@@@@@@@@@u:V7|gxau}%g1mm&i<]K8Z{`IENDB`nux-4.0.6+14.04.20140409/data/UITextures/radiobutton-off-disable.png0000644000015301777760000000600012321344237025134 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F+IDATxڔ=jA߮Ah nsi4`p@mJCN0L$0ۜ!\FifKj>3̓GCBK Nxmq;t !7\z=1>!}l6v犢X, >$ժ]iV%l&=iYڶ=,q3Q:[p)@$#f+=E1 :)\UUg,y>|]c|4,^,4Ma1> :ܧ?$|F/ci =VIENDB`nux-4.0.6+14.04.20140409/data/UITextures/RoundCorner_10px_shadow.tga0000644000015301777760000001542712321344237025112 0ustar pbusernogroup00000000000000 ###(,,,011143336444744484447444844474448444733371114,,,0###(2225RRRShhhhwwwv~wwwviiiiRRRS2225$$$)WWWX~‚„~XXXX$$$( 0003kkkk κkkkk0003)))-mmmmʤmmml)))- [[[[˜\\\\ 6669㽽777:UUUVϝUUUVjjjjܮjjjj!!!&wwwv㸸wwwv!!!&,,,/~羾~,,,01114111433363336444744474447†44474447†44474447†44474447†4447444744474447†44474448†44474447†44474447†44474447†44474447†44474447†44474447†4447444744474447†44474448†44474447†444744474447444744474447444744474447444744474447†444744474447444744474447†44474447444744474447444744474448444744474447444744474447†44474447†4447444744474447†4447444744474447†444744474447444744474447†44474447†4447444744474447†44474447†444744474447444744474448†44474447†44474447†444744474447444744474447†444744474447444744474447†4447444744474447†44474447†4447444744474447†4447444744474447†44474447†4447444744474447†44474447†44474447†44474447†44484447†44474447†44474447†44474447†44484447†44474447†4447444744474447†44484447†44474447†44474448†44474447†44474447†44474447†4447444744474447†44474447444744474447444744474447†444744474447444744474447†44474447†4447444744474447†44474447†44474447†44474447†4447444744474447†4447444744473336444711152225,,,0~羾---1!!!&wwwv㸸xxxx###(jjjiܮkkkkUUUUНVVVV777:㽽7779 [[[[ɜ[[[\ (((,lllkɣllll(((, ///3jjjj κjjjj///3 ###(VVVV~~~}‚ƒ‚ ~~~}VVVW###'1115QQQRhhhgwwwv~~wwwvhhhhQQQR1114"""',,,/1114333644474448444744484447444844474448444744484447444844474448444733361115,,,/"""'TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Stroke_2pxrad_1px.tga0000644000015301777760000000201412321344237023740 0ustar pbusernogroup00000000000000 @@ J᷷I߱OPᨨXXA666ƻ666@TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/TriangleDown.tga0000644000015301777760000000052012321344237023016 0ustar pbusernogroup00000000000000  iiim00070007ZZZZZZ  ҇ҁ$$$j$$$jۉTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/DropShadow_10pxrad.tga0000644000015301777760000000750212321344237024041 0ustar pbusernogroup00000000000000 @@ +@\bfghihihihihihihihihihggc\?, 9f~qqqfff```]]][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]```fffppp~f:  [~~~```LLL>>>555111......̓------σ------------------------ρ------σ---΁---υ------τ--- ---......111555===LLL```}}}\  $foooLLL444$$$ $$$444LLLooof$ ammmEEE(((   '''DDDmmm`B{{{JJJ'''&&&JJJzzzAi^^^111111^^^j*III"""  """III*Eppp======pppDVfff555555fffXb```111111```cf]]]///...]]]fh[[[......[[[hh[[[......[[[ii[[[------[[[hi[[[------[[[ih[[[------[[[ii[[[------[[[hi[[[------[[[ii[[[------[[[ih[[[------[[[hh[[[------[[[hi[[[------[[[ii[[[------[[[ii[[[------[[[ii[[[------[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[ih[[[------[[[hi[[[------[[[hh[[[------[[[hi[[[------[[[hi[[[------[[[hh[[[------[[[ih[[[------[[[hh[[[------[[[ii[[[------[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[ii[[[------[[[hh[[[------[[[ih[[[------[[[ii[[[------[[[hi[[[------[[[ih[[[------[[[hh[[[------[[[ih[[[------[[[hh[[[------[[[hi[[[......[[[ig[[[......[[[hf]]]///...]]]fb```111111___cVfff555555eee[Dppp======oooG*III"""  """III+j^^^111111^^^jC{{{JJJ''''''JJJ{{{A _nnnEEE(((   (((EEEnnn` $epppLLL444$$$ $$$444LLLpppd$ YaaaLLL>>>666111......͉---΁---ρ---΂---ς------τ---΁---χ---΁---ρ...111666>>>LLLaaaZ 8g~qqqfff```]]][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]```fffqqq~g8 *?Ybfhhihihihi hihihihihihihi hihiggbY?+TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Dot-6x6.tga0000644000015301777760000000022612321344237021573 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/TriangleLeft.tga0000644000015301777760000000054012321344237023003 0ustar pbusernogroup00000000000000  $$$jہ ZZZ0007iiimiiim0007ZZZ $$$jہTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/button-mousedown.png0000644000015301777760000000075112321344237023771 0ustar pbusernogroup00000000000000PNG  IHDR@@iq pHYs   cHRMz%u0`:o_FoIDATx1N@ϛTuz$!ShH"C&vgM WO1k 9tm6A1HzIENDB`nux-4.0.6+14.04.20140409/data/UITextures/checkbox-on-mouseover.png0000644000015301777760000000576512321344237024674 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F IDATxڔ?K`7T K\݋[ &~ qps:fp5HѤM^sqP@t m2M<{}½iu 74bJ I=b/ N…PNh S0D|^mDc,Y666666=yzyyFG000000MMccc```'''''' ''''''ZZZZZZ\[$$$!!!XXrrrrrr|񄄄|(666666+VWWW333333TTTVRoundCorner_4pxrad.tga@@@@WWWWWW(+TTTQQQ  QQQQQQ++TTTTTTRoundCorner_2pxrad.tga@@@@B555555ɾB㶶I涶IRoundCorner_1pxrad.tga@@@@BBBBBBHHHHHHCorner_shadow.tga(((,444744474447444744474447444744474447444744474447444744474447444744474448444744474447444744474447444744474447444744474447444744474447444744474447444744474447444844474447444744474447444744474447444744474447444744474448444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474448444844474447444744474447(((,)))-WWWXvvvuvvvuWWWW)))-WWWWWWWX(((,vvvvױvvvv(((,444744484447444744474447444744474447†44474447†44474447†44474447†444744474447444744474447†44474448†44474447444744484447444744484447†44474447†44474447†4447444744474447†4447444744474447†44474447†44474447†4447444744474447†44474447†444744474447444744474447†44474447†4447444744474447†44474447†444744474447444744474447†4447444744474447†44474447†44474447†44474447†444744474447444744474447†44474448†44474447†4447444744474447†44474447†4447444744474447†44474447†44474447†444744474447444744474447†44474447†44484447†44474447†44474447†4447444744474447†44474448†4447444744474447†4447444744474447†44474447444744474447444744474447†4447444844474447†44474447†44474447†44474447444744484447444744484447†44474447†44474447444744474447444744474447†444744474447444744474447†444744474447444744474447†44474447†44474447†44474447†44474447†44474447†44474447†44474447†44474447444744474447444744474447†444744474447444744474447†44474447†44474447†44474448†44474447†44474448†44474447†44474447†4447444744474447†4447444844474447†4447444744474447†44474447†44474447†4447(((,vvvuױvvvv(((,WWWW±WWWX)))-WWWXvvvvvvvuWWWX)))-(((,444744484447444744474447444744474447444744474447444744484447444744474447444744474447444744474447444744484447444744474447444744474447444744474447444744474448444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744484447444844474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444844474447444744474447(((,RoundCorner_10px_shadow.tga"""',,,/1114333644474447444744474448444744474447444744474447444744474447444844484447444744474447444744474447444844474447444744474447444744474447444744474447444744474447444744474447444744474447444844474447444744474447444744474447444744474447444744474447444744474447444744484447444744474447444844474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474448444744474447444744474447444733361115,,,/"""'1115QQQRhhhgwwwv~~wwwvhhhhQQQR1114###(VVVV~~~}~~~}VVVW###'///3jjjjκjjjj///3(((,lllkɣllll(((, [[[[ɜ[[[\ 777:㽽7779UUUUНVVVVjjjiܮkkkk!!!&wwwv㸸xxxx###(,,,0~羾---11115222533364447444744474447†4447444744474447†44474447†44474447†44474447†4447444744474447†44474447†444744474447444744474447†44474447444744474447444744474447†4447444744474447†44474447†44474447†44474448†44474447†44474447†44474447†4448444744474447†44474447†44474447†44484447†44474447†44474447†44474447†44484447†44474447†44474447†4447444744474447†44474447†4447444744474447†4447444744474447†44474447†4447444744474447†444744474447444744474447†444744474447444744474447†44474447†44474448†444744474447444744474447†44474447†4447444744474447†44474447†444744474447444744474447†4447444744474447†4447444744474447†44474447†44474447444744474447444844474447444744474447444744474447†444744474447444744474447†444744474447444744474447444744474447444744474447†44474448†44474447†4447444744474447†44474447†44474447†44474447†44474447†44474447†44474448†44474447†4447444744474447†44474447†44474447†44474447†4447444744473336333611141114,,,/~羾~,,,0!!!&wwwv㸸wwwv!!!&jjjjܮjjjjUUUVϝUUUV6669㽽777: [[[[˜\\\\ )))-mmmmʤmmml)))-0003kkkkκkkkk0003$$$)WWWX~~XXXX$$$(2225RRRShhhhwwwv~wwwviiiiRRRS2225###(,,,01114333644474447444744474447444744474447444744474447444744474447444844474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474448444744474447444744474447444744474447444744474447444844474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444744474447444733371114,,,0###(RoundCorner_4px_shadow.tga 諫TTTT&&&*כFFFH ১SSST㪪UUUU!⪪UUUV"⪪UUUV"⪪UUUV"㪪UUUU#⪪UUUU#⪪UUUV"⪪UUUU#⪪UUUV"⪪UUUU"㪪UUUV#⪪UUUV#⪪UUUV"⪪UUUV#⪪UUUV"㪪UUUU"⪪UUUV#㪪UUUV"⪪UUUU"⪪UUUV#⪪UUUU"⪪UUUV"⪪UUUU"㪪UUUV#⪪UUUV#⪪UUUV#⪪UUUV#⪪UUUV"㪪UUUU"⪪UUUU#⪪UUUV#⪪UUUU#⪪UUUV"⪪UUUV#⪪UUUU#⪪UUUV#⪪UUUU#⪪UUUV#⪪UUUV#⪪UUUU"⪪UUUV"⪪UUUV#⪪UUUU"⪪UUUU"⪪UUUV#⪪UUUV#⪪UUUU"㪪UUUU#⪪UUUV"⪪UUUV"⪪UUUV#⪪UUUU#⪪UUUV#⪪UUUU"⪪UUUV"⪪UUUV#⪪UUUV"⪪UUUU#⪪UUUV"㪪UUUV"㪪UUUV"⪪UUUV#㪪UUUV#⪪UUUV"⪪UUUV#㪪UUUV#⪪UUUV"⪪UUUV"⪪UUUV"⪪UUUV#㪪UUUU#⪪UUUU#⪪UUUV"⪪UUUV"⪪UUUV"⪪UUUV"⪪UUUV#⪪UUUV#⪪UUUV#㪪UUUU#⪪UUUV#⪪UUUV"⪪UUUU#⪪UUUV#⪪UUUU#⪪UUUV#⪪UUUU"⪪UUUV"⪪UUUV#⪪UUUV#⪪UUUV"⪪UUUU#㪪UUUV#⪪UUUV"⪪UUUV#⪪UUUV#㪪UUUV"⪪UUUV"⪪UUUV#⪪UUUV#⪪UUUU#⪪UUUU#⪪UUUU"㪪UUUU"⪪UUUU"⪪UUUU"㪪UUUV#⪪UUUV#⪪UUUU#⪪UUUV#⪪UUUV#㪪UUUU#⪪UUUV"㪪UUUV"⪪UUUV#⪪UUUV#⪪UUUV"⪪UUUV#১SSST!כKKKM;;;=ֿXXXY%%%) VVVW~~~~VVVW...2 EEEGRRRSUUUVUUUVUUUUUUUVUUUUUUUVUUUVUUUUUUUVUUUVUUUVUUUVUUUUUUUVUUUVUUUUUUUVUUUUUUUUUUUVUUUVUUUUUUUUUUUVUUUUUUUUUUUUUUUUUUUVUUUUUUUVUUUVUUUVUUUVUUUVUUUVUUUVUUUUUUUVUUUUUUUUUUUVUUUUUUUVUUUVUUUVUUUVUUUVUUUUUUUVUUUVUUUVUUUUUUUVUUUVUUUVUUUVUUUVUUUVUUUUUUUVUUUVUUUUUUUVUUUUUUUVUUUUUUUVUUUVUUUUUUUVUUUVUUUUUUUVUUUVUUUVUUUVUUUUUUUVUUUVUUUVUUUVUUUVUUUVUUUVUUUVUUUVUUUUUUUUUUUUUUUVUUUVUUUVUUUVUUUUUUUVUUUVUUUVUUUVUUUUUUUVUUUUUUUVUUUVUUUVUUUUUUUUUUUUUUUVUUUUUUUVUUUUUUUVUUUUUUUVUUUVUUUVUUUURRRSJJJK999;$$$)  "##"""""##""#""#"###"#""""#"""########""#"###"#"#""#"#"#""""#"##""###""""#"#"#"""#"########"""#"####"""###"""""#"###" TriangleUp.tga,8iiimiiim00070007ZZZZZZ  $$$j$$$jTriangleDown.tga,8$$$j$$$j  ZZZZZZ00070007iiimiiimTriangleLeft.tga,8$$$j ZZZ0007iiimiiim0007ZZZ $$$jTriangleRight.tga,8$$$j ZZZ0007iiimiiim0007ZZZ $$$jScrollBarTriangleUp.tga (????????????BBBB????BBBB????BBBBScrollBarTriangleDown.tga (BBBB????BBBB????BBBB????????????ScrollBarTriangleLeft.tga (BBBBBBBBBBBB????????????????????ScrollBarTriangleRight.tga (????????????????????BBBBBBBBBBBBWindowSizeGrip2.tga\P@AA~AA~AA~AA~AA~AA~AA~AA~AA~AA~AA~AA~AA~AA~AA~CheckBoxNormalOn.tga\ 0@\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ZZZ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\PPPRRR\\\\\\\\\\\\\\\\\\\\\\\\\\\UUU888\\\\\\\\\\\\\\\\\\\\\\\\\\\XXX'''UUU\\\\\\[[[\\\\\\\\\\\\\\\ZZZ)))888\\\\\\\\\FFFCCC\\\\\\\\\ZZZ***XXX\\\\\\\\\[[[$$$999HHH$$$999\\\\\\\\\\\\\\\SSS  [[[\\\\\\\\\\\\\\\\\\AAAAAA\\\\\\\\\\\\\\\\\\\\\\\\&&&\\\\\\\\\\\\\\\\\\\\\\\\\\\VVVLLL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\TTT\\\\\\\\\\\\\\\\\\CheckBoxNormalOff.tga\ 0@>>>KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK>>>KKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKKKKK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\KKK>>>KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK>>>CheckBoxMouseDownOn.tga\ 0@!!!''',,,///111111111111111111///+++'''222:::???BBBBBBBBBBBBBBBBBB888555,,,:::EEEKKKOOOOOOOOOOOOOOOIII000EEE///???KKKTTTXXXXXXXXXXXXTTT&&&NNNKKK111BBBOOOXXX\\\\\\\\\ZZZ)))888XXXOOO111555;;;XXX\\\\\\ZZZ***XXXXXXOOO111BBB 999HHH$$$999\\\XXXOOO111BBBHHH  [[[\\\XXXOOO111BBBOOO???AAA\\\\\\XXXOOO111BBBOOOXXX&&&\\\\\\\\\XXXOOO///???KKKTTTRRRHHHXXXXXXXXXTTTKKK,,,:::EEEKKKOOOIIIOOOOOOOOOOOOKKKEEECheckBoxMouseDownOff.tga\ 0@!!!''',,,///111111111111111111///,,,'''222:::???BBBBBBBBBBBBBBBBBB???:::,,,:::EEEKKKOOOOOOOOOOOOOOOOOOKKKEEE///???KKKTTTXXXXXXXXXXXXXXXXXXTTTKKK111BBBOOOXXX\\\\\\\\\\\\\\\\\\XXXOOO111BBBOOOXXX\\\\\\\\\\\\\\\\\\XXXOOO111BBBOOOXXX\\\\\\\\\\\\\\\\\\XXXOOO111BBBOOOXXX\\\\\\\\\\\\\\\\\\XXXOOO111BBBOOOXXX\\\\\\\\\\\\\\\\\\XXXOOO111BBBOOOXXX\\\\\\\\\\\\\\\\\\XXXOOO///???KKKTTTXXXXXXXXXXXXXXXXXXTTTKKK,,,:::EEEKKKOOOOOOOOOOOOOOOOOOKKKEEECheckBoxMouseOverOn.tga\ 0@::::::<<>>YYY\\\\\\ZZZ***PPPLLLAAAAAAKKK"""999HHH$$$777TTTLLLAAAAAALLLLLL  XXXTTTLLLAAA???JJJQQQ>>>???WWWQQQJJJ???<<>>III444MMM[[[111o888IIIRRREEE###)))RRR\\\TTT <<>>>>>=== l,,,000333666:::>>>BBBEEEFFFFFFEEE===///222555:::???EEEIIILLLNNNNNNLLLIII000444888>>>EEEKKKOOOSSSTTTTTTSSSOOO...555;;;BBBJJJPPPTTTWWWYYYYYYWWWMMMo777===EEEMMMSSSXXXZZZ[[[[[[ZZZ111o333>>>GGGOOOUUUYYY[[[\\\\\\TTT 555GGGOOOUUUYYY[[[\\\NNN$$$o???SSSXXXJJJ///oRadioMouseOverOn.tga,8 l)))))) l777DDDJJJJJJDDD777>>>PPP]]]mmmfffUUUOOO>>> l999PPPgggjjjEEE(((FFF999 l!!!FFFYYYxxxuuuTTT$$$FFF!!!,,,KKKZZZ^^^\\\LLL"""HHH,,,,,,KKKQQQ444%%%GGG,,,!!!FFFSSS FFF!!! o999QQQ999DDD999 o>>>PPPEEE###'''HHH>>>777DDDJJJJJJDDD777 o****** oRadioMouseOverOff.tga,8 l!!!!!! l,,,777======777,,,111BBBLLLPPPPPPLLLBBB111 l---CCCRRRXXXZZZZZZXXXQQQCCC--- l999MMMXXX[[[\\\\\\[[[XXXMMM999$$$>>>QQQ[[[\\\\\\\\\\\\[[[QQQ>>>###$$$>>>QQQ[[[\\\\\\\\\\\\[[[QQQ>>>###999MMMXXX[[[\\\\\\[[[XXXMMM999 o---CCCRRRXXXZZZZZZXXXRRRCCC--- o222BBBLLLPPPPPPLLLBBB222,,,888======888,,, o"""""" oButtonNormal.tga@@@@'333???AAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAAA???333*@@@LLLQQQSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSQQQLLL@@@666LLLXXX[[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[XXXMMM666???RRR[[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[RRR???BBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBBBBBSSS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SSSBBB???RRR[[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[RRR???666MMMXXX[[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[XXXMMM666@@@LLLRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRLLL@@@*444???BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB???444*ButtonMouseOver.tga@@@@'222===AAACCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCAAA===222* ;;;IIIRRRUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUURRRIII;;; 333IIIWWW```bbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbbbb```WWWIII333>>>RRR```gggiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiggg```RRR>>>AAAUUUbbbiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiibbbUUUBBBCCCVVVbbbiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiibbbVVVCCCDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDDDDVVVccciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiicccVVVDDDCCCVVVbbbiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiibbbVVVCCCAAAUUUbbbiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiibbbUUUBBB>>>RRR```gggiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiggg```RRR>>>333IIIWWW```bbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbbbb```WWWIII333 ;;;IIIRRRUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUURRRIII;;; *222===AAACCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCAAA===222*ButtonMouseDown.tga@@@@'***000222444444555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444///###*!!!000555999<<<>>>???@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????<<<999'''...777===BBBFFFHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHFFFBBB;;;555===DDDIIIMMMPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPPPPPPMMMIIIDDD999BBBIIIOOOSSSUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUSSSOOOIII<</{s8eQâ y |9;y3+cӰh|# -`w-N,ؾP_%OXW}f孶/zv87-!- Q 0 5L Ɏ~#+-c}nvu8;'A>Xc e Z%(YWn(x￷>է%`=63PuVZ3:Y=fI'OX3٣m89O@PW;btSMi8ЬXf i^@R͉zpjg_}ς|~V6^_Ϭ:LWkx,sb7&4e²Z)m=@V^#o 6=q`lְ衘]z\HE>ms=XO y <@C eRgqYqU_ީipC"18>:ʤz IU rr\G0a̳|!f*gmvAz_gK"G +Gf-iUu X*-* T>f[VQ:bvjR,,u 3@-+r,\xh  ~4ᕇ! sX8rf0ReSgx;ٹBŗA#+=yY+Y dw2kê{@ǀU8E#Ⱦ8_KhˆUd#AHq6H0a 4a-[I(XhRXh`0Ps*~5Q}$JF!*Z@z`ql$@ب^X"Y aU af]ۄ`Z兑%88hT@Jq:Jz5b| xhcaL GA 3@00(7RERv{'5dy( DQ=ca=`M7T٣?`(Z4P@U1(ؘ xW+%y!_$U HzHCYxslt,iTY8Iz_ < %Ps-BS}ްM5ɜ{-#z(Mb,ьa[8-E݇r>V4F҄OJ PRۦr\p 9wH'|ٱP6XopVI Xj aݾ`cV@i J")!bqw~&Two $,XX!O%pcH=a7iQuD+0I l EԎf-ب rz!&:$$V$tjdþ^ʄcbYQQA,!?P(? O?T"9 (O,cL( )-G .+yR`c\s %̓gǥˮGFzQot$%](cO)` aa_Q9|g/r(P #*@ wUhŃQ;z ?*qq.wJ,x2( T p+_r?3y(eT>8O) Ww Bq?Tݨ{ww=uQ=~7x2 W:~>֏K"p! v !BoQPLn@Qi8h@lz=⮨OAZR҄AVQ )? K_,π򅄢HNkߏ: jΩn}tM тHoyDF`B'':Uj@q\4?.e*Uutȟr?q=TJ[@- /h B2|J\N:f R9\*3ՓYǒ懌O+0ThPky/Y8:+Yn1^,+WʥjiGۭ/<4oZtPCvi~\3EOvhxh9|c^bͯr%|L9PY x$ *aI@5 v=A&nMwWʎf\2Ye]H&@%@Z:tnpDwڽ,}@p5rE\;Chv z1$6rsOk;'+@%\,O@6N?X ӤBFLjb8g:'y]LR?iOh5c]swg;2Vjvы.8Z0҉u D`)^>I\~Ec:?F1ɵPRIFetcf 2qbPl{`у`I(INR=Sr9V`U>oXmhn ;G˳SAgוႪ!=j[@@A$ qDԌ꘍ޑY uFdT^2QXU#%nN{<$t!M<8UMHȍ]q)W>~O{܌/PL 44C[*)0/v q*/Jֹa0 @IG Ĩ[@zTȓ 9>R'ԞJl&|GFr;X0I\2RXv~BRvPK9hІG xxF$l DPPB]5Jw,B9˻L洂 T` $[<xLcF>K[7ZLB# 2Z7 06$e@I.<#QFv7$'Ai]x`c$X6?Jz2#cH1" u@.cgV޾@@Y0,A$B5L d p :r(XB(,c>w%qEvDAqЃ 8v.A 8p) ۔7Iq%C\hC|L#G( 0e$7- ePr0Iv&WA`f_tH+ 5RCb ЍF&226_)Q9Pֱ=R08]$P@` ַkc tn$MbYH R r4lB1\hGiy'. $^R@ȩTDFNT*%a IARإ: tpR$J 4RAe‘@~ ^ HaOHc >, p$j3t9;0Pv)kAQ\Hxz74_Rvy=$ӂ2!Mᑯ!-pTՐxHH,aܭ 9I*9K{.h~kӆZX"Vj3Vƶɥ+VbBтhyݳT5TCb[94f{YT!u2$j{0 h#.UNҋF;NJf{jA:"^Y}5xH!hk1YPn9Gq$*3XX$ >v hWkqm<z-zx Zf%Z@ hFQ YYחW=k[+1dmm13JJ HaBs9'Lx "eqY+gF^*`CVcy;P>-z$x}[Ʋ,GA㛿Vϡ=7xTtozˤ̐h( \鬯h#ΙIV!S{+u*NyAWAFx&z9S Ua&̪-h̞-KH(CxU'3@!#cm]rD H +r~V*o|Wի$wL 8g;<%xJ?7e}!i>7'VP`x~a܉5359΃N3`l#Q;]@c~_^t.n~,]ՙIENDB`nux-4.0.6+14.04.20140409/data/UITextures/Stroke_4pxrad_2px.tga0000644000015301777760000000217412321344237023752 0ustar pbusernogroup00000000000000 @@ TTTTTT++QQQWWWWWWQQQ  TTTWWWWWWQQQ(+WWW޷WWWTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/checkbox-off.png0000644000015301777760000000545212321344237023001 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FUIDATxұ ѧ2-;06K~w}ذ܎mAK)zJ)NJn7^ c: 5(_&JIENDB`nux-4.0.6+14.04.20140409/data/UITextures/ScrollBarTriangleLeft.tga0000644000015301777760000000035212321344237024610 0ustar pbusernogroup00000000000000 ????????????????????BBBBBBBBBBBBTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Stroke_1pxrad_1px.tga0000644000015301777760000000175412321344237023751 0ustar pbusernogroup00000000000000 @@ HHHHHHBBBBBBTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/ValuatorHorizontalMove.tga0000644000015301777760000000040212321344237025116 0ustar pbusernogroup00000000000000  ~~~~~~~~~~~~~~~~~~~~~~~~TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/WindowSizeGrip.tga0000644000015301777760000000141112321344237023345 0ustar pbusernogroup00000000000000  cccciiih!!!&!!!& cccc    ׆rrrq׌TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/radiobutton-on-disable.png0000644000015301777760000000605512321344237025010 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FXIDATxڔJ@J ,}[,W\k)oV>(I.xw&S3nV9p/s^+Z{<9{xhjz`4&c?9$,K@eI{%I1Li0xܳ(_,YAR#⦷At<^]?GsT[  j +ٻXt=[kwr;.į'U}aqs3رoZ]}u0-b3:|2$C WPTVeUzR;_KE=)8kF-(< ]po>/X:Cj} _)E!i] mFP pa .\p1PNAӴ.E+| њQ`ה@OՀBzMÝz-$b+|@S-nhIfxaG빶˵O`Ѧ 9d U*WR`G$[GΡcd\8iV7Ұ*T$tKs$ l%뀶Non=x3Wms'_|j b&l\W{&s{2JP$"S;Yٸ3y9)JOM~Ҧ!@vGFTwߍiib7ںhޱ@x}|d+܂h !c"bi7wUoUI*W+fA*,1+fl0:=V^>K8fffDMӨiqqW<ZBZ76ObJ M)= ^ڵkLTULLLl6ugYVqu`1x~od{;n~ec뺢80 iwL&199IH.#JXEl&@),CQDx__5_z͡6jIENDB`nux-4.0.6+14.04.20140409/data/UITextures/GraphBarIcon.tga0000644000015301777760000000077012321344237022727 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/RoundCorner_10pxrad.tga0000644000015301777760000000137512321344237024231 0ustar pbusernogroup00000000000000 @@ VWWW333ɭ333TTTV(666Ƴ666+|񄄄|rrrrrrXX$$$ֻ!!!\[ZZZZZZ'''ӽ''' '''Խ'''ccc```MM000̻000FGyyyz>666dz666=@xxx666000̫000666xxx@TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/nux.png0000644000015301777760000001436512321344237021260 0ustar pbusernogroup00000000000000PNG  IHDR\rf pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F IDATxu8Fi ,A tJ Gq, 3<{AQyaOQk%x                     XX1 CQU]iTU}34M< zeYֶm {n[eꙻ[]vqiuaZ&Xū,Kl贐y*A 0eY~v3.~;fA4ӓw4Qsc+gS64`r~va?w,4[Ӷrβ,brI:s,t]W<<<80 vC:,u4M(%45;1ٳ}jи|8Ww뺨~Ern Ð iNGk9,^[Q,1R,Nu]L 1nU.i[5KW XUaEȩQIeZY!-tB3/bCmۊU1E!%e ,K%exDxnSy}oCOH͗{p-gM5}舘T))"):󩐒Mϟ?0MSeY-~?~/mo TX;0Y%u 3R[CmOu)mHQשxp+"Li qRZҞiϥҧU+|'TdV֥HS)ӕ_ 1PSz'|\s)j>N}|Ϝlx )M]o5tҷM9ȱt, @UU=_^^yM-h~߆wӿ^4Mgk^[i(JJRA!>s,뗹(J1 iCGR/d.ȋ̵Ub,}{8=˗_`񅻶hz-ir^ɇ(Qrk[ DaP30=ߞsPa|T: {%k= ͭ@R2BKܢ Pe}kJv%cSl0GⷲndD ~dsEpTpA%0 "1ꎾK<==Xeڶ-oxB(JuNߗE~,R1DO{3ڳңubG-٤>jUga W&ojk񿼼Q;www8ي@yEW3;EyC>rw,v2]'GBg YR>d9 |Җ_kir%+A9u_#LURA=rV9 d\v˱8圾6PR;/T)_ 4d"`JwK77}9LD[8 "mqZH,VatF"[#N*l!m[u5ʩ4=Aw* ͪ(} )\NxjOZ0pHq0->J! w44ڶnDm{m/9d{)^j||/7ðmlxqPRTCJ[V "C"X-$I@ՂN59%;c]|r' 816t%!!@zuE4? v4s˲e?L!Y,* ,Zn!m˵2MS4yr*}:U17Θ `mY9w hPD,?f݉o@` ~ 0_ +@%Tߍtىfv̓fQ @&oPHȘ4yT'k0 @?ZrK͢E-Sr4.R1$re2K?uVr}ua̡AUvȍڒ)0E``ih<6n1̢ʼnʰy|Z%­su]]LCK&%?s,5,gKu'dE.L:|QU(;`˜j纮U_RKOn/q UZ;t?4M6;y : qweK`'C@`0\,v2sCL4Pv02 ㋎[Qsv [ nux-4.0.6+14.04.20140409/data/UITextures/SpinerUp.tga0000644000015301777760000000020612321344237022167 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Matrix3Preview.tga0000644000015301777760000000145312321344237023320 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/TabLeft.tga0000644000015301777760000000024412321344237021745 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Stroke_10pxrad_2px.tga0000644000015301777760000000300512321344237024021 0ustar pbusernogroup00000000000000 @@ UWWW333ɭ333TTTU(666Ƴ666+|333ɐq45p333񄄄}rrrccccccrrrYJJY$$$mm!!![BBBBBB\ZZZjjZZZ'''((''' '''("!!!ZZZjjZZZ\BBBBBB\mn$$$YRRXuuu``````uuus 333ȍt44s333 t(666Ƴ666(RZZZ333333ZZZRTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/VScrollBar.tga0000644000015301777760000000152512321344237022440 0ustar pbusernogroup00000000000000 ????????xxxxxxxx????<<<<ÇÇ????<<<<xxxxxxxx????????TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/TreeNodeOpen.tga0000644000015301777760000000045012321344237022752 0ustar pbusernogroup00000000000000 KKKKffffffff  00000000TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Folder-24x24.tga0000644000015301777760000000165612321344237022430 0ustar pbusernogroup00000000000000    """"Áwwww hhhhIIII;;;;3333....,,,,++++----00007777DDDD&&&& ////0000$$$$qqqq7777nnnn\\\\;;;;&&&&;;;;jjjj((((!!!! """"((((1111NNNN7777 ////nnnn""""  ЄDDDDaaaa ))))6666(((( TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Corner_shadow.tga0000644000015301777760000001500412321344237023221 0ustar pbusernogroup00000000000000 (((,444744484447444844474448444744484447444844474448444744484447(((,)))-WWWXvvvvvvvuWWWX)))-WWWWƒ‚WWWX(((,vvvuױvvvv(((,4447†44474447†44474447†4447444744474447†4447444844474447†4447444744474447†44474447†44474448†44474447†44474448†44474447†44474447†44474447†444744474447444744474447†44474447444744474447444744474447†44474447†44474447†44474447†44474447†44474447†44474447†44474447†444744474447444744474447†444744474447444744474447†44474447444744474447444744474447†44474447†44474447444844484447444744474447†44474447†44474447†4447444844474447†44474447444744474447444744474447†4447444744474447†4447444744474448†44474447†4447444744474447†44474447†44474447†44474447†44484447†444744474447444744474447†44474447†44474447†4447444744474447†44474447†4447444744474447†44474448†44474447†444744474447444744474447†44474447†44474447†44474447†4447444744474447†444744474447444744474447†44474447†4447444744474447†44474447†444744474447444744474447†44474447†4447444744474447†44474447†44474447†4447444744474447†4447444744474447†44474447†44474447†44474447444844484447444744474448†44474447†444744474447444744474447†44474447†44474447†44474447†444744474447444744474447444744474448(((,vvvvױvvvv(((,WWWW‚ƒ‚„WWWX)))-WWWXvvvuvvvuWWWW)))-(((,444744484447444844474448444744484447(((,TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/TreeNodeClose.tga0000644000015301777760000000046212321344237023121 0ustar pbusernogroup00000000000000 0000󁁁 ffffKKKKKKKKffff󁁁 0000TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/FunctionGraphBackground.tga0000644000015301777760000000033012321344237025167 0ustar pbusernogroup00000000000000 MMM___%MMM%MMMMMM___%MMM%MMMMMM___%MMM%MMMMMM___%MMM%MMMMMM%___%MMM%___%MMM___%MMM%MMMMMM___%MMM%MMMMMM___%MMM%MMMMMM___%MMM%MMMTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/ScrollBarTriangleRight.tga0000644000015301777760000000035212321344237024773 0ustar pbusernogroup00000000000000 BBBBBBBBBBBB????????????????????TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/TabRight.tga0000644000015301777760000000024412321344237022130 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/RoundCorner_6pxrad.tga0000644000015301777760000000110412321344237024144 0ustar pbusernogroup00000000000000 @@ tʴtɹɻttʽʽttɻɹttTRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/checkbox-off-mousedown.png0000644000015301777760000000564112321344237025017 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڜi1 D%`XHM3WCH'}"$;_2Zg!G#Y[ ^y{6CUQUD1c "QZ a~[k+NkDiZYɕN;ȺN}_`D,qD5 e˕wnǓ>~=unIENDB`nux-4.0.6+14.04.20140409/data/UITextures/checkbox-off-mouseover.png0000644000015301777760000000545212321344237025023 0ustar pbusernogroup00000000000000PNG  IHDRH- pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FUIDATxұ ѧCf` [Vw6 8Z/]aÎsr;-Cf++#ݸz~'cv+d'o\)(_Nܡ,IENDB`nux-4.0.6+14.04.20140409/data/UITextures/DropShadow_4pxrad.tga0000644000015301777760000000711012321344237023757 0ustar pbusernogroup00000000000000 @@ /{ZYcfhihihihihihihihihihihgdYZ{/ERc~~~iii```\\\[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\```iii~~~dREzdpppMMM888111ˁ...---΅---------φ------σ------τ------ρ---΂---ρ---΁---ϊ---΁...111888MMMoooczS}}}MMM++++++MMM}}}RZhhh888888hhhYd___111111___cg\\\......\\\hh[[[......[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[hi[[[------[[[ii[[[------[[[hh[[[------[[[ih[[[------[[[ih[[[------[[[hi[[[------[[[hh[[[------[[[hh[[[------[[[ih[[[------[[[ii[[[------[[[ih[[[------[[[hh[[[------[[[hi[[[------[[[ih[[[------[[[hh[[[------[[[ii[[[------[[[hh[[[------[[[ih[[[------[[[hh[[[------[[[ii[[[------[[[hi[[[------[[[ih[[[------[[[ii[[[------[[[hh[[[------[[[ii[[[------[[[hi[[[------[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[ih[[[------[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[hh[[[------[[[ih[[[------[[[hi[[[------[[[ii[[[------[[[hh[[[------[[[ii[[[------[[[hh[[[------[[[hh[[[------[[[ih[[[------[[[hh[[[------[[[hh[[[......[[[if\\\......\\\gc___111111___dZiii888888hhhYS~~~MMM++++++MMM}}}Q{bpppNNN999111......́---΁---ρ------ρ------------ρ------------ρ------------τ---΁---υ------ς------ς------ς------ρ...111888MMMpppczARb~~~iii```\\\[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\```iii~~~cRE/|\XbghihihihihihihihihihihihihihigcX\|/TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/ValuatorMove.tga0000644000015301777760000000064212321344237023052 0ustar pbusernogroup00000000000000  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/Stroke_0pxrad_1px.tga0000644000015301777760000000173012321344237023742 0ustar pbusernogroup00000000000000 @@ TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/VectorXLabel.tga0000644000015301777760000000050312321344237022754 0ustar pbusernogroup00000000000000  ````@@@@```` PPPPPPPPߏppppϏ  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/data/UITextures/SpinerDown.tga0000644000015301777760000000020612321344237022512 0ustar pbusernogroup00000000000000  TRUEVISION-XFILE.nux-4.0.6+14.04.20140409/NEWS0000644000015301777760000000000212321344237015424 0ustar pbusernogroup00000000000000 nux-4.0.6+14.04.20140409/COPYING.lgpl-v2.10000644000015301777760000006364212321344237017424 0ustar pbusernogroup00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! nux-4.0.6+14.04.20140409/Nux/0000755000015301777760000000000012321344711015504 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/Nux/PaintLayer.cpp0000644000015301777760000003050112321344237020262 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/GraphicsEngine.h" #include "NuxGraphics/RenderingPipe.h" #include "Utils.h" #include "PaintLayer.h" namespace nux { ColorLayer::ColorLayer(const Color& color, bool write_alpha, const ROPConfig& ROP) { _color = color; m_write_alpha = write_alpha; m_rop = ROP; } void ColorLayer::Renderlayer(GraphicsEngine& graphics_engine) { unsigned int current_red_mask; unsigned int current_green_mask; unsigned int current_blue_mask; unsigned int current_alpha_mask; unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; // Get the current color mask and blend states. They will be restored later. graphics_engine.GetRenderStates().GetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); // Get the current blend states. They will be restored later. graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, m_write_alpha ? GL_TRUE : GL_FALSE); graphics_engine.GetRenderStates().SetBlend(m_rop.Blend, m_rop.SrcBlend, m_rop.DstBlend); graphics_engine.QRP_Color(geometry_.x, geometry_.y, geometry_.GetWidth(), geometry_.GetHeight(), _color); // Restore Color mask and blend states. graphics_engine.GetRenderStates().SetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); // Restore the blend state graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } AbstractPaintLayer* ColorLayer::Clone() const { return new ColorLayer(*this); } void ColorLayer::SetColor(const Color& color) { _color = color; } Color ColorLayer::GetColor() const { return _color; } ///////////////////////////////////////////////////// ShapeLayer::ShapeLayer(UXStyleImageRef image_style, const Color& color, unsigned long corners, bool write_alpha, const ROPConfig& ROP) { m_image_style = image_style; m_color = color; m_write_alpha = write_alpha; m_rop = ROP; m_rop.Blend = true; m_corners = corners; } void ShapeLayer::Renderlayer(GraphicsEngine& graphics_engine) { unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; // Get the current blend states. They will be restored later. graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); GetPainter().PaintShapeCornerROP(graphics_engine, geometry_, m_color, m_image_style, m_corners, m_write_alpha, m_rop); graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } AbstractPaintLayer* ShapeLayer::Clone() const { return new ShapeLayer(*this); } ///////////////////////////////////////////////////// SliceScaledTextureLayer::SliceScaledTextureLayer(UXStyleImageRef image_style, const Color& color, unsigned long corners, bool write_alpha, const ROPConfig& ROP) { m_image_style = image_style; m_color = color; m_write_alpha = write_alpha; m_rop = ROP; m_corners = corners; } void SliceScaledTextureLayer::Renderlayer(GraphicsEngine& graphics_engine) { unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; // Get the current blend states. They will be restored later. graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); GetPainter().PaintTextureShape(graphics_engine, geometry_, m_image_style); graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } AbstractPaintLayer* SliceScaledTextureLayer::Clone() const { return new SliceScaledTextureLayer(*this); } ///////////////////////////////////////////////////// CompositionLayer::CompositionLayer (ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, ObjectPtr texture1, TexCoordXForm texxform1, const Color& color1, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP) : m_source_texture(texture0), m_source_texture_color(color0), m_source_texture_texxform(texxform0), m_foreground_texture(texture1), m_foreground_texture_color(color1), m_foreground_texture_texxform(texxform1), m_write_alpha(write_alpha), m_rop(ROP), m_blend_mode(layer_blend_mode) { } CompositionLayer::CompositionLayer (ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, const Color& blend_color, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP) : m_source_texture(texture0), m_source_texture_color(color0), m_source_texture_texxform(texxform0), m_foreground_color(blend_color), m_write_alpha(write_alpha), m_rop(ROP), m_blend_mode(layer_blend_mode) { } CompositionLayer::CompositionLayer(const Color&base_color, ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP) : m_foreground_texture(texture0), m_foreground_texture_color(color0), m_foreground_texture_texxform(texxform0), m_source_color(base_color), m_write_alpha(write_alpha), m_rop(ROP), m_blend_mode(layer_blend_mode) { } CompositionLayer::CompositionLayer(const Color& base_color, const Color& blend_color, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP) : m_source_color(base_color), m_foreground_color(blend_color), m_write_alpha(write_alpha), m_rop(ROP), m_blend_mode(layer_blend_mode) { } CompositionLayer::~CompositionLayer () { if (m_foreground_texture.IsValid()) m_foreground_texture.Release(); if (m_source_texture.IsValid()) m_source_texture.Release(); } void CompositionLayer::Renderlayer(GraphicsEngine& graphics_engine) { unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; unsigned int current_red_mask; unsigned int current_green_mask; unsigned int current_blue_mask; unsigned int current_alpha_mask; // Get the current color mask and blend states. They will be restored later. graphics_engine.GetRenderStates().GetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, m_write_alpha ? GL_TRUE : GL_FALSE); graphics_engine.GetRenderStates().SetBlend(m_rop.Blend, m_rop.SrcBlend, m_rop.DstBlend); if (m_source_texture.IsValid()) { if (m_foreground_texture.IsValid()) { graphics_engine.QRP_GLSL_TextureLayerOverTexture(geometry_.x, geometry_.y, geometry_.GetWidth(), geometry_.GetHeight(), m_source_texture, m_source_texture_texxform, m_source_texture_color, m_foreground_texture, m_foreground_texture_texxform, m_foreground_texture_color, m_blend_mode); } else { graphics_engine.QRP_GLSL_ColorLayerOverTexture(geometry_.x, geometry_.y, geometry_.GetWidth(), geometry_.GetHeight(), m_source_texture, m_source_texture_texxform, m_source_texture_color, m_foreground_color, m_blend_mode); } } else { if (m_foreground_texture.IsValid()) { graphics_engine.QRP_GLSL_TextureLayerOverColor(geometry_.x, geometry_.y, geometry_.GetWidth(), geometry_.GetHeight(), m_source_color, m_foreground_texture, m_foreground_texture_texxform, m_foreground_texture_color, m_blend_mode); } //When both textures aren't valid assume we are blending two colours. else if (m_source_texture.IsValid() == false && m_foreground_texture.IsValid() == false) { graphics_engine.QRP_GLSL_ColorLayerOverColor(geometry_.x, geometry_.y, geometry_.GetWidth(), geometry_.GetHeight(), m_source_color, m_foreground_color, m_blend_mode); } } graphics_engine.GetRenderStates().SetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } AbstractPaintLayer* CompositionLayer::Clone() const { return new CompositionLayer(*this); } ///////////////////////////////////////////////////// TextureLayer::TextureLayer(ObjectPtr device_texture, TexCoordXForm texxform, const Color& color, bool write_alpha, const ROPConfig& ROP) : m_device_texture(device_texture), m_color(color), m_write_alpha(write_alpha), m_rop(ROP), m_texxform(texxform), m_color_blend_mode(LAYER_BLEND_MODE_LAST) { } TextureLayer::TextureLayer(ObjectPtr device_texture, TexCoordXForm texxform, const Color& color0, bool write_alpha, const ROPConfig& ROP, const Color& blend_color, LayerBlendMode color_blend_mode) : m_device_texture(device_texture), m_color(color0), m_write_alpha(write_alpha), m_rop(ROP), m_texxform(texxform), m_blend_color(blend_color), m_color_blend_mode(color_blend_mode) { } TextureLayer::~TextureLayer() { m_device_texture.Release(); } void TextureLayer::Renderlayer(GraphicsEngine& graphics_engine) { unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; unsigned int current_red_mask; unsigned int current_green_mask; unsigned int current_blue_mask; unsigned int current_alpha_mask; // Get the current color mask and blend states. They will be restored later. graphics_engine.GetRenderStates().GetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, m_write_alpha ? GL_TRUE : GL_FALSE); graphics_engine.GetRenderStates().SetBlend(m_rop.Blend, m_rop.SrcBlend, m_rop.DstBlend); if (m_color_blend_mode == LAYER_BLEND_MODE_LAST) { graphics_engine.QRP_1Tex(geometry_.x, geometry_.y, geometry_.GetWidth(), geometry_.GetHeight(), m_device_texture, m_texxform, m_color); } else { graphics_engine.QRP_GLSL_ColorLayerOverTexture(geometry_.x, geometry_.y, geometry_.GetWidth(), geometry_.GetHeight(), m_device_texture, m_texxform, m_color, m_blend_color, m_color_blend_mode); } // Restore Color mask and blend states. graphics_engine.GetRenderStates().SetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } AbstractPaintLayer* TextureLayer::Clone() const { return new TextureLayer(*this); } ObjectPtr< IOpenGLBaseTexture> TextureLayer::GetDeviceTexture() { return m_device_texture; } } nux-4.0.6+14.04.20140409/Nux/LayeredLayout.cpp0000644000015301777760000003620712321344237021006 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Neil Jagdish Patel * */ #include "Nux.h" #include "View.h" #include "LayeredLayout.h" #include namespace nux { LayeredLayout::LayeredChildProperties::LayeredChildProperties(bool expand, int x, int y, int width, int height) : m_expand(expand), m_x(x), m_y(y), m_width(width), m_height(height) {} LayeredLayout::LayeredChildProperties::~LayeredChildProperties() {} void LayeredLayout::LayeredChildProperties::Update(bool expand, int x, int y, int width, int height) { m_expand = expand; m_x = x; m_y = y; m_width = width; m_height = height; } NUX_IMPLEMENT_OBJECT_TYPE(LayeredLayout); LayeredLayout::LayeredLayout(NUX_FILE_LINE_DECL) : Layout(NUX_FILE_LINE_PARAM), m_active_index(0), m_active_area(NULL), m_paint_all(false), m_input_mode(INPUT_MODE_ACTIVE), m_child_draw_queued(false) { m_ContentStacking = eStackLeft; child_queue_draw.connect(sigc::mem_fun(this, &LayeredLayout::ChildQueueDraw)); } LayeredLayout::~LayeredLayout() { } void LayeredLayout::GetCompositeList(std::list *ViewList) { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsView()) { View *ic = NUX_STATIC_CAST(View*, (*it)); ViewList->push_back(ic); } else if ((*it)->IsLayout()) { Layout *layout = NUX_STATIC_CAST(Layout *, (*it)); layout->GetCompositeList(ViewList); } } } long LayeredLayout::ComputeContentSize() { nux::Geometry base = GetGeometry(); std::list::iterator it; int total_max_width = 0; int total_max_height = 0; int ret = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { Area *area = *it; std::shared_ptr props; Geometry geo = base; AreaPropertyMap::iterator prop_it = area_property_map_.find(area); if (prop_it != area_property_map_.end()) { props = prop_it->second; } else { props = 0; } if (props && props->m_expand) { int max_width, max_height; // It wants to expand, however we need to check that it doesn't need at minimum more // space than we have max_width = base.width >= area->GetMinimumWidth() ? base.width : area->GetMinimumWidth(); max_height = base.height >= area->GetMinimumHeight() ? base.height : area->GetMinimumHeight(); geo.width = max_width; geo.height = max_height; total_max_width = total_max_width >= max_width ? total_max_width : max_width; total_max_height = total_max_height >= max_height ? total_max_height : max_height; } else if (props) { geo.x = base.x + props->m_x; geo.y = base.y + props->m_y; geo.width = props->m_width; geo.height = props->m_height; } (*it)->SetGeometry(geo); (*it)->ComputeContentSize(); } SetBaseSize(total_max_width, total_max_height); if (base.width < total_max_width) ret |= eLargerWidth; else ret |= eCompliantWidth; // We don't complain about getting more space if (base.height < total_max_height) ret |= eLargerHeight; else ret |= eCompliantHeight; // Don't complain about getting more space return ret; } void LayeredLayout::PaintOne(Area *_area, GraphicsEngine &graphics_engine, bool force_draw) { if (_area->IsView()) { View *ic = NUX_STATIC_CAST(View *, _area); ic->ProcessDraw(graphics_engine, force_draw); } else if (_area->IsLayout()) { Layout *layout = NUX_STATIC_CAST(Layout *, _area); layout->ProcessDraw(graphics_engine, force_draw); } } void LayeredLayout::ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); if (m_paint_all) { std::list::iterator it, eit = _layout_element_list.end(); unsigned int alpha = 0, src = 0, dest = 0; graphics_engine.GetRenderStates().GetBlend(alpha, src, dest); graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); nux::GetPainter().PaintBackground(graphics_engine, base); nux::GetPainter().PushBackgroundStack(); for (it = _layout_element_list.begin(); it != eit; ++it) { if ((*it)->IsVisible()) PaintOne(static_cast (*it), graphics_engine, true); } nux::GetPainter().PopBackgroundStack(); graphics_engine.GetRenderStates().SetBlend(alpha, src, dest); m_child_draw_queued = false; } else if (m_active_area && m_active_area->IsVisible()) { PaintOne(m_active_area, graphics_engine, force_draw); } graphics_engine.PopClippingRectangle(); draw_cmd_queued_ = false; } Area* LayeredLayout::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { if (m_active_area == NULL) return NULL; bool mouse_inside = m_active_area->TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; if (m_input_mode == INPUT_MODE_ACTIVE) { if (m_active_area && m_active_area->GetInputEventSensitivity() && m_active_area->GetInputEventSensitivity()) return m_active_area->FindAreaUnderMouse(mouse_position, event_type); } else { std::list::reverse_iterator it, eit = _layout_element_list.rend(); for (it = _layout_element_list.rbegin(); it != eit; ++it) { Area *area = (*it); if (area->IsVisible() && area->GetInputEventSensitivity()) { return m_active_area->FindAreaUnderMouse(mouse_position, event_type); } } } return NULL; } void LayeredLayout::AddLayout(Layout *layout, unsigned int /* stretch_factor */, MinorDimensionPosition /* positioning */, MinorDimensionSize /* extend */, float /* percentage */, LayoutPosition /* position */) { AddLayer(layout); } void LayeredLayout::AddView(Area *view, unsigned int /* stretch_factor */, MinorDimensionPosition /* positioning */, MinorDimensionSize /* extend */, float /* percentage */, LayoutPosition /* position */) { AddLayer(view); } void LayeredLayout::RemoveChildObject(Area *area) { RemoveLayer(area); } void LayeredLayout::Clear() { m_active_index = 0; m_active_area = NULL; Layout::Clear(); } void LayeredLayout::ChildQueueDraw(Area * /* area */) { m_child_draw_queued = true; } void LayeredLayout::ChildVisibilityChanged(Area * /* area */, bool /* visible */) { QueueDraw(); } // // LayeredLayout Methods // void LayeredLayout::AddLayer(Area *area, bool expand, int x, int y, int width, int height) { // return if the area is NULL NUX_RETURN_IF_NULL(area); // Return if the area already has a parent NUX_RETURN_IF_NOTNULL(area->GetParentObject()); std::shared_ptr props(new LayeredChildProperties(expand, x, y, width, height)); AreaPropertyMap::iterator it = area_property_map_.find(area); if (it != area_property_map_.end()) { area_property_map_.erase(it); } area_property_map_[area] = props; if (!m_active_area) { m_active_area = area; } props->m_vis_it = area->OnVisibleChanged.connect(sigc::mem_fun(this, &LayeredLayout::ChildVisibilityChanged)); if (area->IsLayout()) Layout::AddLayout(static_cast (area)); else Layout::AddView(area); QueueDraw(); } void LayeredLayout::UpdateLayer(Area *area, bool expand, int x, int y, int width, int height) { std::shared_ptr props; NUX_RETURN_IF_NULL(area); AreaPropertyMap::iterator it = area_property_map_.find(area); if (it != area_property_map_.end()) { props = it->second; } else { props = 0; } if (props == 0) return; props->Update(expand, x, y, width, height); QueueDraw(); } void LayeredLayout::RemoveLayer(Area *area) { if (area == NULL) return; std::shared_ptr props; AreaPropertyMap::iterator prop_it = area_property_map_.find(area); if (prop_it != area_property_map_.end()) { props = prop_it->second; } else { return; } (*props->m_vis_it).disconnect(); area_property_map_.erase(prop_it); if (m_active_area == area) { std::list::iterator it, eit = _layout_element_list.end(); int index = 0; m_active_index = 0; m_active_area = NULL; for (it = _layout_element_list.begin(); it != eit; ++it, ++index) { if (*it != area) { m_active_area = static_cast (*it); m_active_index = index; break; } } } Layout::RemoveChildObject(area); } void LayeredLayout::SetActiveLayerN(int index_) { std::list::iterator it, eit = _layout_element_list.end(); int i = 0; NUX_RETURN_IF_FALSE((unsigned int)index_ < _layout_element_list.size()); if (index_ == m_active_index) return; m_active_index = index_; m_active_area = NULL; for (it = _layout_element_list.begin(); it != eit; ++it) { if (i == m_active_index && !m_active_area) { m_active_area = static_cast (*it); } if ((*it)->IsView()) { static_cast (*it)->QueueDraw(); } else if ((*it)->IsLayout()) { static_cast (*it)->QueueDraw(); } i++; } QueueDraw(); } int LayeredLayout::GetActiveLayerN() { return m_active_index; } void LayeredLayout::SetActiveLayer (Area *area) { std::list::iterator it, eit = _layout_element_list.end(); int i = 0; for (it = _layout_element_list.begin(); it != eit; ++it) { Area *a = static_cast (*it); if (area == a) { SetActiveLayerN(i); return; } i++; } nuxDebugMsg("[LayeredLayout::LowerBottom] Area(%p) is not a child of LayeredLayout(%p)", area, this); } void LayeredLayout::OnLayerGeometryChanged(Area* area, Geometry geo) { // Set the LayeredLayout to the same saize as the active layer; if (area && (area == m_active_area)) { SetGeometry(geo); } } Area * LayeredLayout::GetActiveLayer() { return m_active_area; } void LayeredLayout::SetPaintAll(bool paint_all) { if (m_paint_all == paint_all) return; m_paint_all = paint_all; QueueDraw(); } bool LayeredLayout::GetPaintAll() { return m_paint_all; } void LayeredLayout::SetInputMode(LayeredLayout::InputMode input_mode) { if (m_input_mode == input_mode) return; m_input_mode = input_mode; } LayeredLayout::InputMode LayeredLayout::GetInputMode() { return m_input_mode; } void LayeredLayout::Raise(Area *area, Area *above) { std::list::iterator it, eit = _layout_element_list.end(); std::list::iterator area_it = eit; std::list::iterator above_it = eit; NUX_RETURN_IF_NULL(area); NUX_RETURN_IF_NULL(above); for (it = _layout_element_list.begin(); it != eit; ++it) { if (above == (*it)) above_it = it; else if (area == (*it)) area_it = it; } if (area_it == eit) { nuxDebugMsg("[LayeredLayout::Raise] Area %p is not a valid layer", area); return; } if (above_it == eit) { nuxDebugMsg("[LayeredLayout::Raise] Area %p is not a valid layer", above); return; } _layout_element_list.erase(area_it); _layout_element_list.insert(++above_it, area); } void LayeredLayout::Lower(Area *area, Area *below) { std::list::iterator it, eit = _layout_element_list.end(); std::list::iterator area_it = eit; std::list::iterator below_it = eit; NUX_RETURN_IF_NULL(area); NUX_RETURN_IF_NULL(below); for (it = _layout_element_list.begin(); it != eit; ++it) { if (below == (*it)) below_it = it; else if (area == (*it)) area_it = it; } if (area_it == eit) { nuxDebugMsg("[LayeredLayout::Lower] Area %p is not a valid layer", area); return; } if (below_it == eit) { nuxDebugMsg("[LayeredLayout::Lower] Area %p is not a valid layer", below); return; } _layout_element_list.erase(area_it); _layout_element_list.insert(below_it, area); } void LayeredLayout::RaiseTop(Area *area) { std::list::iterator it, eit = _layout_element_list.end(); std::list::iterator area_it = eit; NUX_RETURN_IF_NULL(area); for (it = _layout_element_list.begin(); it != eit; ++it) { if (area == (*it)) area_it = it; } if (area_it == eit) { nuxDebugMsg("[LayeredLayout::RaiseTop] Area %p is not a valid layer", area); return; } _layout_element_list.erase(area_it); _layout_element_list.insert(eit, area); } void LayeredLayout::LowerBottom(Area *area) { std::list::iterator it, eit = _layout_element_list.end(); std::list::iterator area_it = eit; NUX_RETURN_IF_NULL(area); for (it = _layout_element_list.begin(); it != eit; ++it) { if (area == (*it)) area_it = it; } if (area_it == eit) { nuxDebugMsg("[LayeredLayout::LowerBottom] Area %p is not a valid layer", area); return; } _layout_element_list.erase(area_it); _layout_element_list.insert(_layout_element_list.begin(), area); } Area* LayeredLayout::KeyNavIteration(KeyNavDirection direction) { if (m_active_area == NULL) return NULL; if (m_active_area->IsVisible() == false) return NULL; if (next_object_to_key_focus_area_) { return NULL; } else { return m_active_area->KeyNavIteration(direction); } return NULL; } } nux-4.0.6+14.04.20140409/Nux/AbstractComboBox.h0000644000015301777760000000344312321344237021060 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ABSTRACTCOMBOBOX_H #define ABSTRACTCOMBOBOX_H namespace nux { class StaticText; class HLayout; class AbstractComboBox: public View { public: AbstractComboBox(NUX_FILE_LINE_PROTO); virtual ~AbstractComboBox(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); StaticText * GetStaticText() { return _pango_static_text; } protected: HLayout *m_hlayout; BasicView *_combo_box_area; BasicView *_combo_box_opening_area; StaticText *_pango_static_text; bool m_MenuIsActive; bool m_IsOpeningMenu; static Color m_sCOMBO_COLOR; static Color m_sCOMBO_BUTTON_COLOR; static Color m_sCOMBO_MOUSEOVER_COLOR; }; } #endif // ABSTRACTCOMBOBOX_H nux-4.0.6+14.04.20140409/Nux/Area.h0000644000015301777760000007267312321344237016547 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef BASEOBJECT_H #define BASEOBJECT_H #include #include #include "NuxCore/InitiallyUnownedObject.h" #include "NuxGraphics/Events.h" #include "Utils.h" #include "WidgetMetrics.h" namespace nux { class WindowThread; class GraphicsEngine; class IOpenGLBaseTexture; class IOpenGLFrameBufferObject; #ifdef NUX_GESTURES_SUPPORT class GestureEvent; #endif // NUX_GESTURES_SUPPORT // In a Horizontal/Vertical Layout, the following enum have the respective meanings: // eFull: the object has the full height/width of the parent layout(minus margins) // ePercentage: the object has a height/width that is a percentage of the parent layout(minus margins) // eFix: the object has a fixed height/width // Another way to see it // eFix = The minor dimension of the object will remain what it is. But the positioning in the // minor dimension inside the layout can be controlled with MinorDimensionPosition. // eFull = The minor dimension of the object will take the entire size that is offered by the parent layout. // MinorDimensionPosition has no effect if MinorDimensionSize = eFull // eContent = The minor dimension of the object will be set to 1 by its parent and later on, the minor dimension will be // resized larger by the children of the element if necessary. // typedef enum { MINOR_SIZE_FULL, MINOR_SIZE_PERCENTAGE, MINOR_SIZE_FIX, MINOR_SIZE_MATCHCONTENT, eFull = MINOR_SIZE_FULL, //!< Deprecated. ePercentage = MINOR_SIZE_PERCENTAGE, //!< Deprecated. eFix = MINOR_SIZE_FIX, //!< Deprecated. eMatchContent = MINOR_SIZE_MATCHCONTENT, //!< Deprecated. } MinorDimensionSize; //! Policy for and element position in the minor dimension of a layout. typedef enum { MINOR_POSITION_START, //!< Place the element at the start of the layout(Hlayout and VLayout) MINOR_POSITION_CENTER, //!< Place the element at the center of the layout(Hlayout and VLayout) MINOR_POSITION_END, //!< Place the element at the end of the layout(Hlayout and VLayout) MINOR_POSITION_TOP = MINOR_POSITION_START, //!< Deprecated. MINOR_POSITION_LEFT = MINOR_POSITION_START, //!< Deprecated. MINOR_POSITION_BOTTOM = MINOR_POSITION_END, //!< Deprecated. MINOR_POSITION_RIGHT = MINOR_POSITION_END, //!< Deprecated. eAbove = MINOR_POSITION_START, //!< Deprecated. eBelow = MINOR_POSITION_END, //!< Deprecated. eLeft = MINOR_POSITION_START, //!< Deprecated. eRight = MINOR_POSITION_END, //!< Deprecated. eCenter = MINOR_POSITION_CENTER, //!< Deprecated. } MinorDimensionPosition; //! Control how a layout distribute its children position. /*! Applies to layouts that have more space than their children can use. These options control how a layouts places its children inside of itself. */ typedef enum { MAJOR_POSITION_CENTER, //!< Stack elements in the center of the layout(for HLayout and VLayout). MAJOR_POSITION_START, //!< Stack elements at the begining of the layout(for HLayout and VLayout). MAJOR_POSITION_END, //!< Stack elements at the end of the layout(for HLayout and VLayout). MAJOR_POSITION_SPREAD, //!< Spread elements evenly inside the layout(for HLayout and VLayout). MAJOR_POSITION_TOP = MAJOR_POSITION_START, //!< Deprecated. MAJOR_POSITION_BOTTOM = MAJOR_POSITION_END, //!< Deprecated. MAJOR_POSITION_LEFT = MAJOR_POSITION_START, //!< Deprecated. MAJOR_POSITION_RIGHT = MAJOR_POSITION_END, //!< Deprecated. eStackTop = MAJOR_POSITION_START, //!< Deprecated. eStackBottom = MAJOR_POSITION_END, //!< Deprecated. eStackLeft = MAJOR_POSITION_START, //!< Deprecated. eStackRight = MAJOR_POSITION_END, //!< Deprecated. eStackCenter = MAJOR_POSITION_CENTER, //!< Deprecated. eStackExpand = MAJOR_POSITION_SPREAD, //!< Deprecated. } LayoutContentDistribution; //! For internal use only. /*! For internal use only. */ typedef enum { SIZE_EQUAL_WIDTH = (1L), SIZE_EQUAL_HEIGHT = (1L) << 1, SIZE_SMALLER_WIDTH = (1L) << 2, SIZE_SMALLER_HEIGHT = (1L) << 3, SIZE_LARGER_WIDTH = (1L) << 4, SIZE_LARGER_HEIGHT = (1L) << 5, SIZE_FORCE_COMPLY = (1L) << 6, eCompliantWidth = SIZE_EQUAL_WIDTH, //!< Deprecated. eCompliantHeight = SIZE_EQUAL_HEIGHT, //!< Deprecated. eSmallerWidth = SIZE_SMALLER_WIDTH, //!< Deprecated. eSmallerHeight = SIZE_SMALLER_HEIGHT, //!< Deprecated. eLargerWidth = SIZE_LARGER_WIDTH, //!< Deprecated. eLargerHeight = SIZE_LARGER_HEIGHT, //!< Deprecated. eForceComply = SIZE_FORCE_COMPLY, //!< Deprecated. } SizeCompliance; enum KeyNavDirection { KEY_NAV_NONE, KEY_NAV_UP, KEY_NAV_DOWN, KEY_NAV_RIGHT, KEY_NAV_LEFT, KEY_NAV_TAB_NEXT, KEY_NAV_TAB_PREVIOUS, KEY_NAV_ENTER, }; class Layout; class View; class Area; class Area: public InitiallyUnownedObject { NUX_DECLARE_OBJECT_TYPE(Area, InitiallyUnownedObject); public: Area(NUX_FILE_LINE_DECL); virtual ~Area(); int GetX() const; int GetY() const; int GetWidth() const; int GetHeight() const; void SetX(int x); void SetY(int y); void SetXY(int x, int y); void SetWidth(int w); void SetHeight(int h); int GetBaseX() const; int GetBaseY() const; int GetBaseWidth() const; int GetBaseHeight() const; void SetBaseX(int x); void SetBaseY(int y); void SetBaseXY(int x, int y); void SetBaseWidth(int w); void SetBaseHeight(int h); //! Set the size of the object. /* Set the size of the object. The size is adjusted to respect the min and max size policy \sa SetWidth(), SetHeight(), SetMinimumSize(), SetMaximumSize(). */ virtual void SetSize(int w, int h); virtual void SetBaseSize(int w, int h); virtual void SetMinimumSize(int w, int h); virtual void SetMaximumSize(int w, int h); virtual void SetMinMaxSize(int w, int h); virtual void SetMinimumWidth(int w); virtual void SetMaximumWidth(int w); virtual void SetMinimumHeight(int h); virtual void SetMaximumHeight(int h); virtual int GetMinimumWidth() const; virtual int GetMaximumWidth() const; virtual int GetMinimumHeight() const; virtual int GetMaximumHeight() const; virtual void ApplyMinWidth(); virtual void ApplyMinHeight(); virtual void ApplyMaxWidth(); virtual void ApplyMaxHeight(); virtual Size GetMinimumSize() const; virtual Size GetMaximumSize() const; //! Get the geometry of the object. /*! @return The Geometry of the object. @sa GetBaseWidth(), GetBaseHeight(), GetBaseX(), GetBaseY(). */ Geometry const& GetGeometry() const; //! Set the geometry of the object. /*! Set the width, height, and x, y position of the object on the screen. @param x Horizontal position. @param y Vertical position. @param w Width. @param h Height. \sa SetBaseWidth(), SetBaseHeight(), SetBaseX(), SetBaseY(). */ virtual void SetGeometry(int x, int y, int w, int h); //! Set the geometry of the object. /*! This is an overloaded member function, provided for convenience. It behaves essentially like SetGeometry(int x, int y, int w, int h). @param geo Geometry object. \sa SetWidth(), SetHeight(), SetX(), SetY(). */ void SetBaseString(std::string const& caption); std::string const& GetBaseString() const; virtual void SetGeometry(const Geometry& geo); //! Deprecated. Use GetToplevel. Area* GetToplevel(); //! Return the root parent of the rendering tree for this area. /*! The root parent of the rendering tree is either a BaseWindow or the main layout. If the object isn't hooked to the rendering tree the function returns NULL. @return The root parent of the rendering tree or NULL. */ Area* GetRootParent(); //! Return the Top level BaseWindow of this area. /*! @return The top level BaseWindow or NULL. */ Area* GetTopLevelViewWindow(); //! Return true is this area has a top level parent. /*! @return True if this area has a top level parent. */ bool HasTopLevelParent(); //! Return true is area is a child of the given parent in the widget tree. /*! @param parent Area to test if it is a parent of this area. @return True if this area is area is a child of parent in the widget tree. */ bool IsChildOf(Area* parent); /*! Test if a point is inside the area. @param p A 2D point. @param event_type The type of mouse event(a parameter of FindAreaUnderMouse). @return True if p is located inside the Area. */ bool TestMousePointerInclusion(const Point& mouse_position, NuxEventType event_type); /*! Test if a point is inside the area and if the area accepts mouse wheel events. @param p A 2D point. @param event_type The type of mouse event(a parameter of FindAreaUnderMouse). @param filter_mouse_wheel_event If the event type is NUX_MOUSE_WHEEL and the mouse is over this area and this area does not accept mouse wheel events, then return false. @return True if p is located inside the Area. */ bool TestMousePointerInclusionFilterMouseWheel(const Point& mouse_position, NuxEventType event); //! Test if the mouse pointer is inside the area. /*! Return true if the mouse pointer is inside the area. @return True if the mouse pointer is inside the area. */ bool IsMousePointerInside() const; virtual long ComputeContentSize(); virtual void ComputeContentPosition(float offsetX, float offsetY); virtual bool IsArea() const; virtual bool IsInputArea() const; virtual bool IsView() const; virtual bool IsLayout() const; virtual bool IsSpaceLayout() const; virtual bool IsViewWindow() const; Area * GetParentObject() const; //! Set visibility of the area /*! If visible, an area will be drawn. Default: true. @param visible if the area is visible to the user */ void SetVisible(bool visible); //! Get the visibility of the area /*! Gets whether the area is visible to the user and will be visible to the user. Default is true. @return whether the area is visible */ bool IsVisible(); //! Deprecated. Use SetInputEventSensitivity. void SetSensitive(bool); //! Set input event sensitivity of the area. /*! A insensitive Area will not receive input events.\n If the Area has a layout, the event will be passed down to it. Sensitivity only control an area's ability to receive input events(keyboard, mouse, touch). An area that is not sensitive will return false in \a TestMousePointerInclusion, \a TestMousePointerInclusionFilterMouseWheel and \a AcceptKeyNavFocus.\n Sensitivity does not affect layouts since they do not process events. By default, an area is sensitive. @param sensitive If the area should receive input events */ void SetInputEventSensitivity(bool sensitive); //! Deprecated. Use GetInputEventSensitivity. bool IsSensitive() const; //! Get input event sensitivity of the area is sensitive /*! Gets whether the area is sensitive to input events @return whether the area is visible */ bool GetInputEventSensitivity() const; sigc::signal ChildFocusChanged; // sends parent + child /*! This signal is received whether the area receiving or loosing the keyboard focus. If the second parameter is true, it means the area is receiving the focus. The third parameter of this signal indicates the keyboard action that triggered this area to receive or loose the keyboard focus. */ sigc::signal key_nav_focus_change; /*! This signal is received when the area has the key focus and the ENTER key has been pressed. */ sigc::signal key_nav_focus_activate; //! Queue a relayout /*! Queues a relayout before the next paint cycle. This is safe to call multiple times within a cycle. */ void QueueRelayout(); //! Get the area scale factor. /*! The scale factor is used to control the layout of area objects inside HLayout and VLayout. \sa HLayout, VLayout. @return the Area scale factor. */ virtual unsigned int GetScaleFactor(); //! Set the area scale factor. /*! The scale factor is used to control the layout of area objects inside HLayout and VLayout. \sa HLayout, VLayout. @param the scale factor. */ virtual void SetScaleFactor(unsigned int sf); virtual MinorDimensionPosition GetPositioning(); virtual void SetPositioning(MinorDimensionPosition p); virtual MinorDimensionSize GetExtend(); virtual void SetExtend(MinorDimensionSize ext); virtual float GetPercentage(); virtual void SetPercentage(float f); virtual bool IsLayoutDone(); virtual void SetLayoutDone(bool b); void Set2DMatrix(const Matrix4 &mat); void Set2DTranslation(float tx, float ty, float tz); Matrix4 Get2DMatrix() const; Matrix4 Get3DMatrix() const; bool Is3DArea() const; //! Return the position of this object with regard to the top left corner of the physical window. /*! Return the position of the Area inside the physical window. For the main layout set in WindowThread, The following functions are equivalent: \li GetGeometry() \li GetRootGeometry() \li GetAbsoluteGeometry() */ virtual Geometry GetAbsoluteGeometry() const; //! Return the area absolute x coordinate. int GetAbsoluteX() const; //! Return the area absolute y coordinate. int GetAbsoluteY() const; //! Return the area absolute width. /*! As long as _2d_xform contains only translations, the absolute width is the same as value returned by GetBaseWidth(); */ int GetAbsoluteWidth() const; //! Return the area absolute height. /*! As long as _2d_xform contains only translations, the absolute height is the same as value returned by GetBaseHeight(); */ int GetAbsoluteHeight() const; //! Return the position of this object with regard to its top level parent(the main layout or a BaseWindow). /*! Return the position of the Area inside the physical window. For the main layout set in WindowThread or for a BaseWindow, GetRootGeometry() is equivalent to GetGeometry(). */ virtual Geometry GetRootGeometry() const; //! Return the area root x coordinate. int GetRootX() const; //! Return the area root y coordinate. int GetRootY() const; //! Return the area root width. /*! As long as _2d_xform contains only translations, the root width is the same as value returned by GetBaseWidth(); */ int GetRootWidth() const; //! Return the area root height. /*! As long as _2d_xform contains only translations, the root width is the same as value returned by GetBaseWidth(); */ int GetRootHeight() const; sigc::signal OnResize; //!< Signal emitted when an area is resized. sigc::signal OnVisibleChanged; sigc::signal OnSensitiveChanged; /*! This signal is only meant to inform of a change of size. When receiving this signal don't do anything that could change the size of this object. Or you risk creating an infinite loop. */ sigc::signal geometry_changed; /*! This signal emitted when the size of the area has changed. It is emitted after geometry_changed. */ sigc::signal size_changed; /*! This signal emitted when the position of the area has changed. It is emitted after geometry_changed. */ sigc::signal position_changed; /*! SetParentObject/UnParentObject are protected API. They are not meant to be used directly by users. Users add widgets to layouts and layout have to be attached to a composition for objects to be rendered. Setting a parent to and child widget does not mean that when the parent is rendered, the child is also rendered. For instance, setting a button to be the child of a check-box means absolutely nothing is terms of rendering. The check-box draw function would have to be aware of the existence of the button in order to render it.\n A view with a parent cannot be parented to another area for rendering. It has to be un-parented first.\n A layout with a parent cannot be parented to another area for rendering. It has to be un-parented first.\n In essence only View and Layouts should be calling SetParentObject/UnParentObject.\n SetParentObject returns true if it was successful. @param parent The object that will become the parent of this area. @return True if the object is successfully parented. */ virtual bool SetParentObject(Area *parent); //! Un-parent and area /*! For un-parented areas the following functions are equivalent: \li GetGeometry() \li GetRootGeometry() \li GetAbsoluteGeometry() */ virtual void UnParentObject(); /*! Return the area under the mouse pointer. @return The Area under the mouse pointer. */ virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual Area* FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state); /*! Mark the path from this area to its top level parent as the one to follow \n to get to the area that has the keyboard. */ void SetPathToKeyFocusArea(); /*! Erase the path from this area to the child area that has the keyboard. */ void ResetDownwardPathToKeyFocusArea(); /*! Erase the path that marks this object as part of the keyboard focus chain, \n from this area to its top level parent. */ void ResetUpwardPathToKeyFocusArea(); //! Return True if the the area knows what to do with the key event. /*! For a View to receive the key_up and key_down signal, it must override this function and return true. @param even_type Event type is either EVENT_KEY_DOWN or EVENT_KEY_UP. @param keysym The key symbol. @param characters The character string of the key. @return bool True if the View wants to received the key events signals. */ virtual bool InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char* character); virtual Area* KeyNavIteration(KeyNavDirection direction); bool HasKeyFocus() const; //! Set to True to initiate a layout reconfiguration when the geometry of this widget changes. /*! When the geometry of an area changes, the new geometry can be recursively propagated to all its parent so a layout reconfiguration is initiated. \sa ReconfigureParentLayout() \sa on_geometry_change_reconfigure_parent_layout_ @param reconfigure_parent_layout Set it to True to reconfigure this area parent layouts. */ void SetReconfigureParentLayoutOnGeometryChange(bool reconfigure_parent_layout); //! Return True if the the parent layouts of this area should be reconfigured on geometry changed. /*! @return True if the parent layouts of this area must be reconfigured on a geometry change. */ bool ReconfigureParentLayoutOnGeometryChange(); //! Enable keyboard event processing. /*! @param accept_key_event Set it to true if the area accepts keyboard events. */ void SetAcceptKeyboardEvent(bool accept_key_event); //! Return true if the Area is interested in keyboard events. /*! @return True if the area accepts in keyboard events. */ bool AcceptKeyboardEvent() const; //! Enable mouse wheel event processing. /*! @param accept_mouse_wheel_event Set it to true if the area accepts mouse wheel events. */ void SetAcceptMouseWheelEvent(bool accept_mouse_wheel_event); //! Return true if the area is accepts mouse wheel events. /*! @return True if the area accepts mouse wheel events. */ bool AcceptMouseWheelEvent() const; protected: /* This function is reimplemented in Layout as it need to perform some special operations. It does nothing for Area and View classes. */ //virtual void RemoveChildObject(smptr(Area)); /*! This signal is only meant to inform that the size is about to change. When overriding this function, don't do anything that could change the size of this object. Or you risk creating an infinite loop. */ virtual void GeometryChangePending(bool /* position_about_to_change */, bool /* size_about_to_change */) {} /*! This signal is only meant to inform that the size has changed. When overriding this function, don't do anything that could change the size of this object. Or you risk creating an infinite loop. */ virtual void GeometryChanged(bool /* position_has_changed */, bool /* size_has_changed */) {} //! Request a Layout recompute after a change of size /* When an object size changes, it is necessary for its parent structure to initiate a layout re computation in order preserve the layout structure defined by the user through the API. */ virtual void RequestBottomUpLayoutComputation(Area *bo_initiator); //! Return the absolute geometry starting with a relative geometry passed as argument. void InnerGetAbsoluteGeometry(Geometry &geometry); //! Return the absolute geometry starting with a relative geometry passed as argument. void InnerGetRootGeometry(Geometry &geometry); bool on_geometry_change_reconfigure_parent_layout_; //! If this variable is true, then this area has the keyboard focus. bool has_key_focus_; void SetNextObjectToKeyFocusArea(Area*); //! Gets the next object in the chain that ends with the area that has the keyboard focus. /*! Gets the next object in the chain that ends with the area that has the keyboard focus. The next object is a child of this area. @return An area that is the next object in the chain that leads to the area that has the keyboard focus. */ Area* GetNextObjectToKeyFocusArea(); //! If this variable is not NULL, then this area is part of the keyboard focus chain. Area* next_object_to_key_focus_area_; /**********************************************/ /*** Begin support for redirected rendering ***/ /**********************************************/ public: //! Redirect the rendering of this view to a texture. /*! Redirect the rendering of this view to a texture. \sa BackupTexture(). @param redirect If true, redirect the rendering of this view to a texture. */ virtual void SetRedirectRenderingToTexture(bool redirect); /*! @return True if the rendering of this view is done in a texture. */ virtual bool RedirectRenderingToTexture() const; //! Return the texture of this View if RedirectRenderingToTexture is enabled. /* Return the texture of this View if RedirectRenderingToTexture is enabled. If RedirectRenderingToTexture() is false, then backup_texture_ is not a valid smart pointer. @return the device texture that contains the rendering of this view. */ ObjectPtr BackupTexture() const; /*! The use of this function is a bit arcan but it gives more rendering options to redirected areas. */ void SetCopyPreviousFboTexture(bool copy); /*! Activate/Deactivate the presentation of the redirected texture in the rendering tree. */ void SetPresentRedirectedView(bool present_redirected_view); /*! @return True if the redirected texture is displayed in the rendering tree. */ bool PresentRedirectedView() const; protected: //! Redirect the rendering of the view to a texture. bool redirect_rendering_to_texture_; bool update_backup_texture_; bool present_redirected_view_; //! The texture that holds the rendering of this view. ObjectPtr backup_texture_; ObjectPtr backup_depth_texture_; ObjectPtr background_texture_; ObjectPtr backup_fbo_; ObjectPtr prev_fbo_; Geometry prev_viewport_; Matrix4 model_view_matrix_; Matrix4 perspective_matrix_; /*! If true, copy the area in the previous fbo texture into background_texture_. */ bool copy_previous_fbo_for_background_; /*! Implemented in nux::View and nux::Layout. Report to a parent view with redirect_rendering_to_texture_ set to true that one of its children needs to be redrawn. */ virtual void PrepareParentRedirectedView(); virtual bool HasParentRedirectedView(); Area* RedirectedAncestor(); /*! Inform this view that one of its children has requested a draw. This view must have its rendering redirected to a texture. @param update True if this view is redirected and one of its children has requested a draw. */ virtual void SetUpdateBackupTextureForChildRendering(bool update); virtual bool UpdateBackupTextureForChildRendering() const; /********************************************/ /*** End support for redirected rendering ***/ /********************************************/ #ifdef NUX_GESTURES_SUPPORT //! Returns the InputArea hit by the given gesture virtual Area* GetInputAreaHitByGesture(const GestureEvent &event); //! Returns whether the gesture from the given event is fully inside this area. /*! For getures from direct devices (e.g. touchscreens), it checks whether all touch points lie within this area's boundaries. For gestures from indirect devices (e.g. touchpads) it checks whether the gesture's focus point lies inside this area. */ bool IsGestureInsideArea(const GestureEvent &event) const; #endif // NUX_GESTURES_SUPPORT private: void ReconfigureParentLayout(Area *child = 0); void CheckMinSize(); void CheckMaxSize(); Geometry geometry_; //!< The area geometry. //! Define a parent child structure /* An object of the class Area may have another of the class Layout as Parent. An object of the class View may have an object of the class Layout as parent. An object of the class Layout may have a parent of the class Layout or View as parent. A Area cannot have children(that may change later). */ Area* parent_area_; bool visible_; //!< Visible state of the area. bool sensitive_; //!< Input sensitive state of the area bool view_enabled_; //!< The enable state of a view. std::string base_string_; //!< A text string property for this area. Size min_size_; //!< A text string property for this area. Size max_size_; //!< A text string property for this area. // Parameters used in layouts unsigned int scale_factor_; //!< Factor for element expansion. MinorDimensionPosition minor_axis_position_; //!< Area position hint MinorDimensionSize minor_axis_size_; //!< Area dimension hint float minor_axis_size_scale_; //!< Area size percentage value. bool layout_done_; //!< Area layout status flag. Matrix4 _2d_xform; //!< 2D transformation matrix for this area and its children. Contains only translations. Matrix4 _3d_xform; //!< 3D transformation matrix for the area in a perspective space. bool _3d_area; //!< True if the area is resides in a 3D space. std::list _children_list; bool accept_mouse_wheel_event_; bool accept_keyboard_event_; WindowThread* window_thread_; friend class Layout; friend class View; friend class WindowCompositor; friend class WindowThread; #if !defined(NUX_MINIMAL) friend class HSplitter; friend class VSplitter; #endif }; } #endif // BASEOBJECT_H nux-4.0.6+14.04.20140409/Nux/GesturesSubscription.cpp0000644000015301777760000002453712321344237022434 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #include "GesturesSubscription.h" #include "Nux.h" #include "NuxCore/Logger.h" #include "Nux/GeisAdapter.h" namespace nux { DECLARE_LOGGER(logger, "nux.gestures_subscription"); GesturesSubscription::GesturesSubscription() : gesture_classes_(DRAG_GESTURE|PINCH_GESTURE|ROTATE_GESTURE), num_touches_(2), #if defined(USE_X11) window_id_(GetWindowThread()->GetGraphicsDisplay().GetWindowHandle()), #else window_id_(0), #endif sub_(nullptr), is_active_(false), drag_threshold_(0.0026f), drag_timeout_(0), pinch_threshold_(1.1f), pinch_timeout_(0), rotate_threshold_(2.0f*3.1415926f/50.0f), rotate_timeout_(0), tap_threshold_(0.0026f), tap_timeout_(300) { } GesturesSubscription::~GesturesSubscription() { if (sub_) geis_subscription_delete(sub_); } void GesturesSubscription::Activate() { if (is_active_) return; is_active_ = true; if (sub_) { GeisStatus status = geis_subscription_activate(sub_); if (status != GEIS_STATUS_SUCCESS) { LOG_ERROR(logger) << "Failed to activate Geis subscription."; } // configuration only works on active subscription (should be fixed in geis) ConfigureGeisSubscription(); } else { CreateGeisSubscriptionWhenPossible(); } } void GesturesSubscription::Deactivate() { if (!is_active_) return; is_active_ = false; if (sub_) { GeisStatus status = geis_subscription_deactivate(sub_); if (status != GEIS_STATUS_SUCCESS) { LOG_ERROR(logger) << "Failed to deactivate Geis subscription."; } } } void GesturesSubscription::SetGestureClasses(int gesture_classes) { SetProperty(gesture_classes_, gesture_classes); #define NUX_ALL_GESTURES (DRAG_GESTURE|PINCH_GESTURE|TAP_GESTURE|TOUCH_GESTURE); unwanted_gesture_classes_ = ~gesture_classes & NUX_ALL_GESTURES; #undef NUX_ALL_GESTURES } void GesturesSubscription::SetNumTouches(unsigned int num_touches) { SetProperty(num_touches_, num_touches); } void GesturesSubscription::SetWindowId(int window_id) { SetProperty(window_id_, window_id); } void GesturesSubscription::SetRecognitionThreshold(GestureClass gesture_class, float threshold) { if (threshold < 0.0f) return; switch(gesture_class) { case DRAG_GESTURE: SetProperty(drag_threshold_, threshold); break; case PINCH_GESTURE: SetProperty(pinch_threshold_, threshold); break; case TAP_GESTURE: SetProperty(tap_threshold_, threshold); break; case ROTATE_GESTURE: SetProperty(rotate_threshold_, threshold); break; default: break; } } void GesturesSubscription::SetRecognitionTimeout(GestureClass gesture_class, int timeout) { if (timeout < 0) return; switch(gesture_class) { case DRAG_GESTURE: SetProperty(drag_timeout_, timeout); break; case PINCH_GESTURE: SetProperty(pinch_timeout_, timeout); break; case TAP_GESTURE: SetProperty(tap_timeout_, timeout); break; case ROTATE_GESTURE: SetProperty(rotate_timeout_, timeout); break; default: break; } } std::vector GesturesSubscription::CreateGeisGestureClasses() { std::vector geis_gesture_classes; #define ADD_GESTURE(name) \ if (gesture_classes_ & name##_GESTURE) \ geis_gesture_classes.push_back(GEIS_GESTURE_##name); ADD_GESTURE(DRAG) ADD_GESTURE(PINCH) ADD_GESTURE(ROTATE) ADD_GESTURE(TAP) ADD_GESTURE(TOUCH) #undef ADD_GESTURE return geis_gesture_classes; } GeisStatus GesturesSubscription::AddGestureClassAndNumTouchesTerm(GeisFilter filter) { GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; std::vector geis_gesture_classes = CreateGeisGestureClasses(); switch (geis_gesture_classes.size()) { case 1: status = geis_filter_add_term(filter, GEIS_FILTER_CLASS, GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[0], GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches_, nullptr); break; case 2: status = geis_filter_add_term(filter, GEIS_FILTER_CLASS, GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[0], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[1], GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches_, nullptr); break; case 3: status = geis_filter_add_term(filter, GEIS_FILTER_CLASS, GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[0], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[1], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[2], GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches_, nullptr); break; case 4: status = geis_filter_add_term(filter, GEIS_FILTER_CLASS, GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[0], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[1], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[2], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[3], GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches_, nullptr); break; case 5: status = geis_filter_add_term(filter, GEIS_FILTER_CLASS, GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[0], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[1], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[2], GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, geis_gesture_classes[4], GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches_, nullptr); break; default: status = geis_filter_add_term(filter, GEIS_FILTER_CLASS, GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches_, nullptr); break; } return status; } void GesturesSubscription::CreateGeisSubscription() { GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; GeisFilter filter = nullptr; Geis geis = GetWindowThread()->GetGeisAdapter()->GetGeisInstance(); sub_ = geis_subscription_new(geis, "nux", GEIS_SUBSCRIPTION_NONE); if (!sub_) { LOG_ERROR(logger) << "Failed to create Geis subscription."; goto cleanup; } filter = geis_filter_new(geis, "filter"); if (!filter) { LOG_ERROR(logger) << "Failed to create Geis filter."; goto cleanup; } status = AddGestureClassAndNumTouchesTerm(filter); if (status != GEIS_STATUS_SUCCESS) { LOG_ERROR(logger) << "Failed to add gesture term to Geis filter."; goto cleanup; } status = geis_filter_add_term(filter, GEIS_FILTER_REGION, GEIS_REGION_ATTRIBUTE_WINDOWID, GEIS_FILTER_OP_EQ, window_id_, nullptr); if (status != GEIS_STATUS_SUCCESS) { LOG_ERROR(logger) << "Failed to add region term to Geis filter."; goto cleanup; } status = geis_subscription_add_filter(sub_, filter); if (status != GEIS_STATUS_SUCCESS) { LOG_ERROR(logger) << "Failed to add filter to subscription."; goto cleanup; } filter = nullptr; // it now belongs to the subscription if (is_active_) { status = geis_subscription_activate(sub_); if (status != GEIS_STATUS_SUCCESS) { LOG_ERROR(logger) << "Failed to activate Geis subscription."; goto cleanup; } // configuration only works on active subscription (should be fixed in geis) ConfigureGeisSubscription(); } cleanup: if (status != GEIS_STATUS_SUCCESS) { geis_filter_delete(filter); geis_subscription_delete(sub_); sub_ = nullptr; } } void GesturesSubscription::CreateGeisSubscriptionWhenPossible() { GeisAdapter *geis_adapter = GetWindowThread()->GetGeisAdapter(); if (geis_adapter->IsInitComplete()) CreateGeisSubscription(); else geis_adapter->init_complete.connect( sigc::mem_fun(this, &GesturesSubscription::CreateGeisSubscription)); } void GesturesSubscription::UpdateGeisSubscription() { nuxAssert(sub_ != nullptr); if (is_active_) geis_subscription_deactivate(sub_); geis_subscription_delete(sub_); // Recreate the subscription only once it's active again if (is_active_) CreateGeisSubscription(); } bool GesturesSubscription::MatchesGesture(const GestureEvent &event) const { if (event.GetTouches().size() != num_touches_) return false; if ((event.GetGestureClasses() & gesture_classes_) == 0) return false; if ((event.GetGestureClasses() & unwanted_gesture_classes_) != 0) return false; return true; } void GesturesSubscription::ConfigureGeisSubscription() { nuxAssert(sub_); GeisStatus status; auto setGeisConfig = [&](const char *name, GeisPointer var) { status = geis_subscription_set_configuration(sub_, name, var); if (status != GEIS_STATUS_SUCCESS) { LOG_ERROR(logger) << "Failed to set Geis subscription configuration " << name; } }; setGeisConfig(GEIS_CONFIG_DRAG_THRESHOLD, &drag_threshold_); setGeisConfig(GEIS_CONFIG_DRAG_TIMEOUT, &drag_timeout_); setGeisConfig(GEIS_CONFIG_PINCH_THRESHOLD, &pinch_threshold_); setGeisConfig(GEIS_CONFIG_PINCH_TIMEOUT, &pinch_timeout_); setGeisConfig(GEIS_CONFIG_TAP_THRESHOLD, &tap_threshold_); setGeisConfig(GEIS_CONFIG_TAP_TIMEOUT, &tap_timeout_); setGeisConfig(GEIS_CONFIG_ROTATE_THRESHOLD, &rotate_threshold_); setGeisConfig(GEIS_CONFIG_ROTATE_TIMEOUT, &rotate_timeout_); } } // namespace nux nux-4.0.6+14.04.20140409/Nux/RangeValueInteger.cpp0000644000015301777760000002035212321344237021564 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "EditTextBox.h" #include "HLayout.h" #include "RangeValueInteger.h" namespace nux { RangeValueInteger::RangeValueInteger(int Value, int MinValue, int MaxValue, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { m_min = MinValue; m_max = MaxValue; m_StartColor = Color(0xff202020); m_EndColor = Color(0xff202020); m_ProgressColor = Color(0xff606060); m_EnableDrawProgress = true; m_CTRL_KEY = 0; m_MarkerPosition = 0; InitializeLayout(); InitializeWidgets(); SetValue(Value); } RangeValueInteger::~RangeValueInteger() { } void RangeValueInteger::InitializeWidgets() { ////////////////// // Set Signals // ////////////////// m_Percentage->mouse_down.connect(sigc::mem_fun(this, &RangeValueInteger::OnReceiveMouseDown)); m_Percentage->mouse_up.connect(sigc::mem_fun(this, &RangeValueInteger::OnReceiveMouseUp)); m_Percentage->mouse_drag.connect(sigc::mem_fun(this, &RangeValueInteger::OnReceiveMouseDrag)); m_ValueString->sigValidateKeyboardEntry.connect(sigc::mem_fun(this, &RangeValueInteger::OnValidateKeyboardEntry)); ////////////////// // Set Geometry // ////////////////// m_ValueString->SetMinimumSize(DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT); m_ValueString->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT)); m_Percentage->SetMinimumSize(2 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT); m_Percentage->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT)); // Set the minimum size of this widget. // This is use by RangeValuePropertyItem::GetItemBestHeight SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); hlayout->AddView(m_ValueString, 0, eCenter, eFull); hlayout->AddView(m_Percentage, 4, eCenter, eFull); //hlayout->AddLayout(&vlayout, 4); hlayout->SetHorizontalExternalMargin(0); hlayout->SetHorizontalInternalMargin(2); hlayout->SetVerticalExternalMargin(0); SetCompositionLayout(hlayout); } void RangeValueInteger::InitializeLayout() { hlayout = new HLayout(NUX_TRACKER_LOCATION); m_Percentage = new BasicView(NUX_TRACKER_LOCATION); m_ValueString = new EditTextBox("", NUX_TRACKER_LOCATION); } void RangeValueInteger::DrawMarker(GraphicsEngine &graphics_engine) { int marker_position_x; int marker_position_y; graphics_engine.PushClippingRectangle(m_Percentage->GetGeometry()); marker_position_x = m_Percentage->GetBaseX() + (m_MarkerPosition - m_min) * m_Percentage->GetBaseWidth() * 1 / (m_max - m_min); marker_position_y = m_Percentage->GetBaseY() + m_Percentage->GetBaseHeight(); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y, marker_position_x, marker_position_y - 5, marker_position_x + 5, marker_position_y, Color(0.0f, 0.0f, 0.0f, 1.0f)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 4, marker_position_y, marker_position_x, marker_position_y - 4, marker_position_x + 4, marker_position_y, Color(0.7f, 0.7f, 0.7f, 1.0f)); graphics_engine.PopClippingRectangle(); } void RangeValueInteger::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { // Percentage Geometry P = m_Percentage->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, m_StartColor, m_StartColor, m_EndColor, m_EndColor); if (m_EnableDrawProgress) { P.SetWidth((m_MarkerPosition - m_min) * (float) P.GetWidth() / (m_max - m_min)); GetPainter().Paint2DQuadColor(graphics_engine, P, m_ProgressColor); } DrawMarker(graphics_engine); } void RangeValueInteger::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { m_ValueString->ProcessDraw(graphics_engine, force_draw); } void RangeValueInteger::SetRange(int min_value, int max_value) { if (min_value < max_value) { m_min = min_value; m_max = max_value; } else { m_min = max_value; m_max = min_value; } if (m_Value < m_min) m_Value = m_min; else if (m_Value > m_max) m_Value = m_max; SetValue(m_Value); } void RangeValueInteger::SetValue(int value) { if (value < m_min) m_Value = m_min; else if (value > m_max) m_Value = m_max; else m_Value = value; m_MarkerPosition = m_Value; m_ValueString->SetText(std::to_string((long long)m_Value)); QueueDraw(); } int RangeValueInteger::GetValue() const { return m_Value; } //////////////// // EMITTERS // //////////////// void RangeValueInteger::OnReceiveMouseDown(int x, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (x < 0) { m_Value = m_min; m_MarkerPosition = m_Value; } else if (x > m_Percentage->GetBaseWidth()) { m_Value = m_max; m_MarkerPosition = m_Value; } else { m_Value = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); m_MarkerPosition = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); if (m_MarkerPosition - m_Value > 0.5f) m_Value++; } m_ValueString->SetText(std::to_string((long long)m_Value)); sigValueChanged.emit(this); sigMouseDown.emit(m_Value); sigValueChanged2.emit(m_Value); QueueDraw(); } void RangeValueInteger::OnReceiveMouseUp(int x, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (x < 0) m_Value = m_min; else if (x > m_Percentage->GetBaseWidth()) m_Value = m_max; else { m_Value = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); if (m_MarkerPosition - m_Value > 0.5f) m_Value++; } m_MarkerPosition = m_Value; m_ValueString->SetText(std::to_string((long long)m_Value)); sigValueChanged.emit(this); sigMouseUp.emit(m_Value); sigValueChanged2.emit(m_Value); QueueDraw(); } void RangeValueInteger::OnReceiveMouseDrag(int x, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (x < 0) { m_Value = m_min; m_MarkerPosition = m_Value; } else if (x > m_Percentage->GetBaseWidth()) { m_Value = m_max; m_MarkerPosition = m_Value; } else { m_Value = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); m_MarkerPosition = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); if (m_MarkerPosition - m_Value > 0.5f) m_Value++; } m_ValueString->SetText(std::to_string((long long)m_Value)); sigValueChanged.emit(this); sigMouseDrag.emit(m_Value); sigValueChanged2.emit(m_Value); QueueDraw(); } void RangeValueInteger::OnKeyboardFocus() { } void RangeValueInteger::OnLostKeyboardFocus() { } void RangeValueInteger::OnValidateKeyboardEntry(EditTextBox* /* textbox */, const std::string &text) { int i; i = CharToInteger(text.c_str()); SetValue(i); sigValueChanged.emit(this); sigSetTypedValue.emit(i); sigValueChanged2.emit(m_Value); QueueDraw(); } void RangeValueInteger::BroadcastValue() { sigValueChanged2.emit(m_Value); } } nux-4.0.6+14.04.20140409/Nux/Dialog.cpp0000644000015301777760000000366612321344237017425 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HLayout.h" #include "VLayout.h" #include "Button.h" #include "Validator.h" #include "WindowCompositor.h" #include "Dialog.h" namespace nux { Dialog::Dialog(const char *WindowName /* = "" */) : FloatingWindow(WindowName) { ShowWindow(false); m_ButtonLayout = new HLayout("Dialog Buttons"); m_OkButton = new Button("OK"); m_OkButton->SetMinimumWidth(60); m_OkButton->SetMinimumHeight(20); m_CancelButton = new Button("Cancel"); m_CancelButton->SetMinimumWidth(60); m_CancelButton->SetMinimumHeight(20); //FIXME - m_OkButton->sigClick.connect(sigc::mem_fun(this, &Dialog::RecvOk)); //FIXME - m_CancelButton->sigClick.connect(sigc::mem_fun(this, &Dialog::RecvCancel)); m_ButtonLayout->SetHorizontalInternalMargin(6); m_ButtonLayout->SetVerticalExternalMargin(2); m_ButtonLayout->AddView(m_OkButton, 0); m_ButtonLayout->AddView(m_CancelButton, 0); // NuxNote: m_ButtonLayout should be moved to the places where it is used... For instance ColorPickerDialog. } Dialog::~Dialog() { } void Dialog::Start(bool StartModal) { ShowWindow(true, StartModal); } } nux-4.0.6+14.04.20140409/Nux/AnimatedTextureArea.cpp0000644000015301777760000001027612321344237022115 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/ImageSurface.h" #include "AnimatedTextureArea.h" namespace nux { AnimatedTextureArea::AnimatedTextureArea(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_UserTexture(0) { SetMinMaxSize(32, 32); mouse_down.connect(sigc::mem_fun(this, &AnimatedTextureArea::RecvMouseDown)); mouse_drag.connect(sigc::mem_fun(this, &AnimatedTextureArea::RecvMouseDrag)); m_TimerFunctor = new TimerFunctor(); m_TimerFunctor->tick.connect(sigc::mem_fun(this, &AnimatedTextureArea::TimerNextFrame)); } AnimatedTextureArea::~AnimatedTextureArea() { GetTimer().RemoveTimerHandler(m_TimerHandler); m_TimerHandler = 0; delete m_TimerFunctor; m_TimerFunctor = 0; } void AnimatedTextureArea::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { if (m_UserTexture) { GetPainter().PaintBackground(graphics_engine, GetGeometry()); graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); nux::Geometry base = GetGeometry(); nux::TexCoordXForm texxform; graphics_engine.QRP_1Tex(base.x, base.y, base.width, base.height, m_UserTexture->GetDeviceTexture(), texxform, nux::color::White); graphics_engine.GetRenderStates().SetBlend(false); } } void AnimatedTextureArea::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void AnimatedTextureArea::SetTexture(TextureFrameAnimation *t) { m_UserTexture = t; if (m_UserTexture) { ObjectPtr< CachedTextureFrameAnimation > Texture = GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(m_UserTexture); ObjectPtr AnimatedTexture = Texture->m_Texture; //Texture->m_Texture.CastRef(); ObjectPtr Texture2D = Texture->m_Texture; //Texture->m_Texture.CastRef(); AnimatedTexture->SetFiltering(GL_LINEAR, GL_LINEAR); AnimatedTexture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); } QueueDraw(); } void AnimatedTextureArea::RecvMouseDown(int x, int y, long /* button_flags */, long /* key_flags */) { sigMouseDown.emit(x, y); } void AnimatedTextureArea::RecvMouseDrag(int x, int y, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { sigMouseDrag.emit(x, y); } void AnimatedTextureArea::StartAnimation() { if (m_TimerHandler.IsValid()) { GetTimer().RemoveTimerHandler(m_TimerHandler); m_TimerHandler = 0; } m_TimerHandler = GetTimer().AddOneShotTimer(41, m_TimerFunctor, 0); QueueDraw(); } void AnimatedTextureArea::StopAnimation() { if (m_TimerHandler.IsValid()) { GetTimer().RemoveTimerHandler(m_TimerHandler); m_TimerHandler = 0; } } void AnimatedTextureArea::TimerNextFrame(void * /* v */) { if (m_UserTexture) { ObjectPtr< CachedTextureFrameAnimation > Texture = GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(m_UserTexture); ObjectPtr AnimatedTexture = Texture->m_Texture; //Texture->m_Texture.CastRef(); ObjectPtr Texture2D = Texture->m_Texture; //Texture->m_Texture.CastRef(); AnimatedTexture->PresentNextFrame(); m_TimerHandler = GetTimer().AddOneShotTimer(41, m_TimerFunctor, 0); } QueueDraw(); } } nux-4.0.6+14.04.20140409/Nux/InputAreaProximity.h0000644000015301777760000000353612321344237021504 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * */ #ifndef NUX_INPUTAREA_PROXIMITY_H #define NUX_INPUTAREA_PROXIMITY_H #include "InputArea.h" namespace nux { class InputAreaProximity { public: InputAreaProximity(InputArea* area, unsigned int proximity); virtual ~InputAreaProximity(); virtual void CheckMousePosition(Point const& mouse); //! Signal emitted when the Mouse is near the input area. /*! @param Point mouse is the current Mouse position. */ sigc::signal mouse_near; //! Signal emitted while the mouse is moving, near, and not yet inside the input area. /*! @param Point mouse is the current Mouse position. @param Point offset is the offset between the mouse and the input area. */ sigc::signal mouse_approaching; //! Signal emitted when the Mouse is moves beyond the input area + proximity. /*! @param Point mouse is the current Mouse position. */ sigc::signal mouse_beyond; protected: ObjectWeakPtr area_; unsigned int proximity_; bool is_mouse_near_; }; } #endif nux-4.0.6+14.04.20140409/Nux/Canvas.cpp0000644000015301777760000001321612321344237017431 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller UnReference (); } void Canvas::Recreate () { if (_surface) cairo_surface_destroy (_surface); if (_cr) cairo_destroy (_cr); if (_last_width < 1 || _last_height < 1) { g_debug ("Width or height of view invalid!"); return; } _surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, _last_width, _last_height); if (cairo_surface_status (_surface) != CAIRO_STATUS_SUCCESS) { g_debug ("Could not create image-surface!"); return; } _cr = cairo_create (_surface); if (cairo_status (_cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (_surface); g_debug ("Could not create cairo-context!"); return; } cairo_set_operator (_cr, CAIRO_OPERATOR_CLEAR); cairo_paint (_cr); _invalid = false; } NBitmapData* Canvas::GetBitmap () { if (_last_width < 1 || _last_height < 1) { g_debug ("Width or height invalid!"); return NULL; } BitmapFormat bitmap_format = BITFMT_B8G8R8A8; NTextureData* bitmap_data = new NTextureData (bitmap_format, _last_width, _last_height, 1); unsigned char* ptr = cairo_image_surface_get_data (_surface); int stride = cairo_image_surface_get_stride (_surface); if (ptr == NULL || stride == 0) { g_debug ("Invalid surface!"); delete bitmap_data; return NULL; } for (int j = 0; j < _last_height; j++) { Memcpy (bitmap_data->GetSurface (0).GetPtrRawData() + j * bitmap_data->GetSurface (0).GetPitch(), (const void *) (&ptr[j * stride]), _last_width * GPixelFormats[bitmap_format].NumComponents); } return bitmap_data; } cairo_surface_t* Canvas::GetCairoSurface () { return _surface; } cairo_t* Canvas::GetCairoContext () { return _cr; } int Canvas::GetLastWidth () { return _last_width; } int Canvas::GetLastHeight () { return _last_height; } // this is really just a stub... Canvas::Paint() being declared as virtual is // meant to be overwritten by a derived class anyway in real-world scenario // whatever needs to be drawn (and adapt to size) happens here in Paint() void Canvas::Paint () { cairo_t* cr = GetCairoContext (); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) return; cairo_scale (cr, 1.0, 1.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_rectangle (cr, 0.0f, 0.0f, (double) GetLastWidth (), (double) GetLastHeight ()); cairo_set_source_rgba (cr, 1.0f, 0.0f, 0.0f, 1.0f); cairo_fill_preserve (cr); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); cairo_stroke (cr); //cairo_surface_write_to_png (GetCairoSurface (), "/tmp/surf-debug.png"); } void Canvas::Draw (GraphicsEngine& graphics_engine, bool /* forceDraw */) { Geometry geom = GetGeometry (); // see if the (cairo-drawn) texture needs to be updated if (_invalid || _last_width != geom.width || _last_height != geom.height) { _last_width = geom.width; _last_height = geom.height; Recreate (); Paint (); NBitmapData* bitmap = GetBitmap (); if (_texture) _texture->UnReference (); _texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture (); _texture->Update (bitmap); delete bitmap; } // draw the texture on screen graphics_engine.PushClippingRectangle (geom); GetWindowThread()->GetGraphicsEngine().GetRenderStates().SetBlend (false); TexCoordXForm texxform; texxform.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP); texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); graphics_engine.QRP_1Tex(geom.x, geom.y, geom.width, geom.height, _texture->GetDeviceTexture (), texxform, Color (1.0f, 1.0f, 1.0f, 1.0f)); graphics_engine.PopClippingRectangle(); } void Canvas::DrawContent(GraphicsEngine& /* graphics_engine */, bool /* forceDraw */) { } void Canvas::Invalidate() { _invalid = true; } void Canvas::PreLayoutManagement() { View::PreLayoutManagement(); } long Canvas::PostLayoutManagement(long layoutResult) { long result = View::PostLayoutManagement(layoutResult); return result; } } nux-4.0.6+14.04.20140409/Nux/IntegerValidator.h0000644000015301777760000000324012321344237021122 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef INTEGERVALIDATOR_H #define INTEGERVALIDATOR_H #include "Validator.h" namespace nux { class IntegerValidator : public Validator { public: IntegerValidator(int Minimum = INT_MIN, int Maximum = INT_MAX); IntegerValidator(const IntegerValidator &validator); IntegerValidator &operator= (const IntegerValidator &rhs); virtual ~IntegerValidator(); virtual Validator *Clone() const; //Virtual Constructor Idiom /*! @return The input value clamped to the range [m_Minimum, m_Maximum]. */ int GetClampedValue(int i) const; virtual void Alternative(const char *str); void SetMinimum(int value); int GetMinimum() const; void SetMaximum(int value); int GetMaximum() const; std::string ToString(int i); int ToInteger(const char *str); private: int m_Minimum; int m_Maximum; }; } #endif // INTEGERVALIDATOR_H nux-4.0.6+14.04.20140409/Nux/TimerProc.h0000644000015301777760000001511712321344237017571 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef TIMERPROC_H #define TIMERPROC_H namespace nux { class TimerHandler; class WindowThread; //! A timeout callback. Fires a signal when a timer expires. class TimeOutSignal : public sigc::trackable { public: sigc::signal tick; sigc::signal expired; }; typedef TimeOutSignal TimerFunctor; class TimerObject; class TimerHandle { public: TimerHandle(); TimerHandle(TimerObject *timer_object); TimerHandle(const TimerHandle &); TimerHandle &operator = (const TimerHandle &); std::shared_ptr const& operator->() const; bool operator==(TimerHandle const& h) const; bool IsValid() const; //! m_d; }; //! A timer manager class created by WindowThread. class TimerHandler { public: enum { TIMERTYPE_UNKNONW = 0L, TIMERTYPE_PERIODIC, TIMERTYPE_DURATION, TIMERTYPE_ITERATION, }; typedef enum { TIMER_STATE_STOPED, TIMER_STATE_PAUSED, TIMER_STATE_RUNNING, } TimerState; TimerHandler(WindowThread *window_thread); //! Add a timer callback. /*! Add a timer callback to the timer manager. When the timer expires, the callback function is executed. The returned TimerObject should not be deleted by the caller. @param Milliseconds period Time before the timer ticks. The timer ticks only once and then it expires. @param timeout_signal The callback to execute when the timer expires. @param Data The callback data @param window_thread Thread safety measure. Pass the WindowThread associated to this TimerHandler if it is called from a different thread than the one where the main thread was created. @return A handle to the timer. */ TimerHandle AddOneShotTimer(unsigned int period, TimeOutSignal *timeout_signal, void *Data, WindowThread* window_thread = NULL); //! Add a periodic timer callback. /*! Add a timer callback to the timer manager. Every time the timer expires, the callback function is executed. The returned TimerHandle should not be deleted by the caller. @param Milliseconds period Time between the timer ticks. The timer will tick 'NumberOfIteration' times. @param Duration The duration over which the timer is repeated. @param timeout_signal The callback to execute when the timer expires. @param Data The callback data @return A handle to the timer. */ TimerHandle AddDurationTimer(unsigned int period, int Duration, TimeOutSignal *timeout_signal, void *Data); //! Add a timer callback to be called a finite number of time. /*! Add a timer callback to the timer manager. The timer callback will be call N times exactly. Every time the timer expires, the callback function is executed. The returned TimerHandle should not be deleted by the caller. @param Milliseconds period Time between the timer ticks. The timer will tick 'NumberOfIteration' times. @param NumberOfIteration The number of time to repeat the wait period. @param timeout_signal The callback to execute when the timer expires. @param Data The callback data @return A handle to the timer. */ TimerHandle AddIterativeTimer(unsigned int period, int NumberOfIteration, TimeOutSignal *timeout_signal, void *Data); //! Search for a timer handle. /*! Search for a timer handle in the timer handle queue. Return true if the timer is found. @param handle Timer handle to search. @return Return true if the timer is found; false otherwise. */ bool FindTimerHandle(TimerHandle& handle); //! Remove a timer; /*! This call stops the timer. @param handle Timer handle to search. @return Return True if the timer is found. */ bool RemoveTimerHandler(TimerHandle& handle); //! Pause a timer. /*! This call pauses a timer. @param handle Timer handle to look for. @return True if the timer is paused. */ bool PauseTimer(TimerHandle& handle); //! Resume the execution of a timer. /*! This call resumes the execution of a timer. @param handle Timer handle to look for. @return True if the timer execution has resumed.. */ bool ResumeTimer(TimerHandle& handle); //! Return the delay until the next timer expires. /*! @return Delay to next timer expiration in milliseconds. */ int DelayUntilNextTimerExpires(); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) int ExecTimerHandler (unsigned int timer_id); #else int ExecTimerHandler(); #endif //! Start the timers that were sett before the system was fully initialized. void StartEarlyTimerObjects(); private: // Prevent copy constructor. TimerHandler(const TimerHandler&); // Prevent assignment operator. TimerHandler& operator = (const TimerHandler&); WindowThread *window_thread_; //!< The WindowThread to which this object belongs. bool is_processing_timers_; void AddHandle(TimerHandle const&); unsigned int GetNumPendingHandler(); std::deque timer_handler_queue_; std::list early_timer_handlers_; //!< timer objects that couldn't be started because the main loop is not runing yet. }; } #endif // TIMERPROC_H nux-4.0.6+14.04.20140409/Nux/TextEntry.h0000644000015301777760000004276312321344237017642 0ustar pbusernogroup00000000000000#ifndef TEXTENTRY_H #define TEXTENTRY_H // Heavily inspired from google gadget code /* * Copyright 2011-2013 Canonical Ltd. * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0(the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "cairo/cairo.h" #include "pango/pango.h" #include "pango/pangocairo.h" #include "NuxGraphics/CairoGraphics.h" namespace nux { class CairoGraphics; class IBusIMEContext; class CairoFont { public: enum Style { STYLE_NORMAL, STYLE_ITALIC }; /** * Enum used to specify font weight. */ enum Weight { WEIGHT_NORMAL, WEIGHT_BOLD }; /** * Constructor for CairoFont. Takes a PangoFontDescription object and its * ownership. Will free the PangoFontDescription object on destruction. */ CairoFont(const std::string &family, /*PangoFontDescription *font,*/ double size, Style style, Weight weight); virtual ~CairoFont(); virtual Style GetStyle() const {return style_;} virtual Weight GetWeight() const {return weight_;} virtual double GetPointSize() const {return size_;} virtual void Destroy() {delete this;} const PangoFontDescription *GetFontDescription() const {return font_;} private: PangoFontDescription *font_; double size_; Style style_; Weight weight_; }; class TextEntry: public View { NUX_DECLARE_OBJECT_TYPE(TextEntry, View); public: TextEntry(const char* text, NUX_FILE_LINE_PROTO); ~TextEntry(); Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual void Draw(GraphicsEngine& graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine& graphics_engine, bool force_draw); void PreLayoutManagement(); long PostLayoutManagement(long layoutResult); // Receivers void RecvMouseDoubleClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvKeyEvent( unsigned long eventType , /*event type*/ unsigned long keysym , /*event keysym*/ unsigned long state , /*event state*/ const char* character , /*character*/ unsigned short keyCount /*key repeat count*/); void RecvStartKeyFocus(); void RecvEndKeyFocus(); bool _size_match_text; BaseTexture *_texture2D; void MainDraw(); void ProcessMouseEvent(int event_type, int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void ProcessKeyEvent ( unsigned long eventType , /*event type*/ unsigned long keysym , /*event keysym*/ unsigned long state , /*event state*/ const char* character , /*character*/ unsigned short keyCount /*key repeat count*/); void FocusInx(); void FocusOutx(); //! Text changed signal /*! This signal is emitted when the text has changed. */ sigc::signal text_changed; sigc::signal activated; sigc::signal cursor_moved; void SetText(const char* text); std::string const& GetText() const; std::string GetTextSelection() const; void SetCompletion(const char* text); // Should use std::string, does not for consistancy std::string const& GetCompletion() const; void SetCompletionColor(const Color& color); Color const& GetCompletionColor() const; void SetTextColor(const Color& color); Color GetTextColor() const; void SetFontFamily(const char* font); void SetFontSize(double font_size); void SetFontOptions(const cairo_font_options_t* options); /** Select text between start and end. */ void Select(int start, int end); /** Select all text */ void SelectAll(); CairoGraphics::Alignment GetAlign() const; void SetAlign(CairoGraphics::Alignment align); bool im_active(); bool im_running(); void MoveCursorToLineStart(); void MoveCursorToLineEnd(); void SetToggleCursorVisibilityOnKeyFocus(bool b); bool GetToggleCursorVisibilityOnKeyFocus() const; /*! When the text entry is in single line mode, the keyboard arrow up/down may be used to navigate to another view. If the parameter of this function is set to true then the text entry returns false on NUX_VK_UP in InspectKeyEvent(). This allows the parent of the text entry to look for another view that can receive the keyboard focus. The default value is true.\n In multi-line mode, keyboard arrow up/down are used to navigate in the text. @param b True to allow the key navigation to move away from the text entry on NUX_VK_UP. */ void SetLoseKeyFocusOnKeyNavDirectionUp(bool b); bool GetLoseKeyFocusOnKeyNavDirectionUp() const; /*! When the text entry is in single line mode, the keyboard arrow up/down may be used to navigate to another view. If the parameter of this function is set to true then the text entry returns false on NUX_VK_DOWN in InspectKeyEvent(). This allows the parent of the text entry to look for another view that can receive the keyboard focus. The default value is true.\n In multi-line mode, keyboard arrow up/down are used to navigate in the text. @param b True to allow the key navigation to move away from the text entry on NUX_VK_DOWN. */ void SetLoseKeyFocusOnKeyNavDirectionDown(bool b); bool GetLoseKeyFocusOnKeyNavDirectionDown() const; /*! Return True if the text has been modified after the text entry has received the keyboard focus.\n If the text entry already has characters typed in and it gets the keyboard focus, this function return false while the text has not been modified. The text can be modified either by typing new characters or addind text through TextEntry::SetText, TextEntry::EnterText, TextEntry::DeleteText. If this text entry does not have the keyboard focus, this function returns false. @return True after the text entry has received the keyboard focus and text has been typed in. */ bool IsInTextInputMode() const; /*! Insert text at current caret position. */ void EnterText(const char* str); /*! Delete text in a specified range, in number of characters. */ void DeleteText(int start, int end); void SetPasswordMode(bool visible); void SetVisibility(bool visible); void SetPasswordChar(const char* c); bool PasswordMode() const; std::string GetPasswordChar(); void PreeditStarted(); void UpdatePreedit(std::string const& preedit, int cursor); void UpdatePreeditAttribs(PangoAttrList* list); void ClearPreedit(); protected: bool _block_focus; // used to selectively ignore focus keyevents virtual void GeometryChanged(bool position_has_changed, bool size_has_changed); /** * Enum used to specify different motion types. */ enum MovementStep { VISUALLY, WORDS, DISPLAY_LINES, DISPLAY_LINE_ENDS, PAGES, BUFFER }; /** * Enum used for the search state of the compose list */ enum SearchState { NO_MATCH, PARTIAL, MATCH }; /** Checks for possible composition sequences */ bool IsInitialCompositionKeySym(unsigned long keysym) const; bool IsInCompositionMode() const; bool HandleComposition(unsigned long keysym); SearchState GetCompositionForList(std::vector const& input, std::string& composition); void QueueTextDraw(); /** Remove the cached layout. */ void ResetLayout(); /** * Create pango layout on-demand. If the layout is not changed, return the * cached one. */ PangoLayout* EnsureLayout(); /** Create a new layout containning current edit content */ PangoLayout* CreateLayout(); /** Create cairo canvas on-demand. */ CairoGraphics* EnsureCanvas(); /** Adjust the scroll information */ void AdjustScroll(); /** * Send out a request to refresh all informations of the edit control * and queue a draw request. * If @c relayout is true then the layout will be regenerated. * */ void QueueRefresh(bool relayout, bool adjust_scroll); /** Reset the input method context */ void ResetImContext(); /** Reset preedit text */ void ResetPreedit(); /** Send out a request to blink the cursor if necessary */ void QueueCursorBlink(); static bool CursorBlinkCallback(TextEntry* data); void ShowCursor(); void HideCursor(); /** Draw the Cursor to the canvas */ void DrawCursor(CairoGraphics* canvas); /** Draw the text to the canvas */ virtual void DrawText(CairoGraphics* canvas); void GetCursorRects(Rect* strong, Rect* weak); void UpdateCursorRegion(); void UpdateSelectionRegion(); /** Move cursor */ void MoveCursor(MovementStep step, int count, bool extend_selection); /** Move cursor visually, meaning left or right */ int MoveVisually(int current_pos, int count); /** Move cursor in words */ int MoveWords(int current_pos, int count); /** Move cursor in display lines */ int MoveDisplayLines(int current_pos, int count); /** Move cursor in pages */ int MovePages(int current_pos, int count); /** Move cursor to the beginning or end of a display line */ int MoveLineEnds(int current_pos, int count); /** Set the current cursor offset, in number of characters. */ void SetCursor(int cursor); /** Get the most reasonable character offset according to the pixel * coordinate in the layout */ int XYToTextIndex(int x, int y); /** Get the offset range that is currently selected,in number of characters.*/ bool GetSelectionBounds(int* start, int* end) const; /** Set the offest range that should be selected, in number of characters. */ void SetSelectionBounds(int selection_bound, int cursor); /** Convert index in text_ into index in layout text. */ int TextIndexToLayoutIndex(int text_index, bool consider_preedit_cursor); /** Convert index in layout text into index in text_. */ int LayoutIndexToTextIndex(int layout_index); /** Get char length at index, in number of bytes. */ int GetCharLength(int index); /** Get previous char length before index, in number of bytes. */ int GetPrevCharLength(int index); /** Select the current word under cursor */ void SelectWord(); /** Select the current display line under cursor */ void SelectLine(); /** Delete the text that is currently selected */ void DeleteSelection(); /** Cut the current selected text to the clipboard */ virtual void CutClipboard(); /** Copy the current selected text to the clipboard */ virtual void CopyClipboard(); /** Paste the text in the clipboard to current offset */ virtual void PasteClipboard(); #if defined(NUX_OS_LINUX) /** Paste the text in the primary clipboard to current offset */ virtual void PastePrimaryClipboard(); #endif /** Delete a character before the offset of the cursor */ void BackSpace(MovementStep step); /** Delete a character at the offset of the cursor */ void Delete(MovementStep step); /** Switch between the overwrite mode and the insert mode*/ void ToggleOverwrite(); /** Gets the color of selection background. */ Color GetSelectionBackgroundColor(); /** Gets the color of selection text. */ Color GetSelectionTextColor(); /** * Gets the cursor location in pango layout. The unit is pixel. */ void GetCursorLocationInLayout(int* strong_x, int* strong_y, int* strong_height, int* weak_x, int* weak_y, int* weak_height); /** The CairoCanvas which hold cairo_t inside */ CairoGraphics* canvas_; /** The cached Pango Layout */ PangoLayout* cached_layout_; /** The text content of the edit control */ std::string text_; /** The preedit text of the edit control */ std::string preedit_; /** Attribute list of the preedit text */ PangoAttrList* preedit_attrs_; /** * The character that should be displayed in invisible mode. * If this is empty, then the edit control is visible */ std::string password_char_; /** The completion string */ std::string completion_; /** The completion colour */ Color completion_color_; /** Last time of mouse double click event. */ unsigned long long last_dblclick_time_; /** The current cursor position in number of bytes. */ int cursor_; /** * The preedit cursor position within the preedit string, * in number of bytes. */ int preedit_cursor_; /** * The current selection bound in number of bytes, * range between cursor_ and selection_bound_ are selected. */ int selection_bound_; /** X offset of current scroll, in pixels */ int scroll_offset_x_; /** Y offset of current scroll, in pixels */ int scroll_offset_y_; /** Timer id of cursor blink callback */ int cursor_blink_timer_; /** * Indicates the status of cursor blinking, * 0 means hide cursor * otherwise means show cursor. * The maximum value would be 2, and decrased by one in each cursor blink * callback, then there would be 2/3 visible time and 1/3 invisible time. */ int cursor_blink_status_; /*! Whether the text is visible, or its characters are masked by a default char (password mode). */ bool visible_; /** Whether the edit control is focused */ bool focused_; /** Whether the input method should be reset */ bool need_im_reset_; /** Whether the keyboard in overwrite mode */ bool overwrite_; /** Whether the button click should select words */ bool select_words_; /** Whether the button click should select lines */ bool select_lines_; /** Whether the left button is pressed */ bool button_; /** Whether the text should be bold */ bool bold_; /** Whether the text should be underlined */ bool underline_; /** Whether the text should be struck-out */ bool strikeout_; /** Whether the text should be italic */ bool italic_; /** Whether the text could be shown in multilines */ bool multiline_; /** Whether the text should be wrapped */ bool wrap_; /** whether the cursor should be displayed */ bool cursor_visible_; /** whether the edit control is readonly */ bool readonly_; /** * Indicates if the content of the edit control has been modified * since last draw */ bool content_modified_; /** Indicates if the selection region has been changed since last draw. */ bool selection_changed_; /** Indicates if the cursor position has been moved since last draw. */ bool cursor_moved_; /** Indicates if the canvas cache needs updating. */ bool update_canvas_; /** The font family of the text */ std::string font_family_; /** The font size of the text */ double font_size_; cairo_font_options_t* font_options_; double font_dpi_; /** The text color of the edit control */ Color _text_color; CairoGraphics::Alignment align_; #if defined(USE_X11) Cursor caret_cursor_; #endif std::list last_selection_region_; std::list selection_region_; std::list last_cursor_region_; std::list cursor_region_; #if defined(USE_X11) IBusIMEContext* ime_; friend class IBusIMEContext; #endif bool ime_active_; bool text_input_mode_; //!< Transient state of the TextEntry. \sa IsInTextInputMode. bool key_nav_mode_; bool lose_key_focus_on_key_nav_direction_up_; bool lose_key_focus_on_key_nav_direction_down_; bool cursor_visible_on_key_focus_only_; std::vector composition_list_; virtual bool InspectKeyEvent(Event const& event); virtual bool InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character); }; } #endif // TEXTENTRY_H nux-4.0.6+14.04.20140409/Nux/GroupBox2.h0000644000015301777760000000402312321344237017506 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GROUPBOX2_H #define GROUPBOX2_H namespace nux { class Layout; /*! A stretch factor of 0 or 1 for the GroupBox has no effect because the GroupBox is designed to tightly adjust to the size of its composition layout. This unlike the Panel widget for instance who does not force itself to adjust to the size of its composition layout. */ class GroupBox2 : public View { public: GroupBox2(const char *Caption = "", NUX_FILE_LINE_PROTO); ~GroupBox2(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual bool SetLayout(Layout *layout); void SetCaption(const char *Caption); protected: virtual bool AcceptKeyNavFocus(); private: virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void ComputeContentPosition(float offsetX, float offsetY); BasicView *m_CaptionArea; Layout *m_layout; static int CAPTION_X_MARGIN; static int X_MARGIN; static int Y_MARGIN; static Color GROUPBOX2_HEADER_BASE_COLOR; static Color GROUPBOX2_HEADER_TEXT_COLOR; static int TOP_HEADER_HEIGHT; }; } #endif // GroupBox2_H nux-4.0.6+14.04.20140409/Nux/Panel.h0000644000015301777760000000436112321344237016723 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef PANEL_H #define PANEL_H #include "ScrollView.h" namespace nux { class Layout; class Panel: public ScrollView { public: Panel(NUX_FILE_LINE_PROTO); ~Panel(); //void AddWidget(View* ic); void AddWidget(View *ic, int stretchfactor = 1); void AddWidget(std::list *ViewList); virtual bool SetLayout(Layout *layout); void clearContent(); // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. virtual void PreLayoutManagement(); // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. virtual long PostLayoutManagement(long LayoutResult); // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. virtual void ComputeContentPosition(float offsetX, float offsetY); protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void ScrollLeft(float stepx, int mousedx); virtual void ScrollRight(float stepx, int mousedx); virtual void ScrollUp(float stepy, int mousedy); virtual void ScrollDown(float stepy, int mousedy); virtual bool AcceptKeyNavFocus(); private: Layout *m_layout; }; } #endif // PANEL_H nux-4.0.6+14.04.20140409/Nux/EMMetrics.cpp0000644000015301777760000000330112321344237020040 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller DisplayWidth(dpy,scr) * 25.4) / (static_cast DisplayWidthMM(dpy,scr))); double yres = ((static_cast DisplayHeight(dpy,scr) * 25.4) / (static_cast DisplayHeightMM(dpy,scr))); dpi = (xres + yres) / 2.0; } // update stored ppe pixels_per_em_ = points * dpi / 72.0; // sanity-check if (pixels_per_em_ == 0.0) pixels_per_em_ = 10.0; // assume points == 10.0, dpi == 96.0 } double EMMetrics::Pixel2EM(int value) { return static_cast (value) / pixels_per_em_; } int EMMetrics::EM2Pixel(double value) { return static_cast (value * pixels_per_em_); } } // nux namespace nux-4.0.6+14.04.20140409/Nux/Button.cpp0000644000015301777760000003061512321344237017473 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Button.h" #include "StaticText.h" #include "HLayout.h" #include "VLayout.h" #include "TextureArea.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(Button); Button::Button(TextureArea *image, NUX_FILE_LINE_DECL) : AbstractButton(NUX_FILE_LINE_PARAM) { image_ = NULL; Initialize(std::string(), image); } Button::Button(const std::string& button_label, NUX_FILE_LINE_DECL) : AbstractButton(NUX_FILE_LINE_PARAM) { image_ = NULL; Initialize(button_label, NULL); } Button::Button(const std::string& button_label, TextureArea *image, NUX_FILE_LINE_DECL) : AbstractButton(NUX_FILE_LINE_PARAM) { image_ = NULL; Initialize(button_label, image); } Button::Button(NUX_FILE_LINE_DECL) : AbstractButton(NUX_FILE_LINE_PARAM) { image_ = NULL; Initialize(std::string(), NULL); } Button::~Button() { if (image_) image_->UnReference(); if (static_text_) static_text_->UnReference(); } void Button::Initialize(const std::string &str, TextureArea *image) { same_size_as_content_ = true; persistent_active_state_ = false; layout_type_ = HORIZONTAL; item_order_ = IMAGE_FIRST; distribution_ = CENTER_OF_LAYOUT; space_between_items_ = 0; layout_top_padding_ = 2; layout_right_padding_ = 2; layout_bottom_padding_ = 2; layout_left_padding_ = 2; int clip = 2; left_clip_ = clip; right_clip_ = clip; top_clip_ = clip; bottom_clip_ = clip; // Set Geometry SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); image_minimum_size_ = Size(16, 16); image_maximum_size_ = Size(AREA_MAX_WIDTH, AREA_MAX_HEIGHT); BuildLayout(str, image); } void Button::SetImage(TextureArea *image) { if (image == NULL) return; BuildLayout(label_, image); } void Button::SetLabel(const std::string &button_label) { BuildLayout(button_label, image_); } TextureArea* Button::GetImage() { if (image_ == NULL) return NULL; TextureArea *texture_area = new TextureArea(); texture_area->SetPaintLayer(image_->GetPaintLayer()); return texture_area; } std::string Button::GetLabel() const { return label_; } void Button::SetImageMinimumSize(int width, int height) { image_minimum_size_ = Size(width, height); if (image_) image_->SetMinimumSize(width, height); } void Button::SetImageMaximumSize(int width, int height) { image_maximum_size_ = Size(width, height); if (image_) image_->SetMaximumSize(width, height); } void Button::SetLayoutPadding(int top, int right, int bottom, int left) { layout_top_padding_ = top >= 0 ? top : 0; layout_right_padding_ = right >= 0 ? right : 0; layout_bottom_padding_ = bottom >= 0 ? bottom : 0; layout_left_padding_ = left >= 0 ? left : 0; if (view_layout_) { static_cast(view_layout_)->SetPadding(layout_top_padding_, layout_right_padding_, layout_bottom_padding_, layout_left_padding_); } ComputeContentSize(); QueueDraw(); } void Button::SetButtonClipRegion(int top_clip, int right_clip, int bottom_clip, int left_clip) { top_clip_ = top_clip >= 0 ? top_clip : 0; right_clip_ = right_clip >= 0 ? right_clip : 0; bottom_clip_ = bottom_clip >= 0 ? bottom_clip : 0; left_clip_ = left_clip >= 0 ? left_clip : 0; } void Button::BuildLayout(const std::string &str, TextureArea* image) { if (image_ != image) { if (image_) { image_->UnReference(); nuxAssert(image_->GetReferenceCount() == 1); image_ = NULL; } if (image) { image_ = new TextureArea(); image_->Reference(); // WARNING: GetPaintLayer returns a clone and SetPaintLayer makes a copy of the clone // UnReference temp otherwise it will be lost and cause a mem leak. AbstractPaintLayer *temp = image->GetPaintLayer(); image_->SetPaintLayer(temp); delete temp; SetImageMinimumSize(image->GetMinimumWidth(), image->GetMinimumHeight()); SetImageMaximumSize(image->GetMaximumWidth(), image->GetMaximumHeight()); } } bool create_new_text = false; if (static_text_ && (str != static_text_->GetText())) { create_new_text = true; } if ((static_text_ == NULL) && (str != "")) { create_new_text = true; } if (create_new_text) { if (static_text_) { static_text_->UnReference(); nuxAssert(static_text_->GetReferenceCount() == 1); static_text_ = NULL; } if (str != "") { label_ = str; static_text_ = new StaticText(str, NUX_TRACKER_LOCATION); static_text_->Reference(); static_text_->SetTextColor(label_color_); } } RemoveLayout(); LinearLayout *layout = NULL; if (static_text_ && image_) { if ((layout_type_ == HORIZONTAL) && (item_order_ == IMAGE_FIRST)) { layout = new HLayout(NUX_TRACKER_LOCATION); layout->AddView(image_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->AddView(static_text_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->SetHorizontalInternalMargin(space_between_items_); } else if ((layout_type_ == HORIZONTAL) && (item_order_ == LABEL_FIRST)) { layout = new HLayout(NUX_TRACKER_LOCATION); layout->AddView(static_text_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->AddView(image_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->SetHorizontalInternalMargin(space_between_items_); } else if ((layout_type_ == VERTICAL) && (item_order_ == IMAGE_FIRST)) { layout = new VLayout(NUX_TRACKER_LOCATION); layout->AddView(image_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->AddView(static_text_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->SetVerticalInternalMargin(space_between_items_); } else if ((layout_type_ == VERTICAL) && (item_order_ == LABEL_FIRST)) { layout = new VLayout(NUX_TRACKER_LOCATION); layout->AddView(static_text_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->AddView(image_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); layout->SetVerticalInternalMargin(space_between_items_); } // Both image_ and static_text_ have a reference count of 2. nuxAssert(image_->GetReferenceCount() == 2); nuxAssert(static_text_->GetReferenceCount() == 2); } else if (static_text_) { if (layout_type_ == HORIZONTAL) { layout = new HLayout(NUX_TRACKER_LOCATION); layout->AddView(static_text_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); } else if (layout_type_ == VERTICAL) { layout = new VLayout(NUX_TRACKER_LOCATION); layout->AddView(static_text_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); } nuxAssert(static_text_->GetReferenceCount() == 2); } else if (image_) { if (layout_type_ == HORIZONTAL) { layout = new HLayout(NUX_TRACKER_LOCATION); layout->AddView(image_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); } else if (layout_type_ == VERTICAL) { layout = new VLayout(NUX_TRACKER_LOCATION); layout->AddView(image_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); } nuxAssert(image_->GetReferenceCount() == 2); } if (static_text_) { static_text_->SetInputEventSensitivity(false); static_text_->SetTextPointSize(label_font_size_); } if (image_) { image_->SetInputEventSensitivity(false); } if (layout) { switch(distribution_) { case START_OF_LAYOUT: layout->SetContentDistribution(MAJOR_POSITION_LEFT); break; case END_OF_LAYOUT: layout->SetContentDistribution(MAJOR_POSITION_RIGHT); break; case CENTER_OF_LAYOUT: layout->SetContentDistribution(MAJOR_POSITION_CENTER); break; case SPREAD_OVER_LAYOUT: layout->SetContentDistribution(MAJOR_POSITION_SPREAD); break; } } if (layout) { layout->SetHorizontalInternalMargin(space_between_items_); layout->SetPadding(layout_top_padding_, layout_right_padding_, layout_bottom_padding_, layout_left_padding_); } if (layout) { SetLayout(layout); } ComputeContentSize(); QueueDraw(); } void Button::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); UXStyleImageRef ref_style = eIMAGE_STYLE_NONE; if (visual_state_ == VISUAL_STATE_PRESSED) { ref_style = eBUTTON_FOCUS; } else if (visual_state_ == VISUAL_STATE_PRELIGHT) { ref_style = eBUTTON_PRELIGHT; } else { ref_style = eBUTTON_NORMAL; } TexCoordXForm texxform; ROPConfig rop; rop.Blend = true; rop.SrcBlend = GL_ONE; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; GetPainter().PushDrawSliceScaledTextureLayer(graphics_engine, base, ref_style, color::White, eAllCorners, true, rop); if (GetCompositionLayout()) { GetPainter().PushPaintLayerStack(); { Geometry clip_geo = base; clip_geo.OffsetPosition(left_clip_, top_clip_); clip_geo.OffsetSize(-left_clip_ - right_clip_, -top_clip_ - bottom_clip_); graphics_engine.PushClippingRectangle(clip_geo); GetCompositionLayout()->ProcessDraw(graphics_engine, true); graphics_engine.PopClippingRectangle(); } GetPainter().PopPaintLayerStack(); } GetPainter().PopPaintLayer(); graphics_engine.PopClippingRectangle(); } long Button::ComputeContentSize() { return View::ComputeContentSize(); } void Button::Activate() { if (persistent_active_state_ == false) { return; } if (active_ == true) { // already active return; } active_ = true; state_change.emit(this); QueueDraw(); } void Button::Deactivate() { if (persistent_active_state_ == false) { return; } if (active_ == false) { // already deactivated return; } active_ = false; state_change.emit(this); QueueDraw(); } void Button::RecvClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (persistent_active_state_) { active_ = !active_; } click.emit(this); state_change.emit(this); QueueDraw(); } void Button::SetDistribution(Distribution distribution) { distribution_ = distribution; BuildLayout(label_, image_); } void Button::SetItemOrder(ItemOrder item_order) { item_order_ = item_order; BuildLayout(label_, image_); } void Button::SetLayoutType(LayoutType layout_type) { layout_type_ = layout_type; BuildLayout(label_, image_); } void Button::SetSpaceBetweenItems(int space_between_items) { space_between_items_ = (space_between_items >= 0) ? space_between_items : 0; if (view_layout_) { static_cast(view_layout_)->SetSpaceBetweenChildren(space_between_items_); } ComputeContentSize(); QueueDraw(); } void Button::SetLabelFontSize(int point) { AbstractButton::SetLabelFontSize(point); if (static_text_ == NULL) return; ComputeContentSize(); QueueDraw(); } } nux-4.0.6+14.04.20140409/Nux/SystemThread.h0000644000015301777760000000532512321344237020301 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef SYSTEMTHREAD_H #define SYSTEMTHREAD_H namespace nux { class WindowCompositor; class WindowThread; class SystemThread: public AbstractThread { NUX_DECLARE_OBJECT_TYPE(SystemThread, AbstractThread); public: SystemThread(AbstractThread *Parent = 0); ~SystemThread(); virtual ThreadState Start(void *arg); protected: virtual int Run(void *arg); virtual ThreadState StartChildThread(AbstractThread *thread, bool Modal); virtual void AddChildThread(AbstractThread *); virtual void RemoveChildThread(AbstractThread *); virtual void ChildHasFinished(AbstractThread *app); virtual void TerminateChildThreads(); // std::list m_ChildThread; // SystemThread* m_Parent; // ThreadUserInitFunc m_UserInitFunc; // ThreadUserExitFunc m_UserExitFunc; /*! Info: Constructor-like function. Will be called by EntryPoint before executing the thread body. Override this function to provide your extra initialization. NOTE: do not confuse it with the classes constructor */ virtual bool ThreadCtor(); /*! Info: Destructor-like function. Will be called by EntryPoint after executing the thread body. Override this function to provide your extra destruction. NOTE: do not confuse it with the classes constructor */ virtual bool ThreadDtor(); /*! This pointer maybe set by the user in ThreadInitFunc and reused in ThreadExitFunc */ private: SystemThread(const SystemThread &); // Does not make sense for a singleton. This is a self assignment. SystemThread &operator= (const SystemThread &); // Declare operator adress-of as private SystemThread *operator &(); std::string m_ThreadName; friend SystemThread *CreateSystemThread(AbstractThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData); friend class WindowThread; }; } #endif // SYSTEMTHREAD_H nux-4.0.6+14.04.20140409/Nux/HScrollBar.h0000644000015301777760000001101712321344237017653 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef HSCROLLBAR_H #define HSCROLLBAR_H #include "TimerProc.h" #include "ScrollBar.h" namespace nux { class HLayout; class HScrollBar : public ScrollBar { public: HScrollBar(NUX_FILE_LINE_PROTO); ~HScrollBar(); void DrawLeftTriangle(GraphicsEngine &graphics_engine, int width, int height, const Geometry &geo, BasePainter &painter); void DrawRightTriangle(GraphicsEngine &graphics_engine, int width, int height, const Geometry &geo, BasePainter &painter); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); private: virtual void DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) {}; void HScrollBarHandler(void *v); void ScrollRight(void *v); void ScrollLeft(void *v); void TrackLeft(void *v); void TrackRight(void *v); public: void SetContainerSize(int x, int y, int w, int h); void SetContentSize(int x, int y, int w, int h); void SetContentOffset(float dx, float dy); void ComputeScrolling(); ///////////////// // RECEIVERS // ///////////////// void SetValue(float value); void SetParameterName(const char *parameter_name); //////////////// // EMITTERS // //////////////// void RecvStartScrollRight(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvStartScrollLeft(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvEndScrollRight(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvEndScrollLeft(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTrackMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTrackMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTrackMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnSliderMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnSliderMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnSliderMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); /////////////// // SIGNALS // /////////////// sigc::signal sigClick; sigc::signal OnScrollLeft; sigc::signal OnScrollRight; sigc::signal sigHScrollBarSliderMouseDown; bool b_MouseDownTimer; bool b_MouseUpTimer; float m_color_factor; protected: // When the Scrollbar is used standalone, it is necessary to call ComputeScrolling at the end of the layout. virtual long PostLayoutManagement(long LayoutResult); virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); bool AtMinimum(); bool AtMaximum(); HLayout *hlayout; BasicView *_slider; BasicView *_scroll_left_button; BasicView *_scroll_right_button; BasicView *_track; int content_width_; int content_height_; float content_offset_x_; float content_offset_y_; int container_width_; int container_height_; int m_TrackWidth; int m_TrackHeight; int m_SlideBarOffsetX; int m_SlideBarOffsetY; float stepX; float stepY; int m_SliderDragPositionX; int m_SliderDragPositionY; TimerFunctor *callback; TimerFunctor *left_callback; TimerFunctor *right_callback; TimerFunctor *trackleft_callback; TimerFunctor *trackright_callback; TimerHandle m_LeftTimerHandler; TimerHandle m_RightTimerHandler; TimerHandle m_TrackLeftTimerHandler; TimerHandle m_TrackRightTimerHandler; Point m_TrackMouseCoord; friend class HLayout; friend class ScrollView; }; } #endif // HSCROLLBAR_H nux-4.0.6+14.04.20140409/Nux/BasicView.h0000644000015301777760000000206612321344237017540 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #ifndef BASIC_VIEW_H #define BASIC_VIEW_H namespace nux { //! A very basic View object with no rendering. class BasicView: public nux::View { NUX_DECLARE_OBJECT_TYPE(BasicView, View); public: BasicView(NUX_FILE_LINE_PROTO); ~BasicView(); protected: void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw); }; } #endif // BASIC_VIEW_H nux-4.0.6+14.04.20140409/Nux/Validator.cpp0000644000015301777760000000460012321344237020140 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Validator.h" namespace nux { Validator::Validator() { } Validator::~Validator() { } bool Validator::InitRegExp() { #if defined(NUX_OS_WINDOWS) regex_ = _regexp_str.c_str(); return true; #else const char *error; int erroffset; _regexp = pcre_compile( _regexp_str.c_str(), /* the pattern */ PCRE_MULTILINE, &error, /* for error message */ &erroffset, /* for error offset */ 0); /* use default character tables */ if (!_regexp) { nuxDebugMsg("[IntegerValidator::IntegerValidator] Invalid regular expression: %s", _regexp_str.c_str()); return false; } return true; #endif } Validator::State Validator::Validate(const char* str) const { #if defined(NUX_OS_WINDOWS) if (str == NULL) return Validator::Invalid; std::string search_string = str; if (std::regex_match(search_string.begin(), search_string.end(), regex_)) { return Validator::Acceptable; } return Validator::Acceptable; #else if (_regexp == 0) return Validator::Invalid; int out_vector [10]; unsigned int offset = 0; int len = (int) strlen(str); // See the "PCRE DISCUSSION OF STACK USAGE" and why it maybe necessary to limit the stack usage. pcre_extra extra; extra.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra.match_limit_recursion = 2000; int rc = pcre_exec(_regexp, &extra, str, len, offset, 0, out_vector, 10); if (rc <= -1) { return Validator::Invalid; } return Validator::Acceptable; #endif } } nux-4.0.6+14.04.20140409/Nux/Painter.h0000644000015301777760000005162712321344237017275 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef PAINTER_H #define PAINTER_H #include #include #include #include "Utils.h" #include "NuxGraphics/GraphicsEngine.h" #include "PaintLayer.h" namespace nux { class TextLineRenderer; class BaseTexture; class GeometryPositioning { public: GeometryPositioning(); GeometryPositioning( HorizontalAlignment horizontal_aligment, VerticalAlignment vertical_aligment, bool stretch_horizontal = FALSE, bool stretch_vertical = FALSE, int horizontal_margin = 0, int vertical_margin = 0); ~GeometryPositioning(); bool m_stretch_horizontal; // if TRUE, the content width will be stretched over the width of the container. bool m_stretch_vertical; // if TRUE, the content height will be stretched over the height of the container. void SetAlignment(HorizontalAlignment ha, VerticalAlignment va) { m_vertical_aligment = va; m_horizontal_aligment = ha; } VerticalAlignment m_vertical_aligment; HorizontalAlignment m_horizontal_aligment; int m_horizontal_margin; // Add a margin to the horizontal alignment int m_vertical_margin; // Add a margin to the vertical alignment }; //! Compute the position of one geometry inside an other. /*! Compute the position of one geometry inside an other. @container_geo The container geometry @content_geo The content geometry @GeometryPositioning The parameter to use to compute the position of the content. @return the computed geometry. */ Geometry ComputeGeometryPositioning(const Geometry &container_geo, const Geometry &content_geo, GeometryPositioning gctx); //! State of UI controls /* Class storing the states of User interface controls such button, radio, checkbox, combobox. */ class InteractState { public: /* Default constructor. All states are set to false. */ InteractState(); InteractState(bool on, bool focus, bool prelight, bool disable); ~InteractState(); bool is_on; bool is_focus; bool is_prelight; bool is_disable; }; // enum PainterBackgroundType // { // eColorBackground = 0, // eShapeBackground, // eShapeCornerBackground, // eTextureBackground, // }; class TextureAlignmentStyle { public: TextureAlignmentStyle() { horz_alignment = eTACenter; vert_alignment = eTACenter; horizontal_margin = 0; vertical_margin = 0; }; TextureAlignmentStyle(TextureAlignment horz_align, TextureAlignment vert_align) { horz_alignment = horz_align; vert_alignment = vert_align; horizontal_margin = 0; vertical_margin = 0; }; ~TextureAlignmentStyle() {}; enum TextureAlignment horz_alignment; enum TextureAlignment vert_alignment; int horizontal_margin; int vertical_margin; }; class BasePainter { public: BasePainter(WindowThread *window_thread); virtual ~BasePainter(); int intTest; //! Draw unscaled texture at position(x, y). The size of the quad is the size of the texture. virtual void Draw2DTexture(GraphicsEngine &graphics_engine, BaseTexture *Texture, int x, int y) const; virtual void Draw2DTextureAligned(GraphicsEngine &graphics_engine, BaseTexture *Texture, const Geometry &g, TextureAlignmentStyle tex_align) const; /////////////////// //////////////////// // TEXT PAINTING // //////////////////// virtual int PaintColorTextLineEdit(GraphicsEngine &graphics_engine, const Geometry &g, std::string const& Str, Color TextColor, bool WriteAlphaChannel, Color SelectedTextColor, Color SelectedTextBackgroundColor, Color TextBlinkColor, Color CursorColor, bool ShowCursor, unsigned int CursorPosition, int offset = 0, int selection_start = 0, int selection_end = 0) const; virtual int PaintTextLineStatic(GraphicsEngine &graphics_engine, ObjectPtr Font, Geometry const& g, std::string const& text_line, Color const& color = Color(0.0f, 0.0f, 0.0f, 1.0f), bool WriteAlphaChannel = true, TextAlignment alignment = eAlignTextLeft) const; void Paint2DQuadColor(GraphicsEngine &graphics_engine, const Geometry &g, const Color &c0) const; void Paint2DQuadColor(GraphicsEngine &graphics_engine, const Geometry &g, const Color &c0_top_left, const Color &c1_bottom_left, const Color &c2_bottom_right, const Color &c3_top_right) const; void Paint2DQuadColor(GraphicsEngine &graphics_engine, int x, int y, int width, int height, const Color &c0) const; void Paint2DQuadColor(GraphicsEngine &graphics_engine, int x, int y, int width, int height, const Color &c0_top_left, const Color &c1_bottom_left, const Color &c2_bottom_right, const Color &c3_top_right) const; //! Paint a 2D quad with a gradient color going from Top to Bottom. /*! Paint a 2D quad with a gradient color going from Top to Bottom. @param g Geometry of the quad. @param TopColor color at the top of the quad. @param TopColor color at the bottom of the quad. */ void Paint2DQuadVGradient(GraphicsEngine &graphics_engine, const Geometry &g, Color TopColor, Color BottomColor) const; //! Paint a 2D quad with a gradient color going from Left to Right. /*! Paint a 2D quad with a gradient color going from Left to Right. @param g Geometry of the quad. @param LeftColor color at the top of the quad. @param RightColor color at the bottom of the quad. */ void Paint2DQuadHGradient(GraphicsEngine &graphics_engine, const Geometry &g, Color LeftColor, Color RightColor) const; void Paint2DQuadWireframe(GraphicsEngine &graphics_engine, const Geometry &g, Color c0) const; void Paint2DQuadWireframe(GraphicsEngine &graphics_engine, const Geometry &g, Color c_top_left, Color c_bottom_left, Color c_bottom_right, Color c_top_right) const; void Paint2DQuadWireframe(GraphicsEngine &graphics_engine, int x, int y, int width, int height, Color c0) const; void Paint2DQuadWireframe(GraphicsEngine &graphics_engine, int x, int y, int width, int height, Color c_top_left, Color c_bottom_left, Color c_bottom_right, Color c_top_right) const; void Draw2DTriangleColor(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, int x2, int y2, Color c0); void Draw2DTriangleColor(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2); ////////////////////// // DRAW LINES // ////////////////////// void Draw2DLine(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, Color c0) const; void Draw2DLine(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, Color c0, Color c1) const; //////////////////// // Themes // //////////////////// void PaintShape(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, bool WriteAlpha = true) const; void PaintShapeCorner(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, long corners, bool WriteAlpha = true) const; void PaintShapeROP(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, bool WriteAlpha = true, const ROPConfig &ROP = ROPConfig::Default) const; void PaintShapeCornerROP(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, long corners, bool WriteAlpha = true, const ROPConfig &ROP = ROPConfig::Default) const; void PaintTextureShape(GraphicsEngine &graphics_engine, const Geometry &geo, UXStyleImageRef style) const; void PaintTextureShape(GraphicsEngine &graphics_engine, const Geometry &geo, BaseTexture *Texture, int border_left, int border_right, int border_top, int border_bottom, bool draw_borders_only, bool premultiply = true) const; //! Draw Check Box. /*! Draw a Check box. */ void PaintCheckBox(GraphicsEngine &graphics_engine, const Geometry &geo, const InteractState &interaction_state, Color check_mark_color = Color(0x0), Color check_box_color = Color(0x0)); void PaintRadioButton(GraphicsEngine &graphics_engine, const Geometry &geo, const InteractState &interaction_state, Color check_mark_color = Color(0x0), Color check_box_color = Color(0x0)); void PaintHorizontalGradientQuad(GraphicsEngine &graphics_engine, const Geometry &geo, int num_color, float *percentage_array, Color *color_array); public: void PushColorLayer(GraphicsEngine &graphics_engine, const Geometry &geo, Color color, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushShapeLayer(GraphicsEngine &graphics_engine, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners = eAllCorners, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushSliceScaledTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners = eAllCorners, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushColorizeTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha, const ROPConfig &ROP, const Color &blend_color, LayerBlendMode layer_blend_mode); void PushDrawColorLayer(GraphicsEngine &graphics_engine, const Geometry &geo, Color color, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushDrawShapeLayer(GraphicsEngine &graphics_engine, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners = eAllCorners, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushDrawSliceScaledTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners = eAllCorners, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushDrawTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default); void PushDrawColorizeTextureLayer(GraphicsEngine& graphics_engine, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha, const ROPConfig &ROP, const Color &blend_color, LayerBlendMode layer_blend_mode); void PushCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, ObjectPtr texture1, TexCoordXForm texxform1, const Color &color1, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP); void PushDrawCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, ObjectPtr texture1, TexCoordXForm texxform1, const Color &color1, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP); void PushCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, const Color& blend_color, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP); void PushDrawCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, const Color& blend_color, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP); void PushCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, const Color& base_color, ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP); void PushDrawCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, const Color& base_color, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP); void PushLayer(GraphicsEngine &graphics_engine, const Geometry &geo, AbstractPaintLayer *layer); void PushDrawLayer(GraphicsEngine &graphics_engine, const Geometry &geo, AbstractPaintLayer *layer); //! Render a paint layer. /*! When calling this function make sure to assign a correct geometry to the paint layer parameter. */ void RenderSinglePaintLayer(GraphicsEngine &graphics_engine, Geometry geo, AbstractPaintLayer *paint_layer); //! Deprecated. Use PopPaintLayer. void PopBackground(int level = 1); //! Pop the top most paint layers from the active paint layer stack. /*! Pop the top most paint layers from the active paint layer stack. @param level The number of layer to pop off. */ void PopPaintLayer(int level = 1); //! Deprecated. Use EmptyActivePaintLayerStack. void EmptyBackgroundStack(); //! Empty the active paint layer stack. /*! Empty the active paint layer stack. All paint layers in the active stack are deleted. */ void EmptyActivePaintLayerStack(); //! Deprecated. Use PaintActivePaintLayerStack. void PaintBackground(GraphicsEngine &graphics_engine, const Geometry &geo); //! Paint all the layers in the active paint layer stack. /*! Paint all the layers in the active paint layer stack. */ void PaintActivePaintLayerStack(GraphicsEngine &graphics_engine, const Geometry &geo); //! Paint all layers in all stacks /* Paint all layers in all stacks with the current model-view and projection matrices. This is useful for redirected rendering to textures. */ void PaintAllLayerStack(GraphicsEngine& graphics_engine, const Geometry& geo); //! Deprecated. Use PushPaintLayerStack. void PushBackgroundStack(); //! Push the current paint layer stack. /*! Push the current paint layer stack. */ void PushPaintLayerStack(); //! Deprecated. Use PopPaintLayerStack. void PopBackgroundStack(); //! Pop a previously pushed paint layer stack. /*! Pop a previously pushed paint layer stack. */ void PopPaintLayerStack(); private: //! Clear all the pushed paint layers. /*! Clear all the pushed paint layers. Each layer in a paint layer stack is deleted. */ void EmptyPushedPaintLayerStack(); std::list active_paint_layer_stack_; std::list > pushed_paint_layer_stack_; WindowThread *window_thread_; //!< The WindowThread to which this object belongs. }; class PushBackgroundScope { public: PushBackgroundScope(BasePainter &painter, GraphicsEngine &graphics_engine, const Geometry &geo, UXStyleImageRef image_style, bool PushAndDraw = false) : m_painter(painter) { if (PushAndDraw) m_painter.PushDrawShapeLayer(graphics_engine, geo, image_style, color::White, eAllCorners); else m_painter.PushShapeLayer(graphics_engine, geo, image_style, color::White, eAllCorners); } ~PushBackgroundScope() { //m_painter.PopBackground(); } private: BasePainter &m_painter; }; class PushShapeBackgroundScope { public: PushShapeBackgroundScope(BasePainter &painter, GraphicsEngine &graphics_engine, const Geometry &geo, UXStyleImageRef image_style, const Color &color, bool PushAndDraw = false, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default) : m_painter(painter) { if (PushAndDraw) m_painter.PushDrawShapeLayer(graphics_engine, geo, image_style, color, eAllCorners, WriteAlpha, ROP); else m_painter.PushShapeLayer(graphics_engine, geo, image_style, color, eAllCorners, WriteAlpha, ROP); } ~PushShapeBackgroundScope() { m_painter.PopBackground(); } private: BasePainter &m_painter; }; class PushShapeCornerBackgroundScope { public: PushShapeCornerBackgroundScope(BasePainter &painter, GraphicsEngine &graphics_engine, const Geometry &geo, UXStyleImageRef image_style, const Color &color, long corners, bool PushAndDraw = false, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default) : m_painter(painter) { if (PushAndDraw) m_painter.PushDrawShapeLayer(graphics_engine, geo, image_style, color, corners, WriteAlpha, ROP); else m_painter.PushShapeLayer(graphics_engine, geo, image_style, color, corners, WriteAlpha, ROP); } ~PushShapeCornerBackgroundScope() { m_painter.PopBackground(); } private: BasePainter &m_painter; }; class PushColorBackgroundScope { public: PushColorBackgroundScope(BasePainter &painter, GraphicsEngine &graphics_engine, const Geometry &geo, const Color &color, bool PushAndDraw = false, bool WriteAlpha = false, const ROPConfig &ROP = ROPConfig::Default) : m_painter(painter) { if (PushAndDraw) m_painter.PushDrawColorLayer(graphics_engine, geo, color, WriteAlpha, ROP); else m_painter.PushColorLayer(graphics_engine, geo, color, WriteAlpha, ROP); } ~PushColorBackgroundScope() { m_painter.PopBackground(); } private: BasePainter &m_painter; }; } #endif // PAINTER_H nux-4.0.6+14.04.20140409/Nux/GridVLayout.cpp0000644000015301777760000002732012321344237020430 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "View.h" #include "GridVLayout.h" #include "HLayout.h" #include "VLayout.h" namespace nux { static const int VERROR = 0; NUX_IMPLEMENT_OBJECT_TYPE(GridVLayout); GridVLayout::GridVLayout(NUX_FILE_LINE_DECL) : Layout(NUX_FILE_LINE_PARAM) { #if DEBUG_LAYOUT m_h_in_margin = 10; m_h_out_margin = 10; m_v_in_margin = 10; m_v_out_margin = 10; #endif _children_size = Size(64, 64); _force_children_size = true; _partial_visibility = true; _num_row = 1; _num_column = 1; _dynamic_column = true; _width_match_content = true; // Start packing the elements from the top. Is the layout has more space than the elements can use, // leave that space at the bottom of the GridVLayout. m_ContentStacking = eStackLeft; SetMinimumSize(32, 32); } GridVLayout::~GridVLayout() { } int GridVLayout::GetChildPos(Area *child) { int position = 0; std::list::const_iterator it; for (it = GetChildren().begin(); it != GetChildren().end(); it++) { if ((*it) == child) break; } return position; } Area* GridVLayout::GetChildAtPosition(int pos) { int position = 0; std::list::const_iterator it; for (it = GetChildren().begin(); it != GetChildren().end(); it++) { if (position == pos) return (*it); } return NULL; } void GridVLayout::EnablePartialVisibility(bool partial_visibility) { _partial_visibility = partial_visibility; } void GridVLayout::SetChildrenSize(int width, int height) { _children_size = Size(width, height); } Size GridVLayout::GetChildrenSize() const { return _children_size; } void GridVLayout::ForceChildrenSize(bool force) { _force_children_size = force; } int GridVLayout::GetNumColumn() const { return _num_column; } int GridVLayout::GetNumRow() const { return _num_row; } void GridVLayout::SetWidthMatchContent(bool match_content) { _width_match_content = match_content; } bool GridVLayout::GetWidthMatchContent() const { return _width_match_content; } void GridVLayout::GetCompositeList(std::list *ViewList) { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsView()) { View *ic = static_cast(*it); ViewList->push_back(ic); } else if ((*it)->IsLayout()) { Layout *layout = static_cast(*it); layout->GetCompositeList(ViewList); } } } long GridVLayout::ComputeContentSize() { std::list elements; if (GetScaleFactor() == 0) { ApplyMinHeight(); } if (_layout_element_list.size() == 0) { return eCompliantHeight | eCompliantWidth; } int num_elements = 0; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible()) { (*it)->SetLayoutDone(false); elements.push_back(*it); num_elements++; } } int original_width = GetBaseWidth(); nux::Geometry base = GetGeometry(); it = elements.begin(); int num_row = 0; int num_column = 0; if (num_elements > 0) ++num_column; if (_dynamic_column) { int X = base.x + m_h_out_margin; int Y = base.y + m_v_out_margin; bool first_element_of_column = true; for (int i = 0; i < num_elements; i++) { if (num_column == 1) num_row++; if (first_element_of_column) { first_element_of_column = false; } if (_force_children_size) { (*it)->SetMinimumSize(_children_size.width, _children_size.height); } (*it)->SetGeometry(nux::Geometry(X, Y, _children_size.width, _children_size.height)); (*it)->ComputeContentSize(); Y += _children_size.height + m_v_in_margin; it++; if ((!_partial_visibility) && (Y + _children_size.height > base.y + base.height - m_v_out_margin)) { X += _children_size.width + m_h_in_margin; Y = base.y + m_v_out_margin; first_element_of_column = true; if (i < num_elements - 1) ++num_column; } else if (Y >= base.y + base.height) { X += _children_size.width + m_h_in_margin; Y = base.y + m_v_out_margin; first_element_of_column = true; if (i < num_elements - 1) ++num_column; } } } _num_row = num_row; _num_column = num_column; if ((GetScaleFactor() == 0) || _width_match_content) { int w = num_column * _children_size.width + 2 * m_h_out_margin + (num_column - 1) * m_h_in_margin; SetMinimumWidth(w); SetBaseWidth(w); } long size_compliance = 0L; if (GetBaseWidth() > original_width + VERROR) { #if DEBUG_LAYOUT_COMPUTATION // The layout has been resized larger in WIDTH to tightly pack its content. // Or you can say that the layout refuse to be smaller than total WIDTH of its elements. std::cout << "ComputeContentSize: VLayout Width block at " << GetWidth() << std::endl; #endif size_compliance |= eLargerWidth; // need scrollbar } else if (GetBaseWidth() + VERROR < original_width) { #if DEBUG_LAYOUT_COMPUTATION // The layout is smaller. std::cout << "ComputeContentSize: VLayout Width smaller = " << GetWidth() << std::endl; #endif size_compliance |= eSmallerWidth; } else { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: VLayout Width compliant = " << GetWidth() << std::endl; #endif size_compliance |= eCompliantWidth; } { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: VLayout Height compliant = " << m_fittingHeight << std::endl; #endif size_compliance |= eCompliantHeight; } return size_compliance; } void GridVLayout::ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw) { std::list elements; std::list::iterator it = _layout_element_list.begin(); graphics_engine.PushModelViewMatrix(Get2DMatrix()); for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if ((*it)->IsVisible()) elements.push_back(*it); } it = elements.begin(); Geometry base = GetGeometry(); Geometry const& parent_geometry = GetToplevel() ? GetToplevel()->GetAbsoluteGeometry() : GetAbsoluteGeometry(); bool geometry_is_visible = parent_geometry.IsIntersecting(GetAbsoluteGeometry()); graphics_engine.PushClippingRectangle(base); for (int i = 0; i < _num_column; i++) { for (int j = 0; j < _num_row; j++) { if (it == elements.end()) break; // Test if the element is inside the Grid before rendering. if (geometry_is_visible) { int X = base.x + m_h_out_margin + i * (_children_size.width + m_h_in_margin); int Y = base.y + m_v_out_margin + j * (_children_size.height + m_v_in_margin); graphics_engine.PushClippingRectangle(Geometry(X, Y, _children_size.width, _children_size.height)); if ((*it)->IsView()) { View *ic = static_cast(*it); ic->ProcessDraw(graphics_engine, force_draw); } else if ((*it)->IsLayout()) { Layout *layout = static_cast(*it); layout->ProcessDraw(graphics_engine, force_draw); } graphics_engine.PopClippingRectangle(); } it++; } } graphics_engine.PopClippingRectangle(); graphics_engine.PopModelViewMatrix(); draw_cmd_queued_ = false; } Area* GridVLayout::KeyNavIteration(KeyNavDirection direction) { if (_layout_element_list.size() == 0) return NULL; if (IsVisible() == false) return NULL; if (next_object_to_key_focus_area_) { std::list::iterator it; std::list::iterator it_next; it = std::find(_layout_element_list.begin(), _layout_element_list.end(), next_object_to_key_focus_area_); it_next = it; ++it_next; if (it == _layout_element_list.end()) { // Should never happen nuxAssert(0); return NULL; } int position = GetChildPos(*it); // note that(*it) == next_object_to_key_focus_area_ int nun_column = GetNumColumn(); int nun_row = GetNumRow(); if ((direction == KEY_NAV_UP) && (it == _layout_element_list.begin())) { // first item return NULL; } if ((direction == KEY_NAV_DOWN) && (it_next == _layout_element_list.end())) { // last item return NULL; } if ((direction == KEY_NAV_UP) && ((position % nun_row) == 0)) { // Left edge return NULL; } if ((direction == KEY_NAV_DOWN) && (position == (position / nun_row) * nun_row + (nun_row -1))) { // right edge return NULL; } if ((direction == KEY_NAV_LEFT) && ((position / nun_row) == 0)) { // top edge return NULL; } if ((direction == KEY_NAV_RIGHT) && ((position / nun_row) == nun_column)) { // bottom edge return NULL; } ////// if (direction == KEY_NAV_UP) { --it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { int pos = GetChildPos(*it); if (it == _layout_element_list.begin() || ((pos % nun_row) == 0)) break; --it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_DOWN) { ++it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; int pos = GetChildPos(*it); if ((it == _layout_element_list.end()) || (pos == (pos / nun_row) * nun_row + (nun_row -1))) break; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_LEFT) { for (int i = 0; i < nun_row; ++i) { --it; } return (*it)->KeyNavIteration(direction); } if (direction == KEY_NAV_RIGHT) { for (int i = 0; i < nun_row; ++i) { ++it; if (it == _layout_element_list.end()) return NULL; } return (*it)->KeyNavIteration(direction); } } else { std::list::iterator it; it = _layout_element_list.begin(); return (*it)->KeyNavIteration(direction); } return NULL; } } nux-4.0.6+14.04.20140409/Nux/RadioButton.h0000644000015301777760000000627012321344237020117 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RADIO_BUTTON_H #define RADIO_BUTTON_H #include "AbstractCheckedButton.h" namespace nux { class HLayout; class InputArea; class StaticText; class RadioButtonGroup; //! RadioButton class /*! A RadioButton class. Work with the RadioButtonGroup to allow "one to many" selection.\n The RadioButton class cannot be vertically resized. It can only be resized horizontally. The vertical size is always match the size of the content (check area + label). */ class RadioButton: public AbstractCheckedButton { NUX_DECLARE_OBJECT_TYPE(RadioButton, AbstractCheckedButton); public: RadioButton(const std::string& str, bool state = false, NUX_FILE_LINE_PROTO); virtual ~RadioButton(); //! Emitted when the button is clicked. sigc::signal click; //! Emitted when the active state changes. /*! Emitted when the active state changes, as a result of a mouse click or an API call.\n \sa Activate, Deactivate. */ sigc::signal state_change; //! Activate the radio button. /*! Activate the radio button. If this radio button is part of a RadioButtonGroup, it will emit the signal state_change. */ virtual void Activate(); //! Deactivate the radio button. /*! Deactivate the radio button. */ virtual void Deactivate(); protected: virtual void Draw(GraphicsEngine& graphics_engine, bool force_draw); virtual void RecvClick(int x, int y, unsigned long button_flags, unsigned long key_flags); bool block_changed_signal_; void SetRadioButtonGroup(RadioButtonGroup* radio_button_group); ObjectWeakPtr GetRadioButtonGroup(); //! Intended for RadioButtonGroup only. void SetStatePrivate(bool state); //! Intended for RadioButtonGroup only. void SetStatePrivate(bool state, bool emit_signal); ObjectWeakPtr radio_button_group_; int radio_group_index_; private: //! Override of Area::SetMinimumHeight and made private. /*! Prevent changing the minimum height of the StaticText view. */ virtual void SetMinimumHeight(int h){}; //! Override of Area::SetMaximumHeight and made private. /*! Prevent changing the maximum height of the StaticText view. */ virtual void SetMaximumHeight(int h){}; friend class RadioButtonGroup; }; } #endif // RADIO_BUTTON_H nux-4.0.6+14.04.20140409/Nux/Makefile.am0000644000015301777760000002061612321344237017550 0ustar pbusernogroup00000000000000CLEANFILES = DISTCLEANFILES = EXTRA_DIST = lib_LTLIBRARIES = \ libnux-@NUX_API_VERSION@.la libnux_@NUX_API_VERSION@_la_CPPFLAGS= \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DPKGDATADIR=\""$(pkgdatadir)/@NUX_API_VERSION@"\" \ -DG_LOG_DOMAIN=\"Nux\" \ $(GCC_FLAGS) \ $(NUX_CFLAGS) \ $(IBUS_CFLAGS) \ $(GEIS_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(COVERAGE_CFLAGS) libnux_@NUX_API_VERSION@_la_LIBADD = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(top_builddir)/NuxGraphics/libnux-graphics-@NUX_API_VERSION@.la \ $(NUX_LIBS) \ $(IBUS_LIBS) \ $(GEIS_LIBS) libnux_@NUX_API_VERSION@_la_LDFLAGS = \ $(NUX_LT_LDFLAGS) \ $(COVERAGE_LDFLAGS) source_cpp = \ $(srcdir)/AbstractButton.cpp \ $(srcdir)/AbstractCheckedButton.cpp \ $(srcdir)/AbstractComboBox.cpp \ $(srcdir)/AbstractPaintLayer.cpp \ $(srcdir)/AbstractThread.cpp \ $(srcdir)/Area.cpp \ $(srcdir)/BaseWindow.cpp \ $(srcdir)/BasicView.cpp \ $(srcdir)/Button.cpp \ $(srcdir)/CairoWrapper.cpp \ $(srcdir)/Canvas.cpp \ $(srcdir)/CheckBox.cpp \ $(srcdir)/ClientArea.cpp \ $(srcdir)/Coverflow.cpp \ $(srcdir)/CoverflowItem.cpp \ $(srcdir)/CoverflowModel.cpp \ $(srcdir)/EMMetrics.cpp \ $(srcdir)/GridHLayout.cpp \ $(srcdir)/HLayout.cpp \ $(srcdir)/HSplitter.cpp \ $(srcdir)/InputArea.cpp \ $(srcdir)/KeyboardHandler.cpp \ $(srcdir)/KineticScrolling/AxisDecelerationAnimation.cpp \ $(srcdir)/KineticScrolling/KineticAxisScroller.cpp \ $(srcdir)/KineticScrolling/KineticScroller.cpp \ $(srcdir)/KineticScrolling/KineticScrollingTickSource.cpp \ $(srcdir)/KineticScrolling/VelocityCalculator.cpp \ $(srcdir)/KineticScrollView.cpp \ $(srcdir)/LayeredLayout.cpp \ $(srcdir)/Layout.cpp \ $(srcdir)/LinearLayout.cpp \ $(srcdir)/MainLoopGLib.cpp \ $(srcdir)/Nux.cpp \ $(srcdir)/NuxGlobalInitializer.cpp \ $(srcdir)/Painter.cpp \ $(srcdir)/PaintLayer.cpp \ $(srcdir)/StaticText.cpp \ $(srcdir)/StaticTextBox.cpp \ $(srcdir)/SystemThread.cpp \ $(srcdir)/TextEntry.cpp \ $(srcdir)/TextLoader.cpp \ $(srcdir)/TextureArea.cpp \ $(srcdir)/Theme.cpp \ $(srcdir)/TimerProc.cpp \ $(srcdir)/Utils.cpp \ $(srcdir)/VLayout.cpp \ $(srcdir)/View.cpp \ $(srcdir)/VSplitter.cpp \ $(srcdir)/WidgetMetrics.cpp \ $(srcdir)/WindowCompositor.cpp \ $(srcdir)/WindowThread.cpp if !NUX_MINIMAL source_cpp += \ $(srcdir)/ActionItem.cpp \ $(srcdir)/AnimatedTextureArea.cpp \ $(srcdir)/ColorEditor.cpp \ $(srcdir)/ColorPickerDialog.cpp \ $(srcdir)/ColorPreview.cpp \ $(srcdir)/Dialog.cpp \ $(srcdir)/DoubleValidator.cpp \ $(srcdir)/EditTextBox.cpp \ $(srcdir)/FileSelector.cpp \ $(srcdir)/FloatingWindow.cpp \ $(srcdir)/GroupBox.cpp \ $(srcdir)/GroupBox2.cpp \ $(srcdir)/HexRegExpValidator.cpp \ $(srcdir)/HScrollBar.cpp \ $(srcdir)/IntegerValidator.cpp \ $(srcdir)/MenuPage.cpp \ $(srcdir)/MenuBar.cpp \ $(srcdir)/MouseAreaCtrl.cpp \ $(srcdir)/NumericValuator.cpp \ $(srcdir)/Panel.cpp \ $(srcdir)/PopUpWindow.cpp \ $(srcdir)/InputAreaProximity.cpp \ $(srcdir)/RadioButton.cpp \ $(srcdir)/RadioButtonGroup.cpp \ $(srcdir)/RangeValue.cpp \ $(srcdir)/RangeValueInteger.cpp \ $(srcdir)/RGBValuator.cpp \ $(srcdir)/ScrollBar.cpp \ $(srcdir)/ScrollView.cpp \ $(srcdir)/SpinBox.cpp \ $(srcdir)/SpinBoxDouble.cpp \ $(srcdir)/SpinBox_Logic.cpp \ $(srcdir)/TabView.cpp \ $(srcdir)/Timeline.cpp \ $(srcdir)/TimelineEasings.cpp \ $(srcdir)/ToggleButton.cpp \ $(srcdir)/ToolButton.cpp \ $(srcdir)/Validator.cpp \ $(srcdir)/VScrollBar.cpp endif if USE_X11 source_cpp += \ $(srcdir)/InputMethodIBus.cpp \ $(srcdir)/XICClient.cpp \ $(srcdir)/XIMCallbacks.cpp \ $(srcdir)/XIMController.cpp endif if HAVE_GEIS source_cpp += \ $(srcdir)/GeisAdapter.cpp \ $(srcdir)/Gesture.cpp \ $(srcdir)/GestureBroker.cpp \ $(srcdir)/GesturesSubscription.cpp endif source_h = \ $(builddir)/Features.h \ $(srcdir)/AbstractButton.h \ $(srcdir)/AbstractCheckedButton.h \ $(srcdir)/AbstractComboBox.h \ $(srcdir)/AbstractPaintLayer.h \ $(srcdir)/AbstractThread.h \ $(srcdir)/Area.h \ $(srcdir)/BaseWindow.h \ $(srcdir)/BasicView.h \ $(srcdir)/Button.h \ $(srcdir)/CairoWrapper.h \ $(srcdir)/Canvas.h \ $(srcdir)/CheckBox.h \ $(srcdir)/ClientArea.h \ $(srcdir)/Coverflow.h \ $(srcdir)/CoverflowItem.h \ $(srcdir)/CoverflowModel.h \ $(srcdir)/EMMetrics.h \ $(srcdir)/GridHLayout.h \ $(srcdir)/HLayout.h \ $(srcdir)/HSplitter.h \ $(srcdir)/InputArea.h \ $(srcdir)/KeyboardHandler.h \ $(srcdir)/KineticScrolling/AxisDecelerationAnimation.h \ $(srcdir)/KineticScrolling/KineticAxisScroller.h \ $(srcdir)/KineticScrolling/KineticScroller.h \ $(srcdir)/KineticScrolling/KineticScrollingEnums.h \ $(srcdir)/KineticScrolling/KineticScrollingTickSource.h \ $(srcdir)/KineticScrolling/VelocityCalculator.h \ $(srcdir)/KineticScrollView.h \ $(srcdir)/LayeredLayout.h \ $(srcdir)/Layout.h \ $(srcdir)/LinearLayout.h \ $(srcdir)/MainLoopGLib.h \ $(srcdir)/Nux.h \ $(srcdir)/NuxGlobalInitializer.h \ $(srcdir)/Painter.h \ $(srcdir)/PaintLayer.h \ $(srcdir)/StaticText.h \ $(srcdir)/StaticTextBox.h \ $(srcdir)/SystemThread.h \ $(srcdir)/TextEntry.h \ $(srcdir)/TextLoader.h \ $(srcdir)/TextureArea.h \ $(srcdir)/Theme.h \ $(srcdir)/TimerProc.h \ $(srcdir)/Utils.h \ $(srcdir)/VLayout.h \ $(srcdir)/View.h \ $(srcdir)/VSplitter.h \ $(srcdir)/WidgetMetrics.h \ $(srcdir)/WindowCompositor.h \ $(srcdir)/WindowThread.h if !NUX_MINIMAL source_h += \ $(builddir)/ABI.h \ $(srcdir)/ActionItem.h \ $(srcdir)/AnimatedTextureArea.h \ $(srcdir)/ColorEditor.h \ $(srcdir)/ColorPickerDialog.h \ $(srcdir)/ColorPreview.h \ $(srcdir)/Dialog.h \ $(srcdir)/DoubleValidator.h \ $(srcdir)/EditTextBox.h \ $(srcdir)/FileSelector.h \ $(srcdir)/FloatingWindow.h \ $(srcdir)/GroupBox.h \ $(srcdir)/GroupBox2.h \ $(srcdir)/HexRegExpValidator.h \ $(srcdir)/HScrollBar.h \ $(srcdir)/IntegerValidator.h \ $(srcdir)/MenuPage.h \ $(srcdir)/MenuBar.h \ $(srcdir)/MouseAreaCtrl.h \ $(srcdir)/NumericValuator.h \ $(srcdir)/NuxTimerTickSource.h \ $(srcdir)/Panel.h \ $(srcdir)/PopUpWindow.h \ $(srcdir)/InputAreaProximity.h \ $(srcdir)/RadioButton.h \ $(srcdir)/RadioButtonGroup.h \ $(srcdir)/RangeValue.h \ $(srcdir)/RangeValueInteger.h \ $(srcdir)/Readme.txt \ $(srcdir)/RGBValuator.h \ $(srcdir)/ScrollBar.h \ $(srcdir)/ScrollView.h \ $(srcdir)/SpinBox.h \ $(srcdir)/SpinBoxDouble.h \ $(srcdir)/SpinBox_Logic.h \ $(srcdir)/TabView.h \ $(srcdir)/TextEntryComposeSeqs.h \ $(srcdir)/Timeline.h \ $(srcdir)/TimelineEasings.h \ $(srcdir)/ToolButton.h \ $(srcdir)/ToggleButton.h \ $(srcdir)/Validator.h \ $(srcdir)/VScrollBar.h endif if USE_X11 source_h += \ $(srcdir)/InputMethodIBus.h \ $(srcdir)/XICClient.h \ $(srcdir)/XIMController.h endif if HAVE_GEIS source_h += \ $(srcdir)/GeisAdapter.h \ $(srcdir)/Gesture.h \ $(srcdir)/GestureBroker.h \ $(srcdir)/GesturesSubscription.h endif nuxprogramframework_cpp = \ $(srcdir)/ProgramFramework/ProgramTemplate.cpp \ $(srcdir)/ProgramFramework/TestView.cpp \ $(srcdir)/ProgramFramework/TestTextEntry.cpp nuxprogramframework_h = \ $(srcdir)/ProgramFramework/ProgramTemplate.h \ $(srcdir)/ProgramFramework/TestView.h \ $(srcdir)/ProgramFramework/TestTextEntry.h libnux_@NUX_API_VERSION@_la_SOURCES = \ $(source_cpp) \ $(source_h) \ $(nuxprogramframework_cpp) \ $(nuxprogramframework_h) nuxdir = $(includedir)/Nux-@NUX_API_VERSION@/Nux nux_HEADERS = $(source_h) nuxprogramframeworkdir = $(includedir)/Nux-@NUX_API_VERSION@/Nux/ProgramFramework nuxprogramframework_HEADERS = $(nuxprogramframework_h) kineticscrolling_h = \ $(srcdir)/KineticScrolling/AxisDecelerationAnimation.h \ $(srcdir)/KineticScrolling/KineticAxisScroller.h \ $(srcdir)/KineticScrolling/KineticScroller.h \ $(srcdir)/KineticScrolling/KineticScrollingEnums.h \ $(srcdir)/KineticScrolling/KineticScrollingTickSource.h \ $(srcdir)/KineticScrolling/VelocityCalculator.h kineticscrollingdir = $(includedir)/Nux-@NUX_API_VERSION@/Nux/KineticScrolling kineticscrolling_HEADERS = $(kineticscrolling_h) # pkg-config file nux-@NUX_API_VERSION@.pc: nux.pc $(AM_V_GEN) cp -f nux.pc nux-@NUX_API_VERSION@.pc pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = nux-@NUX_API_VERSION@.pc CLEANFILES += nux-@NUX_API_VERSION@.pc DISTCLEANFILES += nux.pc EXTRA_DIST += nux.pc.in nux-4.0.6+14.04.20140409/Nux/Validator.h0000644000015301777760000000270312321344237017607 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef VALIDATOR_H #define VALIDATOR_H #if defined(NUX_OS_WINDOWS) #include #else #include #endif namespace nux { class Validator { public: enum State { Invalid = 0, Intermediate, Acceptable }; Validator(); virtual ~Validator(); virtual Validator *Clone() const = 0; //Virtual Constructor Idiom virtual Validator::State Validate(const char *str) const; virtual void Alternative(const char * /* str */) {} protected: bool InitRegExp(); std::string _regexp_str; #if defined(NUX_OS_WINDOWS) std::regex regex_; #else pcre *_regexp; #endif }; } #endif // VALIDATOR_H nux-4.0.6+14.04.20140409/Nux/Painter.cpp0000644000015301777760000012456312321344237017630 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "InputArea.h" #include "Painter.h" #include "NuxGraphics/GLTextureResourceManager.h" namespace nux { const unsigned int STENCIL_TEST_REF = 0xFF; const unsigned int STENCIL_TEST_MASK = 0xFFFFFFFF; const unsigned int STENCIL_CLEAR = 0x0; const float ALPHA_TEST_REF = 0.0f; GeometryPositioning::GeometryPositioning() { m_stretch_horizontal = true; m_stretch_vertical = true; m_vertical_aligment = eVACenter; m_horizontal_aligment = eHACenter; m_horizontal_margin = 0; m_vertical_margin = 0; } GeometryPositioning::GeometryPositioning( HorizontalAlignment /* horizontal_aligment */, VerticalAlignment /* vertical_aligment */, bool stretch_horizontal, bool stretch_vertical, int horizontal_margin, int vertical_margin) { m_stretch_horizontal = stretch_horizontal; m_stretch_vertical = stretch_vertical; m_vertical_aligment = eVACenter; m_horizontal_aligment = eHACenter; m_horizontal_margin = horizontal_margin; m_vertical_margin = vertical_margin; } GeometryPositioning::~GeometryPositioning() { } Geometry ComputeGeometryPositioning(const Geometry &container_geo, const Geometry &content_geo, GeometryPositioning gctx) { int x_pos, y_pos; int w, h; if (gctx.m_stretch_horizontal) { w = container_geo.GetWidth() - 2 * gctx.m_horizontal_margin; } else { w = content_geo.GetWidth(); } if (gctx.m_stretch_horizontal) { h = container_geo.GetHeight() - 2 * gctx.m_vertical_margin; } else { h = content_geo.GetHeight(); } if (gctx.m_horizontal_aligment == eHACenter) { int offset = (container_geo.GetWidth() - w) / 2.0f; //offset = (offset < 0) ? 0 : offset; x_pos = container_geo.x + offset; } else if (gctx.m_horizontal_aligment == eHALeft) { x_pos = container_geo.x + gctx.m_horizontal_margin; if (x_pos > container_geo.x + container_geo.GetWidth()) x_pos = container_geo.x; } else if (gctx.m_horizontal_aligment == eHARight) { x_pos = container_geo.x + container_geo.GetWidth() - w - gctx.m_horizontal_margin; if (x_pos < container_geo.x) x_pos = container_geo.x; } else { x_pos = container_geo.x + gctx.m_horizontal_margin; } if (gctx.m_vertical_aligment == eVACenter) { int offset = (container_geo.GetHeight() - h) / 2.0f; //offset = (offset < 0) ? 0 : offset; y_pos = container_geo.y + offset; } else if (gctx.m_vertical_aligment == eVATop) { y_pos = container_geo.y + gctx.m_vertical_margin; if (y_pos > container_geo.y + container_geo.GetHeight()) y_pos = container_geo.y; } else if (gctx.m_vertical_aligment == eVABottom) { y_pos = container_geo.y + container_geo.GetHeight() - h - gctx.m_vertical_margin; if (y_pos < container_geo.y) y_pos = container_geo.y; } else { y_pos = container_geo.y + gctx.m_vertical_margin; } return Geometry(x_pos, y_pos, w, h); } InteractState::InteractState() { is_on = false; is_focus = false; is_prelight = false; is_disable = false; } InteractState::InteractState(bool on, bool focus, bool prelight, bool disable) { is_on = on; is_focus = focus; is_prelight = prelight; is_disable = disable; } InteractState::~InteractState() { } BasePainter::BasePainter(WindowThread *window_thread) : window_thread_(window_thread) { } BasePainter::~BasePainter() { EmptyBackgroundStack(); } int BasePainter::PaintColorTextLineEdit(GraphicsEngine &graphics_engine, const Geometry &g, std::string const& Str, Color TextColor, bool WriteAlphaChannel, Color SelectedTextColor, Color SelectedTextBackgroundColor, Color TextBlinkColor, Color CursorColor, bool ShowCursor, unsigned int CursorPosition, int offset, int selection_start, int selection_end) const { PageBBox page; page.xmin = g.x; page.xmax = g.x + g.GetWidth(); page.ymin = g.y; page.ymax = g.y + g.GetHeight(); page.x_margin = DEFAULT_TEXT_X_MARGIN; page.y_margin = DEFAULT_TEXT_Y_MARGIN; return graphics_engine.RenderColorTextLineEdit(GetSysFont(), page, Str, TextColor, WriteAlphaChannel, SelectedTextColor, SelectedTextBackgroundColor, TextBlinkColor, CursorColor, ShowCursor, CursorPosition, offset, selection_start, selection_end); } int BasePainter::PaintTextLineStatic(GraphicsEngine &graphics_engine, ObjectPtr Font, Geometry const& g, std::string const& text_line, Color const& color, bool WriteAlphaChannel, TextAlignment alignment) const { PageBBox page; page.xmin = g.x; page.xmax = g.x + g.GetWidth(); page.ymin = g.y; page.ymax = g.y + g.GetHeight(); page.x_margin = DEFAULT_TEXT_X_MARGIN; page.y_margin = DEFAULT_TEXT_Y_MARGIN; return graphics_engine.RenderColorTextLineStatic(Font, page, text_line, color, WriteAlphaChannel, alignment); } void BasePainter::Draw2DTexture(GraphicsEngine &graphics_engine, BaseTexture *texture, int x, int y) const { float tex_w, tex_h; tex_w = (float) texture->GetWidth(); tex_h = (float) texture->GetHeight(); TexCoordXForm texxform; graphics_engine.QRP_1Tex(x, y, tex_w, tex_h, texture->GetDeviceTexture(), texxform, color::White); } void BasePainter::Draw2DTextureAligned(GraphicsEngine &graphics_engine, BaseTexture *texture, const Geometry &g, TextureAlignmentStyle tex_align) const { int x_pos, y_pos; int tex_w, tex_h; tex_w = (float) texture->GetWidth(); tex_h = (float) texture->GetHeight(); if (tex_align.horz_alignment == eTACenter) { int offset = (g.GetWidth() - tex_w) / 2.0f; offset = (offset < 0) ? 0 : offset; x_pos = g.x + offset; } else if (tex_align.horz_alignment == eTALeft) { x_pos = g.x + tex_align.horizontal_margin; } else if (tex_align.horz_alignment == eTARight) { x_pos = g.x + g.GetWidth() - tex_w - tex_align.horizontal_margin; } else { x_pos = g.x + tex_align.horizontal_margin; } if (tex_align.vert_alignment == eTACenter) { int offset = (g.GetHeight() - tex_h) / 2.0f; offset = (offset < 0) ? 0 : offset; y_pos = g.y + offset; } else if (tex_align.vert_alignment == eTATop) { y_pos = g.y + tex_align.vertical_margin; } else if (tex_align.vert_alignment == eTABottom) { y_pos = g.y + g.GetHeight() - tex_h - tex_align.vertical_margin; } else { y_pos = g.y + tex_align.vertical_margin; } PaintTextureShape(graphics_engine, Geometry(x_pos, y_pos, tex_w, tex_h), texture, 0, 0, 0, 0, 0); } /////////////////// // Draw QUADS // /////////////////// void BasePainter::Paint2DQuadColor(GraphicsEngine &graphics_engine, const Geometry &g, const Color &c0) const { graphics_engine.QRP_Color(g.x, g.y, g.GetWidth(), g.GetHeight(), c0); } void BasePainter::Paint2DQuadColor(GraphicsEngine &graphics_engine, const Geometry &g, const Color &c0_top_left, const Color &c1_bottom_left, const Color &c2_bottom_right, const Color &c3_top_right) const { graphics_engine.QRP_Color(g.x, g.y, g.GetWidth(), g.GetHeight(), c0_top_left, c1_bottom_left, c2_bottom_right, c3_top_right); } void BasePainter::Paint2DQuadColor(GraphicsEngine &graphics_engine, int x, int y, int width, int height, const Color &c0) const { graphics_engine.QRP_Color(x, y, width, height, c0); } void BasePainter::Paint2DQuadColor(GraphicsEngine &graphics_engine, int x, int y, int width, int height, const Color &c0_top_left, const Color &c1_bottom_left, const Color &c2_bottom_right, const Color &c3_top_right) const { graphics_engine.QRP_Color(x, y, width, height, c0_top_left, c1_bottom_left, c2_bottom_right, c3_top_right); } void BasePainter::Paint2DQuadVGradient(GraphicsEngine &graphics_engine, const Geometry &g, Color TopColor, Color BottomColor) const { Paint2DQuadColor(graphics_engine, g, TopColor, BottomColor, BottomColor, TopColor); } void BasePainter::Paint2DQuadHGradient(GraphicsEngine &graphics_engine, const Geometry &g, Color LeftColor, Color RightColor) const { Paint2DQuadColor(graphics_engine, g, LeftColor, LeftColor, RightColor, LeftColor); } ///////////////////////////// // Draw QUADS WIREFRAME // ///////////////////////////// void BasePainter::Paint2DQuadWireframe(GraphicsEngine &graphics_engine, const Geometry &g, Color c0) const { graphics_engine.QRP_QuadWireframe(g.x, g.y, g.GetWidth(), g.GetHeight(), c0, c0, c0, c0); } // void BasePainter::Paint2DQuadWireframe(GraphicsEngine& graphics_engine, const Geometry &g, Color c0_left, Color c1_right) const // { // graphics_engine.QRP_QuadWireframe(g.x, g.y, g.GetWidth(), g.GetHeight(), c0_left, c0_left, c1_right, c1_right); // } void BasePainter::Paint2DQuadWireframe(GraphicsEngine &graphics_engine, const Geometry &g, Color c_top_left, Color c_bottom_left, Color c_bottom_right, Color c_top_right) const { graphics_engine.QRP_QuadWireframe(g.x, g.y, g.GetWidth(), g.GetHeight(), c_top_left, c_bottom_left, c_bottom_right, c_top_right); } void BasePainter::Paint2DQuadWireframe(GraphicsEngine &graphics_engine, int x, int y, int width, int height, Color c0) const { graphics_engine.QRP_QuadWireframe(x, y, width, height, c0, c0, c0, c0); } // void BasePainter::Paint2DQuadWireframe(GraphicsEngine& graphics_engine, int x, int y, int width, int height, Color c0_left, Color c1_right) const // { // graphics_engine.QRP_QuadWireframe(x, y, width, height, c0_left, c0_left, c1_right, c1_right); // } void BasePainter::Paint2DQuadWireframe(GraphicsEngine &graphics_engine, int x, int y, int width, int height, Color c_top_left, Color c_bottom_left, Color c_bottom_right, Color c_top_right) const { graphics_engine.QRP_QuadWireframe(x, y, width, height, c_top_left, c_bottom_left, c_bottom_right, c_top_right); } ////////////////////// // Draw TRIANGLES // ////////////////////// void BasePainter::Draw2DTriangleColor(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, int x2, int y2, Color c0) { graphics_engine.QRP_Triangle(x0, y0, x1, y1, x2, y2, c0); } void BasePainter::Draw2DTriangleColor(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2) { graphics_engine.QRP_Triangle(x0, y0, x1, y1, x2, y2, c0, c1, c2); } ////////////////////// // DRAW LINES // ////////////////////// void BasePainter::Draw2DLine(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, Color c0) const { graphics_engine.QRP_Line(x0, y0, x1, y1, c0); } void BasePainter::Draw2DLine(GraphicsEngine &graphics_engine, int x0, int y0, int x1, int y1, Color c0, Color c1) const { graphics_engine.QRP_Line(x0, y0, x1, y1, c0, c1); } //////////////////// // Themes // //////////////////// void BasePainter::PaintShape(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, bool WriteAlpha) const { ROPConfig ROP; ROP.Blend = true; ROP.SrcBlend = GL_SRC_ALPHA; ROP.DstBlend = GL_ONE_MINUS_SRC_ALPHA; PaintShapeCornerROP(graphics_engine, geo, c0, style, eCornerTopLeft | eCornerTopRight | eCornerBottomLeft | eCornerBottomRight, WriteAlpha, ROP); } void BasePainter::PaintShapeCorner(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, long corners, bool WriteAlpha) const { ROPConfig ROP; ROP.Blend = true; ROP.SrcBlend = GL_SRC_ALPHA; ROP.DstBlend = GL_ONE_MINUS_SRC_ALPHA; PaintShapeCornerROP(graphics_engine, geo, c0, style, corners, WriteAlpha, ROP); } void BasePainter::PaintShapeROP(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, bool WriteAlpha, const ROPConfig &ROP) const { PaintShapeCornerROP(graphics_engine, geo, c0, style, eCornerTopLeft | eCornerTopRight | eCornerBottomLeft | eCornerBottomRight, WriteAlpha, ROP); } void BasePainter::PaintShapeCornerROP(GraphicsEngine &graphics_engine, const Geometry &geo, const Color &c0, UXStyleImageRef style, long corners, bool WriteAlpha, const ROPConfig &ROP) const { const PainterImage *pimage = GetTheme().GetImage(style); if (pimage == 0) return; BaseTexture *texture = pimage->texture; int border_left = pimage->border_left; int border_right = pimage->border_right; int border_top = pimage->border_top; int border_bottom = pimage->border_bottom; bool draw_borders_only = pimage->draw_borders_only; unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; unsigned int current_red_mask; unsigned int current_green_mask; unsigned int current_blue_mask; unsigned int current_alpha_mask; // Get the current color mask and blend states. They will be restored later. graphics_engine.GetRenderStates().GetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, WriteAlpha ? GL_TRUE : GL_FALSE); graphics_engine.GetRenderStates().SetBlend(ROP.Blend, ROP.SrcBlend, ROP.DstBlend); int tex_w = texture->GetWidth(); int tex_h = texture->GetHeight(); int r_x = geo.x; int r_y = geo.y; int r_w = geo.GetWidth(); int r_h = geo.GetHeight(); TexCoordXForm texxform; texxform.SetTexCoordType(TexCoordXForm::UNNORMALIZED_COORD); if (r_w < border_left + border_right) { // Do not apply this correction: just show the drawing as it is; //border_left = border_right = 0; } if (r_h < border_top + border_bottom) { // Do not apply this correction: just show the drawing as it is; //border_top = border_bottom = 0; } // Draw TOP-LEFT CORNER if (corners & eCornerTopLeft) { texxform.u0 = 0; texxform.v0 = 0; texxform.u1 = border_left; texxform.v1 = border_top; graphics_engine.QRP_ColorModTexAlpha(r_x, r_y, border_left, border_top, texture->GetDeviceTexture(), texxform, c0); } else { graphics_engine.QRP_Color(r_x, r_y, border_left, border_top, c0); } // Draw TOP-RIGHT CORNER if (corners & eCornerTopRight) { texxform.u0 = tex_w - border_right; texxform.v0 = 0; texxform.u1 = tex_w; texxform.v1 = border_top; graphics_engine.QRP_ColorModTexAlpha(r_x + r_w - border_right, r_y, border_right, border_top, texture->GetDeviceTexture(), texxform, c0); } else { graphics_engine.QRP_Color(r_x + r_w - border_right, r_y, border_right, border_top, c0); } // Draw BOTTOM-LEFT CORNER if (corners & eCornerBottomLeft) { texxform.u0 = 0; texxform.v0 = tex_h - border_bottom; texxform.u1 = border_left; texxform.v1 = tex_h; graphics_engine.QRP_ColorModTexAlpha(r_x, r_y + r_h - border_bottom, border_left, border_bottom, texture->GetDeviceTexture(), texxform, c0); } else { graphics_engine.QRP_Color(r_x, r_y + r_h - border_bottom, border_left, border_bottom, c0); } // Draw BOTTOM-RIGHT CORNER if (corners & eCornerBottomRight) { texxform.u0 = tex_w - border_right; texxform.v0 = tex_h - border_bottom; texxform.u1 = tex_w; texxform.v1 = tex_h; graphics_engine.QRP_ColorModTexAlpha(r_x + r_w - border_right, r_y + r_h - border_bottom, border_right, border_bottom, texture->GetDeviceTexture(), texxform, c0); } else { graphics_engine.QRP_Color(r_x + r_w - border_right, r_y + r_h - border_bottom, border_right, border_bottom, c0); } texxform.u0 = border_left; texxform.v0 = 0; texxform.u1 = tex_w - border_right; texxform.v1 = border_top; graphics_engine.QRP_ColorModTexAlpha(r_x + border_left, r_y, r_w - border_left - border_right, border_top, texture->GetDeviceTexture(), texxform, c0); // Draw BOTTOM BORDER texxform.u0 = border_left; texxform.v0 = tex_h - border_bottom; texxform.u1 = tex_w - border_right; texxform.v1 = tex_h; graphics_engine.QRP_ColorModTexAlpha(r_x + border_left, r_y + r_h - border_bottom, r_w - border_left - border_right, border_bottom, texture->GetDeviceTexture(), texxform, c0); // Draw LEFT BORDER texxform.u0 = 0; texxform.v0 = border_top; texxform.u1 = border_left; texxform.v1 = tex_h - border_bottom; graphics_engine.QRP_ColorModTexAlpha(r_x, r_y + border_top, border_left, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, c0); // Draw RIGHT BORDER texxform.u0 = tex_w - border_right; texxform.v0 = border_top; texxform.u1 = tex_w; texxform.v1 = tex_h - border_bottom; graphics_engine.QRP_ColorModTexAlpha(r_x + r_w - border_right, r_y + border_top, border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, c0); // Draw CENTER if (draw_borders_only == false) { texxform.u0 = border_left; texxform.v0 = border_top; texxform.u1 = tex_w - border_right; texxform.v1 = tex_h - border_bottom; graphics_engine.QRP_ColorModTexAlpha(r_x + border_left, r_y + border_top, r_w - border_left - border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, c0); } // Restore Color mask and blend states. graphics_engine.GetRenderStates().SetColorMask(current_red_mask, current_green_mask, current_blue_mask, current_alpha_mask); graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } void BasePainter::PaintTextureShape(GraphicsEngine &graphics_engine, const Geometry &geo, UXStyleImageRef style) const { const PainterImage *pimage = GetTheme().GetImage(style); if (pimage == 0) return; BaseTexture *texture = pimage->texture; int border_left = pimage->border_left; int border_right = pimage->border_right; int border_top = pimage->border_top; int border_bottom = pimage->border_bottom; bool draw_borders_only = pimage->draw_borders_only; PaintTextureShape(graphics_engine, geo, texture, border_left, border_right, border_top, border_bottom, draw_borders_only); } void BasePainter::PaintTextureShape(GraphicsEngine &graphics_engine, const Geometry &geo, BaseTexture *texture, int border_left, int border_right, int border_top, int border_bottom, bool draw_borders_only, bool premultiply) const { int tex_w = texture->GetWidth(); int tex_h = texture->GetHeight(); int r_x = geo.x; int r_y = geo.y; int r_w = geo.GetWidth(); int r_h = geo.GetHeight(); if (r_w < border_left + border_right) { border_left = border_right = 0; } if (r_h < border_top + border_bottom) { border_top = border_bottom = 0; } if (premultiply) graphics_engine.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); else graphics_engine.GetRenderStates().SetBlend(TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); TexCoordXForm texxform; texxform.SetTexCoordType(TexCoordXForm::UNNORMALIZED_COORD); // Draw TOP-LEFT CORNER texxform.u0 = 0; texxform.v0 = 0; texxform.u1 = border_left; texxform.v1 = border_top; graphics_engine.QRP_1Tex(r_x, r_y, border_left, border_top, texture->GetDeviceTexture(), texxform, color::White); // Draw TOP-RIGHT CORNER texxform.u0 = tex_w - border_right; texxform.v0 = 0; texxform.u1 = tex_w; texxform.v1 = border_top; graphics_engine.QRP_1Tex(r_x + r_w - border_right, r_y, border_right, border_top, texture->GetDeviceTexture(), texxform, color::White); // Draw BOTTOM-LEFT CORNER texxform.u0 = 0; texxform.v0 = tex_h - border_bottom; texxform.u1 = border_left; texxform.v1 = tex_h; graphics_engine.QRP_1Tex(r_x, r_y + r_h - border_bottom, border_left, border_bottom, texture->GetDeviceTexture(), texxform, color::White); // Draw BOTTOM-RIGHT CORNER texxform.u0 = tex_w - border_right; texxform.v0 = tex_h - border_bottom; texxform.u1 = tex_w; texxform.v1 = tex_h; graphics_engine.QRP_1Tex(r_x + r_w - border_right, r_y + r_h - border_bottom, border_right, border_bottom, texture->GetDeviceTexture(), texxform, color::White); // Draw TOP BORDER texxform.u0 = border_left; texxform.v0 = 0; texxform.u1 = tex_w - border_right; texxform.v1 = border_top; graphics_engine.QRP_1Tex(r_x + border_left, r_y, r_w - border_left - border_right, border_top, texture->GetDeviceTexture(), texxform, color::White); // Draw BOTTOM BORDER texxform.u0 = border_left; texxform.v0 = tex_h - border_bottom; texxform.u1 = tex_w - border_right; texxform.v1 = tex_h; graphics_engine.QRP_1Tex(r_x + border_left, r_y + r_h - border_bottom, r_w - border_left - border_right, border_bottom, texture->GetDeviceTexture(), texxform, color::White); // Draw LEFT BORDER texxform.u0 = 0; texxform.v0 = border_top; texxform.u1 = border_left; texxform.v1 = tex_h - border_bottom; graphics_engine.QRP_1Tex(r_x, r_y + border_top, border_left, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, color::White); // Draw RIGHT BORDER texxform.u0 = tex_w - border_right; texxform.v0 = border_top; texxform.u1 = tex_w; texxform.v1 = tex_h - border_bottom; graphics_engine.QRP_1Tex(r_x + r_w - border_right, r_y + border_top, border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, color::White); // Draw CENTER if (draw_borders_only == false) { texxform.u0 = border_left; texxform.v0 = border_top; texxform.u1 = tex_w - border_right; texxform.v1 = tex_h - border_bottom; graphics_engine.QRP_1Tex(r_x + border_left, r_y + border_top, r_w - border_left - border_right, r_h - border_top - border_bottom, texture->GetDeviceTexture(), texxform, color::White); } graphics_engine.GetRenderStates().SetBlend(FALSE); } void BasePainter::PaintHorizontalGradientQuad(GraphicsEngine &graphics_engine, const Geometry &geo, int array_size, float *percentage_array, Color *color_array) { for (int i = 0; i < array_size - 1; i++) { float p0 = percentage_array[i] / 100.0f; float p1 = percentage_array[i+1] / 100.0f; Paint2DQuadColor(graphics_engine, geo.x, geo.y + geo.GetHeight() * p0, geo.GetWidth(), geo.GetHeight() * p1 - geo.GetHeight() * p0, color_array[i], color_array[i], color_array[i+1], color_array[i+1]); } } void BasePainter::PaintCheckBox(GraphicsEngine &graphics_engine, const Geometry &geo, const InteractState &interaction_state, Color /* check_mark_color */, Color /* check_box_color */) { GeometryPositioning pctx(eHACenter, eVACenter); pctx.m_stretch_horizontal = false; pctx.m_stretch_vertical = false; const PainterImage *pimage = GetTheme().GetImage(eCHECKBOX_NORMAL_ON); if (pimage == 0) return; BaseTexture *texture = pimage->texture; Geometry content_geo(0, 0, texture->GetWidth(), texture->GetHeight()) ; content_geo = ComputeGeometryPositioning(geo, content_geo, pctx); graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (interaction_state.is_focus && interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eCHECKBOX_FOCUS_ON)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_focus && !interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eCHECKBOX_FOCUS_OFF)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_prelight && interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eCHECKBOX_PRELIGHT_ON)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_prelight && !interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eCHECKBOX_PRELIGHT_OFF)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eCHECKBOX_NORMAL_ON)->texture, content_geo.x, content_geo.y); } else { Draw2DTexture(graphics_engine, GetTheme().GetImage(eCHECKBOX_NORMAL_OFF)->texture, content_geo.x, content_geo.y); } graphics_engine.GetRenderStates().SetBlend(false); } void BasePainter::PaintRadioButton(GraphicsEngine &graphics_engine, const Geometry &geo, const InteractState &interaction_state, Color /* check_mark_color */, Color /* check_box_color */) { PaintBackground(graphics_engine, geo); GeometryPositioning pctx(eHACenter, eVACenter); pctx.m_stretch_horizontal = false; pctx.m_stretch_vertical = false; const PainterImage *pimage = GetTheme().GetImage(eRADIO_NORMAL_ON); if (pimage == 0) return; BaseTexture *texture = pimage->texture; Geometry content_geo(0, 0, texture->GetWidth(), texture->GetHeight()) ; content_geo = ComputeGeometryPositioning(geo, content_geo, pctx); graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (interaction_state.is_focus && interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eRADIO_FOCUS_ON)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_focus && !interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eRADIO_FOCUS_OFF)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_prelight && interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eRADIO_PRELIGHT_ON)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_prelight && !interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eRADIO_PRELIGHT_OFF)->texture, content_geo.x, content_geo.y); } else if (interaction_state.is_on) { Draw2DTexture(graphics_engine, GetTheme().GetImage(eRADIO_NORMAL_ON)->texture, content_geo.x, content_geo.y); } else { Draw2DTexture(graphics_engine, GetTheme().GetImage(eRADIO_NORMAL_OFF)->texture, content_geo.x, content_geo.y); } graphics_engine.GetRenderStates().SetBlend(false); } void BasePainter::PaintActivePaintLayerStack(GraphicsEngine &graphics_engine, const Geometry &geo) { if (active_paint_layer_stack_.empty()) { return; } std::list::const_reverse_iterator rev_it; bool clear_background = false; if (pushed_paint_layer_stack_.empty()) { // This is the first stack of layers. Clear the background clear_background = true; } for (rev_it = active_paint_layer_stack_.rbegin(); rev_it != active_paint_layer_stack_.rend(); rev_it++) { AbstractPaintLayer *layer = (*rev_it); Geometry layer_geo = layer->GetGeometry(); graphics_engine.PushClippingRectangle(geo); graphics_engine.SetModelViewMatrix(layer->GetModelViewMatrix()); if (clear_background) { Paint2DQuadColor(graphics_engine, layer_geo, Color(0x0)); clear_background = false; } RenderSinglePaintLayer(graphics_engine, layer_geo, layer); // restore the model view matrix stack and the clipping rectangle stack. graphics_engine.ApplyModelViewMatrix(); graphics_engine.PopClippingRectangle(); } } void BasePainter::PaintBackground(GraphicsEngine& graphics_engine, const Geometry& geo) { PaintActivePaintLayerStack(graphics_engine, geo); } void BasePainter::PaintAllLayerStack(GraphicsEngine& graphics_engine, const Geometry& geo) { std::list >::const_iterator stack_it; std::list::const_reverse_iterator rev_layer_it; bool clear_background = true; for (stack_it = pushed_paint_layer_stack_.begin(); stack_it != pushed_paint_layer_stack_.end(); stack_it++) { std::list stack = (*stack_it); for (rev_layer_it = stack.rbegin(); rev_layer_it != stack.rend(); rev_layer_it++) { AbstractPaintLayer* layer = (*rev_layer_it); Geometry layer_geo = layer->GetGeometry(); graphics_engine.PushClippingRectangle(geo); if (clear_background) { Paint2DQuadColor(graphics_engine, layer_geo, Color(0x0)); clear_background = false; } RenderSinglePaintLayer(graphics_engine, layer_geo, layer); graphics_engine.PopClippingRectangle(); } } } void BasePainter::RenderSinglePaintLayer(GraphicsEngine &graphics_engine, Geometry /* geo */, AbstractPaintLayer *paint_layer) { paint_layer->Renderlayer(graphics_engine); } void BasePainter::PushLayer(GraphicsEngine & /* graphics_engine */, const Geometry &geo, AbstractPaintLayer *layer) { AbstractPaintLayer *l = layer->Clone(); l->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); l->SetGeometry(geo); active_paint_layer_stack_.push_front(l); } void BasePainter::PushDrawLayer(GraphicsEngine &graphics_engine, const Geometry &geo, AbstractPaintLayer *layer) { PushLayer(graphics_engine, geo, layer); PaintBackground(graphics_engine, geo); } void BasePainter::PushColorLayer(GraphicsEngine & /* graphics_engine */, const Geometry &geo, Color color, bool WriteAlpha, const ROPConfig &ROP) { ColorLayer *cl = new ColorLayer(color, WriteAlpha, ROP); cl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); cl->SetGeometry(geo); active_paint_layer_stack_.push_front(cl); } void BasePainter::PushDrawColorLayer(GraphicsEngine &graphics_engine, const Geometry &geo, Color color, bool WriteAlpha, const ROPConfig &ROP) { PushColorLayer(graphics_engine, geo, color, WriteAlpha, ROP); PaintBackground(graphics_engine, geo); } void BasePainter::PushShapeLayer(GraphicsEngine & /* graphics_engine */, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners, bool WriteAlpha, const ROPConfig &ROP) { ShapeLayer *sl = new ShapeLayer(imageStyle, color, Corners, WriteAlpha, ROP); sl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); sl->SetGeometry(geo); active_paint_layer_stack_.push_front(sl); } void BasePainter::PushDrawShapeLayer(GraphicsEngine &graphics_engine, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners, bool WriteAlpha, const ROPConfig &ROP) { PushShapeLayer(graphics_engine, geo, imageStyle, color, Corners, WriteAlpha, ROP); PaintBackground(graphics_engine, geo); } void BasePainter::PushSliceScaledTextureLayer(GraphicsEngine & /* graphics_engine */, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners, bool WriteAlpha, const ROPConfig &ROP) { SliceScaledTextureLayer *sl = new SliceScaledTextureLayer(imageStyle, color, Corners, WriteAlpha, ROP); sl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); sl->SetGeometry(geo); active_paint_layer_stack_.push_front(sl); } void BasePainter::PushDrawSliceScaledTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, UXStyleImageRef imageStyle, const Color &color, unsigned long Corners, bool WriteAlpha, const ROPConfig &ROP) { PushSliceScaledTextureLayer(graphics_engine, geo, imageStyle, color, Corners, WriteAlpha, ROP); PaintBackground(graphics_engine, geo); } void BasePainter::PushTextureLayer(GraphicsEngine & /* graphics_engine */, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha, const ROPConfig &ROP) { TextureLayer *tl = new TextureLayer(DeviceTexture, texxform, color, WriteAlpha, ROP); tl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); tl->SetGeometry(geo); active_paint_layer_stack_.push_front(tl); } void BasePainter::PushCompositionLayer (GraphicsEngine & /* graphics_engine */, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, ObjectPtr texture1, TexCoordXForm texxform1, const Color &color1, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP) { CompositionLayer *cl = new CompositionLayer (texture0, texxform0, color0, texture1, texxform1, color1, layer_blend_mode, WriteAlpha, ROP); cl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); cl->SetGeometry(geo); active_paint_layer_stack_.push_front(cl); } void BasePainter::PushCompositionLayer (GraphicsEngine & /* graphics_engine */, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, const Color& blend_color, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP) { CompositionLayer *cl = new CompositionLayer (texture0, texxform0, color0, blend_color, layer_blend_mode, WriteAlpha, ROP); cl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); cl->SetGeometry(geo); active_paint_layer_stack_.push_front(cl); } void BasePainter::PushCompositionLayer (GraphicsEngine & /* graphics_engine */, Geometry geo, const Color& base_color, ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP) { CompositionLayer *cl = new CompositionLayer (base_color, texture0, texxform0, color0, layer_blend_mode, WriteAlpha, ROP); cl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); cl->SetGeometry(geo); active_paint_layer_stack_.push_front(cl); } void BasePainter::PushDrawCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, const Color& blend_color, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP) { PushCompositionLayer(graphics_engine, geo, texture0, texxform0, color0, blend_color, layer_blend_mode, WriteAlpha, ROP); PaintBackground(graphics_engine, geo); } void BasePainter::PushDrawCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, ObjectPtr texture1, TexCoordXForm texxform1, const Color &color1, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP) { PushCompositionLayer(graphics_engine, geo, texture0, texxform0, color0, texture1, texxform1, color1, layer_blend_mode, WriteAlpha, ROP); PaintBackground(graphics_engine, geo); } void BasePainter::PushDrawCompositionLayer (GraphicsEngine &graphics_engine, Geometry geo, const Color& base_color, ObjectPtr texture0, TexCoordXForm texxform0, const Color &color0, LayerBlendMode layer_blend_mode, bool WriteAlpha, const ROPConfig &ROP) { PushCompositionLayer(graphics_engine, geo, base_color, texture0, texxform0, color0, layer_blend_mode, WriteAlpha, ROP); } void BasePainter::PushColorizeTextureLayer(GraphicsEngine & /* graphics_engine */, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha, const ROPConfig &ROP, const Color &blend_color, LayerBlendMode layer_blend_mode) { TextureLayer *tl = new TextureLayer(DeviceTexture, texxform, color, WriteAlpha, ROP, blend_color, layer_blend_mode); tl->SetModelViewMatrix(window_thread_->GetGraphicsEngine().GetModelViewMatrix()); tl->SetGeometry(geo); active_paint_layer_stack_.push_front(tl); } void BasePainter::PushDrawTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha, const ROPConfig &ROP) { PushTextureLayer(graphics_engine, geo, DeviceTexture, texxform, color, WriteAlpha, ROP); PaintBackground(graphics_engine, geo); } void BasePainter::PushDrawColorizeTextureLayer(GraphicsEngine &graphics_engine, Geometry geo, ObjectPtr DeviceTexture, TexCoordXForm texxform, const Color &color, bool WriteAlpha, const ROPConfig &ROP, const Color &blend_color, LayerBlendMode layer_blend_mode) { PushColorizeTextureLayer(graphics_engine, geo, DeviceTexture, texxform, color, WriteAlpha, ROP, blend_color, layer_blend_mode); PaintBackground(graphics_engine, geo); } void BasePainter::PopBackground(int level) { PopPaintLayer(level); } void BasePainter::PopPaintLayer(int level) { nuxAssert(level >= 0); while ((level >= 1) && (!active_paint_layer_stack_.empty())) { AbstractPaintLayer *paint_layer = (*active_paint_layer_stack_.begin()); delete paint_layer; active_paint_layer_stack_.pop_front(); level--; } } void BasePainter::EmptyBackgroundStack() { EmptyActivePaintLayerStack(); } void BasePainter::EmptyActivePaintLayerStack() { std::list::iterator background_layer_it; for (background_layer_it = active_paint_layer_stack_.begin(); background_layer_it != active_paint_layer_stack_.end(); ++background_layer_it) { delete(*background_layer_it); } active_paint_layer_stack_.clear(); } void BasePainter::EmptyPushedPaintLayerStack() { std::list >::iterator pushed_paint_layer_it; for (pushed_paint_layer_it = pushed_paint_layer_stack_.begin(); pushed_paint_layer_it != pushed_paint_layer_stack_.end(); ++pushed_paint_layer_it) { std::list paint_layer_stack = *pushed_paint_layer_it; { std::list::iterator paint_layer_it; for (paint_layer_it = paint_layer_stack.begin(); paint_layer_it != paint_layer_stack.end(); ++paint_layer_it) { delete(*paint_layer_it); } paint_layer_stack.clear(); } } active_paint_layer_stack_.clear(); } void BasePainter::PushBackgroundStack() { PushPaintLayerStack(); } void BasePainter::PushPaintLayerStack() { pushed_paint_layer_stack_.push_back(active_paint_layer_stack_); active_paint_layer_stack_.clear(); } void BasePainter::PopBackgroundStack() { PopPaintLayerStack(); } void BasePainter::PopPaintLayerStack() { // clear and delete EmptyActivePaintLayerStack(); active_paint_layer_stack_ = pushed_paint_layer_stack_.back(); pushed_paint_layer_stack_.pop_back(); } } nux-4.0.6+14.04.20140409/Nux/AbstractPaintLayer.h0000644000015301777760000000330012321344237021410 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ABSTRACTPAINTLAYER_H #define ABSTRACTPAINTLAYER_H namespace nux { class AbstractPaintLayer { public: enum PaintLayerType { PaintLayer_Color, PaintLayer_Shape, PaintLayer_ShapeROP, PaintLayer_Texture, PaintLayer_DeviceTexture, PaintLayer_ImageStyle, }; AbstractPaintLayer(); virtual ~AbstractPaintLayer(); virtual AbstractPaintLayer *Clone() const = 0; //Virtual Constructor Idiom virtual void Renderlayer(GraphicsEngine &graphics_engine) = 0; virtual void SetGeometry(const Geometry &geo); //! Preserve the model view matrix at the moment layer is pushed on the paint layer stack. See Painter class. void SetModelViewMatrix(const Matrix4 &mat); Matrix4 GetModelViewMatrix(); Geometry const& GetGeometry() const; protected: Geometry geometry_; Matrix4 model_view_matrix_; }; } #endif // ABSTRACTPAINTLAYER_H nux-4.0.6+14.04.20140409/Nux/Button.h0000644000015301777760000002156312321344237017142 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef BUTTON_H #define BUTTON_H #include "AbstractButton.h" namespace nux { class HLayout; class VLayout; class TextureArea; class StaticText; // Deprecated // Image position with regard to the text enum Position { NUX_POSITION_LEFT, // image on left, text on the right NUX_POSITION_RIGHT, // text on the left, image on right NUX_POSITION_TOP, // image above text NUX_POSITION_BOTTOM // image below text }; //! A Button with styling(image + text) /*! The Button class has a non persistent active state. It returns to a normal state after a mouse click. For a Button is a persistent active state, use the ToggleButton class. This widget is also known as a PushButton. */ class Button: public AbstractButton { NUX_DECLARE_OBJECT_TYPE(Button, View); public: enum LayoutType { HORIZONTAL, VERTICAL, }; enum ItemOrder { IMAGE_FIRST, LABEL_FIRST, }; enum Distribution { START_OF_LAYOUT, END_OF_LAYOUT, CENTER_OF_LAYOUT, SPREAD_OVER_LAYOUT, }; Button(TextureArea *image, NUX_FILE_LINE_PROTO); Button(const std::string& button_label, NUX_FILE_LINE_PROTO); Button(const std::string& button_label, TextureArea *image, NUX_FILE_LINE_PROTO); Button(NUX_FILE_LINE_PROTO); virtual ~Button(); //! Emitted when the button is clicked. sigc::signal click; //! Emitted when the active state changes. /*! Emitted when the active state changes, as a result of a mouse click or an API call.\n \sa Activate, Deactivate. */ sigc::signal state_change; //! Set the label. /*! Set the label of this Button. If the \a label argument is an empty string, then the the Button label is destroyed, and the content of the Button is re-arranged accordingly. @param label The label of the Button. */ void SetLabel(const std::string &button_label); //!Return the label of this Button. /*! Return the label of this Button. @return The Button label string. */ std::string GetLabel() const; //! Set the image. /*! Set the image of this Button. If the \a image argument is NULL and this Button has an image, then the image is destroyed, and the content of the button is re-arranged accordingly.\n This Button make a copy of the \a image argument if it is not NULL. The source image should be destroyed after if it is no longer needed.\n The minimum and maximum size of the internal image are set to the minimum and maximum size of the \a image argument. \sa SetImageMinimumSize, SetImageMaximumSize. @param A TextureArea. */ void SetImage(TextureArea *image); //! Get the image. /*! Returns a new TextureArea with the same content as the internal TextureArea of this Button. The returned TextureArea has a floating reference.\n If the Button doesn't have an image, the function returns NULL. @return A TextureArea. */ TextureArea* GetImage(); //! Set the minimum size of the image in the Button. /*! Set the minimum size of the image in the Button.\n When setting an image into this Button with \a SetImage, the minimum size is set to the one of the \a image argument of \a SetImage. \sa SetImage. @param width Minimum width of the image. @param height Minimum height of the image. */ void SetImageMinimumSize(int width, int height); //! Set the maximum size of the image in the Button. /*! Set the maximum size of the image in the Button.\n When setting an image into this Button with \a SetImage, the maximum size is set to the one of the \a image argument of \a SetImage. \sa SetImage. @param width Maximum width of the image. @param height Maximum height of the image. */ void SetImageMaximumSize(int width, int height); //! Set the padding of the internal layout. /*! Set the padding of the internal layout.\n The default value is 2 for top, right, bottom and left padding. @param top Top padding. @param right Right padding. @param bottom Bottom padding. @param left Left padding. */ void SetLayoutPadding(int top, int right, int bottom, int left); //! Add a clipping rectangle inside the button. /*! Add an internal clipping rectangle inside the button. This will clip the rendering of anything inside the button. The default value is 2 for top, right, bottom and left clipping. @param top Top clipping. @param right Right clipping. @param bottom Bottom clipping. @param left Left clipping. */ void SetButtonClipRegion(int top_clip, int right_clip, int bottom_clip, int left_clip); //! Set the distribution of elements inside the layout. /*! Set how elements are distributed in the layout. The distribution takes effect only if the element don't use all the space available in the layout. In that case, they may be distributed toward the start, middle or end of the layout. @param distribution Distribution of elements inside the layout. */ void SetDistribution(Distribution distribution); //! Set the order of the image and label inside the layout. /*! Set the order of the image and label in the layout. Either the image comes first or the label. This is true in an horizontal or vertical layout configuration. @param item_order Order of the image and label inside the layout. */ void SetItemOrder(ItemOrder item_order); //! Set the layout type. /*! Set the layout type. With an horizontal layout type, the image and the label are arranged horizontally, while with a vertical layout type, they are arranged vertically. You may call SetItemOrder to choose if the image or the label come first in an horizontal(from left to right) or vertical(top to bottom) configuration. @param layout_type The layout type. */ void SetLayoutType(LayoutType layout_type); //! Set the space between the image and the label. /*! Set the space between the image and the label. @param space_between_items The space between the image and the label inside the layout. */ void SetSpaceBetweenItems(int space_between_items); //! Activate the button. /*! Activate the button. If this object is a Button, then it has no persistent state and the function does nothing. */ void Activate(); //! Deactivate the button. /*! Deactivate the button. If this object is a Button, then it has no persistent state and the function does nothing. */ void Deactivate(); virtual void SetLabelFontSize(int point); protected: LayoutType layout_type_; //!< The button layout type. ItemOrder item_order_; //!< Ordering of the text and image. Distribution distribution_; //!< Distribution of the image and text inside the Button layout. int space_between_items_; //!< Space between the Button image and text. bool persistent_active_state_; //!< The button's persistent state flag. int layout_left_padding_; int layout_right_padding_; int layout_top_padding_; int layout_bottom_padding_; int left_clip_; int right_clip_; int top_clip_; int bottom_clip_; bool SetLabelProperty(std::string &value, std::string const &str); void Initialize(const std::string &str, TextureArea* texture_area); void BuildLayout(const std::string &str, TextureArea* texture_area); TextureArea *image_; Size image_minimum_size_; Size image_maximum_size_; virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void RecvClick(int x, int y, unsigned long button_flags, unsigned long key_flags); // virtual void PreLayoutManagement(); // virtual long PostLayoutManagement(long LayoutResult); virtual long ComputeContentSize(); }; //typedef Button ToggleButton; } #endif // BUTTON_H nux-4.0.6+14.04.20140409/Nux/Coverflow.cpp0000755000015301777760000012610112321344237020165 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith * Jay Taoko */ #include "Nux.h" #include "HLayout.h" #include "StaticText.h" #include "TextLoader.h" #include "NuxGraphics/GraphicsDisplay.h" #include "NuxGraphics/GLShader.h" #include "NuxGraphics/GpuDevice.h" #include "NuxGraphics/GLDeviceObjects.h" #include "NuxGraphics/GLShader.h" #include "NuxGraphics/GraphicsEngine.h" #include "NuxGraphics/IOpenGLBaseTexture.h" #include #include "Coverflow.h" namespace nux { namespace { float EaseSin(float x) { return sin(x * nux::constants::pi / 2.0f); } float RoundFloor(float x) { return std::floor(x + 0.5f); } std::string texture_vertex_code = "attribute vec4 iVertex; \n\ attribute vec4 iTextureCoord0; \n\ attribute vec4 iVertexColor; \n\ uniform mat4 ViewProjectionMatrix; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * (iVertex); \n\ varyTexCoord0 = iTextureCoord0; \n\ varyVertexColor = iVertexColor; \n\ }"; std::string texture_fragment_code = "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ void main() \n\ { \n\ vec4 v = texture2D(TextureObject0, varyTexCoord0.xy); \n\ gl_FragColor = v*varyVertexColor; \n\ }"; std::string single_color_fragment_code = "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ void main() \n\ { \n\ gl_FragColor = varyVertexColor; \n\ }"; struct Vec4_ { float x; float y; float z; float rot; }; struct VelocityEvent { float velocity; gint64 time; }; struct Cover { Vec4_ position; float opacity; bool selected; bool mouse_over; CoverflowItem::Ptr item; }; typedef std::vector CoverList; } } namespace nux { struct Coverflow::Impl : public sigc::trackable { Impl(Coverflow* parent); ~Impl(); void HandleKeyDown(unsigned long eventType, unsigned long keysym, unsigned long state, const char* character, unsigned short keyCount); void HandleKeyUp(unsigned int keysym, unsigned long x11_key_code, unsigned long special_keys_state); void HandleMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void HandleMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void HandleMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); void HandleMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void HandleMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void HandleMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void HandleMouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void HandleMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags); void HandleGeometryChange(Area* area, Geometry geo); void DrawCover(nux::GraphicsEngine& graphics_engine, nux::DrawAreaContext &ctx, Cover const& cover); void RenderCover(nux::GraphicsEngine& graphics_engine, Cover const& cover, int width, int height, nux::Matrix4 combined_matrix); void LoadVertexBuffer(int VertexLocation, int TextureCoord0Location, int VertexColorLocation, float* VtxBuffer); CoverList GetCoverList(float animation_progress, gint64 timestep); void OnItemAdded(CoverflowModel* owner, CoverflowItem::Ptr new_item); void OnItemRemoved(CoverflowModel* owner, CoverflowItem::Ptr old_item); void OnSelectionChanged(CoverflowModel* owner, CoverflowItem::Ptr selection); void SetPosition(float position, bool animate); void UpdateModelSelection(); float GetCurrentVelocity(int ms); void MaybeQueueDraw(); bool CoverAtPoint(int x, int y, Cover& out_cover); void Get3DBoundingBox(float distance_from_camera, nux::Point2& top_left_corner, nux::Point2& bottom_right_corner); void GetCoverScreenCoord(Cover const& cover, nux::Vector4& P0, nux::Vector4& P1, nux::Vector4& P2, nux::Vector4& P3); bool TestMouseOverCover(int x, int y, Cover const& cover); bool TestCoverVisible(Cover const& cover); static gboolean OnAnimationTimeout(gpointer data); static gboolean OnVelocityTimeout(gpointer data); nux::Vector3 camera_position_; nux::Vector3 camera_rotation_; nux::ObjectPtr cover_shader_program_; nux::ObjectPtr highlight_shader_program_; nux::Matrix4 perspective_; nux::Matrix4 modelview_; std::vector velocity_events_; Coverflow* parent_; guint animation_handle_; float camera_drift_factor_; gint64 last_draw_time_; float last_position_; bool mouse_inside_view_; float position_; gint64 position_set_time_; float saved_position_; float velocity_; guint velocity_handle_; nux::Point2 mouse_down_position_; nux::Point2 mouse_position_; CoverList last_covers_; float cover_width_in_3d_space_; float near_clip_plan_; float far_clip_plan_; TextLoader text_loader_; ObjectPtr drop_shadow_texture_; sigc::connection model_selection_connection_; }; Coverflow::Impl::Impl(Coverflow* parent) : parent_(parent) , animation_handle_(0) , camera_drift_factor_(0) , last_draw_time_(0) , last_position_(0) , mouse_inside_view_(false) , position_(0) , position_set_time_(0) , saved_position_(0) , velocity_(0) , velocity_handle_(0) , cover_width_in_3d_space_(1.0f) , near_clip_plan_(1.0f) , far_clip_plan_(200.0f) { mouse_position_ = nux::Point2(0, 0); parent_->key_down.connect(sigc::mem_fun(this, &Impl::HandleKeyDown)); parent_->key_up.connect(sigc::mem_fun(this, &Impl::HandleKeyUp)); parent_->mouse_move.connect(sigc::mem_fun(this, &Impl::HandleMouseMove)); parent_->mouse_enter.connect(sigc::mem_fun(this, &Impl::HandleMouseEnter)); parent_->mouse_leave.connect(sigc::mem_fun(this, &Impl::HandleMouseLeave)); parent_->mouse_click.connect(sigc::mem_fun(this, &Impl::HandleMouseClick)); parent_->mouse_drag.connect(sigc::mem_fun(this, &Impl::HandleMouseDrag)); parent_->mouse_up.connect(sigc::mem_fun(this, &Impl::HandleMouseUp)); parent_->mouse_down.connect(sigc::mem_fun(this, &Impl::HandleMouseDown)); parent_->mouse_wheel.connect(sigc::mem_fun(this, &Impl::HandleMouseWheel)); parent_->geometry_changed.connect(sigc::mem_fun(this, &Impl::HandleGeometryChange)); camera_position_.x = 0.0f; camera_position_.y = 0.0f; camera_position_.z = 5.0f; camera_rotation_.x = 0.0f; camera_rotation_.y = 0.0f; camera_rotation_.z = 0.0f; // Create a shader to render a textured quad. { // Create the GLSL shader objects: Vertex, Fragment and the Program. // The Program object act as a container for the Vertex and Fragment object. nux::ObjectPtr fragment_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); nux::ObjectPtr vertex_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); cover_shader_program_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); // Set the actual shader code into the Vertex and Fragment objects. vertex_shader_prog_->SetShaderCode(texture_vertex_code.c_str()); fragment_shader_prog_->SetShaderCode(texture_fragment_code.c_str()); // Remove all Vertex and Fragment objects from the Program (Not necessary here but do it anyway). cover_shader_program_->ClearShaderObjects(); // Add the Vertex and Fragment objects to the Program object. cover_shader_program_->AddShaderObject(vertex_shader_prog_); cover_shader_program_->AddShaderObject(fragment_shader_prog_); // Link cover_shader_program_->Link(); // The shaders have been loaded into the program. They can be discarded. vertex_shader_prog_.Release(); fragment_shader_prog_.Release(); } // Create a shader to render a the cover highlight. { // Create the GLSL shader objects: Vertex, Fragment and the Program. // The Program object act as a container for the Vertex and Fragment object. nux::ObjectPtr fragment_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); nux::ObjectPtr vertex_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); highlight_shader_program_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); // Set the actual shader code into the Vertex and Fragment objects. vertex_shader_prog_->SetShaderCode(texture_vertex_code.c_str()); fragment_shader_prog_->SetShaderCode(single_color_fragment_code.c_str()); // Remove all Vertex and Fragment objects from the Program (Not necessary here but do it anyway). highlight_shader_program_->ClearShaderObjects(); // Add the Vertex and Fragment objects to the Program object. highlight_shader_program_->AddShaderObject(vertex_shader_prog_); highlight_shader_program_->AddShaderObject(fragment_shader_prog_); // Link highlight_shader_program_->Link(); // The shaders have been loaded into the program. They can be discarded. vertex_shader_prog_.Release(); fragment_shader_prog_.Release(); } text_loader_.font_size = 10; std::string resource_path = NUX_FIND_RESOURCE_LOCATION_NOFAIL("UITextures/coverflow.oval-shadow.png"); BaseTexture* texture = LoadTextureFromFile(resource_path.c_str()); drop_shadow_texture_ = texture->GetDeviceTexture(); texture->UnReference(); text_loader_.lines = 2; } Coverflow::Impl::~Impl() { if (animation_handle_) { g_source_remove(animation_handle_); animation_handle_ = 0; } } void Coverflow::Impl::UpdateModelSelection() { model_selection_connection_.disconnect(); parent_->model()->SetSelection((size_t)RoundFloor(position_)); model_selection_connection_ = parent_->model()->selection_changed.connect(sigc::mem_fun(this, &Coverflow::Impl::OnSelectionChanged)); } void Coverflow::Impl::Get3DBoundingBox(float distance_from_camera, nux::Point2& top_left_corner, nux::Point2& bottom_right_corner) { int width = parent_->GetBaseWidth(); int height = parent_->GetBaseHeight(); top_left_corner.y = std::tan(DEGTORAD(parent_->fov() * 0.5f)) * distance_from_camera; top_left_corner.x = -top_left_corner.y * (width / (float)height); bottom_right_corner.x = -top_left_corner.x; bottom_right_corner.y = -top_left_corner.y; } void Coverflow::Impl::GetCoverScreenCoord(Cover const& cover, nux::Vector4& out_p0, nux::Vector4& out_p1, nux::Vector4& out_p2, nux::Vector4& out_p3) { if (cover.item->GetTexture().IsNull()) return; int width = parent_->GetBaseWidth(); int height = parent_->GetBaseHeight(); ObjectPtr texture = cover.item->GetTexture()->GetDeviceTexture(); float ratio = texture->GetWidth()/(float)texture->GetHeight(); float fx = cover_width_in_3d_space_/2.0f; float fy_top = cover.position.y + (cover_width_in_3d_space_) * (1.0f/ratio); float fy_bot = cover.position.y; if (parent_->true_perspective) { modelview_ = nux::Matrix4::TRANSLATE(-camera_position_.x, -camera_position_.y, -camera_position_.z) * nux::Matrix4::ROTATEX(DEGTORAD(-camera_rotation_.x)) * nux::Matrix4::ROTATEY(DEGTORAD(-camera_rotation_.y)) * nux::Matrix4::ROTATEZ(DEGTORAD(-camera_rotation_.z)) * nux::Matrix4::TRANSLATE(cover.position.x, 0.0f, cover.position.z); } else { modelview_ = nux::Matrix4::TRANSLATE(-camera_position_.x, -camera_position_.y, -camera_position_.z) * nux::Matrix4::ROTATEX(DEGTORAD(-camera_rotation_.x)) * nux::Matrix4::ROTATEY(DEGTORAD(-camera_rotation_.y)) * nux::Matrix4::ROTATEZ(DEGTORAD(-camera_rotation_.z)) * nux::Matrix4::TRANSLATE(0.0f, 0.0f, cover.position.z); } nux::Matrix4 m = nux::Matrix4::ROTATEY(DEGTORAD(cover.position.rot)); nux::Matrix4 combined_matrix = perspective_ * modelview_ * m; nux::Vector4 p0(-fx, fy_top, 0.0f, 1.0f); nux::Vector4 p1(-fx, fy_bot, 0.0f, 1.0f); nux::Vector4 p2(fx, fy_bot, 0.0f, 1.0f); nux::Vector4 p3(fx, fy_top, 0.0f, 1.0f); nux::Vector4 p0_proj = combined_matrix * p0; nux::Vector4 p1_proj = combined_matrix * p1; nux::Vector4 p2_proj = combined_matrix * p2; nux::Vector4 p3_proj = combined_matrix * p3; p0_proj.x = p0_proj.x/p0_proj.w; p0_proj.y = p0_proj.y/p0_proj.w; p0_proj.z = p0_proj.z/p0_proj.w; p1_proj.x = p1_proj.x/p1_proj.w; p1_proj.y = p1_proj.y/p1_proj.w; p1_proj.z = p1_proj.z/p1_proj.w; p2_proj.x = p2_proj.x/p2_proj.w; p2_proj.y = p2_proj.y/p2_proj.w; p2_proj.z = p2_proj.z/p2_proj.w; p3_proj.x = p3_proj.x/p3_proj.w; p3_proj.y = p3_proj.y/p3_proj.w; p3_proj.z = p3_proj.z/p3_proj.w; p0_proj.x = width * (p0_proj.x + 1.0f)/2.0f; p1_proj.x = width * (p1_proj.x + 1.0f)/2.0f; p2_proj.x = width * (p2_proj.x + 1.0f)/2.0f; p3_proj.x = width * (p3_proj.x + 1.0f)/2.0f; p0_proj.y = -height * (p0_proj.y - 1.0f)/2.0f; p1_proj.y = -height * (p1_proj.y - 1.0f)/2.0f; p2_proj.y = -height * (p2_proj.y - 1.0f)/2.0f; p3_proj.y = -height * (p3_proj.y - 1.0f)/2.0f; float scalar = 0.0f; if (!parent_->true_perspective) { nux::Point2 top_left, bottom_right; Get3DBoundingBox(camera_position_.z, top_left, bottom_right); scalar = parent_->GetGeometry().width / (bottom_right.x - top_left.x); } out_p0.x = p0_proj.x + cover.position.x * scalar; out_p0.y = p0_proj.y; out_p1.x = p1_proj.x + cover.position.x * scalar; out_p1.y = p1_proj.y; out_p2.x = p2_proj.x + cover.position.x * scalar; out_p2.y = p2_proj.y; out_p3.x = p3_proj.x + cover.position.x * scalar; out_p3.y = p3_proj.y; } bool Coverflow::Impl::TestMouseOverCover(int x, int y, Cover const& cover) { nux::Vector4 P0; nux::Vector4 P1; nux::Vector4 P2; nux::Vector4 P3; GetCoverScreenCoord(cover, P0, P1, P2, P3); // The polygon is convex and P0->P1->P2->P3 follows the right hand rule bool test01 = ((y - P0.y) * (P1.x - P0.x) - (x - P0.x) * (P1.y - P0.y)) <= 0.0f; bool test12 = ((y - P1.y) * (P2.x - P1.x) - (x - P1.x) * (P2.y - P1.y)) <= 0.0f; bool test23 = ((y - P2.y) * (P3.x - P2.x) - (x - P2.x) * (P3.y - P2.y)) <= 0.0f; bool test30 = ((y - P3.y) * (P0.x - P3.x) - (x - P3.x) * (P0.y - P3.y)) <= 0.0f; if (test01 && test12 && test23 && test30) { return true; } return false; } bool Coverflow::Impl::TestCoverVisible(Cover const& cover) { int width = parent_->GetBaseWidth(); int height = parent_->GetBaseHeight(); nux::Vector4 P0; nux::Vector4 P1; nux::Vector4 P2; nux::Vector4 P3; GetCoverScreenCoord(cover, P0, P1, P2, P3); bool test0 = ((P0.x >= 0) && (P0.x < width)) && ((P0.y >= 0) && (P0.y < height)); bool test1 = ((P1.x >= 0) && (P1.x < width)) && ((P1.y >= 0) && (P1.y < height)); bool test2 = ((P2.x >= 0) && (P2.x < width)) && ((P2.y >= 0) && (P2.y < height)); bool test3 = ((P3.x >= 0) && (P3.x < width)) && ((P3.y >= 0) && (P3.y < height)); if (test0 || test1 || test2 || test3) { // The quad is convex. If any of its vertices is inside the view, then the quad is visible. return true; } return false; } bool Coverflow::Impl::CoverAtPoint(int /* x */, int /* y */, Cover& out_cover) { Cover best; CoverList::iterator it; for (it = last_covers_.begin(); it != last_covers_.end(); ++it) { Cover cover = *it; if (cover.item->GetTexture().IsNull()) continue; if (cover.position.rot > 0 && TestMouseOverCover(mouse_position_.x, mouse_position_.y, cover)) { best = cover; } } CoverList::reverse_iterator rit; for (rit = last_covers_.rbegin(); rit != last_covers_.rend(); ++rit) { Cover cover = *rit; if (cover.item->GetTexture().IsNull()) continue; if (cover.position.rot <= 0 && TestMouseOverCover(mouse_position_.x, mouse_position_.y, cover)) { best = cover; } } if (best.item) { out_cover = best; return true; } return false; } void Coverflow::Impl::HandleKeyDown(unsigned long /* eventType */ , /*event type*/ unsigned long keysym , /*event keysym*/ unsigned long /* state */ , /*event state*/ const char* /* character */ , /*character*/ unsigned short /* keyCount */ /*key repeat count*/) { switch (keysym) { case NUX_VK_LEFT: parent_->model()->SelectPrev(); break; case NUX_VK_RIGHT: parent_->model()->SelectNext(); break; } } void Coverflow::Impl::HandleMouseClick(int x, int y, unsigned long button_flags, unsigned long /* key_flags */) { if (std::abs(mouse_down_position_.x - x) > 10 || std::abs(mouse_down_position_.y - y) > 10) return; Cover best; if (CoverAtPoint(x, y, best)) { if (abs(best.position.rot) <= .001) { best.item->Activate(nux::GetEventButton(button_flags)); } else { SetPosition((float)parent_->model()->IndexOf(best.item), true); UpdateModelSelection(); } } } void Coverflow::Impl::HandleKeyUp(unsigned int keysym, unsigned long /* x11_key_code */, unsigned long /* special_keys_state */) { switch (keysym) { case NUX_VK_ENTER: case NUX_KP_ENTER: { Cover best; if (CoverAtPoint(0, 0, best)) best.item->Activate(1); break; } default: break; } } void Coverflow::Impl::HandleMouseMove(int x, int y, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { mouse_position_.x = x; mouse_position_.y = y; MaybeQueueDraw(); } void Coverflow::Impl::HandleMouseEnter(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { mouse_position_.x = x; mouse_position_.y = y; mouse_inside_view_ = true; MaybeQueueDraw(); } void Coverflow::Impl::HandleMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { mouse_position_.x = 0xFFFFFFFF; mouse_position_.y = 0xFFFFFFFF; mouse_inside_view_ = false; MaybeQueueDraw(); } void Coverflow::Impl::HandleMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { velocity_ = 0; // stop an current velocity based animations mouse_down_position_.x = x; mouse_down_position_.y = y; MaybeQueueDraw(); } bool TooOld (VelocityEvent event) { gint64 current_time = g_get_monotonic_time(); int ms = (current_time - event.time) / 1000; return ms > 1000; } float Coverflow::Impl::GetCurrentVelocity(int cutoff_ms) { gint64 current_time = g_get_monotonic_time(); float result = 0.0f; std::vector::iterator it; for (it = velocity_events_.begin(); it != velocity_events_.end(); ++it) { VelocityEvent event = *it; int ms = (current_time - event.time) / 1000; if (ms > cutoff_ms) continue; result += event.velocity; } result = result / (cutoff_ms / 16); // 16ms timestep velocity_events_.erase(std::remove_if(velocity_events_.begin(), velocity_events_.end(), &TooOld), velocity_events_.end()); return result; } void Coverflow::Impl::HandleMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { MaybeQueueDraw(); velocity_ = GetCurrentVelocity(32); if (velocity_ != 0 && !velocity_handle_) { velocity_handle_ = g_timeout_add(16, &Coverflow::Impl::OnVelocityTimeout, this); } else if (!velocity_handle_) { SetPosition(RoundFloor(position_), true); UpdateModelSelection(); } } void Coverflow::Impl::HandleMouseDrag(int /* x */, int /* y */, int dx, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { nux::Point2 top_left, bottom_right; Get3DBoundingBox(camera_position_.z, top_left, bottom_right); nux::Geometry geo = parent_->GetGeometry(); float scalar = (((float)bottom_right.x - (float)top_left.x) / (float)geo.width) / parent_->space_between_icons; SetPosition(position_ - (dx * scalar * parent_->mouse_drag_rate), false); } void Coverflow::Impl::HandleMouseWheel(int /* x */, int /* y */, int /* wheel_delta */, unsigned long /* button_flags */, unsigned long /* key_flags */) { // do nothing yet } void Coverflow::Impl::HandleGeometryChange(Area* /* area */, Geometry /* geo */) { } CoverList Coverflow::Impl::GetCoverList(float animation_progress, gint64 /* timestep */) { CoverList results; animation_progress = std::min(1.0f, animation_progress); float coverflow_position = position_ - ((position_ - saved_position_) * (1.0f - animation_progress)); size_t i = 0; float flat_right = parent_->space_between_icons * (parent_->flat_icons) + .1; float flat_left = -flat_right; CoverflowModel::CoverflowItemList::const_iterator it; for (it = parent_->model()->Items().begin(); it != parent_->model()->Items().end(); ++it) { CoverflowItem::Ptr item = *it; float item_position = (float)i - coverflow_position; Cover cover; cover.opacity = 1.0f; cover.selected = item == parent_->model()->Selection(); cover.item = item; // This position refers to the bottom center of the cover. cover.position.x = 0; cover.position.y = -0.5f + parent_->y_offset; cover.position.z = 0; cover.position.rot = 0; float x = item_position * parent_->space_between_icons; cover.position.x = x; float neg_pinch = 1.0f - parent_->pinching; if (x < flat_left) { cover.position.rot = (atan((x - flat_left) * parent_->folding_rate) / (nux::constants::pi / 2)) * -parent_->folding_angle; float scale_in_factor = neg_pinch + (1.0f - (std::abs(cover.position.rot) / parent_->folding_angle)) * parent_->pinching; cover.position.x = flat_left - ((flat_left - x) * scale_in_factor); } else if (x > flat_right) { cover.position.rot = (atan((x - flat_right) * parent_->folding_rate) / (nux::constants::pi / 2)) * -parent_->folding_angle; float scale_in_factor = neg_pinch+ (1.0f - (std::abs(cover.position.rot) / parent_->folding_angle)) * parent_->pinching; cover.position.x = flat_right + ((x - flat_right) * scale_in_factor); } if (cover.selected && parent_->pop_out_selected) cover.position.z = 0.3f; float fold_progress = std::abs(cover.position.rot / parent_->folding_angle()); cover.position.z -= parent_->folding_depth() * fold_progress; nux::Point2 top_left, bottom_right; Get3DBoundingBox(camera_position_.z, top_left, bottom_right); float window_width = bottom_right.x - top_left.x; float distance_from_edge = std::max(0.0f, std::abs(bottom_right.x) - std::abs(cover.position.x)); cover.opacity = std::min(1.0f, distance_from_edge / (window_width * parent_->edge_fade)); results.push_back(cover); ++i; } last_position_ = coverflow_position; return results; } void Coverflow::Impl::SetPosition(float position, bool animate) { float min = std::min((float)parent_->flat_icons,(float)parent_->model()->Items().size() - 1.0f); float max = std::max(0.0f, (float)parent_->model()->Items().size() - 1.0f - (float)parent_->flat_icons); position = std::max(min, std::min(max, position)); if (position == position_) return; if (animate) { position_set_time_ = g_get_monotonic_time(); saved_position_ = last_position_; } else { position_set_time_ = 0; } position_ = position; VelocityEvent ve; ve.velocity = position_ - last_position_; ve.time = g_get_monotonic_time(); velocity_events_.push_back(ve); MaybeQueueDraw(); } void Coverflow::Impl::OnItemAdded(CoverflowModel* /* owner */, CoverflowItem::Ptr /* new_item */) { SetPosition(position_, true); MaybeQueueDraw(); } void Coverflow::Impl::OnItemRemoved(CoverflowModel* /* owner */, CoverflowItem::Ptr /* old_item */) { SetPosition(position_, true); MaybeQueueDraw(); } void Coverflow::Impl::OnSelectionChanged(CoverflowModel* /* owner */, CoverflowItem::Ptr /* selection */) { size_t selection_index = parent_->model()->SelectionIndex(); if (selection_index > (position_ + parent_->flat_icons)) SetPosition(selection_index - parent_->flat_icons, true); else if (selection_index < (position_ - parent_->flat_icons)) SetPosition(selection_index + parent_->flat_icons, true); MaybeQueueDraw(); } void Coverflow::Impl::MaybeQueueDraw() { if (!animation_handle_) animation_handle_ = g_timeout_add(0, &Coverflow::Impl::OnAnimationTimeout, this); } void Coverflow::Impl::LoadVertexBuffer(int VertexLocation, int TextureCoord0Location, int VertexColorLocation, float* VtxBuffer) { CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } } void Coverflow::Impl::RenderCover(nux::GraphicsEngine& graphics_engine, Cover const& cover, int width, int height, nux::Matrix4 combined_matrix) { ObjectPtr texture = cover.item->GetTexture()->GetDeviceTexture(); nux::TexCoordXForm texxform; nux::Color ref_color = nux::color::White; QRP_Compute_Texture_Coord(width, height, texture, texxform); float ratio = texture->GetWidth()/(float)texture->GetHeight(); float drop_shadow_ratio = drop_shadow_texture_->GetWidth()/(float)drop_shadow_texture_->GetHeight(); float fx = cover_width_in_3d_space_/2.0f; float fy_top = cover.position.y + (cover_width_in_3d_space_) * (1.0f/ratio); float fy_bot = cover.position.y; float fy_bot_reflec = cover.position.y - (cover_width_in_3d_space_) * (1.0f/ratio) * parent_->reflection_size; float fx_shadow = 0.5 * (1.1 * cover_width_in_3d_space_); float fy_top_shadow = fy_bot + 0.5 * (1.4 * cover_width_in_3d_space_) * (1.0f/drop_shadow_ratio); float fy_bot_shadow = fy_bot - 0.5 * (1.4 * cover_width_in_3d_space_) * (1.0f/drop_shadow_ratio); cover_shader_program_->Begin(); int TextureObjectLocation = cover_shader_program_->GetUniformLocationARB("TextureObject0"); int VertexLocation = cover_shader_program_->GetAttributeLocation("iVertex"); int TextureCoord0Location = cover_shader_program_->GetAttributeLocation("iTextureCoord0"); int VertexColorLocation = cover_shader_program_->GetAttributeLocation("iVertexColor"); int VPMatrixLocation = cover_shader_program_->GetUniformLocationARB("ViewProjectionMatrix"); nux::Matrix4 MVPMatrix = perspective_ * combined_matrix; cover_shader_program_->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, true, (GLfloat*) &(MVPMatrix.m)); // *** Compute the opacities *** float angular_opacity = 1.0f; if (parent_->folding_angle == 0) { angular_opacity = 1.0f; } else { float rotation_ratio = std::abs(cover.position.rot / parent_->folding_angle); angular_opacity = 1.0f - rotation_ratio; } float opacity = 1.0f - std::abs(cover.position.x) / (parent_->reflection_fadeout_distance); if (opacity < 0.0f) { opacity = 0.0f; } opacity *= angular_opacity; drop_shadow_texture_->SetFiltering (GL_LINEAR, GL_LINEAR); graphics_engine.SetTexture(GL_TEXTURE0, drop_shadow_texture_); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); // **** Render the cover drop shadow **** if (parent_->show_drop_shadow) { Color color = ref_color * cover.opacity * angular_opacity; float VtxBuffer[] = { -fx_shadow, fy_top_shadow, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 0, color.red, color.green, color.blue, color.alpha, -fx_shadow, fy_bot_shadow, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 0, color.red, color.green, color.blue, color.alpha, fx_shadow, fy_bot_shadow, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 0, color.red, color.green, color.blue, color.alpha, fx_shadow, fy_top_shadow, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 0, color.red, color.green, color.blue, color.alpha, }; LoadVertexBuffer(VertexLocation, TextureCoord0Location, VertexColorLocation, VtxBuffer); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); } texture->SetFiltering (GL_LINEAR, GL_LINEAR); graphics_engine.SetTexture(GL_TEXTURE0, texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); // **** Render the cover **** { Color color = ref_color * cover.opacity; float VtxBuffer[] = { -fx, fy_top, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 0, color.red, color.green, color.blue, color.alpha, -fx, fy_bot, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 0, color.red, color.green, color.blue, color.alpha, fx, fy_bot, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 0, color.red, color.green, color.blue, color.alpha, fx, fy_top, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 0, color.red, color.green, color.blue, color.alpha, }; LoadVertexBuffer(VertexLocation, TextureCoord0Location, VertexColorLocation, VtxBuffer); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); } // **** Reflection opacity **** if (parent_->show_reflection) { texxform.flip_v_coord = true; QRP_Compute_Texture_Coord(width, height, texture, texxform); // texture offset use to prevent the texture from scaling when the reflection size changes. float toff = 1.0f - parent_->reflection_size; float opacity_start = opacity*parent_->reflection_strength * cover.opacity; float opacity_end = 0.0f; float VtxBuffer[] = { -fx, fy_bot, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 0, opacity_start, opacity_start, opacity_start, opacity_start, -fx, fy_bot_reflec, 0.0f, 1.0f, texxform.u0, texxform.v1 + toff, 0, 0, opacity_end, opacity_end, opacity_end, opacity_end, fx, fy_bot_reflec, 0.0f, 1.0f, texxform.u1, texxform.v1 + toff, 0, 0, opacity_end, opacity_end, opacity_end, opacity_end, fx, fy_bot, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 0, opacity_start, opacity_start, opacity_start, opacity_start, }; LoadVertexBuffer(VertexLocation, TextureCoord0Location, VertexColorLocation, VtxBuffer); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); } // **** Render Cover label **** if (parent_->show_labels()) { if (!cover.item->text_texture().IsValid()) { nux::Point2 top_left, bottom_right; Get3DBoundingBox(camera_position_.z, top_left, bottom_right); int individual_width = (int) RoundFloor((float)width / (bottom_right.x - top_left.x)); char *escaped_text = g_markup_escape_text(cover.item->name().c_str(), -1); text_loader_.text = escaped_text; text_loader_.width = individual_width; text_loader_.minimum_width = individual_width; cover.item->text_texture = text_loader_.CreateTexture(); g_free(escaped_text); } if (cover.item->text_texture().IsValid()) { ObjectPtr label_texture = cover.item->text_texture()->GetDeviceTexture(); QRP_Compute_Texture_Coord(label_texture->GetWidth(), label_texture->GetHeight(), label_texture, texxform); ratio = label_texture->GetWidth() / (float)label_texture->GetHeight(); float fx = cover_width_in_3d_space_ / 2.0f; float fy_top_text = fy_bot - 0.05f; // push it down a bit float fy_bot_text = fy_top_text - (cover_width_in_3d_space_) * (1.0f/ratio); label_texture->SetFiltering(GL_NEAREST, GL_NEAREST); graphics_engine.SetTexture(GL_TEXTURE0, label_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); texxform.flip_v_coord = true; QRP_Compute_Texture_Coord(width, height, texture, texxform); float opacity_start = angular_opacity; float opacity_end = angular_opacity; if (cover.position.rot != 0.0f) { opacity_start = 0.4f * angular_opacity; opacity_end = 0.4f * angular_opacity; } float VtxBuffer[] = { -fx, fy_top_text, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 0, opacity_start, opacity_start, opacity_start, opacity_start, -fx, fy_bot_text, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 0, opacity_end, opacity_end, opacity_end, opacity_end, fx, fy_bot_text, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 0, opacity_end, opacity_end, opacity_end, opacity_end, fx, fy_top_text, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 0, opacity_start, opacity_start, opacity_start, opacity_start, }; LoadVertexBuffer(VertexLocation, TextureCoord0Location, VertexColorLocation, VtxBuffer); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); } } CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); cover_shader_program_->End(); } void Coverflow::Impl::DrawCover(nux::GraphicsEngine& graphics_engine, nux::DrawAreaContext &ctx, Cover const& cover) { if (cover.item->GetTexture().IsNull() || !TestCoverVisible(cover)) return; int width = parent_->GetBaseWidth(); int height = parent_->GetBaseHeight(); // Note that (cover.position.x, cover.position.y, cover.position.z) is the position of the bottom // center of the cover in 3d space. // We translate the cover to an y coordinate of 0.0 in the matrix below and we take care of rendering // the cover at the right location in Y. if (parent_->true_perspective) { modelview_ = nux::Matrix4::TRANSLATE(-camera_position_.x, -camera_position_.y, -camera_position_.z) * nux::Matrix4::ROTATEX(DEGTORAD(-camera_rotation_.x)) * nux::Matrix4::ROTATEY(DEGTORAD(camera_drift_factor_ * parent_->camera_motion_drift_angle + -camera_rotation_.y)) * nux::Matrix4::ROTATEZ(DEGTORAD(-camera_rotation_.z)) * nux::Matrix4::TRANSLATE(cover.position.x, 0.0f, cover.position.z); } else { modelview_ = nux::Matrix4::TRANSLATE(-camera_position_.x, -camera_position_.y, -camera_position_.z) * nux::Matrix4::ROTATEX(DEGTORAD(-camera_rotation_.x)) * nux::Matrix4::ROTATEY(DEGTORAD(camera_drift_factor_ * parent_->camera_motion_drift_angle + -camera_rotation_.y)) * nux::Matrix4::ROTATEZ(DEGTORAD(-camera_rotation_.z)) * nux::Matrix4::TRANSLATE(0.0f, 0.0f, cover.position.z); nux::Point2 top_left, bottom_right; Get3DBoundingBox(camera_position_.z, top_left, bottom_right); float scalar = ctx.width / (bottom_right.x - top_left.x); glViewport((int) (cover.position.x * scalar), 0.0f, ctx.width, ctx.height); } nux::Matrix4 m = nux::Matrix4::ROTATEY(DEGTORAD(cover.position.rot)); nux::Matrix4 combined_matrix = modelview_ * m; RenderCover(graphics_engine, cover, width, height, combined_matrix); } gboolean Coverflow::Impl::OnAnimationTimeout(gpointer data) { Coverflow::Impl* self = static_cast (data); self->parent_->QueueDraw(); self->animation_handle_ = 0; return FALSE; } gboolean Coverflow::Impl::OnVelocityTimeout(gpointer data) { Coverflow::Impl* self = static_cast(data); if (self->velocity_ == 0) { self->SetPosition(RoundFloor(self->position_), true); self->UpdateModelSelection(); self->velocity_handle_ = 0; return FALSE; } self->SetPosition(self->position_ + self->velocity_, false); self->velocity_ = (std::max(0.0f, std::abs(self->velocity_) - self->parent_->kinetic_scroll_rate)) * (self->velocity_ / std::abs(self->velocity_)); self->MaybeQueueDraw(); return TRUE; } NUX_IMPLEMENT_OBJECT_TYPE(Coverflow); Coverflow::Coverflow() : animation_length(250) , camera_motion_drift_angle(10.0f) , camera_motion_drift_enabled(false) , edge_fade(0.07) , flat_icons(2) , folding_angle(90.0f) , folding_depth(0.0f) , folding_rate(2) , fov(45) , kinetic_scroll_rate(0.1f) , mouse_drag_rate(1) , pinching(.6) , pop_out_selected(false) , reflection_fadeout_distance(4.0f) , reflection_strength(0.45f) , space_between_icons(1.25f) , model(CoverflowModel::Ptr(new CoverflowModel())) , show_labels(true) , show_drop_shadow(false) , show_reflection(false) , true_perspective(true) , reflection_size(1.0f) , pimpl(new Impl(this)) { SetAcceptKeyboardEvent(true); model()->item_added.connect(sigc::mem_fun(pimpl, &Coverflow::Impl::OnItemAdded)); model()->item_removed.connect(sigc::mem_fun(pimpl, &Coverflow::Impl::OnItemRemoved)); pimpl->model_selection_connection_ = model()->selection_changed.connect(sigc::mem_fun(pimpl, &Coverflow::Impl::OnSelectionChanged)); } Coverflow::~Coverflow() { delete pimpl; } void Coverflow::SetCameraDistance(float distance) { pimpl->camera_position_.z = distance; pimpl->MaybeQueueDraw(); } bool Coverflow::InspectKeyEvent(unsigned int /* eventType */, unsigned int /* keysym */, const char* /* character */) { return true; } void Coverflow::ClientDraw(nux::GraphicsEngine& graphics_engine, nux::DrawAreaContext &ctx, bool /* force_draw */) { gint64 current_time = g_get_monotonic_time(); float animation_progress = std::min(1.0f, (current_time - pimpl->position_set_time_) / static_cast(animation_length() * 1000)); gint64 timestep = (current_time - pimpl->last_draw_time_) / 1000; graphics_engine.GetRenderStates().SetBlend(true); graphics_engine.GetRenderStates().SetPremultipliedBlend(SRC_OVER); graphics_engine.GetRenderStates().SetColorMask(true, true, true, true); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glViewport(0, 0, ctx.width, ctx.height); pimpl->perspective_.Perspective(DEGTORAD(fov()), (float)ctx.width / (float)ctx.height, pimpl->near_clip_plan_, pimpl->far_clip_plan_); if (camera_motion_drift_enabled) { float current_velocity = pimpl->GetCurrentVelocity(250); pimpl->camera_drift_factor_ = std::max(-1.0f, std::min(1.0f, current_velocity / 1.5f)); } CoverList covers = pimpl->GetCoverList(EaseSin(animation_progress), timestep); CoverList::iterator it; for (it = covers.begin(); it != covers.end(); ++it) { Cover cover = *it; if (cover.position.rot > 0) pimpl->DrawCover(graphics_engine, ctx, cover); else break; } CoverList::reverse_iterator rit; for (rit = covers.rbegin(); rit != covers.rend(); ++rit) { Cover cover = *rit; if (cover.position.rot <= 0) pimpl->DrawCover(graphics_engine, ctx, cover); } //graphics_engine.GetRenderStates().SetBlend(false); if ((pimpl->camera_drift_factor_ != 0 || animation_progress < 1.0f) && !pimpl->animation_handle_) { pimpl->animation_handle_ = g_timeout_add(0, &Coverflow::Impl::OnAnimationTimeout, pimpl); } pimpl->last_draw_time_ = current_time; pimpl->last_covers_ = covers; } bool Coverflow::AcceptKeyNavFocus() { return true; } float Coverflow::ViewportWidthAtDepth(float depth) { nux::Point2 top_left; nux::Point2 bottom_right; pimpl->Get3DBoundingBox(pimpl->camera_position_.z + depth, top_left, bottom_right); return bottom_right.x - top_left.x; } float Coverflow::ViewportHeightAtDepth(float depth) { nux::Point2 top_left; nux::Point2 bottom_right; pimpl->Get3DBoundingBox(pimpl->camera_position_.z + depth, top_left, bottom_right); return top_left.y - bottom_right.y; } } // namespace nux nux-4.0.6+14.04.20140409/Nux/ScrollBar.cpp0000644000015301777760000000250312321344237020076 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "ScrollBar.h" namespace nux { ScrollBar::ScrollBar(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { m_visible = 1; m_ScrollUnit = 5; visibility_percentage_ = 0.0f; } ScrollBar::~ScrollBar() { } void ScrollBar::SetScrollUnit(int unit) { nuxAssert(unit > 0); m_ScrollUnit = unit; if (m_ScrollUnit <= 0) m_ScrollUnit = 5; } int ScrollBar::GetScrollUnit() const { return m_ScrollUnit; } bool ScrollBar::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/nux.pc.in0000644000015301777760000000052212321344237017251 0ustar pbusernogroup00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Nux Description: Nux OpenGL Toolkit Version: @VERSION@ Libs: -L${libdir} -lnux-@NUX_API_VERSION@ Cflags: -I${includedir}/Nux-@NUX_API_VERSION@ Requires: glib-2.0 nux-core-@NUX_API_VERSION@ nux-graphics-@NUX_API_VERSION@ @GL_PKGS@ sigc++-2.0 libpcre nux-4.0.6+14.04.20140409/Nux/InputArea.cpp0000644000015301777760000003272312321344237020112 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include #include #include #include #include "NuxCore/Logger.h" #include "Nux.h" #include "InputArea.h" #include "NuxGraphics/GraphicsEngine.h" #include "WindowCompositor.h" #ifdef NUX_GESTURES_SUPPORT #include "GesturesSubscription.h" #endif namespace nux { DECLARE_LOGGER(logger, "nux.inputarea"); NUX_IMPLEMENT_OBJECT_TYPE(InputArea); InputArea::InputArea(NUX_FILE_LINE_DECL) : Area(NUX_FILE_LINE_PARAM) , area_color_(color::Green) , accept_key_nav_focus_on_mouse_down_(true) , accept_key_nav_focus_on_mouse_enter_(false) , is_tracking_child_mouse_events_(false) { SetGeometry(0, 0, 1, 1); mouse_in_ = false; _capture_mouse_down_any_where_else = false; _double_click = false; _dnd_enabled_as_source = false; _dnd_enabled_as_target = false; _dnd_safety_x = 0; _dnd_safety_y = 0; _keyboard_receiver_ignore_mouse_down_outside = false; } InputArea::~InputArea() { while (GetWindowCompositor().GrabPointerRemove(this)); while (GetWindowCompositor().GrabKeyboardRemove(this)); } void InputArea::OnDraw(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { // Draw Nothing! // For debug Only: // graphics_engine.QRP_Color(GetBaseX(), GetBaseY(), GetBaseWidth(), GetBaseHeight(), area_color_); } bool InputArea::HasKeyboardFocus() { return GetWindowThread()->GetWindowCompositor().GetKeyFocusArea() == this; } bool InputArea::IsMouseInside() { return mouse_in_; } // TODO: DEPRECATED bool InputArea::MouseFocusOnOtherArea() { return false; } void InputArea::CaptureMouseDownAnyWhereElse(bool b) { _capture_mouse_down_any_where_else = b; } bool InputArea::IsCaptureMouseDownAnyWhereElse() const { return _capture_mouse_down_any_where_else; } void InputArea::EnableDoubleClick(bool double_click) { _double_click = double_click; } bool InputArea::DoubleClickEnabled() const { return _double_click; } void InputArea::SetKeyboardReceiverIgnoreMouseDownOutside(bool ignore_mouse_down_outside) { _keyboard_receiver_ignore_mouse_down_outside = ignore_mouse_down_outside; } bool InputArea::KeyboardReceiverIgnoreMouseDownOutside() { return _keyboard_receiver_ignore_mouse_down_outside; } void InputArea::HandleDndMove(Event &event) { #if defined(DRAG_AND_DROP_SUPPORTED) std::list mimes; mimes = GetWindowThread()->GetGraphicsDisplay().GetDndMimeTypes(); std::list::iterator it; ProcessDndMove(event.x, event.y, mimes); for (it = mimes.begin(); it != mimes.end(); it++) g_free(*it); #endif } void InputArea::HandleDndDrop(Event &event) { #if defined(DRAG_AND_DROP_SUPPORTED) ProcessDndDrop(event.x, event.y); #endif } #if defined(NUX_OS_LINUX) void InputArea::SendDndStatus(bool accept, DndAction action, Geometry region) { #if defined(DRAG_AND_DROP_SUPPORTED) GetWindowThread()->GetGraphicsDisplay().SendDndStatus(accept, action, Rect(region.x, region.y, region.width, region.height)); #endif } void InputArea::SendDndFinished(bool accepted, DndAction action) { #if defined(DRAG_AND_DROP_SUPPORTED) GetWindowThread()->GetGraphicsDisplay().SendDndFinished(accepted, action); #endif } void InputArea::ProcessDndMove(int x, int y, std::list /* mimes */) { #if defined(DRAG_AND_DROP_SUPPORTED) // must learn to deal with x/y offsets Area *parent = GetToplevel(); if (parent) { x += parent->GetGeometry().x; y += parent->GetGeometry().y; } SendDndStatus(false, DNDACTION_NONE, Geometry(x, y, GetGeometry().width, GetGeometry().height)); #endif } void InputArea::ProcessDndDrop(int /* x */, int /* y */) { #if defined(DRAG_AND_DROP_SUPPORTED) SendDndFinished(false, DNDACTION_NONE); #endif } void InputArea::ProcessDndEnter() { } void InputArea::ProcessDndLeave() { } void InputArea::SetDndEnabled(bool as_source, bool as_target) { #if defined(DRAG_AND_DROP_SUPPORTED) _dnd_enabled_as_source = as_source; _dnd_enabled_as_target = as_target; #endif } bool InputArea::DndSourceDragBegin() { return false; } NBitmapData* InputArea::DndSourceGetDragImage() { return 0; } std::list InputArea::DndSourceGetDragTypes() { std::list types; types.push_back("text/plain;charset=utf-8"); types.push_back("UTF8_STRING"); return types; } const char * InputArea::DndSourceGetDataForType(const char *type, int *size, int *format) { *format = 8; if (g_str_equal(type, "text/plain;charset=utf-8") || g_str_equal(type, "UTF8_STRING")) { *size = (int) strlen("this is just a test"); return "this is just a test"; } *size = 0; return 0; } void InputArea::InnerDndSourceDragFinished(DndAction result, void *data) { #if defined(DRAG_AND_DROP_SUPPORTED) InputArea *self = static_cast (data); self->DndSourceDragFinished(result); #endif } void InputArea::DndSourceDragFinished(DndAction /* result */) { } void InputArea::StartDragAsSource() { #if defined(DRAG_AND_DROP_SUPPORTED) GraphicsDisplay::DndSourceFuncs funcs; funcs.get_drag_image = &InputArea::InnerDndSourceGetDragImage; funcs.get_drag_types = &InputArea::InnerDndSourceGetDragTypes; funcs.get_data_for_type = &InputArea::InnerDndSourceGetDataForType; funcs.drag_finished = &InputArea::InnerDndSourceDragFinished; if (DndSourceDragBegin()) GetWindowThread()->GetGraphicsDisplay().StartDndDrag(funcs, this); #endif } #endif void InputArea::GrabPointer() { GetWindowThread()->GetWindowCompositor().GrabPointerAdd(this); } void InputArea::UnGrabPointer() { GetWindowThread()->GetWindowCompositor().GrabPointerRemove(this); } void InputArea::GrabKeyboard() { GetWindowThread()->GetWindowCompositor().GrabKeyboardAdd(this); } void InputArea::UnGrabKeyboard() { GetWindowThread()->GetWindowCompositor().GrabKeyboardRemove(this); } bool InputArea::OwnsPointerGrab() { return GetWindowThread()->GetWindowCompositor().GetPointerGrabArea() == this; } bool InputArea::OwnsKeyboardGrab() { return GetWindowThread()->GetWindowCompositor().GetKeyboardGrabArea() == this; } bool InputArea::IsMouseOwner() { return (GetWindowThread()->GetWindowCompositor().GetMouseOwnerArea() == this); } // == Signals with 1 to 1 mapping to input device == void InputArea::EmitMouseDownSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_down.emit(x, y, mouse_button_state, special_keys_state); } void InputArea::EmitMouseUpSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_up.emit(x, y, mouse_button_state, special_keys_state); } void InputArea::EmitMouseMoveSignal(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_move.emit(x, y, dx, dy, mouse_button_state, special_keys_state); } void InputArea::EmitMouseWheelSignal(int x, int y, int wheel_delta, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_wheel.emit(x, y, wheel_delta, mouse_button_state, special_keys_state); } void InputArea::EmitKeyDownSignal(unsigned int /* key_symbol */, unsigned long /* x11_key_code */, unsigned long /* special_keys_state */) { //OnKeyPressed.emit(key_symbol, x11_key_code, special_keys_state); } void InputArea::EmitKeyUpSignal(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state) { key_up.emit(key_symbol, x11_key_code, special_keys_state); } void InputArea::EmitKeyEventSignal(unsigned long event_type, unsigned int key_sym, unsigned long special_keys_state, const char* text, int key_repeat_count) { key_down.emit( event_type, key_sym, special_keys_state, text, key_repeat_count); } void InputArea::EmitMouseDragSignal(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_drag.emit(x, y, dx, dy, mouse_button_state, special_keys_state); } void InputArea::EmitMouseEnterSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_in_ = true; mouse_enter.emit(x, y, mouse_button_state, special_keys_state); } void InputArea::EmitMouseLeaveSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_in_ = false; mouse_leave.emit(x, y, mouse_button_state, special_keys_state); } void InputArea::EmitMouseClickSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_click.emit(x, y, mouse_button_state, special_keys_state); } void InputArea::EmitMouseDoubleClickSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_double_click.emit(x, y, mouse_button_state, special_keys_state); } void InputArea::EmitMouseDownOutsideArea(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) { mouse_down_outside_pointer_grab_area.emit(x, y, mouse_button_state, special_keys_state); } void InputArea::EmitMouseCancelSignal() { mouse_cancel.emit(); } Area* InputArea::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { if (TestMousePointerInclusion(mouse_position, event_type)) { return this; } return NULL; } Area* InputArea::FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state) { if (has_key_focus_) { return this; } else if (next_object_to_key_focus_area_) { return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state); } return NULL; } bool InputArea::AcceptKeyNavFocus() { return false; } bool InputArea::AcceptKeyNavFocusOnMouseDown() const { return accept_key_nav_focus_on_mouse_down_; } bool InputArea::AcceptKeyNavFocusOnMouseEnter() const { return accept_key_nav_focus_on_mouse_enter_; } void InputArea::SetAcceptKeyNavFocusOnMouseDown(bool accept) { accept_key_nav_focus_on_mouse_down_ = accept; } void InputArea::SetAcceptKeyNavFocusOnMouseEnter(bool accept) { accept_key_nav_focus_on_mouse_enter_ = accept; } bool InputArea::AcceptKeyNavFocus() const { if (GetInputEventSensitivity() == false) return false; return true; } #ifdef NUX_GESTURES_SUPPORT void InputArea::CreateGesturesSubscription(int gesture_classes, unsigned int num_touches) { GesturesSubscription *subscription = new GesturesSubscription; subscription->SetGestureClasses(gesture_classes); subscription->SetNumTouches(num_touches); subscription->Activate(); gestures_subscriptions_.push_back(ShGesturesSubscription(subscription)); } void InputArea::AddGesturesSubscription( std::shared_ptr &subscription) { for (auto sub : gestures_subscriptions_) { if (sub.get() == subscription.get()) return; } gestures_subscriptions_.push_back(subscription); } void InputArea::RemoveGesturesSubscription( std::shared_ptr &subscription) { std::list >::iterator it; for (it = gestures_subscriptions_.begin(); it != gestures_subscriptions_.end(); ++it) { if (it->get() == subscription.get()) { gestures_subscriptions_.erase(it); return; } ++it; } } const std::list& InputArea::GetGesturesSubscriptions() const { return gestures_subscriptions_; } bool InputArea::HasSubscriptionForGesture(const nux::GestureEvent &event) const { for (const auto subscription : gestures_subscriptions_) { if (subscription->MatchesGesture(event)) return true; } return false; } Area* InputArea::GetInputAreaHitByGesture(const nux::GestureEvent &event) { if (!IsVisible()) return nullptr; if (!HasSubscriptionForGesture(event)) return nullptr; if (!IsGestureInsideArea(event)) return nullptr; return this; } #endif // NUX_GESTURES_SUPPORT void InputArea::SetTrackChildMouseEvents(bool enable) { is_tracking_child_mouse_events_ = enable; } bool InputArea::IsTrackingChildMouseEvents() const { return is_tracking_child_mouse_events_; } bool InputArea::ChildMouseEvent(const Event&) { return false; } } // namespace nux nux-4.0.6+14.04.20140409/Nux/Panel.cpp0000644000015301777760000001056212321344237017256 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "WindowCompositor.h" #include "VScrollBar.h" #include "HScrollBar.h" #include "Panel.h" namespace nux { Panel::Panel(NUX_FILE_LINE_DECL) : ScrollView(NUX_FILE_LINE_PARAM) , m_layout(0) { m_top_border = 0; m_border = 0; } Panel::~Panel() { // Delete all the interface object: This is a problem... The widget should be destroy by there associated parameters //delete vlayout; m_layout = NULL; } void Panel::Draw(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void Panel::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { graphics_engine.PushClippingRectangle(GetGeometry()); graphics_engine.PushClippingRectangle(Rect(m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight)); if (m_layout) { graphics_engine.PushClippingRectangle(m_layout->GetGeometry()); m_layout->ProcessDraw(graphics_engine, force_draw); graphics_engine.PopClippingRectangle(); } graphics_engine.PopClippingRectangle(); if (m_vertical_scrollbar_enable) { _vscrollbar->ProcessDraw(graphics_engine, force_draw); } if (m_horizontal_scrollbar_enable) { _hscrollbar->ProcessDraw(graphics_engine, force_draw); } graphics_engine.PopClippingRectangle(); } void Panel::AddWidget(View *ic, int stretchfactor) { if (ic && m_layout) { m_layout->AddView(ic, stretchfactor); // if (stretchfactor ==0): the WidgetLayout geometry will be set to SetGeometry(0,0,1,1); // and the children will take their natural size by expending WidgetLayout. // If the parent of WidgetLayout offers more space, it won't be used by WidgetLayout. ComputeContentSize(); } } void Panel::AddWidget(std::list *ViewList) { std::list::iterator it; for (it = ViewList->begin(); it != ViewList->end(); it++) { AddWidget((*it)); } } bool Panel::SetLayout(Layout *layout) { if (View::SetLayout(layout) == false) { return false; } m_layout = view_layout_; FormatContent(); return true; } void Panel::clearContent() { m_layout->Clear(); } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. void Panel::PreLayoutManagement() { ScrollView::PreLayoutManagement(); } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. long Panel::PostLayoutManagement(long LayoutResult) { long result = ScrollView::PostLayoutManagement(LayoutResult); return result; } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. void Panel::ComputeContentPosition(float offsetX, float offsetY) { ScrollView::ComputeContentPosition(offsetX, offsetY); } void Panel::ScrollLeft(float stepx, int mousedx) { ScrollView::ScrollLeft(stepx, mousedx); ComputeContentSize(); QueueDraw(); } void Panel::ScrollRight(float stepx, int mousedx) { ScrollView::ScrollRight(stepx, mousedx); ComputeContentSize(); QueueDraw(); } void Panel::ScrollUp(float stepy, int mousedy) { ScrollView::ScrollUp(stepy, mousedy); ComputeContentSize(); QueueDraw(); } void Panel::ScrollDown(float stepy, int mousedy) { ScrollView::ScrollDown(stepy, mousedy); ComputeContentSize(); QueueDraw(); } bool Panel::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/XIMController.cpp0000644000015301777760000000736412321344237020726 0ustar pbusernogroup00000000000000/* * Copyright 2012-2013 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * */ #include #include "XIMController.h" #include "NuxCore/Logger.h" DECLARE_LOGGER(logger, "xim.controller"); namespace nux { XIMController::XIMController(Display* display) : display_(display) , window_(0) , xim_(nullptr) { InitXIMCallback(); } XIMController::~XIMController() { // The XIC must be destroyed before the XIM xic_client_.DestroyXIC(); if (xim_) XCloseIM(xim_); } void XIMController::SetFocusedWindow(Window window) { window_ = window; if (xim_) xic_client_.ResetXIC(xim_, window, display_); } void XIMController::SetCurrentTextEntry(TextEntry* text_entry) { xic_client_.SetCurrentTextEntry(text_entry); if (xim_) xic_client_.ResetXIC(xim_, window_, display_); } void XIMController::RemoveFocusedWindow() { window_ = 0; xic_client_.DestroyXIC(); } bool XIMController::IsXICValid() const { return xic_client_.HasXIC(); } XIC XIMController::GetXIC() const { return xic_client_.GetXIC(); } void XIMController::FocusInXIC() { xic_client_.FocusInXIC(); } void XIMController::FocusOutXIC() { xic_client_.FocusOutXIC(); xic_client_.SetCurrentTextEntry(nullptr); } Window XIMController::GetCurrentWindow() const { return window_; } void XIMController::InitXIMCallback() { char* const xmodifier = getenv("XMODIFIERS"); if (xmodifier && strstr(xmodifier,"ibus") != NULL) { LOG_WARN(logger) << "IBus natively supported."; return; } if (setlocale(LC_ALL, "") == NULL) { LOG_WARN(logger) << "Cannot setlocale."; } if (XSupportsLocale()) { if (XSetLocaleModifiers("") == NULL) { LOG_WARN(logger) << "XSetLocalModifiers Failed."; } XRegisterIMInstantiateCallback(display_, NULL, NULL, NULL, XIMController::SetupXIMClientCallback, (XPointer)this); } } void XIMController::SetupXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data) { XIMController* self = (XIMController*)client_data; self->SetupXIM(); } void XIMController::EndXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data) { XIMController* self = (XIMController*)client_data; self->xim_ = NULL; self->xic_client_.Reinitialize(); self->InitXIMCallback(); } void XIMController::SetupXIM() { xim_ = XOpenIM(display_, NULL, NULL, NULL); if (xim_) { SetupXIMDestroyedCallback(); if (window_) xic_client_.ResetXIC(xim_, window_, display_); XUnregisterIMInstantiateCallback (display_, NULL, NULL, NULL, XIMController::SetupXIMClientCallback, (XPointer)this); } else { LOG_WARN(logger) << "Failed to open IM."; } } void XIMController::SetupXIMDestroyedCallback() { XIMCallback destroy_callback; destroy_callback.callback = (XIMProc)XIMController::EndXIMClientCallback; destroy_callback.client_data = (XPointer)this; XSetIMValues (xim_, XNDestroyCallback, &destroy_callback, NULL); } } //namespace nux nux-4.0.6+14.04.20140409/Nux/EMMetrics.h0000644000015301777760000000176512321344237017521 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller namespace nux { class EMMetrics { public: EMMetrics(Display* dpy, int scr, double points); double Pixel2EM(int value); int EM2Pixel(double value); private: double pixels_per_em_; }; } #endif // NUX_EMMETRICS_H nux-4.0.6+14.04.20140409/Nux/AbstractPaintLayer.cpp0000644000015301777760000000104612321344237021750 0ustar pbusernogroup00000000000000#include "Nux.h" #include "AbstractPaintLayer.h" namespace nux { AbstractPaintLayer::AbstractPaintLayer() { } AbstractPaintLayer::~AbstractPaintLayer() { } void AbstractPaintLayer::SetGeometry(const Geometry &geo) { geometry_ = geo; } Geometry const& AbstractPaintLayer::GetGeometry() const { return geometry_; } void AbstractPaintLayer::SetModelViewMatrix(const Matrix4 &mat) { model_view_matrix_ = mat; } Matrix4 AbstractPaintLayer::GetModelViewMatrix() { return model_view_matrix_; } } nux-4.0.6+14.04.20140409/Nux/CheckBox.h0000644000015301777760000000500012321344237017341 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef CHECKBOX_H #define CHECKBOX_H #include "AbstractCheckedButton.h" namespace nux { class HLayout; class InputArea; class StaticText; //! CheckBox class /*! A CheckBox class.\n The CheckBox class cannot be vertically resized. It can only be resized horizontally. The vertical size is always match the size of the content (check area + label). */ class CheckBox: public AbstractCheckedButton { NUX_DECLARE_OBJECT_TYPE(CheckBox, AbstractCheckedButton); public: CheckBox(const std::string &str, bool state = false, NUX_FILE_LINE_PROTO); virtual ~CheckBox(); //! Emitted when the button is clicked. sigc::signal click; //! Emitted when the active state changes. /*! Emitted when the active state changes, as a result of a mouse click or an API call.\n \sa Activate, Deactivate. */ sigc::signal state_change; //! Activate the check box. /*! Activate the check box. */ virtual void Activate(); //! Deactivate the check box. /*! Deactivate the check box. */ virtual void Deactivate(); protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void RecvClick(int x, int y, unsigned long button_flags, unsigned long key_flags); private: //! Override of Area::SetMinimumHeight and made private. /*! Prevent changing the minimum height of the StaticText view. */ virtual void SetMinimumHeight(int h){}; //! Override of Area::SetMaximumHeight and made private. /*! Prevent changing the maximum height of the StaticText view. */ virtual void SetMaximumHeight(int h){}; }; } #endif // CHECKBOX_H nux-4.0.6+14.04.20140409/Nux/CoverflowModel.cpp0000644000015301777760000000625012321344237021145 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith */ #include "CoverflowModel.h" namespace nux { struct CoverflowModel::Impl { Impl(CoverflowModel *parent); ~Impl(); CoverflowModel* parent_; size_t selection_index_; CoverflowItemList items_; }; CoverflowModel::Impl::Impl(CoverflowModel* parent) : parent_(parent) , selection_index_(0) { } CoverflowModel::Impl::~Impl() { } NUX_IMPLEMENT_OBJECT_TYPE(CoverflowModel); CoverflowModel::CoverflowModel() : pimpl(new CoverflowModel::Impl(this)) { } CoverflowModel::~CoverflowModel() { delete pimpl; } CoverflowModel::CoverflowItemList const& CoverflowModel::Items() const { return pimpl->items_; } void CoverflowModel::AddItem(CoverflowItem::Ptr const& item) { pimpl->items_.push_back(item); item_added.emit(this, item); SetSelection(pimpl->selection_index_); // perform bounds check } void CoverflowModel::InsertItem(CoverflowItem::Ptr const& item, size_t index) { pimpl->items_.insert(pimpl->items_.begin() + std::max(index, pimpl->items_.size()), item); item_added.emit(this, item); SetSelection(pimpl->selection_index_); // perform bounds check } void CoverflowModel::RemoveItem(CoverflowItem::Ptr const& item) { pimpl->items_.erase(std::remove(pimpl->items_.begin(), pimpl->items_.end(), item), pimpl->items_.end()); item_removed.emit(this, item); SetSelection(pimpl->selection_index_); // perform bounds check } size_t CoverflowModel::IndexOf(CoverflowItem::Ptr const& item) { size_t i = 0; CoverflowItemList::iterator it; for (it = pimpl->items_.begin(); it != pimpl->items_.end(); ++it) { CoverflowItem::Ptr compare = *it; if (item == compare) return i; ++i; } return 0; } CoverflowItem::Ptr CoverflowModel::Selection() { if (pimpl->selection_index_ >= pimpl->items_.size()) return CoverflowItem::Ptr(); return pimpl->items_[pimpl->selection_index_]; } size_t CoverflowModel::SelectionIndex() { return pimpl->selection_index_; } void CoverflowModel::SetSelection(size_t index) { index = std::min(index, pimpl->items_.size() - 1); if (index != pimpl->selection_index_) { pimpl->selection_index_ = index; selection_changed.emit(this, Selection()); } } void CoverflowModel::SetSelection(CoverflowItem::Ptr item) { SetSelection(IndexOf(item)); } void CoverflowModel::SelectNext() { SetSelection(pimpl->selection_index_ + 1); } void CoverflowModel::SelectPrev() { if (pimpl->selection_index_ == 0) return; SetSelection(pimpl->selection_index_ - 1); } } nux-4.0.6+14.04.20140409/Nux/XICClient.h0000644000015301777760000000415112321344237017443 0ustar pbusernogroup00000000000000/* * Copyright 2012-2013 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * */ #ifndef XICCLIENT_H #define XICCLIENT_H /* Xlib.h is the default header that is included and has the core functionallity */ #include namespace nux { class TextEntry; class XICClient { public: XICClient(); void ResetXIC(XIM xim, Window window, Display* display); void SetCurrentTextEntry(TextEntry* text_entry_); bool HasXIC() const; XIC GetXIC() const; void Reinitialize(); void FocusInXIC(); void FocusOutXIC(); bool IsFocused() const; void DestroyXIC(); private: void SetupXIC(XIM xim, Window window, Display* display); void SetupXIMStyle(XIM xim); XVaNestedList GetPreeditCallbacks(); XVaNestedList GetStatusCallbacks(); XIMStyle FilterXIMStyle(); static int PreeditStartCallback(XIC xic, XPointer clientdata, XPointer data); static int PreeditDoneCallback(XIC xic, XPointer clientdata, XPointer data); static int PreeditDrawCallback(XIC xic, XPointer clientdata, XIMPreeditDrawCallbackStruct* call_data); TextEntry* text_entry_; XIC xic_; XIMStyle xim_style_; XIMCallback preedit_start_cb_; XIMCallback preedit_done_cb_; XIMCallback preedit_draw_cb_; XIMCallback preedit_caret_cb_; XIMCallback status_start_cb_; XIMCallback status_done_cb_; XIMCallback status_draw_cb_; bool focused_; }; } //namespace nux #endif // XICClient.h nux-4.0.6+14.04.20140409/Nux/RadioButtonGroup.h0000644000015301777760000000534712321344237021140 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RADIOBUTTONLOGIC_H #define RADIOBUTTONLOGIC_H namespace nux { class RadioButton; //! RadioButtonGroup select one of many radio button in a group. /*! RadioButtonGroup does not hold a strong reference on radio buttons. */ class RadioButtonGroup: public InitiallyUnownedObject { NUX_DECLARE_OBJECT_TYPE(RadioButtonGroup, InitiallyUnownedObject); public: RadioButtonGroup(NUX_FILE_LINE_PROTO); ~RadioButtonGroup(); //! Add a radio button to the group. /* The first radio button added to the group gets its check state set to true. When a radio button is added to a group that is not empty, its check state is set to false. */ void ConnectButton(RadioButton* radio); //! Remove a radio button from the group. /* When a radio button is removed, the previous button in the group gets its check state set to true; */ void DisconnectButton(RadioButton* radio); //! Set the active radio button. /* Set the active radio button in the group. If \i emit_signal is true, all the button in the group emit their \i state_changed signal.\n If the parameter \i radio is already active and \i emit_signal is true, the \i state_changed signal will be emitted.\n The active button is the last one to emit its \i state_changed signal. @param radio The button to activate. @param emit_signal If true, emit the state_changed signal of all the buttons in the group. */ void SetActiveButton(RadioButton* radio, bool emit_signal = true); private: //! Return the number of buttons in the group. /*! Return the number of buttons in the group. @return The number of buttons in the group. */ int GetNumButtons(); void NotifyClick(RadioButton* radio); std::vector > radio_button_array_; int active_button_index_; friend class RadioButton; }; } #endif // RADIOBUTTONLOGIC_H nux-4.0.6+14.04.20140409/Nux/TextLoader.cpp0000644000015301777760000001744112321344237020275 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith */ #include "TextLoader.h" #include "NuxGraphics/CairoGraphics.h" #include #include #include namespace nux { struct TextLoader::Impl { Impl(TextLoader* parent); ~Impl(); void RasterizeText(void* cairo_context, Color color); Size ComputeTextSize(); std::string GetPangoFontName(); TextLoader* parent_; float padding_x_; float padding_y_; }; TextLoader::Impl::Impl(TextLoader* parent) : parent_(parent) , padding_x_(0) , padding_y_(0) { } TextLoader::Impl::~Impl() { } std::string TextLoader::Impl::GetPangoFontName() { std::ostringstream os; os << parent_->font_name() << " " << parent_->font_size(); return std::string(os.str()); } Size TextLoader::Impl::ComputeTextSize() { cairo_surface_t* pango_surface = NULL; cairo_t* cairo_ctx = NULL; PangoLayout* pango_layout = NULL; PangoFontDescription* font_desc = NULL; PangoContext* pango_ctx = NULL; PangoRectangle ink_rect = {0, 0, 0, 0}; PangoRectangle logical_rect = {0, 0, 0, 0}; int dpi = 96; std::string pango_font_name = GetPangoFontName(); // Create Cairo surface. pango_surface = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1); // Create Cairo context. cairo_ctx = cairo_create(pango_surface); // Create layout. pango_layout = pango_cairo_create_layout(cairo_ctx); { pango_layout_set_wrap (pango_layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(pango_layout, PANGO_ELLIPSIZE_END); pango_layout_set_markup (pango_layout, parent_->text().c_str(), -1); pango_layout_set_height (pango_layout, -parent_->lines()); // Sets the width to which the lines of the PangoLayout should wrap or ellipsized. The default value is -1: no width set. pango_layout_set_width(pango_layout, parent_->width * PANGO_SCALE); } // Create font description: "[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]" font_desc = pango_font_description_from_string(pango_font_name.c_str()); { pango_font_description_set_weight(font_desc, PANGO_WEIGHT_NORMAL); pango_layout_set_font_description(pango_layout, font_desc); } // Get Pango context pango_ctx = pango_layout_get_context(pango_layout); // is not ref'ed // Set font options CairoFontOptions font_options; { cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_DEFAULT); cairo_font_options_set_subpixel_order(font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_set_font_options(cairo_ctx, font_options); pango_cairo_context_set_font_options(pango_ctx, font_options); } // use some default DPI-value pango_cairo_context_set_resolution(pango_ctx, dpi); pango_layout_context_changed(pango_layout); pango_layout_get_extents(pango_layout, &ink_rect, &logical_rect); int text_width = std::ceil((float)logical_rect.width / PANGO_SCALE); int text_height = std::ceil((float)logical_rect.height / PANGO_SCALE); padding_x_ = text_width - logical_rect.width / PANGO_SCALE; padding_y_ = text_height - logical_rect.height / PANGO_SCALE; text_width = std::min(text_width, parent_->width()); // clean up pango_font_description_free(font_desc); g_object_unref(pango_layout); cairo_destroy(cairo_ctx); cairo_surface_destroy(pango_surface); return Size(text_width, text_height); } void TextLoader::Impl::RasterizeText(void* cairo_context, Color /* color */) { cairo_t* cairo_ctx = (cairo_t*) cairo_context; PangoLayout* pango_layout = NULL; PangoFontDescription* font_desc = NULL; PangoContext* pango_ctx = NULL; int dpi = 96; // Create layout. pango_layout = pango_cairo_create_layout(cairo_ctx); { pango_layout_set_wrap (pango_layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(pango_layout, PANGO_ELLIPSIZE_END); pango_layout_set_alignment(pango_layout, (PangoAlignment)parent_->alignment()); pango_layout_set_markup (pango_layout, parent_->text().c_str(), -1); pango_layout_set_height (pango_layout, -parent_->lines()); // Sets the width to which the lines of the PangoLayout should wrap or ellipsized. The default value is -1: no width set. pango_layout_set_width(pango_layout, parent_->width * PANGO_SCALE); } // Create font description: "[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]" font_desc = pango_font_description_from_string(GetPangoFontName().c_str()); { pango_font_description_set_weight(font_desc, PANGO_WEIGHT_NORMAL); pango_layout_set_font_description(pango_layout, font_desc); } // Get Pango context pango_ctx = pango_layout_get_context(pango_layout); // is not ref'ed // Set font options CairoFontOptions font_options; { cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_DEFAULT); cairo_font_options_set_subpixel_order (font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_set_font_options(cairo_ctx, font_options); pango_cairo_context_set_font_options(pango_ctx, font_options); } pango_cairo_context_set_resolution(pango_ctx, dpi); cairo_set_source_rgba(cairo_ctx, 1.0, 1.0, 1.0, 1.0); pango_layout_context_changed(pango_layout); cairo_move_to(cairo_ctx, padding_x_, padding_y_); pango_cairo_show_layout(cairo_ctx, pango_layout); // clean up pango_font_description_free(font_desc); g_object_unref(pango_layout); } TextLoader::TextLoader() : alignment(TextAlignment::ALIGN_CENTER) , font_name("Ubuntu") , font_size(10) , width(-1) , minimum_width(0) , lines(1) , pimpl(new TextLoader::Impl(this)) { } TextLoader::~TextLoader() { delete pimpl; } ObjectPtr TextLoader::CreateTexture() { ObjectPtr result; Size sz = pimpl->ComputeTextSize(); if (sz.width == 0 || sz.height == 0) return result; CairoGraphics* cairo_graphics = new CairoGraphics(CAIRO_FORMAT_ARGB32, std::max(sz.width, minimum_width()), sz.height); cairo_t* cairo_ctx = cairo_graphics->GetContext(); cairo_set_operator(cairo_ctx, CAIRO_OPERATOR_CLEAR); cairo_paint(cairo_ctx); cairo_set_operator(cairo_ctx, CAIRO_OPERATOR_OVER); pimpl->RasterizeText(cairo_ctx, color); NBitmapData* bitmap = cairo_graphics->GetBitmap(); // NTexture2D is the high level representation of an image that is backed by // an actual opengl texture. BaseTexture* rasterized_text_texture = NULL; rasterized_text_texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); rasterized_text_texture->Update(bitmap); result = rasterized_text_texture; rasterized_text_texture->UnReference(); // get rid of our ref so the owner is the only one who gets it rasterized_text_texture = NULL; delete bitmap; cairo_destroy(cairo_ctx); delete cairo_graphics; cairo_graphics = NULL; return result; } } nux-4.0.6+14.04.20140409/Nux/HSplitter.cpp0000644000015301777760000005015712321344237020141 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HSplitter.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "WindowCompositor.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(HSplitter); static const int HSPLITTERHEIGHT = 5; static const int HSTICK_SIZE = 5; HSplitter::HSplitter(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { new_addition = false; m_initial_config = true; m_focus_splitter_index = -1; m_ResizeOnSplitterRelease = true; mvt_dx = 0; mvt_dy = 0; m_current_x = 0; m_current_y = 0; m_current_width = 200; m_current_height = 200; //SetMinimumSize(200,200); SetGeometry(Geometry(m_current_x, m_current_y, m_current_width, m_current_height)); } HSplitter::~HSplitter() { std::vector< Area* >::iterator it0; for (it0 = m_InterfaceObject.begin(); it0 != m_InterfaceObject.end(); it0++) { (*it0)->UnParentObject(); } m_InterfaceObject.clear(); std::vector< MySplitter* >::iterator it2; for (it2 = m_SplitterObject.begin(); it2 != m_SplitterObject.end(); it2++) { (*it2)->UnParentObject(); } m_SplitterObject.clear(); m_SplitConfig.clear(); } void HSplitter::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { graphics_engine.PushClippingRectangle(GetGeometry()); Geometry base = GetGeometry(); // std::vector::iterator it; // for (it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++) // { // (*it)->ProcessDraw(force_draw); // } GetPainter().PaintBackground(graphics_engine, base); std::vector::iterator it_splitter; for (it_splitter = m_SplitterObject.begin(); it_splitter != m_SplitterObject.end(); it_splitter++) { Geometry geo = (*it_splitter)->GetGeometry(); Geometry grip_geo; int w = 20; if (geo.GetWidth() > w) { grip_geo.SetX(geo.x + (geo.GetWidth() - w) / 2); grip_geo.SetY(geo.y); grip_geo.SetWidth(w); grip_geo.SetHeight(geo.GetHeight()); } else { grip_geo.SetX(geo.x - (w - geo.GetWidth()) / 2); grip_geo.SetY(geo.y); grip_geo.SetWidth(w); grip_geo.SetHeight(geo.GetHeight()); } GetPainter().Draw2DLine(graphics_engine, grip_geo.x, grip_geo.y + 1, grip_geo.x + grip_geo.GetWidth(), grip_geo.y + 1, Color(0xFF111111)); GetPainter().Draw2DLine(graphics_engine, grip_geo.x, grip_geo.y + 3, grip_geo.x + grip_geo.GetWidth(), grip_geo.y + 3, Color(0xFF111111)); } graphics_engine.PopClippingRectangle(); } void HSplitter::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); bool need_redraw = IsRedrawNeeded(); std::vector::iterator it_splitter; std::vector::iterator it; //for(it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++) for (it = m_InterfaceObject.begin(), it_splitter = m_SplitterObject.begin(); it != m_InterfaceObject.end(); it++, it_splitter++) { Geometry sgeo = (*it_splitter)->GetGeometry(); graphics_engine.PushClippingRectangle(Rect( base.x, base.y, base.GetWidth(), sgeo.y - base.y)); base.SetY(sgeo.y + sgeo.GetHeight()); if (force_draw || need_redraw) { if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = static_cast(*it); ic->ProcessDraw(graphics_engine, true); } else if ((*it)->Type().IsObjectType(HLayout::StaticObjectType)) { HLayout *layout = static_cast(*it); layout->ProcessDraw(graphics_engine, true); } else if ((*it)->Type().IsObjectType(VLayout::StaticObjectType)) { VLayout *layout = static_cast(*it); layout->ProcessDraw(graphics_engine, true); } } else { if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = static_cast(*it); ic->ProcessDraw(graphics_engine, false); } else if ((*it)->Type().IsObjectType(HLayout::StaticObjectType)) { HLayout *layout = static_cast(*it); layout->ProcessDraw(graphics_engine, false); } else if ((*it)->Type().IsObjectType(VLayout::StaticObjectType)) { VLayout *layout = static_cast(*it); layout->ProcessDraw(graphics_engine, false); } } graphics_engine.PopClippingRectangle(); } graphics_engine.PopClippingRectangle(); } void HSplitter::OverlayDrawing(GraphicsEngine &graphics_engine) { unsigned int num_element = (unsigned int) m_SplitterObject.size(); Geometry base = GetGeometry(); if (m_focus_splitter_index >= 0) { Geometry geo = m_SplitterObject[m_focus_splitter_index]->GetGeometry(); geo.OffsetPosition(mvt_dx, mvt_dy); if (m_focus_splitter_index == 0 && num_element > 1) { if (geo.y < base.y) { geo.SetY(base.y); } if (geo.y + HSPLITTERHEIGHT > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().y) { geo.SetY(m_SplitterObject[m_focus_splitter_index+1]->GetGeometry().y - HSPLITTERHEIGHT); } } if ((m_focus_splitter_index > 0) && (m_focus_splitter_index < (int) num_element - 1)) { if (geo.y < m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().y + HSPLITTERHEIGHT) { geo.SetY(m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().y + HSPLITTERHEIGHT); } if (geo.y + HSPLITTERHEIGHT > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().y) { geo.SetY(m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().y - HSPLITTERHEIGHT); } } graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); { GetPainter().Paint2DQuadColor(graphics_engine, geo, Color(0xBB868686)); } graphics_engine.GetRenderStates().SetBlend(false); } } void HSplitter::AddWidget(Area *ic, float stretchfactor) { if (ic) { MySplitter *splitter = new MySplitter; splitter->SetParentObject(this); //splitter->SinkReference(); unsigned int no = (unsigned int) m_InterfaceObject.size(); splitter->mouse_down.connect(sigc::bind(sigc::mem_fun(this, &HSplitter::OnSplitterMouseDown), no)); splitter->mouse_drag.connect(sigc::bind(sigc::mem_fun(this, &HSplitter::OnSplitterMouseDrag), no)); splitter->mouse_up.connect(sigc::bind(sigc::mem_fun(this, &HSplitter::OnSplitterMouseUp), no)); ic->SetParentObject(this); m_InterfaceObject.push_back(ic); m_SplitterObject.push_back(splitter); m_SplitConfig.push_back(stretchfactor); new_addition = true; ComputeContentSize(); } } void HSplitter::clearContent() { m_InterfaceObject.clear(); } long HSplitter::ComputeContentSize() { unsigned int num_element = (unsigned int) m_InterfaceObject.size(); int x = GetBaseX(); int y = GetBaseY(); int w = GetBaseWidth(); int h = GetBaseHeight(); if ((w == 0) || (h == 0)) { return eCompliantHeight | eCompliantWidth; } if (num_element < 1) { m_current_height = h; m_current_width = w; m_current_x = x; m_current_y = y; new_addition = false; return eCompliantHeight | eCompliantWidth; } std::vector::iterator it; std::vector::iterator it_splitter; if (new_addition) { ResetSplitConfig(); new_addition = false; } if (m_current_width != w) { for (unsigned int i = 0; i < num_element; i++) { Geometry splitter_geo = m_SplitterObject[i]->GetGeometry(); splitter_geo.SetWidth(w); splitter_geo.SetX(x); m_SplitterObject[i]->SetGeometry(splitter_geo); } } if (m_current_height != h) { int size_to_distribute = h - num_element * HSPLITTERHEIGHT; int previous_spliter_end = m_current_y; int new_spliter_end = y; for (unsigned int i = 0; i < num_element; i++) { Geometry splitter_geo = m_SplitterObject[i]->GetGeometry(); // compute percentage of space occupied by the element i; // width of element i = m_SplitterObject[i]->GetY() - previous_splliter_end int splitter_start = m_SplitterObject[i]->GetBaseY(); float percent = float(splitter_start - previous_spliter_end) / float(m_current_height - num_element * HSPLITTERHEIGHT); if (percent > 1.0f) percent = 1.0f; splitter_geo.SetY(new_spliter_end + size_to_distribute * percent); previous_spliter_end = splitter_start + HSPLITTERHEIGHT; new_spliter_end = new_spliter_end + size_to_distribute * percent + HSPLITTERHEIGHT; m_SplitterObject[i]->SetGeometry(splitter_geo); } if (m_SplitterObject[0]->GetBaseY() < y) { m_SplitterObject[0]->SetBaseY(y); } m_SplitterObject[num_element-1]->SetBaseY(y + h - HSPLITTERHEIGHT); } int accheight = y; for (unsigned int i = 0; i < num_element; i++) { Geometry splitter_geo = m_SplitterObject[i]->GetGeometry(); //m_InterfaceObject[i]->SetGeometry(Geometry(x, accheight, w, splitter_geo.y - accheight)); if (m_InterfaceObject[i]->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = static_cast(m_InterfaceObject[i]); ic->SetGeometry(Geometry(x, accheight, w, splitter_geo.y - accheight)); // if we are already computing the layout from the main window down, we need to call // ComputeElementLayout to force the computing of this element layout. GetWindowThread()->ComputeElementLayout(ic); } else if (m_InterfaceObject[i]->Type().IsDerivedFromType(Layout::StaticObjectType)) { Layout *layout = static_cast(m_InterfaceObject[i]); layout->SetGeometry(Geometry(x, accheight, w, splitter_geo.y - accheight)); // if we are already computing the layout from the main window down, we need to call // ComputeElementLayout to force the computing of this element layout. GetWindowThread()->ComputeElementLayout(layout); } accheight += splitter_geo.y - accheight + HSPLITTERHEIGHT; } m_current_height = h; m_current_width = w; m_current_x = x; m_current_y = y; return eCompliantHeight | eCompliantWidth; } void HSplitter::ResetSplitConfig() { int x = GetBaseX(); int y = GetBaseY(); int w = GetBaseWidth(); int h = GetBaseHeight(); unsigned int num_element = (unsigned int) m_InterfaceObject.size(); if (num_element < 1) { return; } float max_stretch = 0.0f; float stretchfactor; for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++) { stretchfactor = m_SplitConfig[i]; if (max_stretch < stretchfactor) { max_stretch = stretchfactor; } } float total = 0; for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++) { stretchfactor = m_SplitConfig[i]; total += stretchfactor / max_stretch; } int availableheight = (h - num_element * HSPLITTERHEIGHT); float max_size = float(availableheight) / total; for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++) { stretchfactor = m_SplitConfig[i]; y += stretchfactor * max_size / max_stretch; Geometry geo(x, y, w, HSPLITTERHEIGHT); m_SplitterObject[i]->SetGeometry(geo); } m_SplitterObject[num_element-1]->SetBaseX(y + h - HSPLITTERHEIGHT); m_initial_config = true; } void HSplitter::OnSplitterMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */, int header_pos) { m_point = Point(x, y); m_focus_splitter_index = header_pos; GetWindowThread()->GetWindowCompositor().SetWidgetDrawingOverlay(this, GetWindowThread()->GetWindowCompositor().GetProcessingTopView()); // Hint for the window to initiate a redraw GetWindowThread()->RequestRedraw(); } void HSplitter::OnSplitterMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */, int header_pos) { if (mvt_dy) { Geometry geo = m_SplitterObject[header_pos]->GetGeometry(); geo.OffsetPosition(0, mvt_dy); unsigned int num_element = (unsigned int) m_SplitterObject.size(); if (header_pos < (int) num_element - 1) { // Make the splitter bar stick to the next one if the distance between them is less than HSTICK_SIZE. if (m_SplitterObject[header_pos + 1]->GetGeometry().y - geo.y - HSPLITTERHEIGHT < HSTICK_SIZE) geo.SetY( m_SplitterObject[header_pos + 1]->GetGeometry().y - HSPLITTERHEIGHT ); } m_SplitterObject[header_pos]->SetGeometry(geo); ResizeSplitter(header_pos); } m_focus_splitter_index = -1; mvt_dx = 0; mvt_dy = 0; // End overlay drawing; GetWindowThread()->GetWindowCompositor().SetWidgetDrawingOverlay(0, GetWindowThread()->GetWindowCompositor().GetProcessingTopView()); // Hint for the window to initiate a redraw GetWindowThread()->RequestRedraw(); } void HSplitter::OnSplitterMouseDrag(int /* x */, int y, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */, int header_pos) { Geometry geo = m_SplitterObject[header_pos]->GetGeometry(); int num_element = (int) m_SplitterObject.size(); if (header_pos == num_element - 1) { // The last splitter cannot be moved return; } mvt_dx = 0; mvt_dy = (y - m_point.y); if (m_ResizeOnSplitterRelease == false) { // Continuously redraw resize and redraw the 2 parts of the widget. // This is slow. geo.OffsetPosition(mvt_dx, mvt_dy); m_SplitterObject[header_pos]->SetGeometry(geo); ResizeSplitter(header_pos); mvt_dx = 0; mvt_dy = 0; } // Hint for the window to initiate a redraw GetWindowThread()->RequestRedraw(); } void HSplitter::ResizeSplitter(int header_pos) { int num_element = (int) m_SplitterObject.size(); if ((header_pos == 0) && (m_SplitterObject[header_pos]->GetBaseY() < GetBaseY())) { m_SplitterObject[header_pos]->SetBaseY(GetBaseY()); } if ((header_pos == num_element - 1) && (m_SplitterObject[header_pos]->GetBaseY() > GetBaseY() + GetBaseHeight() - HSPLITTERHEIGHT)) { m_SplitterObject[header_pos]->SetBaseY(GetBaseY() + GetBaseHeight() - HSPLITTERHEIGHT); } if (header_pos < (int) num_element - 1) { int posy0, posy1; posy0 = m_SplitterObject[header_pos]->GetBaseY(); posy1 = m_SplitterObject[header_pos + 1]->GetBaseY(); if (posy0 > posy1 - HSPLITTERHEIGHT) { posy0 = posy1 - HSPLITTERHEIGHT; m_SplitterObject[header_pos]->SetBaseY(posy0); } } if (0 < header_pos) { int posy0, posy1; posy0 = m_SplitterObject[header_pos]->GetBaseY(); posy1 = m_SplitterObject[header_pos - 1]->GetBaseY(); if (posy0 < posy1 + HSPLITTERHEIGHT) { posy0 = posy1 + HSPLITTERHEIGHT; m_SplitterObject[header_pos]->SetBaseY(posy0); } } ComputeContentSize(); QueueDraw(); } // HSplitter need to re implement DoneRedraw because it does not // have a m_compositionlayout where its child are located; void HSplitter::DoneRedraw() { std::vector::iterator it; for (it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++) { //(*it)->DoneRedraw(); if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = static_cast(*it); ic->DoneRedraw(); } } } Area* HSplitter::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; std::vector::iterator splitter_it; for (splitter_it = m_SplitterObject.begin(); splitter_it != m_SplitterObject.end(); splitter_it++) { Area* found_area = (*splitter_it)->FindAreaUnderMouse(mouse_position, event_type); if (found_area) return found_area; } std::vector::iterator it; for (it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); it++) { Area* found_area = (*it)->FindAreaUnderMouse(mouse_position, event_type); if (found_area) return found_area; } if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } bool HSplitter::AcceptKeyNavFocus() { return false; } Area* HSplitter::KeyNavIteration(KeyNavDirection direction) { if (m_InterfaceObject.empty()) return NULL; if (next_object_to_key_focus_area_) { if ((direction == KEY_NAV_LEFT) || (direction == KEY_NAV_RIGHT)) { // Don't know what to do with this return NULL; } std::vector::iterator it; std::vector::iterator it_next; it = std::find(m_InterfaceObject.begin(), m_InterfaceObject.end(), next_object_to_key_focus_area_); if (it == m_InterfaceObject.end()) { // Should never happen nuxAssert(0); return NULL; } it_next = it; ++it_next; if ((direction == KEY_NAV_UP) && (it == m_InterfaceObject.begin())) { // can't go further return NULL; } if ((direction == KEY_NAV_DOWN) && (it_next == m_InterfaceObject.end())) { // can't go further return NULL; } if (direction == KEY_NAV_UP) { --it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { if (it == m_InterfaceObject.begin()) break; --it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_DOWN) { ++it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == m_InterfaceObject.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } } else { Area* key_nav_focus = NULL; if (direction == KEY_NAV_UP) { std::vector::reverse_iterator it = m_InterfaceObject.rbegin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == m_InterfaceObject.rend()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } else { std::vector::iterator it = m_InterfaceObject.begin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == m_InterfaceObject.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } return key_nav_focus; } return NULL; } } nux-4.0.6+14.04.20140409/Nux/FloatingWindow.cpp0000644000015301777760000003603012321344237021150 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "HLayout.h" #include "WindowThread.h" #include "WindowCompositor.h" #include "FloatingWindow.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(FloatingWindow); /* Elements inside the Window have coordinates based on the top-left corner of the window. This is true whether we are drawing or computing the layout. When computing the layout, use x_root and y_root to pass the top-left corner position of the window. When drawing, make a similar adjustment. */ FloatingWindow::FloatingWindow(const char *WindowName, NUX_FILE_LINE_DECL) : BaseWindow(WindowName, NUX_FILE_LINE_PARAM) { m_bIsVisible = false; m_bSizeMatchLayout = false; m_bIsModal = false; m_bIsVisibleSizeGrip = true; m_SizeGripDragPositionX = 0; m_SizeGripDragPositionY = 0; m_hasTitleBar = true; _resize_handle_width = 20; _resize_handle_height = 20; _title_bar_height = 20; _minimize_button = new BasicView(NUX_TRACKER_LOCATION); _minimize_button->SetParentObject(this); _resize_handle = new BasicView(NUX_TRACKER_LOCATION); _resize_handle->SinkReference(); _resize_handle->SetParentObject(this); _title_bar = new BasicView(NUX_TRACKER_LOCATION); _title_bar->SinkReference(); _title_bar->SetParentObject(this); _close_button = new BasicView(NUX_TRACKER_LOCATION); _window_title_bar = new StaticTextBox("", NUX_TRACKER_LOCATION); _title_bar_layout = new HLayout(NUX_TRACKER_LOCATION); _title_bar_layout->Reference(); _minimize_button->SetMinMaxSize(20, 20); _minimize_button->SetGeometry(Geometry(0, 0, 20, 20)); _close_button->SetMinimumSize(20, 20); _close_button->SetGeometry(Geometry(0, 0, 20, 20)); _resize_handle->SetMinimumSize(_resize_handle_width, _resize_handle_height); _resize_handle->SetGeometry(Geometry(0, 0, _resize_handle_width, _resize_handle_height)); _title_bar->mouse_down.connect(sigc::mem_fun(this, &FloatingWindow::RecvTitleBarMouseDown)); _title_bar->mouse_drag.connect(sigc::mem_fun(this, &FloatingWindow::RecvTitleBarMouseDrag)); _close_button->mouse_click.connect(sigc::mem_fun(this, &FloatingWindow::RecvCloseButtonClick)); _resize_handle->mouse_drag.connect(sigc::mem_fun(this, &FloatingWindow::OnSizeGrigMouseDrag)); _resize_handle->mouse_down.connect(sigc::mem_fun(this, &FloatingWindow::OnSizeGrigMouseDown)); _title_bar_layout->AddView((_window_title_bar), 1, eCenter, eFix); _title_bar_layout->AddView((_close_button), 0, eCenter, eFix); _title_bar_layout->SetParentObject(this); if (HasTitleBar()) SetTopBorder(24); else SetTopBorder(6); SetBorder(2); SetMinimumSize(32, 32); SetGeometry(Geometry(100, 100, 320, 200)); std::string Path = NUX_FINDRESOURCELOCATION("UITextures/AddButton.png"); MinimizeIcon = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); MinimizeIcon->Update(Path.c_str()); Path = NUX_FINDRESOURCELOCATION("UITextures/CancelButton.png"); CloseIcon = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); CloseIcon->Update(Path.c_str()); SetWindowTitle(WindowName); } FloatingWindow::~FloatingWindow() { m_InterfaceObject.clear(); _resize_handle->UnParentObject(); _resize_handle->UnReference(); _title_bar->UnParentObject(); _title_bar->UnReference(); _minimize_button->UnReference(); CloseIcon->UnReference(); MinimizeIcon->UnReference(); _title_bar_layout->UnParentObject(); _title_bar_layout->UnReference(); } Area* FloatingWindow::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; NUX_RETURN_VALUE_IF_TRUE(_resize_handle->TestMousePointerInclusion(mouse_position, event_type), _resize_handle); NUX_RETURN_VALUE_IF_TRUE(_close_button->TestMousePointerInclusion(mouse_position, event_type), _close_button); if (HasTitleBar()) { NUX_RETURN_VALUE_IF_TRUE(_title_bar->TestMousePointerInclusion(mouse_position, event_type), _title_bar); } // if (_title_bar_layout) // { // nuxAssert(_title_bar_layout->IsLayout()); // Area* found_area = _title_bar_layout->FindAreaUnderMouse(mouse_position, event_type); // if (found_area) // return found_area; // } if (m_layout) { nuxAssert(m_layout->IsLayout()); Area* found_area = m_layout->FindAreaUnderMouse(mouse_position, event_type); if (found_area) return found_area; } if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } void FloatingWindow::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); // The elements position inside the window are referenced to top-left window corner. So bring base to(0, 0). base.SetX(0); base.SetY(0); graphics_engine.PushClippingRectangle(base); GetPainter().PushDrawShapeLayer(graphics_engine, base, eSHAPE_CORNER_ROUND10, Color(0xFF707070), eCornerTopLeft | eCornerTopRight, true); if (HasTitleBar()) { GetPainter().PaintShapeCorner(graphics_engine, Geometry(_title_bar->GetBaseX(), _title_bar->GetBaseY(), _title_bar->GetBaseWidth(), _title_bar->GetBaseHeight()), Color(0xFF2f2f2f), eSHAPE_CORNER_ROUND10, eCornerTopLeft | eCornerTopRight); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), _window_title_bar->GetGeometry(), _window_title, Color(0xFFFFFFFF), true, eAlignTextCenter); GetPainter().Draw2DTextureAligned(graphics_engine, CloseIcon, _close_button->GetGeometry(), TextureAlignmentStyle(eTACenter, eTACenter)); } GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } void FloatingWindow::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); // The elements position inside the window are referenced to top-left window corner. So bring base to(0, 0). base.SetX(0); base.SetY(0); GetPainter().PushShapeLayer(graphics_engine, base, eSHAPE_CORNER_ROUND10, Color(0xFF707070), eCornerTopLeft | eCornerTopRight, true); if (m_layout) { graphics_engine.PushClippingRectangle(base); m_layout->ProcessDraw(graphics_engine, force_draw); graphics_engine.PopClippingRectangle(); } GetPainter().PopBackground(); } void FloatingWindow::EnableTitleBar(bool b) { m_hasTitleBar = b; ComputeContentSize(); } bool FloatingWindow::HasTitleBar() const { return m_hasTitleBar; } void FloatingWindow::OnSizeGrigMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (IsSizeMatchContent()) { return; } // Do not let the _resize_handle test the event because the window is not displaying it; int XGrip = x; int YGrip = y; // We want to false on one half of the size grip square to register a mouse down. This is meant to leave more room // for the scrollbar buttons(if any) at the bottom right of the window. if ((XGrip > 0) && (YGrip > 0) && (XGrip > _resize_handle_height - YGrip)) { // has grip } m_SizeGripDragPositionX = x; m_SizeGripDragPositionY = y; //GetWindowCompositor().SetMouseFocusArea(this); } void FloatingWindow::OnSizeGrigMouseDrag(int x, int y, int dx, int dy, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (IsSizeMatchContent()) { return; } Geometry geo; geo = GetGeometry(); int ddx = 0; int ddy = 0; if ((dx > 0) && (x > m_SizeGripDragPositionX)) { ddx = dx; } if ((dx < 0) && (x < m_SizeGripDragPositionX)) { ddx = dx; } if ((dy > 0) && (y > m_SizeGripDragPositionY)) { ddy = dy; } if ((dy < 0) && (y < m_SizeGripDragPositionY)) { ddy = dy; } geo.OffsetSize(ddx, ddy); SetGeometry(geo); #if defined(USE_X11) if (m_input_window != 0) { //nuxDebugMsg("Resize Input window: %d, %d, %d, %d", geo.x, geo.y, geo.width, geo.height); m_input_window->SetGeometry(GetGeometry()); } #endif GetWindowThread()->QueueObjectLayout(this); QueueDraw(); } void FloatingWindow::RecvTitleBarMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { _title_bar_mouse_down_location = Point(x, y); } void FloatingWindow::RecvTitleBarMouseDrag(int /* x */, int /* y */, int dx, int dy, unsigned long /* button_flags */, unsigned long /* key_flags */) { Geometry geo; geo = GetGeometry(); geo.OffsetPosition(dx, dy); // Set the Window Size and Position Area::SetGeometry(geo); // No need to compute the window layout elements [LayoutWindowElements()]. They haven't changed. // No need to compute the layout [ComputeContentSize()]. It hasn't changed. _title_bar->SetGeometry(Geometry(0, 0, geo.GetWidth(), _title_bar_height)); #if defined(USE_X11) if (m_input_window != 0) { //nuxDebugMsg("Resize Input window: %d, %d, %d, %d", geo.x, geo.y, geo.width, geo.height); m_input_window->SetGeometry(GetGeometry()); } #endif QueueDraw(); } void FloatingWindow::RecvCloseButtonClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { #if defined(USE_X11) // Disable the input window if there is one. EnableInputWindow(false); #endif StopModal(); } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. void FloatingWindow::PreLayoutManagement() { Geometry geo = GetGeometry(); if (m_configure_notify_callback) { (*m_configure_notify_callback) (GetGraphicsDisplay()->GetWindowWidth(), GetGraphicsDisplay()->GetWindowHeight(), geo, m_configure_notify_callback_data); if (geo.IsNull()) { nuxDebugMsg("[FloatingWindow::PreLayoutManagement] Received an invalid Geometry."); geo = GetGeometry(); } else { Area::SetGeometry(geo); // Get the geometry adjusted with respect to min and max dimension of this area. geo = GetGeometry(); } } // Drag Bar Geometry if (HasTitleBar()) { _title_bar->SetGeometry(Geometry(0, 0, geo.GetWidth(), _title_bar_height)); } // Size grip Geometry Geometry SizeGripGeometry(geo.GetWidth() - _resize_handle_width, geo.GetHeight() - _resize_handle_height, _resize_handle_width, _resize_handle_height); _resize_handle->SetGeometry(SizeGripGeometry); if (m_layout) { Geometry layout_geo = Geometry(m_Border, m_TopBorder, geo.GetWidth() - 2 * m_Border, geo.GetHeight() - m_Border - m_TopBorder); m_layout->SetGeometry(layout_geo); } } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. long FloatingWindow::PostLayoutManagement(long /* LayoutResult */) { if (IsSizeMatchContent() && m_layout) { Geometry layout_geometry = m_layout->GetGeometry(); Geometry WindowGeometry = Geometry(GetGeometry().x, GetGeometry().y, layout_geometry.GetWidth() + 2 * m_Border, layout_geometry.GetHeight() + m_Border + m_TopBorder); Area::SetGeometry(WindowGeometry); } Geometry geo = GetGeometry(); // Drag Bar Geometry if (HasTitleBar()) { _title_bar->SetGeometry(Geometry(0, 0, geo.GetWidth(), _title_bar_height)); } // Size grip Geometry Geometry temp(geo.GetWidth() - _resize_handle_width, geo.GetHeight() - _resize_handle_height, _resize_handle_width, _resize_handle_height); _resize_handle->SetGeometry(temp); // Title Bar _title_bar_layout->SetGeometry(_title_bar->GetGeometry()); GetWindowThread()->ComputeElementLayout(_title_bar_layout); // A FloatingWindow must kill the result of the management and pass it to the parent Layout. return (eCompliantHeight | eCompliantWidth); //return result; } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. void FloatingWindow::ComputeContentPosition(float /* offsetX */, float /* offsetY */) { //ScrollView::ComputeContentPosition(offsetX, offsetY); Geometry geo = GetGeometry(); // Drag Bar Geometry if (HasTitleBar()) { _title_bar->SetGeometry(Geometry(0, 0, geo.GetWidth(), _title_bar_height)); } // Size grip Geometry Geometry temp(geo.GetWidth() - _resize_handle_width, geo.GetHeight() - _resize_handle_height, _resize_handle_width, _resize_handle_height); _resize_handle->SetGeometry(temp); // Title Bar _title_bar_layout->SetGeometry(_title_bar->GetGeometry()); GetWindowThread()->ComputeElementLayout(_title_bar_layout); } void FloatingWindow::LayoutWindowElements() { // Define the geometry of some of the component of the window. Otherwise, if the composition layout is not set, // then the component won't be correctly placed after a SetGeometry. This can be redundant if the composition layout is set. Geometry base = GetGeometry(); _title_bar->SetGeometry(Geometry(0, 0, base.GetWidth(), _title_bar_height)); _title_bar_layout->SetGeometry(_title_bar->GetGeometry()); GetWindowThread()->ComputeElementLayout(_title_bar_layout); // Size grip Geometry Geometry temp(base.GetWidth() - _resize_handle_width, base.GetHeight() - _resize_handle_height, _resize_handle_width, _resize_handle_height); _resize_handle->SetGeometry(temp); } void FloatingWindow::SetWindowTitle(const char *title) { NUX_RETURN_IF_NULL(title) _window_title = title; } std::string FloatingWindow::GetWindowTitle() { return _window_title; } } nux-4.0.6+14.04.20140409/Nux/MenuBar.h0000644000015301777760000000647612321344237017226 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef MENUBAR_H #define MENUBAR_H #include "ScrollView.h" #include "ToolButton.h" #include "MenuPage.h" #include "Painter.h" namespace nux { class PopupBox; class BaseWindow; class MenuBar; class HLayout; class MenuBarItem: public Object { public: NUX_DECLARE_OBJECT_TYPE(MenuBarItem, Object); MenuBarItem(NUX_FILE_LINE_PROTO); ~MenuBarItem(); private: BasicView *area; MenuPage *menu; BaseTexture *icon; // should be 24x24 friend class MenuBar; }; class MenuBar: public View { NUX_DECLARE_OBJECT_TYPE(MenuBar, View); public: MenuBar(NUX_FILE_LINE_PROTO); ~MenuBar(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); //void AddActionItem(ActionItem* actionItem); void AddMenu(const char *MenuLabel, MenuPage *popup); void AddMenu(const char *MenuLabel, MenuPage *menu, BaseTexture *icon); ///////////////// // EMITERS // ///////////////// private: void EmitItemMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags, MenuBarItem *menubar_item); void EmitItemMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags, MenuBarItem *menubar_item); void EmitItemMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags, MenuBarItem *menubar_item); void EmitItemMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, MenuBarItem *menubar_item); void RecvItemMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags, MenuBarItem *menubar_item); void RecvSigActionTriggered(MenuPage *, ActionItem *); void RecvSigTerminateMenuCascade(); //! Process a mouse down event outside of the menu cascade. /* Process a mouse down event outside of the menu cascade. The menu bar checks if the mouse down happened on one of its menu bar item. If yes, it let the menu bar item process the event. if no, it will initiate the closure of the menu cascade. \param menu menu item \param x coordinate of the mouse down event \param y coordinate of the mouse down event */ void RecvSigMouseDownOutsideMenuCascade(MenuPage *menu, int x, int y); protected: private: std::list< MenuBarItem * > m_MenuBarItemList; HLayout *m_hlayout; bool m_MenuIsActive; MenuBarItem *m_CurrentMenu; bool m_IsOpeningMenu; BaseWindow *m_MenuBarWindow; }; } #endif // MENUBAR_H nux-4.0.6+14.04.20140409/Nux/InputArea.h0000644000015301777760000004654212321344237017563 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef INPUTAREA_H #define INPUTAREA_H #include "Area.h" #if defined(NUX_OS_WINDOWS) #include "NuxGraphics/Events.h" #elif defined(NUX_OS_LINUX) #include "NuxGraphics/Events.h" #endif #include "NuxGraphics/GraphicsDisplay.h" #ifdef NUX_GESTURES_SUPPORT #include #include #include "Nux/GesturesSubscription.h" #endif namespace nux { #ifdef NUX_GESTURES_SUPPORT class GestureEvent; #endif class WindowCompositor; class InputArea; typedef InputArea CoreArea; class InputArea : public Area { public: NUX_DECLARE_OBJECT_TYPE(InputArea, Area); public: InputArea(NUX_FILE_LINE_PROTO); virtual ~InputArea(); //! Draw InputArea. /*! Draw a colored quad using m_AreaColor. Override this function to define a custom drawing function. If force_draw is true then the system requests that all objects redraw themselves completely. \param force_draw. */ virtual void OnDraw(GraphicsEngine &graphics_engine, bool force_draw); virtual void OverlayDrawing(GraphicsEngine & /* graphics_engine */) {} bool HasKeyboardFocus(); bool MouseFocusOnOtherArea(); void CaptureMouseDownAnyWhereElse(bool b); bool IsCaptureMouseDownAnyWhereElse() const; Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); Area* FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state); virtual bool AcceptKeyNavFocus() const; /*! Sets whether this InputArea wants to know about all mouse events sent to a child InputArea. ChildMouseEvent() will be called for every mouse event that a child InputArea receives. \param enable Whether this InputArea should be informed about child mouse events \sa ChildMouseEvent(), IsTrackingChildMouseEvents() */ void SetTrackChildMouseEvents(bool enable); /*! Returns whether this InputArea wants to be informed about child mouse events. This property is false by default. \sa SetTrackChildMouseEvents(), ChildMouseEvent() */ bool IsTrackingChildMouseEvents() const; /*! Called when a mouse event is sent to a child InputArea. If you return true, mouse ownership will be moved to this InputArea and the child InputArea will receive a MOUSE_CANCEL event. If you return false, nothing happens and the child will keep its ownership over the mouse and therefore get further mouse events. The default implementation just returns false; \return Whether you want to take ownership over the mouse. \sa SetTrackChildMouseEvents */ virtual bool ChildMouseEvent(const Event& event); protected: private: bool _dnd_enabled_as_source; bool _dnd_enabled_as_target; public: // Override the virtual methods from Object Base // Here, we get a change to update the text of the keyboard handler. void SetKeyboardReceiverIgnoreMouseDownOutside(bool ignore_mouse_down_outside); void SetAcceptKeyNavFocusOnMouseDown(bool accept); void SetAcceptKeyNavFocusOnMouseEnter(bool accept); bool KeyboardReceiverIgnoreMouseDownOutside(); virtual bool IsArea() const { return true; } void GrabPointer(); void GrabKeyboard(); void UnGrabPointer(); void UnGrabKeyboard(); bool OwnsPointerGrab(); bool OwnsKeyboardGrab(); //! Return true if this Area is the owner of the mouse pointer. /*! The owner of the mouse pointer is the Area that has received a Mouse down event and the mouse button responsible for the event is still pressed. @return True if this Area is the owner of the mouse pointer. */ bool IsMouseOwner(); //! Returns true if the mouse pointer has been determined as inside the this area, following event processing. /*! Returns true if during a call to FindAreaUnderMouse, this area has been determined to be directly under the mouse pointer. Note that this is true only for the first area that is found. There might be other areas that which have the mouse pointer inside of them. \n Call Area::IsMousePointerInside to find out if the mouse pointer is inside an area. @return Return true if the mouse pointer is inside the Area. */ bool IsMouseInside(); //! Enable the double click event signal on this InputArea. void EnableDoubleClick(bool double_click); //! Returns true if the double click signal is enable for this InputArea. bool DoubleClickEnabled() const; bool mouse_in_; #if defined(NUX_OS_LINUX) void HandleDndEnter() {ProcessDndEnter();} void HandleDndLeave() {ProcessDndLeave();} #endif private: //! Event processing in exclusive mode. /*! Bypass OnEvent and performs a simplified event processing mechanism. */ long ProcessEventInExclusiveMode(Event &event, long TraverseInfo, long ProcessEventInfo); void HandleDndMove (Event &event); void HandleDndDrop (Event &event); //! Color of the InputArea /* Color of the InputArea use to draw a colored quad when OnDraw() is called. */ Color area_color_; int _dnd_safety_x; int _dnd_safety_y; protected: bool _capture_mouse_down_any_where_else; bool _double_click; //!< If True, this InputArea can emit the signal mouse_double_click. Default is false. bool _keyboard_receiver_ignore_mouse_down_outside; bool accept_key_nav_focus_on_mouse_down_; bool accept_key_nav_focus_on_mouse_enter_; #if defined(NUX_OS_LINUX) // DnD support // Rather than being implemented with signals, DND support is implemented with protected virtual function. // This ensure that a class and it subclass don't process the same event more than once! virtual void ProcessDndMove (int x, int y, std::listmimes); virtual void ProcessDndDrop (int x, int y); virtual void ProcessDndEnter(); virtual void ProcessDndLeave(); void SendDndStatus(bool accept, DndAction action, Geometry region); void SendDndFinished(bool accepted, DndAction action); void SetDndEnabled(bool as_source, bool as_target); virtual bool DndSourceDragBegin (); virtual NBitmapData * DndSourceGetDragImage (); virtual std::list DndSourceGetDragTypes (); virtual const char * DndSourceGetDataForType(const char *type, int *size, int *format); virtual void DndSourceDragFinished (DndAction result); void StartDragAsSource(); static NBitmapData * InnerDndSourceGetDragImage(void *data) { return static_cast (data)->DndSourceGetDragImage(); } static std::list InnerDndSourceGetDragTypes(void *data) { return static_cast (data)->DndSourceGetDragTypes(); } static void InnerDndSourceDragFinished(DndAction result, void *data); static const char * InnerDndSourceGetDataForType(const char *type, int *size, int *format, void *data) { return static_cast (data)->DndSourceGetDataForType(type, size, format); } #endif public: #ifdef NUX_GESTURES_SUPPORT //! Creates a new gesture subscription for this input area and activates it /* Convenience function. It's the same as doing the following: ShGesturesSubscription sub(new GesturesSubscription); sub->SetGestureClasses(gesture_classes); sub->SetNumTouches(num_touches); sub->Activate(); input_area->AddGesturesSubscription(sub); */ void CreateGesturesSubscription(int gesture_classes, unsigned int num_touches); //! Adds a gestures subscription to this input area. /*! A single subscription can be shared among multiple InputAreas. */ void AddGesturesSubscription(ShGesturesSubscription &subscription); //! Removes a gestures subscription from this input area. void RemoveGesturesSubscription(ShGesturesSubscription &subscription); //! Returns all multitouch gestures subscriptions that this area cares about. /*! An input area will receive GestureEvents for multitouch gestures that hit his area and matches any active subscription present in this list. */ const std::list &GetGesturesSubscriptions() const; //! Returns whether this area has a subscription that matches the gesture event bool HasSubscriptionForGesture(const GestureEvent &event) const; //! Returns the InputArea hit by the given gesture /*! If this area or any of its children is hit by the gesture from the given event, that area will be returned. Otherwise, it returns nullptr. */ virtual Area* GetInputAreaHitByGesture(const GestureEvent &event); private: std::list gestures_subscriptions_; #endif // NUX_GESTURES_SUPPORT public: //! Signal emitted when the Mouse moves over the InputArea surface. sigc::signal mouse_move; // send the current position inside the area //! Signal emitted when the InputArea receives a mouse down event. /*! @param void Return type of the callback hooked to this signal. @param int Mouse X position(1st parameter of the callback). @param int Mouse Y position(2nd parameter of the callback). @param unsigned long Mouse button states(3rd parameter of the callback). @param unsigned long Keyboard special keys states(4th parameter of the callback). */ sigc::signal mouse_down; //! Signal emitted when the InputArea receives a mouse up event. /*! @param void Return type of the callback hooked to this signal. @param int Mouse X position(1st parameter of the callback). @param int Mouse Y position(2nd parameter of the callback). @param unsigned long Mouse button states(3rd parameter of the callback). @param unsigned long Keyboard special keys states(4th parameter of the callback). */ sigc::signal mouse_up; //! Signal emitted when the InputArea receives a mouse enter event. /*! @param void Return type of the callback hooked to this signal. @param int Mouse X position(1st parameter of the callback). @param int Mouse Y position(2nd parameter of the callback). @param unsigned long Mouse button states(3rd parameter of the callback). @param unsigned long Keyboard special keys states(4th parameter of the callback). */ sigc::signal mouse_enter; //! Signal emitted when the InputArea receives a mouse leave event. /*! @param void Return type of the callback hooked to this signal. @param int Mouse X position(1st parameter of the callback). @param int Mouse Y position(2nd parameter of the callback). @param unsigned long Mouse button states(3rd parameter of the callback). @param unsigned long Keyboard special keys states(4th parameter of the callback). */ sigc::signal mouse_leave; //! Signal emitted when the InputArea receives a mouse down followed later by a mouse release over its surface. /*! @param void Return type of the callback hooked to this signal. @param int Mouse X position(1st parameter of the callback). @param int Mouse Y position(2nd parameter of the callback). @param unsigned long Mouse button states(3rd parameter of the callback). @param unsigned long Keyboard special keys states(4th parameter of the callback). */ sigc::signal mouse_click; //! Signal emitted when the InputArea receives a double click event. /*! @param void Return type of the callback hooked to this signal. @param int Mouse X position(1st parameter of the callback). @param int Mouse Y position(2nd parameter of the callback). @param unsigned long Mouse button states(3rd parameter of the callback). @param unsigned long Keyboard special keys states(4th parameter of the callback). */ sigc::signal mouse_double_click; //! Signal emitted when the InputArea receives a mouse down event, followed later by a mouse move event(while the mouse is still pressed). /*! @param void Return type of the callback hooked to this signal. @param int Mouse X position(1st parameter of the callback). @param int Mouse Y position(2nd parameter of the callback). @param int Mouse X delta(3thr parameter of the callback). @param int Mouse Y delta(4th parameter of the callback). @param unsigned long Mouse button states(5th parameter of the callback). @param unsigned long Keyboard special keys states(6th parameter of the callback). */ sigc::signal mouse_drag; // send(current X, current Y, delta X, delta Y) //! Signal emitted when the InputArea receives a mouse wheel event. sigc::signal < void, int, // window x int, // window y int, // mouse wheel delta: +120/-120 correspond to one notch of the wheel unsigned long, // mouse state unsigned long // key state > mouse_wheel; // send(current X, current Y, delta X, delta Y) //! Signal emitted when the InputArea loses ownership over a pressed mouse. /*! Any actions or changes caused by the previous mouse_down should be reverted. */ sigc::signal mouse_cancel; //! Signal emitted when the InputArea receives a key release event. sigc::signal key_up; //! Signal emitted when the area gets the keyboard focus. The is a result of a mouse down event or a call to ForceStartFocus. sigc::signal begin_key_focus; //! Signal emitted when the area looses the keyboard focus. sigc::signal end_key_focus; sigc::signal < void, unsigned long , /*event type*/ unsigned long , /*event keysym*/ unsigned long , /*event state*/ const char* , /*character*/ unsigned short /*key repeat count*/ > key_down; //! Signal emitted when a mouse down event occurs outside of this area /*! If this area is inside the main layout, then the position is relative to the top left corner of the window. If this area is a BaseWindow, then the position is relative to the top left corner of the window. If this area is inside a BaseWindow, then the position is relative to the top left corner of the BaseWIndow. @param int Position of the mouse down event. @param int Position of the mouse down event. @param ulong Mouse button states. @param ulong Keyboard modifiers states. */ sigc::signal mouse_down_outside_pointer_grab_area; sigc::signal start_keyboard_grab; sigc::signal end_keyboard_grab; #ifdef NUX_GESTURES_SUPPORT //! Called whenever a GestureEvent is received /*! You should reimplement this method to handle gestures. Typically you would add code to make this area react to the gestures received. In order to receive events from a given kind of gesture, an area has to have a corresponding gesture subscription. See CreateGesturesSubscription() and AddGesturesSubscription(). This method is called only with gestures that have already been accepted. Therefore you shouldn't call GestureEvent::Accept() or GestureEvent::Reject() from here as there's no point in doing so. Default implementation just returns GestureDeliveryRequest::NONE. */ virtual GestureDeliveryRequest GestureEvent(const GestureEvent & /* event */) { return GestureDeliveryRequest::NONE; } #endif protected: virtual bool AcceptKeyNavFocus(); virtual bool AcceptKeyNavFocusOnMouseDown() const; virtual bool AcceptKeyNavFocusOnMouseEnter() const; // == Signals with 1 to 1 mapping to input device == virtual void EmitMouseDownSignal (int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseUpSignal (int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseMoveSignal (int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseWheelSignal (int x, int y, int wheel_delta, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitKeyDownSignal (unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state); virtual void EmitKeyUpSignal (unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state); virtual void EmitKeyEventSignal (unsigned long event_type, unsigned int key_symbol, unsigned long special_keys_state, const char* text, int key_repeat_count); // == Interpreted signals == // Mouse down + mouse move on an area virtual void EmitMouseDragSignal (int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseEnterSignal (int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseLeaveSignal (int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseClickSignal (int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseDoubleClickSignal(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseDownOutsideArea (int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state); virtual void EmitMouseCancelSignal(); friend class WindowCompositor; private: bool is_tracking_child_mouse_events_; }; } #endif // INPUTAREA_H nux-4.0.6+14.04.20140409/Nux/WindowCompositor.h0000644000015301777760000005532012321344237021213 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef WINDOWCOMPOSITOR_H #define WINDOWCOMPOSITOR_H #include #include "BaseWindow.h" #include #include #include #ifdef NUX_GESTURES_SUPPORT #include #include "Gesture.h" #include "GestureBroker.h" #endif namespace nux { class MenuPage; class PBuffer; class WindowThread; class View; class InputArea; class InputAreaProximity; class Area; class PaintLayer; class Event; //! A user interface composition class created by WindowThread. class WindowCompositor : public sigc::trackable { public: typedef ObjectWeakPtr WeakBaseWindowPtr; typedef std::function ForEachBaseWindowFunc; WindowCompositor(WindowThread* window_thread); ~WindowCompositor(); //! Get the Geometry of the tooltip based on the BaseWindow that initiated it. Geometry GetTooltipGeometry() const; //! Get the Geometry of the tooltip based on the MainWindow. Geometry GetTooltipMainWindowGeometry() const; // bool MouseDown(Point pt); // // bool MouseMove(Point pt); // bool MouseUp(Point pt); void ProcessEvent(Event& event); //==================================== void MouseEventCycle(Event& event); void DndEventCycle(Event& event); Point _mouse_position_on_owner; Point _mouse_position; //! Get Mouse position relative to the top left corner of the window. Point GetMousePosition(); int GetProximityListSize() const; void AddAreaInProximityList(InputAreaProximity* area_prox); void RemoveAreaInProximityList(InputAreaProximity* area_prox); void KeyboardEventCycle(Event& event); #if !defined(NUX_MINIMAL) void MenuEventCycle(Event& event); MenuPage* _mouse_owner_menu_page; MenuPage* _mouse_over_menu_page; #endif bool _starting_menu_event_cycle; bool _menu_is_active; //! Set the area that has the keyboard focus. /*! Set the area that has the keyboard focus. If the \i area parameter is NULL, \n the area that has the keyboard focus looses it and the function returns false. @param The area that that gets the keyboard focus. @param The key nav direction that initiated the focus to the provided area. @return True if the area succeeded to get the keyboard focus or it already has it. */ bool SetKeyFocusArea(InputArea* area, KeyNavDirection direction = KEY_NAV_NONE); //! Return the area that has the keyboard focus. /*! Return the area that has the keyboard focus. @return The area that has the keyboard focus. */ InputArea* GetKeyFocusArea(); void ForEachBaseWindow(ForEachBaseWindowFunc const&); //! Signal emitted when a BaseWindow becomes visible. /*! This signal is emitted after the BaseWindow has emitted it own sigVisible signal. */ sigc::signal sigVisibleViewWindow; //!< Signal emitted when the BaseWindow becomes visible. //! Signal emitted when a BaseWindow becomes hidden. /*! This signal is emitted after the BaseWindow has emitted it own sigHidden signal. */ sigc::signal sigHiddenViewWindow; //!< Signal emitted when the BaseWindow becomes hidden. private: /*** Helper functions for MouseEventCycle() ***/ void UpdateKeyNavFocusOnMouseDown(); /* Keeps track of mouse movement and emits mouse_move and mouse_drag accordingly. */ void TrackMouseMovement(const Event &event, bool area_under_mouse_changed); /* Updates mouse_over_area_ and emits mouse_enter and mouse_leave signals accordingly. Returns whether mouse_over_area_ has changed */ bool UpdateWhatAreaIsUnderMouse(const Event& event); /* Processes NUX_MOUSEWHEEL events */ void ProcessMouseWheelEvent(Event& event); /* Updates mouse_owner_area_ and emits mouse_down, mouse_up, mouse_click and mouse_double_click accordingly. */ void UpdateMouseOwner(const Event& event, bool area_under_mouse_changed); /* Feed the appropriate InputArea::ChildMouseEvent() and switch mouse ownership (including the emission of mouse_cancel) if asked to. */ void UpdateEventTrackingByMouseOwnerAncestor(const Event& event); void FindAncestorInterestedInChildMouseEvents(Area *area); //! Traverse the widget tree and found the area that is right below the mouse pointer. void FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type, ObjectWeakPtr& area_under_mouse_pointer); void GetAreaUnderMouse(const Point& mouse_position, NuxEventType event_type, ObjectWeakPtr& area_under_mouse_pointer, WeakBaseWindowPtr& window); //! Traverse the widget tree and found the area has the key focus. void FindKeyFocusArea(NuxEventType event_type, unsigned int key_symbol, unsigned int special_keys_state, ObjectWeakPtr& key_focus_area, WeakBaseWindowPtr& window); //! Traverse the widget tree and found the area has the key focus, but start from a specified widget. void FindKeyFocusAreaFrom(NuxEventType event_type, unsigned int key_symbol, unsigned int special_keys_state, InputArea* root_search_area, ObjectWeakPtr& key_focus_area, WeakBaseWindowPtr& window); void ResetMousePointerAreas(); //! Get the area upon which the mouse button is currently down. ObjectWeakPtr const& GetMouseOwnerArea() const; //! Set the area upon which the mouse button is currently down. void SetMouseOwnerArea(InputArea* area); //! Set the area that is right below the mouse pointer. void SetMouseOverArea(InputArea* area); void SendKeyEvent(InputArea* input_area, NuxEventType event_type, unsigned int key_sym, unsigned long x11_key_code, unsigned long special_keys_state, const char* text, int key_repeat_count); //! Checks the list of porximities to see if the mouse is near any areas. void CheckMouseNearArea(Event const& event); //! The InputArea that has the keyboard navigation focus. /*! The InputArea that has the mouse focus also has the keyboard focus. That is if _mouse_focus_area is not Null then _mouse_focus_area is equal to _mouse_focus_area; */ ObjectWeakPtr key_focus_area_; ObjectWeakPtr mouse_owner_area_; ObjectWeakPtr mouse_over_area_; /* An ancestor of the current mouse owner area that wants to be notified about all mouse events that a descendant receives and optionally take ownership over the mouse at any given moment. \sa InputArea::ChildMouseEvent() */ /* TODO: Make it a list/vector once the need for nested trackers. */ ObjectWeakPtr interested_mouse_owner_ancestor_; int dnd_safety_x_; int dnd_safety_y_; public: /*! This signal is similar to Area::key_nav_focus_change. It is emitted from the WindowCompositor. The user only needs to listen to this signal to find out the area that has received the keyboard focus.\n The signal is received whether the area receiving or loosing the keyboard focus.\n If the second parameter is true, it means the area is receiving the focus.\n The third parameter of this signal indicates the keyboard action that triggered this area \n to receive or loose the keyboard focus. */ sigc::signal key_nav_focus_change; /*! This signal is similar to Area::key_nav_focus_activate. It is emitted from the WindowCompositor. The user only needs to listen to this signal to find out the area that has has been activated through the keyboard (ENTER key has been pressed).\n */ sigc::signal key_nav_focus_activate; //==================================== public: /*! Set and external fbo to draw Nux BaseWindow into. This external fbo will be restored after Nux completes it rendering. The external fbo is used only in embedded mode. \n If the fbo_object parameter 0, then the reference fbo is invalid and will not be used. @param draw_fbo_object The opengl index of the GL_DRAW_FRAMEBUFFER_EXT. @param read_fbo_object The opengl index of the GL_READ_FRAMEBUFFER_EXT. @param fbo_geometry The geometry of the fbo. */ void SetReferenceFramebuffer(unsigned int draw_fbo_object, unsigned int read_fbo_object, const Geometry &fbo_geometry); /*! Bind the reference opengl framebuffer object. @return True if no error was detected. */ bool RestoreReferenceFramebuffer(); void RestoreMainFramebuffer(); ObjectPtr& GetWindowFrameBufferObject() { return m_FrameBufferObject; } ObjectPtr m_FrameBufferObject; void StartModalWindow(WeakBaseWindowPtr); void StopModalWindow(WeakBaseWindowPtr); #if !defined(NUX_MINIMAL) void AddMenu(MenuPage* menu, BaseWindow* window, bool OverrideCurrentMenuChain = true); void RemoveMenu(MenuPage* menu); void CleanMenu(); #endif void PushModalWindow(WeakBaseWindowPtr window); void SetWidgetDrawingOverlay(InputArea* ic, BaseWindow* OverlayWindow); InputArea* GetWidgetDrawingOverlay(); void SetTooltip(InputArea* TooltipArea, const char* TooltipText, int x, int y); /*! Return true if the mouse is still inside the area that initiated the tooltip; @param x The mouse x coordinate on screen. @param y The mouse y coordinate on screen. @return Return true is the mouse is still inside the area. */ bool ValidateMouseInsideTooltipArea(int x, int y); /*! Return true if there is a valid tooltip active. @return Return true if there is a valid tooltip active. */ bool IsTooltipActive(); void CancelTooltip(); void SetBackgroundPaintLayer(AbstractPaintLayer* bkg); /*! A special BaseWindow that is always on top of all other BaseWindow. It is even above the BaseWindow that is selected. */ void SetAlwaysOnFrontWindow(BaseWindow* window); //! Set the rendering surface for the current rendering. /*! This function is used to restore the rendering surface according to the system state. This is necessary after using a custom frame buffer object. */ void RestoreRenderingSurface(); //! Get the backup texture data of this BaseWindow, void* GetBackupTextureData(BaseWindow* base_window, int& width, int& height, int& format); //! Reset the DND focus area /*! Set the DND focus area to NULL. \sa _dnd_area; */ void ResetDnDArea(); // SetDnDArea is declared as private. //void SetDnDArea(InputArea* area); InputArea* GetDnDArea(); //! Get the top view that is being processed(event or rendering). /*! Get the active ViewWindow during and event processing or rendering. */ BaseWindow* GetProcessingTopView() { return m_CurrentWindow.GetPointer(); } // Pointer Grab API //! Add an area at the top of the pointer grab stack /*! Add an area at the top of the pointer grab stack. The area at the top of the pointer grab stack has the exclusivity on the pointer events. And area can be added multiple times to the stack but not successively. @param area The area to put at the top of the pointer grab stack. @return True if the Area was successfully added at the top of the pointer grab stack. */ bool GrabPointerAdd(InputArea* area); //! Remove an area from the pointer grab stack /*! If the Area was added multiple time to the pointer grab stack then the top most instance of the parameter area is removed. @param area The area to remove from the top of the pointer grab stack. @return True if the Area was successfully removed. */ bool GrabPointerRemove(InputArea* area); //! Returns True if the area parameter is inside the pointer grab stack. bool IsInPointerGrabStack(InputArea* area); //! Returns the area at the top of the pointer grab stack. InputArea* GetPointerGrabArea(); // Keyboard Grab API //! Add an area at the top of the keyboard grab stack /*! Add an area at the top of the keyboard grab stack. The area at the top of the keyboard grab stack has the exclusivity on the keyboard events. And area can be added multiple times to the stack but not successively. @param area The area to put at the top of the keyboard grab stack. @return True if the Area was successfully added at the top of the keyboard grab stack. */ bool GrabKeyboardAdd(InputArea* area); //! Remove an area from the keyboard grab stack /*! If the Area was added multiple time to the keyboard grab stack then the top most instance of the parameter area is removed. @param area The area to remove from the top of the keyboard grab stack. @return True if the Area was successfully removed. */ bool GrabKeyboardRemove(InputArea* area); //! Returns True if the area parameter is inside the keyboard grab stack. bool IsInKeyboardGrabStack(InputArea* area); //! Returns the area at the top of the keyboard grab stack. InputArea* GetKeyboardGrabArea(); // We use Rectangle texture to attach to the frame-buffer because some GPU like the Geforce FX 5600 do not // have support for ARB_texture_non_power_of_two. However it does support ARB_texture_recatangle. struct RenderTargetTextures { ObjectPtr color_rt; ObjectPtr depth_rt; }; //! Return the RenderTargetTextures structure of a BaseWindow. /*! Return the color and depth texture of a BaseWindow. @param window The BaseWindow. @return A structure that contains the color and depth texture of a BaseWindow. */ RenderTargetTextures& GetWindowBuffer(BaseWindow* window); #ifdef NUX_GESTURES_SUPPORT InputArea *LocateGestureTarget(const GestureEvent &event); void SetGestureBroker(std::unique_ptr gesture_broker); #endif private: typedef std::list WindowList; //! Render the interface. void Draw(bool SizeConfigurationEvent, bool force_draw); void DrawPopup(bool force_draw); void DrawMenu(bool force_draw); void DrawOverlay(bool force_draw); void DrawTooltip(bool force_draw); //! Render all top views. /*! @force_draw True if the entire surface of the backup rendering mush flushed. @WindowList The list of top views. @draw_modal True if the top view that is modal is to be rendered. */ void RenderTopViews(bool force_draw, WindowList&, bool draw_modal); void PresentAnyReadyWindows(); //! Render the content of a top view. void RenderTopViewContent(BaseWindow* window, bool force_draw); void RenderMainWindowComposition(bool force_draw); /*! Render a textured quad the quad has the size of the texture. The texture maybe the main window texture or a BaseWindow texture. @param HWTexture Texture to render. @param x Coordinates of the top left corner of the quad. @param y Coordinates of the top left corner of the quad. @param RenderToMainTexture If true, render to the main window texture. If false, render to the default back buffer. @param BluredBackground If true, the texture is blended with the blurred version of the main window texture. */ void PresentBufferToScreen(ObjectPtr HWTexture, int x, int y, bool RenderToMainTexture, bool BluredBackground = false, float opacity=1.0f, bool premultiply = false); //! Push a floating view just above another floating view. /*! Note that only the top_floating_view is moving. The overall position of the reference view is not changing. @param top_floating_view The view to place above bottom_floating_view. @param top_floating_view The reference view that will be below top_floating_view. @param strict If true and top_floating_view is already above bottom_floating_view, then bring top_floating_view lower so that it is strictly above bottom_floating_view. */ void PushHigher(BaseWindow* top_floating_view, BaseWindow* bottom_floating_view, bool strict = false); //! Push a floating view at the top of the stack. void PushToFront(BaseWindow* bottom_floating_view); //! Push a floating view at the bottom of the stack. void PushToBack(BaseWindow* bottom_floating_view); //! Set the top view that is about to be processed(event or rendering). /*! Before event processing or rendering, this should be called to set the ViewWindow that is about to be processed. This function is used internally by the system. */ void SetProcessingTopView(BaseWindow* window) { m_CurrentWindow = window; } private: void EnsureAlwaysOnFrontWindow(); void FormatRenderTargets(int width, int height); //void UpdatePostProcessRT(); /*! Floating Area need to be informed when the main window has been resized. @param Width New width of the window. @param Height New height of the window. */ void FloatingAreaConfigureNotify(int Width, int Height); void RegisterWindow(BaseWindow*); // UnRegister is called via the object destroyed event, hence the Object*. void UnRegisterWindow(Object*); ObjectPtr m_MainColorRT; ObjectPtr m_MainDepthRT; WeakBaseWindowPtr m_CurrentWindow; //!< BaseWindow where event processing or rendering is happening. WeakBaseWindowPtr m_MenuWindow; //!< The BaseWindow that owns the menu being displayed; void SetDnDArea(InputArea* area); // DnD support InputArea* _dnd_area; //!< the area where the mouse is located during a DND action. //! True while events are being processed inside ProcessEvent(). bool inside_event_cycle_; //! True while inside the rendering cycle. bool inside_rendering_cycle_; InputArea* OverlayDrawingCommand; WeakBaseWindowPtr m_OverlayWindow; //!< The window that owns the overlay; WeakBaseWindowPtr _tooltip_window; //!< The window that owns the tooltip; Geometry _tooltip_geometry; //!< The geometry of the entire tooltip It includes the decoration surrounding the text such as round corners. Geometry _tooltip_mainwindow_geometry; //!< Same as _tooltip_geometry but based on the entire physical window of the application. Geometry _tooltip_text_geometry; //!< The geometry of the text area of the tooltip. bool on_menu_closure_continue_with_event_; AbstractPaintLayer* m_Background; WindowList _view_window_list; WindowList _modal_view_window_list; WeakBaseWindowPtr _always_on_front_window; //!< Floating view that always remains on top. #if !defined(NUX_MINIMAL) std::list* _menu_chain; #endif std::map _window_to_texture_map; bool m_MenuRemoved; // Window Geometry int m_Width; int m_Height; std::string m_TooltipText; InputArea* m_TooltipArea; int m_TooltipX; int m_TooltipY; //! The fbo to restore after Nux rendering in embedded mode. unsigned int draw_reference_fbo_; unsigned int read_reference_fbo_; Geometry reference_fbo_geometry_; //! True if the platform has support for depth textures. bool platform_support_for_depth_texture_; //! Pointer grab stack. /*! The head of the list is the top of the stack. \sa GrabPointerAdd, GrabPointerRemove. */ std::list pointer_grab_stack_; //! Keyboard grab stack. /*! The head of the list is the top of the stack. \sa GrabKeyboardAdd, GrabKeyboardRemove. */ std::list keyboard_grab_stack_; //! List of views that will get checked for the mouse_near signal /*! A list of views that will be checked if \near the mouse. Must add views to this \list to be checked. */ std::list area_proximities_; private: WindowThread* window_thread_; //!< The WindowThread to which this object belongs. #ifdef NUX_GESTURES_SUPPORT std::unique_ptr gesture_broker_; #endif WindowList* currently_rendering_windows_; Geometry* current_global_clip_rect_; //! Perform some action before destruction. /*! Perform some action before destruction. This function should only be called from WindowThread::ThreadDtor(). It will invalidate the area that currently has the keyboard focus. */ void BeforeDestructor(); WindowCompositor(const WindowCompositor&); // Does not make sense for a singleton. This is a self assignment. WindowCompositor& operator= (const WindowCompositor&); // Declare operator address-of as private WindowCompositor* operator & (); friend class InputArea; friend class WindowThread; friend class TimerHandler; friend class MenuBar; friend class MenuPage; friend class BaseWindow; friend class HSplitter; friend class VSplitter; friend class TableCtrl; friend class View; friend class TestWindowCompositor; }; #ifdef NUX_GESTURES_SUPPORT class DefaultGestureBroker : public GestureBroker { public: DefaultGestureBroker(WindowCompositor *window_compositor); private: std::vector virtual FindGestureTargets(const nux::GestureEvent &event); WindowCompositor *window_compositor_; }; #endif } #endif // WINDOWCOMPOSITOR_H nux-4.0.6+14.04.20140409/Nux/View.h0000644000015301777760000001604512321344237016600 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ABSTRACTOBJECTBASE_H #define ABSTRACTOBJECTBASE_H #include "Nux.h" #include "NuxCore/Property.h" #define NeedRedraw QueueDraw namespace nux { class Layout; #ifdef NUX_GESTURES_SUPPORT class GestureEvent; #endif class View: public InputArea { NUX_DECLARE_OBJECT_TYPE(View, InputArea); public: View(NUX_FILE_LINE_DECL); virtual ~View(); public: /* If ComputeContentSize is called while outside of the layout process (\sa IsInsideLayoutCycle) then the parents of this object maybe added to the layout queue if this view size changes. \sa Area::ReconfigureParentLayout. */ virtual long ComputeContentSize(); virtual void ComputeContentPosition(float offsetX, float offsetY); //! Enable a View. /*! Enable the view. The view cannot receive events. As for the rendering, each view handle its own rendering while is enabled state. */ virtual void EnableView(); //! Disable a View. /*! Disable the view. The view cannot receive input events(keyboard, mouse, touch). As for the rendering, each view handle its own rendering while is disabled state. */ virtual void DisableView(); //! Set the enable state of the view. /*! Set the enable state of the view. @param enable. The state of the view to be set. */ virtual void SetEnableView(bool enable); //! Gets the enable state of the View. /*! @return True if the view is active. */ bool IsViewEnabled() const; public: virtual void ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw); //! Causes a redraw. The widget parameter draw_cmd_queued_ is set to true. The widget Draw() and DrawContent() are called. /*! Emits the signal \i queue_draw. */ virtual void QueueDraw(); //! Causes a soft redraw. The widget parameter draw_cmd_queued_ is set to false. The widget DrawContent() is called. virtual void NeedSoftRedraw(); virtual bool IsRedrawNeeded(); virtual void DoneRedraw(); virtual void OverlayDrawing(GraphicsEngine & /* graphics_engine */) {} //Layout Bridge bool SearchInAllSubNodes(Area *bo); bool SearchInFirstSubNodes(Area *bo); /* void SetGeometry(int x, int y, int w, int h);*/ //! Set Geometry /* Set the Geometry of the View and the geometry of the Default Background Area. For simple interface control UI classes(RGBValuator...), this is enough. For others, they have to overwrite the function and do the appropriate computations for their component. */ virtual void SetGeometry(const Geometry &geo); //! Return true if this object can break the layout. /* Return true if this object can break the layout, meaning, the layout can be done on the composition layout only without recomputing the whole window layout. */ virtual bool CanBreakLayout() { return false; } virtual void SetTextColor(const Color &color); virtual Color GetTextColor() const; //! Get the default layout of this view. /*! Get the default layout of this view. @return The default layout of this view. */ virtual Layout* GetLayout(); //! Set the default layout for this view. /*! Set the default layout for this view. Assigns a scale factor of 1 to the layout. @param layout A Layout object. */ virtual bool SetLayout(Layout *layout); sigc::signal LayoutAdded; sigc::signal LayoutRemoved; void SetFont(ObjectPtr font); ObjectPtr GetFont(); sigc::signal queue_draw; //!< Signal emitted when a view is scheduled for a draw. sigc::signal child_queue_draw; //!< Signal emitted when a child of this view is scheduled for a draw. virtual Area* KeyNavIteration(KeyNavDirection direction); virtual bool AcceptKeyNavFocus(); virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual Area* FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state); #ifdef NUX_GESTURES_SUPPORT virtual Area* GetInputAreaHitByGesture(const nux::GestureEvent &event); #endif protected: virtual void ChildViewQueuedDraw(Area* area); void BeginBackupTextureRendering(GraphicsEngine& graphics_engine, bool force_draw); void EndBackupTextureRendering(GraphicsEngine& graphics_engine, bool force_draw); void OnChildFocusChanged(/*Area *parent,*/ Area *child); sigc::connection _on_focus_changed_handler; virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw) = 0; virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void PreResizeGeometry(); virtual void PostResizeGeometry(); void InitializeWidgets(); void InitializeLayout(); Color m_TextColor; //! Deprecated. Use GetLayout(); virtual Layout* GetCompositionLayout(); //! Deprecated. Use SetLayout(); virtual bool SetCompositionLayout(Layout *layout); void RemoveLayout(); void RemoveCompositionLayout(); /*! Accessed inside ContentDraw() to help determine if some parts needs to be rendered. Do not use it elsewhere. @return True if Draw() was called before ContentDraw(). */ bool IsFullRedraw() const; virtual void GeometryChangePending(bool position_about_to_change, bool size_about_to_change); virtual void GeometryChanged(bool position_has_changed, bool size_has_changed); Layout *view_layout_; bool draw_cmd_queued_; // _font; friend class WindowCompositor; friend class Layout; friend class Area; friend class LayeredLayout; friend class Canvas; friend class VSplitter; friend class HSplitter; }; } #endif // ABSTRACTOBJECTBASE_H nux-4.0.6+14.04.20140409/Nux/PaintLayer.h0000644000015301777760000001201012321344237017722 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef PAINTLAYER_H #define PAINTLAYER_H #include "AbstractPaintLayer.h" #include "NuxGraphics/GraphicsEngine.h" namespace nux { class BaseTexture; class ColorLayer: public AbstractPaintLayer { public: ColorLayer(const Color& color, bool WriteAlpha = false, const ROPConfig& ROP = ROPConfig::Default); void SetColor(const Color& color); Color GetColor() const; virtual void Renderlayer(GraphicsEngine& graphics_engine); virtual AbstractPaintLayer* Clone() const; private: Color _color; bool m_write_alpha; ROPConfig m_rop; }; class ShapeLayer: public AbstractPaintLayer { public: ShapeLayer(UXStyleImageRef imageStyle, const Color& color, unsigned long Corners = eAllCorners, bool WriteAlpha = false, const ROPConfig& ROP = ROPConfig::Default); virtual void Renderlayer(GraphicsEngine& graphics_engine); virtual AbstractPaintLayer* Clone() const; private: UXStyleImageRef m_image_style; Color m_color; bool m_write_alpha; ROPConfig m_rop; unsigned long m_corners; }; class SliceScaledTextureLayer: public AbstractPaintLayer { public: SliceScaledTextureLayer(UXStyleImageRef imageStyle, const Color& color, unsigned long Corners = eAllCorners, bool WriteAlpha = false, const ROPConfig& ROP = ROPConfig::Default); virtual void Renderlayer(GraphicsEngine& graphics_engine); virtual AbstractPaintLayer* Clone() const; private: UXStyleImageRef m_image_style; Color m_color; bool m_write_alpha; ROPConfig m_rop; unsigned long m_corners; }; class CompositionLayer: public AbstractPaintLayer { public: //! Layer blend operation. /*! Blend(texture0*color0, texture1*color1); */ CompositionLayer(ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, ObjectPtr texture1, TexCoordXForm texxform1, const Color& color1, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP); //! Layer blend operation. /*! Blend(texture0*color0, blend_color); */ CompositionLayer(ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, const Color& blend_color, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP); //! Layer blend operation. /*! Blend(texture0*color0, color0); */ CompositionLayer(const Color& base_color, ObjectPtr texture0, TexCoordXForm texxform0, const Color& color0, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP); CompositionLayer(const Color& base_color, const Color& blend_color, LayerBlendMode layer_blend_mode, bool write_alpha, const ROPConfig& ROP); virtual ~CompositionLayer(); virtual void Renderlayer(GraphicsEngine& graphics_engine); virtual AbstractPaintLayer* Clone() const; private: ObjectPtr m_source_texture; Color m_source_texture_color; TexCoordXForm m_source_texture_texxform; ObjectPtr m_foreground_texture; Color m_foreground_texture_color; TexCoordXForm m_foreground_texture_texxform; Color m_source_color; Color m_foreground_color; bool m_write_alpha; ROPConfig m_rop; LayerBlendMode m_blend_mode; }; class TextureLayer: public AbstractPaintLayer { public: TextureLayer(ObjectPtr< IOpenGLBaseTexture > device_texture, TexCoordXForm texxform, const Color& color, bool WriteAlpha = false, const ROPConfig& ROP = ROPConfig::Default); TextureLayer(ObjectPtr device_texture, TexCoordXForm texxform, const Color& color0, bool write_alpha, const ROPConfig& ROP, const Color& blend_color, LayerBlendMode color_blend_mode); virtual ~TextureLayer(); virtual void Renderlayer(GraphicsEngine& graphics_engine); virtual AbstractPaintLayer* Clone() const; virtual ObjectPtr< IOpenGLBaseTexture> GetDeviceTexture(); private: ObjectPtr< IOpenGLBaseTexture > m_device_texture; Color m_color; bool m_write_alpha; ROPConfig m_rop; TexCoordXForm m_texxform; Color m_blend_color; LayerBlendMode m_color_blend_mode; }; } #endif // PAINTLAYER_H nux-4.0.6+14.04.20140409/Nux/GridHLayout.h0000644000015301777760000001122612321344237020055 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GRIDHLAYOUT_H #define GRIDHLAYOUT_H #include "Layout.h" namespace nux { //! An horizontal grid layout. /*! Fills the grid from left to right and going down. */ class GridHLayout: public Layout { // The grid layout goes through the child elements and assign them a size and position. // 0 1 2 3 4 5 // 6 7 8 9 10 11 // 12 13 .. .. .. .. // This is a left to right fill, going down. NUX_DECLARE_OBJECT_TYPE(GridHLayout, Layout); public: enum FillingOrder { FILL_HORIZONTAL, FILL_VERTICAL }; GridHLayout(NUX_FILE_LINE_PROTO); ~GridHLayout(); virtual void GetCompositeList(std::list *ViewList); //! Control the visibility of elements on the bottom edge. /*! Controls how the layout places the elements at its bottom edge. @param partial_visibility If True, the layout will position elements at its bottom edge even if they are partially visible. */ void EnablePartialVisibility(bool partial_visibility); //! Set the size of the grid element. /*! Set the size of the grid element. @param width Width of elements. @param height Height of elements. */ void SetChildrenSize(int width, int height); //! Get the size of the grid element. /*! @return Size of the grid elements. */ Size GetChildrenSize() const; //! Force the grid elements size. /*! Force the grid elements size to be the one provided by SetChildrenSize. */ void ForceChildrenSize(bool force); //! Get the number of columns in the grid. int GetNumColumn() const; //! Get the number of rows in the grid. int GetNumRow() const; //! Make the grid width match the size of its content. /*! @param match_content If True, force the height of the layout to match the height of the content. This can also be achieve if the stretch factor of this layout is set to 0; */ void MatchContentSize(bool match_content); //! Return True if the grid width match the size of its content. bool IsMatchingContentSize() const; //! Draw Element /*! Draw all elements inside the layout. If force_draw is true then the system requests that all objects redraw themselves completely. @param force_draw @param TraverseInfo @param ProcessEventInfo @return The state of the Process Event. */ virtual void ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw); void SetSpaceBetweenChildren(int horizontal_space, int vertical_space); void SetFillingOrder(FillingOrder order); FillingOrder GetFillingOrder() const; protected: long ComputeLayoutRowOrder(); long ComputeLayoutColumnOrder(); virtual long ComputeContentSize(); int GetChildPos(Area *child); Area* GetChildAtPosition(int pos); Area* KeyNavIterationRowOrder(KeyNavDirection direction); Area* KeyNavIterationColumnOrder(KeyNavDirection direction); virtual Area* KeyNavIteration(KeyNavDirection direction); FillingOrder filling_order_; int m_v_in_margin; int m_h_in_margin; private: Size _children_size; bool _dynamic_column; bool _force_children_size; bool _partial_visibility; bool match_content_size_; //!< If True, for the height of the layout to match the height of the content. int _num_row; int _num_column; // //! Compute the how elements are spread inside the layout // /*! // @param remaining_width Size that remains after subtracting elements width, inner and outer margins from the content width. // @param offset_space The space at the left of all elements. // @param element_margin The margin between elements. // */ // void ComputeStacking(int remaining_width, int &offset_space, int &element_margin); }; } #endif // GRIDHLAYOUT_H nux-4.0.6+14.04.20140409/Nux/ColorPickerDialog.cpp0000644000015301777760000000335512321344237021555 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Button.h" #include "ColorPickerDialog.h" namespace nux { static Color DummyColor; ColorPickerDialog::ColorPickerDialog() : m_Color(DummyColor) { SetWindowTitle("Color Picker"); SetWindowSizeMatchLayout(true); m_Vlayout = new VLayout("Color Picker"); m_ColorEditor = new ColorEditor(); m_Vlayout->AddView(m_ColorEditor); m_Vlayout->AddLayout(m_ButtonLayout); m_Vlayout->SetScaleFactor(0); // Set layout for the window SetLayout(m_Vlayout); } ColorPickerDialog::~ColorPickerDialog() { } void ColorPickerDialog::StartDialog(Color &color, color::Model /* ColorModel */, bool StartModal) { Dialog::Start(StartModal); m_Color = color; } void ColorPickerDialog::RecvOk() { m_Color = m_ColorEditor->GetRGBColor(); m_Color = color::Black; ShowWindow(FALSE); } void ColorPickerDialog::RecvCancel() { m_Color = DummyColor; ShowWindow(FALSE); } } nux-4.0.6+14.04.20140409/Nux/ClientArea.h0000644000015301777760000000676012321344237017700 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef CLIENTAREA_H #define CLIENTAREA_H #include "InputArea.h" #include "Painter.h" #include "View.h" #include "TimerProc.h" namespace nux { class ClientArea; struct ClientAreaDraw { ClientArea *clientarea; Geometry clipgeometry; }; class ClientArea: public View { public: ClientArea(NUX_FILE_LINE_PROTO); ~ClientArea(); virtual void BeginDraw(GraphicsEngine &graphics_engine, bool force_draw); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); void EnableClientDraw(bool b) { m_IsClientAreaEnabled = b; }; bool IsClientDrawEnabled() const { return m_IsClientAreaEnabled; }; virtual void ClientDraw(GraphicsEngine &graphics_engine, DrawAreaContext &ctx, bool force_draw); virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); virtual void RecvKeyEvent( unsigned long , /*event type*/ unsigned long , /*event keysym*/ unsigned long , /*event state*/ const char* , /*character*/ unsigned short /*key repeat count*/ ); sigc::signal sigClientDraw; void SetClientViewport(GraphicsEngine &graphics_engine); void Setup2DMode(GraphicsEngine &graphics_engine); // Before the client start drawing we set up a framebuffer object. We don't want the client to start messing // up the whole rendering by. If we setup a framebuffer instead, the client can never know the framebuffer // we use fror the whole rendering. all we have to do is to copy the client framebuffer into the main framebuffer // after the client as finished with the draw. ObjectPtr& GetWindowFrameBufferObject() { return m_FrameBufferObject; } ObjectPtr m_FrameBufferObject; protected: virtual bool AcceptKeyNavFocus(); private: // We use Rectangle texture to attach to the framebuffer because some GPU like the Geforce FX 5600 do not // have support for ARB_texture_non_power_of_two. However it does support ARB_texture_recatangle. ObjectPtr m_MainColorRT; ObjectPtr m_MainDepthRT; DrawAreaContext m_ctx; bool m_IsClientAreaEnabled; }; } #endif // CLIENTAREA_H nux-4.0.6+14.04.20140409/Nux/GroupBox.cpp0000644000015301777760000001175112321344237017765 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "GroupBox.h" namespace nux { GroupBox::GroupBox(const char * /* Caption */, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_layout(0) { m_CaptionArea.SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); m_CaptionArea.SetBaseSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); SetMinimumSize(DEFAULT_WIDGET_WIDTH + 5, PRACTICAL_WIDGET_HEIGHT + 5); SetBaseSize(DEFAULT_WIDGET_WIDTH + 5, 2 * PRACTICAL_WIDGET_HEIGHT); SetCaption(""); } GroupBox::~GroupBox() { } void GroupBox::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { graphics_engine.PushClippingRectangle(GetGeometry()); Geometry wireborder_geo = GetGeometry(); wireborder_geo.OffsetPosition(0, 10); wireborder_geo.OffsetSize(0, -10); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), m_CaptionArea.GetGeometry(), m_CaptionArea.GetBaseString(), GetTextColor(), true, eAlignTextCenter); if (m_layout != 0) { m_layout->QueueDraw(); } graphics_engine.PopClippingRectangle(); } void GroupBox::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { graphics_engine.PushClippingRectangle(GetGeometry()); if (m_layout) { graphics_engine.PushClippingRectangle(m_layout->GetGeometry()); m_layout->ProcessDraw(graphics_engine, force_draw); graphics_engine.PopClippingRectangle(); } graphics_engine.PopClippingRectangle(); } bool GroupBox::SetLayout(Layout *layout) { if (View::SetLayout(layout) == false) { return false; } m_layout = layout; return true; // Geometry geo = GetGeometry(); // Geometry layout_geo = Geometry(geo.x + m_border, geo.y + m_top_border, // geo.GetWidth() - 2*m_border, geo.GetHeight() - m_border - m_top_border); // m_layout->SetGeometry(layout_geo); } void GroupBox::PreLayoutManagement() { // Give the managed layout appropriate size and position.. if (view_layout_) { Geometry layout_geo = GetGeometry(); layout_geo.OffsetPosition(2, 20); layout_geo.OffsetSize(-4, -22); view_layout_->SetGeometry(layout_geo); } } long GroupBox::PostLayoutManagement(long /* LayoutResult */) { // A Group box must tightly group its children. // So it must embrace the size that was compute for the composition layout. // Only the size is change is important here of the GroupBox is important here. long ret = 0; Geometry old_geo = Area::GetGeometry(); if (view_layout_) { Geometry base = view_layout_->GetGeometry(); base.OffsetPosition(-2, -20); base.OffsetSize(4, 22); Area::SetGeometry(base); } Geometry base = GetGeometry(); m_CaptionArea.SetBaseXY(base.x + 6, base.y); if (old_geo.GetWidth() > base.GetWidth()) ret |= eLargerWidth; else if (old_geo.GetWidth() < base.GetWidth()) ret |= eSmallerWidth; else ret |= eCompliantWidth; if (old_geo.GetHeight() > base.GetHeight()) ret |= eLargerHeight; else if (old_geo.GetHeight() < base.GetHeight()) ret |= eSmallerHeight; else ret |= eCompliantHeight; return ret; } void GroupBox::ComputeContentPosition(float offsetX, float offsetY) { if (view_layout_) { view_layout_->SetBaseX(GetBaseX() + 2); view_layout_->SetBaseY(GetBaseY() + 20); view_layout_->ComputeContentPosition(offsetX, offsetY); } Geometry base = GetGeometry(); m_CaptionArea.SetBaseXY(base.x + 6, base.y); } void GroupBox::SetCaption(const char *name) { if ((name == 0) || strlen(name) == 0) { m_CaptionArea.SetBaseString(""); m_CaptionArea.SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); m_CaptionArea.SetBaseSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); } else { m_CaptionArea.SetBaseString(name); m_CaptionArea.SetMinimumSize(4 + GetSysBoldFont()->GetStringWidth(name), PRACTICAL_WIDGET_HEIGHT); m_CaptionArea.SetBaseSize(4 + GetSysBoldFont()->GetStringWidth(name), PRACTICAL_WIDGET_HEIGHT); } } bool GroupBox::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/HexRegExpValidator.h0000644000015301777760000000326612321344237021374 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef HEXREGEXPVALIDATOR_H #define HEXREGEXPVALIDATOR_H #include "Validator.h" namespace nux { class HexRegExpValidator : public Validator { public: HexRegExpValidator(int Minimum = INT_MIN, int Maximum = INT_MAX); HexRegExpValidator(const HexRegExpValidator &validator); HexRegExpValidator &operator= (const HexRegExpValidator &rhs); virtual ~HexRegExpValidator(); virtual Validator *Clone() const; //Virtual Constructor Idiom /*! @return The input value clamped to the range [m_Minimum, m_Maximum]. */ int GetClampedValue(int i) const; virtual void Alternative(const char *str); void SetMinimum(int value); int GetMinimum() const; void SetMaximum(int value); int GetMaximum() const; std::string ToString(int i); int ToInteger(const char *str); private: int m_Minimum; int m_Maximum; }; } #endif // HEXREGEXPVALIDATOR_H nux-4.0.6+14.04.20140409/Nux/TimelineEasings.cpp0000644000015301777760000000401312321344237021271 0ustar pbusernogroup00000000000000#include "Nux.h" #include "Timeline.h" #include "TimelineEasings.h" namespace nux { TimelineEaseInOutQuad::TimelineEaseInOutQuad(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL) : Timeline(msecs, Caption, NUX_FILE_LINE_PARAM) { } double TimelineEaseInOutQuad::GetEasing() { double prog = GetProgress(); prog *= 2.0; if (prog < 1) { return (prog * prog) * 0.5; } prog -= 1.0; return -0.5 * (prog * (prog - 2) - 1); } TimelineEaseInQuad::TimelineEaseInQuad(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL) : Timeline(msecs, Caption, NUX_FILE_LINE_PARAM) { } double TimelineEaseInQuad::GetEasing() { double prog = GetProgress(); return prog * prog; } TimelineEaseOutQuad::TimelineEaseOutQuad(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL) : Timeline(msecs, Caption, NUX_FILE_LINE_PARAM) { } double TimelineEaseOutQuad::GetEasing() { double prog = GetProgress(); return -1.0 * prog * (prog - 2); } TimelineEaseInOutCubic::TimelineEaseInOutCubic(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL) : Timeline(msecs, Caption, NUX_FILE_LINE_PARAM) { } double TimelineEaseInOutCubic::GetEasing() { double prog = GetProgress(); prog *= 2.0; if (prog < 1) { return (prog * prog * prog) * 0.5; } prog -= 2.0; return 0.5 * (prog * prog * prog + 2.0); } TimelineEaseInCubic::TimelineEaseInCubic(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL) : Timeline(msecs, Caption, NUX_FILE_LINE_PARAM) { } double TimelineEaseInCubic::GetEasing() { double prog = GetProgress(); return prog * prog * prog; } TimelineEaseOutCubic::TimelineEaseOutCubic(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL) : Timeline(msecs, Caption, NUX_FILE_LINE_PARAM) { } double TimelineEaseOutCubic::GetEasing() { double prog = GetProgress(); prog -= 1.0; return prog * prog * prog + 1.0; } } nux-4.0.6+14.04.20140409/Nux/RangeValue.h0000644000015301777760000000675712321344237017730 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RANGEVALUE_H #define RANGEVALUE_H namespace nux { class HLayout; class EditTextBox; class RangeValue : public View { NUX_DECLARE_OBJECT_TYPE(RangeValue, View); public: RangeValue(float Value = 0, float MinValue = 0.0f, float MaxValue = 1.0f, NUX_FILE_LINE_PROTO); virtual ~RangeValue(); void DrawMarker(GraphicsEngine &graphics_engine); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); ///////////////// // RECEIVERS // ///////////////// void SetRange(float min_value, float max_value); void SetValue(float value); float GetValue() const; float GetMinValue() const { return m_min; } float GetMaxValue() const { return m_max; } void SetBackgroundColor(const Color &color); const Color GetBackgroundColor() const; void setStartToEndColor(Color color_start, Color color_end) { m_StartColor = color_start; m_EndColor = color_end; } void setStartColor(Color color) { m_StartColor = color; } void setEndColor(Color color) { m_EndColor = color; } void setProgressColor(Color color) { m_ProgressColor = color; } void EnableDrawProgress(bool b) { m_EnableDrawProgress = b; } //////////////// // EMITTERS // //////////////// void OnReceiveMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnKeyboardFocus(); void OnLostKeyboardFocus(); void OnValidateKeyboardEntry(EditTextBox *textbox, const std::string &text); bool IsCtrlKeyPressed() const { return m_CTRL_KEY; } // signals sigc::signal sigValueChanged; sigc::signal sigFloatChanged; sigc::signal sigMouseDown; sigc::signal sigMouseUp; sigc::signal sigMouseDrag; sigc::signal sigSetTypedValue; //sigc::signal sigValidateKeyboarEntry; void EmitFloatChangedSignal(); protected: void InitializeWidgets(); void InitializeLayout(); protected: HLayout *hlayout; EditTextBox *m_ValueString; BasicView *m_Percentage; Color m_StartColor; Color m_EndColor; Color m_ProgressColor; Color m_BackgroundColor; bool m_EnableDrawProgress; long m_CTRL_KEY; float m_Value; float m_min, m_max; }; } #endif // RANGEVALUE_H nux-4.0.6+14.04.20140409/Nux/CoverflowItem.cpp0000644000015301777760000000161312321344237021001 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith */ #include "CoverflowItem.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(CoverflowItem); CoverflowItem::CoverflowItem(std::string const& name_) : name(name_) { } } nux-4.0.6+14.04.20140409/Nux/ScrollBar.h0000644000015301777760000000326512321344237017551 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef SCROLLBAR_H #define SCROLLBAR_H namespace nux { class ScrollView; class ScrollBar : public View //public ValuatorAbstraction { public: ScrollBar(NUX_FILE_LINE_PROTO); ~ScrollBar(); private: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw) = 0; virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw) = 0; public: int visible() const { return m_visible; } void clear_visible() { m_visible = 0; } void set_visible() { m_visible = 1; } void resize(int x, int y, int w, int h) { SetGeometry(Geometry(x, y, w, h)); } void SetScrollUnit(int unit); int GetScrollUnit() const; protected: virtual bool AcceptKeyNavFocus(); int m_ScrollUnit; int m_visible; float visibility_percentage_; friend class ScrollView; }; } #endif // SCROLLBAR_H nux-4.0.6+14.04.20140409/Nux/AbstractThread.cpp0000644000015301777760000000413612321344237021112 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "AbstractThread.h" namespace nux { class WindowThread; class SystemThread; NUX_IMPLEMENT_OBJECT_TYPE(AbstractThread); AbstractThread::AbstractThread(AbstractThread *Parent) : parent_(Parent) , user_init_func_(NULL) , user_exit_func_(NULL) { } AbstractThread::~AbstractThread() { } void AbstractThread::TerminateChildWindows() { std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); it++) { if ((*it)->Type().IsObjectType(WindowThread::StaticObjectType)) { // Exit the main loop of a window. static_cast(*it)->ExitMainLoop(); } } } void AbstractThread::JoinChildThreads() { #if defined(NUX_OS_WINDOWS) size_t sz = children_thread_list_.size(); if (sz == 0) { return; } HANDLE *hdl = new HANDLE[sz]; int i = 0; std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); ++it, ++i) { hdl[i] = (*it)->GetThreadHandle(); } unsigned int result = WaitForMultipleObjects(sz, hdl, FALSE, INFINITE); #else //#error WindowThread::JoinChildThreads has not been implemented for this platform. // Todo #endif return; } } nux-4.0.6+14.04.20140409/Nux/CoverflowModel.h0000644000015301777760000000356312321344237020616 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith */ #ifndef NUX_COVERFLOWMODEL_H #define NUX_COVERFLOWMODEL_H #include #include #include #include "CoverflowItem.h" namespace nux { class CoverflowModel : public InitiallyUnownedObject { NUX_DECLARE_OBJECT_TYPE(CoverflowModel, InitiallyUnownedObject); public: typedef ObjectPtr Ptr; typedef std::vector CoverflowItemList; CoverflowModel(); ~CoverflowModel(); CoverflowItemList const& Items() const; void AddItem(CoverflowItem::Ptr const& item); void InsertItem(CoverflowItem::Ptr const& item, size_t index); void RemoveItem(CoverflowItem::Ptr const& item); size_t IndexOf(CoverflowItem::Ptr const& item); CoverflowItem::Ptr Selection(); size_t SelectionIndex(); void SetSelection(size_t index); void SetSelection(CoverflowItem::Ptr item); void SelectNext(); void SelectPrev(); sigc::signal item_added; sigc::signal item_removed; sigc::signal selection_changed; private: struct Impl; Impl* pimpl; }; } #endif nux-4.0.6+14.04.20140409/Nux/AbstractButton.h0000644000015301777760000001040112321344237020613 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ABSTRACTBUTTON_H #define ABSTRACTBUTTON_H #include "View.h" #include "NuxCore/Property.h" namespace nux { class StaticText; enum ButtonVisualState { VISUAL_STATE_PRESSED = 0, VISUAL_STATE_NORMAL = 1, VISUAL_STATE_PRELIGHT = 2, VISUAL_STATE_DISABLED = 3 }; //! The base class of button type widgets. /*! AbstractButton is the direct base class of Button, CheckBox and RadioButton. It is a base class for ToggleButton. */ class AbstractButton : public View { NUX_DECLARE_OBJECT_TYPE(AbstractButton, View); public: AbstractButton(NUX_FILE_LINE_PROTO); virtual ~AbstractButton(); sigc::signal visual_state_change; //! Returns the visual state of the AbstractButton /*! Returns the visual state of the AbstractButton. @return The visual state of the AbstractButton. */ ButtonVisualState GetVisualState(); //! Return the active state of the button. /*! Return the active state of the button. A Button has a non-persistent active state. It always returns false. CheckBox, RadionButton and ToggleButton return true if they are active. @return True if the button object is in an active state. */ bool Active() const; //! Activate the button. /*! Activate the button. If this object is a Button, then it has no persistent state and the function does nothing. */ virtual void Activate() = 0; //! Deactivate the button. /*! Deactivate the button. If this object is a Button, then it has no persistent state and the function does nothing. */ virtual void Deactivate() = 0; //! Set the state of the button. /*! Set the sate of the button. The button is either activated or deactivated. @param active The button state. */ virtual void SetActive(bool active); //! Set the text color. /*! Set the text color. @param color the text color. */ void SetLabelColor(const Color &color); //! Get the text color. /*! Get the text color. @return The text color. */ Color GetLabelColor(); //! Get the button visual state. /*! Get the button visual state. @return The button visual state. */ ButtonVisualState GetVisualState() const; virtual void SetLabelFontSize(int point); int GetLabelFontSize() const; protected: //! The state of the AbstractButton. bool active_; bool mouse_pressed_; //! Visual state of the button object. ButtonVisualState visual_state_; // Common attribute for all the classes that inherit from AbstractButton. std::string label_; Color label_color_; StaticText *static_text_; int label_font_size_; bool same_size_as_content_; int pre_layout_width_; int pre_layout_height_; virtual void RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvClick (int x, int y, unsigned long button_flags, unsigned long key_flags) = 0; }; } #endif // ABSTRACTBUTTON_H nux-4.0.6+14.04.20140409/Nux/GridVLayout.h0000644000015301777760000000727212321344237020101 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GRIDVLAYOUT_H #define GRIDVLAYOUT_H #include "Layout.h" namespace nux { //! A vertical grid layout /*! Fills the grid from top to bottom and going right. */ class GridVLayout: public Layout { // The grid layout goes through the child elements and assign them a size and position. // 0 3 6 9 .. // 1 4 7 10 .. // 2 5 8 .. // This is a top to bottom fill, going right. NUX_DECLARE_OBJECT_TYPE(GridVLayout, Layout); public: GridVLayout(NUX_FILE_LINE_PROTO); ~GridVLayout(); virtual long ComputeContentSize(); virtual void GetCompositeList(std::list *ViewList); //! Control the visibility of elements on the bottom edge. /*! Controls how the layout places the elements at its bottom edge. @param partial_visibility If True, the layout will position elements at its bottom edge even if they are partially visible. */ void EnablePartialVisibility(bool partial_visibility); //! Set the size of the grid element. /*! Set the size of the grid element. @param width Width of elements. @param height Height of elements. */ void SetChildrenSize(int width, int height); //! Get the size of the grid element. /*! @return Size of the grid elements. */ Size GetChildrenSize() const; //! Force the grid elements size. /*! Force the grid elements size to be the one provided by SetChildrenSize. */ void ForceChildrenSize(bool force); //! Get the number of columns in the grid. int GetNumColumn() const; //! Get the number of rows in the grid. int GetNumRow() const; //! Make the grid width match the size of its content. /*! @param match_content If True, force the width of the layout to match the height of the content. This can also be achieve if the stretch factor of this layout is set to 0; */ void SetWidthMatchContent(bool match_content); //! Return True if the grid width match the size of its content. bool GetWidthMatchContent() const; //! Draw Element /*! Draw all elements inside the layout. If force_draw is true then the system requests that all objects redraw themselves completely. @param force_draw @param TraverseInfo @param ProcessEventInfo @return The state of the Process Event. */ virtual void ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw); protected: int GetChildPos(Area *child); Area* GetChildAtPosition(int pos); virtual Area* KeyNavIteration(KeyNavDirection direction); private: Size _children_size; bool _dynamic_column; bool _force_children_size; bool _partial_visibility; bool _width_match_content; //!< If True, for the width of the layout to match the width of the content. int _num_row; int _num_column; }; } #endif // GRIDVLAYOUT_H nux-4.0.6+14.04.20140409/Nux/KeyboardHandler.cpp0000644000015301777760000005765412321344237021272 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "KeyboardHandler.h" #include "Utils.h" #include "NuxGraphics/GraphicsEngine.h" #include "NuxCore/Win32Dialogs/NWin32Clipboard.h" namespace nux { int BaseKeyboardHandler::s_jump_offset_at_borders = 60; int BaseKeyboardHandler::s_cursor_width = 4; BaseKeyboardHandler::BaseKeyboardHandler() { m_text_positionx = 0; m_text_positiony = 0; m_previous_cursor_position = 0; m_clip_region = Rect(0, 0, 100, 20); m_KeyType = eAlphaNumeric; m_first_visible_char = 0; m_mouse_drag = false; m_mouse_inside_text_area = true; m_entering_focus = false; m_Font = GetSysFont(); m_caret = m_selection_start = 0; m_insert_mode = true; } BaseKeyboardHandler::~BaseKeyboardHandler() { } void BaseKeyboardHandler::DeleteSelectionText() { int nFirst = Min(m_caret, m_selection_start); int nLast = Max(m_caret, m_selection_start); // Update caret and selection PlaceCaret(nFirst); m_selection_start = m_caret; // Remove the characters for (int i = nFirst; i < nLast; ++i) m_textline.erase(nFirst, 1); } void BaseKeyboardHandler::InsertChar(unsigned int /* character */) { } void BaseKeyboardHandler::ClearText() { m_text_positionx = 0; m_text_positiony = 0; m_caret = 0; m_previous_cursor_position = 0; m_textline.clear(); } void BaseKeyboardHandler::PlaceCaret(unsigned int nCP) { nuxAssert(((int)nCP >= 0) && (nCP <= (unsigned int) m_textline.length())); m_previous_cursor_position = m_caret; m_caret = nCP; } unsigned int BaseKeyboardHandler::NextWordPosition(unsigned int cp) { unsigned int num_char = (unsigned int) m_textline.length(); if (cp == num_char) return cp; unsigned int c = cp + 1; while (c < num_char - 1) { if (( m_textline[c] == char(' ')) && (m_textline[c+1] != char(' '))) return c + 1; c++; } return num_char; } unsigned int BaseKeyboardHandler::PrevWordPosition(unsigned int cp) { if (cp == 0) return 0; unsigned int c = cp - 1; while (c > 1) { if (( m_textline[c] != char(' ')) && (m_textline[c-1] == char(' '))) return c; c--; } return 0; } void BaseKeyboardHandler::MouseDown(int x, int y) { ResolveCaretPosition(x, y); m_mouse_drag = true; m_mouse_inside_text_area = true; m_entering_focus = false; } void BaseKeyboardHandler::MouseUp(int /* x */, int /* y */) { m_mouse_drag = false; m_entering_focus = false; } void BaseKeyboardHandler::MouseDrag(int x, int y) { if (m_entering_focus) return; ResolveCaretPosition(x, y); m_mouse_inside_text_area = true; } void BaseKeyboardHandler::EnterFocus() { m_entering_focus = true; } void BaseKeyboardHandler::ResolveCaretPosition(int x, int /* y */) { if (m_entering_focus) return; if (m_textline.length() == 0) return; unsigned int StrLength = (unsigned int) m_textline.length(); int total = m_text_positionx; unsigned int nCP = StrLength; for (unsigned int i = 0; i < StrLength; i++) { unsigned int cw0 = GetFont()->GetCharWidth(m_textline[i]); unsigned int cw1 = 0; if (i+1 < StrLength) { cw1 = GetFont()->GetCharWidth(m_textline[i+1]); } { if (total == x) { nCP = i; break; } else if (x < total + (int) cw0 / 2) { nCP = i; break; } else if (x < total + (int) cw1 / 2) { // I don't quite understand why we need this??? nCP = i + 1; break; } } total += cw0; } PlaceCaret(nCP); if (!m_mouse_drag) { m_selection_start = m_caret; } } void BaseKeyboardHandler::CaretAutoScroll(int x, int /* y */, Geometry geo) { if (m_entering_focus) return; if (m_textline.length() == 0) return; int StrLength = (int) m_textline.length(); //nuxDebugMsg("[BaseKeyboardHandler::ResolveCaretPosition]"); if (x < geo.x) { if (m_mouse_inside_text_area) { while (m_caret && (GetFont()->GetCharStringWidth(m_textline.c_str(), m_caret) + m_text_positionx > 0)) { --m_caret; //nuxDebugMsg("Group Add: %c", m_textline[m_caret]); } m_mouse_inside_text_area = false; } else if (m_caret) { --m_caret; //nuxDebugMsg("Add Char: %c", m_textline[m_caret]); } else { m_caret = 0; } } else if (x > geo.x + geo.GetWidth()) { if (m_mouse_inside_text_area) { while ((m_caret != StrLength) && (GetFont()->GetCharStringWidth(m_textline.c_str(), m_caret) + m_text_positionx < geo.GetWidth())) { ++m_caret; //nuxDebugMsg("Group Add: %c", m_textline[m_caret-1]); } m_mouse_inside_text_area = false; } else if (m_caret < StrLength) { ++m_caret; //nuxDebugMsg("Group Add: %c", m_textline[m_caret-1]); } else { m_caret = StrLength; } } AdjustCursorAndTextPosition(); } long BaseKeyboardHandler::ProcessKey( unsigned long eventType /*event type*/, unsigned long keysym /*event keysym*/, unsigned long state /*event state*/, char character /*character*/, const Geometry & /* g */) { //if(event.event_type != I_AsciiKey && event.event_type != I_KeyPress && event.event_type != I_KeyRelease) if (eventType != NUX_KEYDOWN) return 0; m_need_redraw = true; //unsigned key = event.ascii_code; unsigned key = 0; if (character != 0) key = character; long virtual_code = keysym; if (key != 0) { switch(m_KeyType) { case eDecimalNumber: { // Check if Key code is in ".0123456789"; // Be careful because WM_KEYDOWN and WM_KEYUP send a key value // that gets here. If key pad 0 is press/released, WM_KEYDOWN/WM_KEYUP will send key = key_kp0. // It is WM_CHAR who send key = 0x30 = '0'. Therefore, do not use strchr(".0123456789", key) to test // if key is a digit character. When using strchr(".0123456789", key_kp0) we get a positive result // and the result is unexpected. if ((key >= char('0') && key <= char('9')) || (key == char('.')) || (key == char('-')) || (key == char('+'))) { if ( m_caret != m_selection_start ) { DeleteSelectionText(); } // '-' and '+' can only be at position 0 of the number if ((key == char('-')) || (key == char('+'))) { if ((m_caret == 0) && (m_textline[0] != char('+')) && (m_textline[0] != char('-'))) { // If we are in overwrite mode and there is already // a char at the caret's position, simply replace it. // Otherwise, we insert the char as normal. if ( !m_insert_mode && m_caret < (int) m_textline.length()) { m_textline[m_caret] = key; PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } else { // Insert the char if ( m_caret <= (int) m_textline.length()) { m_textline.insert(m_caret, 1, key); PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } } } } else { // If we are in overwrite mode and there is already // a char at the caret's position, simply replace it. // Otherwise, we insert the char as normal. if ( !m_insert_mode && m_caret < (int) m_textline.length()) { m_textline[m_caret] = key; PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } else { // Insert the char if ( m_caret <= (int) m_textline.length()) { m_textline.insert(m_caret, 1, key); PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } } } } break; } case eIntegerNumber: { // Check if Key code is in "0123456789"; if ((key >= char('0') && key <= char('9')) || (key == char('-')) || (key == char('+'))) { if ( m_caret != m_selection_start ) { DeleteSelectionText(); } // '-' and '+' can only be at position 0 of the number if ((key == char('-')) || (key == char('+'))) { // If we are in overwrite mode and there is already // a char at the caret's position, simply replace it. // Otherwise, we insert the char as normal. if (!m_insert_mode && (m_caret < (int) m_textline.length())) { m_textline[m_caret] = key; PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } else { // Insert the char if ( m_caret <= (int) m_textline.length()) { m_textline.insert(m_caret, 1, key); PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } } } else { // If we are in overwrite mode and there is already // a char at the caret's position, simply replace it. // Otherwise, we insert the char as normal. if (!m_insert_mode && (m_caret < (int) m_textline.length())) { m_textline[m_caret] = key; PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } else { // Insert the char if (m_caret <= (int) m_textline.length()) { m_textline.insert(m_caret, 1, key); PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } } } } break; } case eHexadecimalNumber: { if ((key >= char('0') && key <= char('9')) || (key >= char('a') && key <= char('f')) || (key >= char('A') && key <= char('F')) || (key == char('-')) || (key == char('+'))) //if(strchr("0123456789abcdefABCDEF", key)) { if (m_caret != m_selection_start) { DeleteSelectionText(); } // If we are in overwrite mode and there is already // a char at the caret's position, simply replace it. // Otherwise, we insert the char as normal. if (!m_insert_mode && (m_caret < (int) m_textline.length())) { m_textline[m_caret] = key; PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } else { // Insert the char if (m_caret <= (int) m_textline.length()) { m_textline.insert(m_caret, 1, key); PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } } } break; } case eBinaryNumber: { //if(strchr("01", key)) if ((key >= char('0') && key <= char('1'))) { if ( m_caret != m_selection_start ) { DeleteSelectionText(); } // If we are in overwrite mode and there is already // a char at the caret's position, simply replace it. // Otherwise, we insert the char as normal. if (!m_insert_mode && (m_caret < (int) m_textline.length())) { m_textline[m_caret] = key; PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } else { // Insert the char if (m_caret <= (int) m_textline.length()) { m_textline.insert(m_caret, 1, key); PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } } } break; } case eAlphaNumeric: default: { if (key > 0x1F && key < 0x7f) { if (m_caret != m_selection_start) { DeleteSelectionText(); } // If we are in overwrite mode and there is already // a char at the caret's position, simply replace it. // Otherwise, we insert the char as normal. if (!m_insert_mode && (m_caret < (int) m_textline.length())) { m_textline[m_caret] = key; PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } else { // Insert the char if (m_caret <= (int) m_textline.length()) { m_textline.insert(m_caret, 1, key); PlaceCaret(m_caret + 1 ); m_selection_start = m_caret; } } } break; } } } // CTRL+C if ((virtual_code == NUX_VK_C) && (state & NUX_STATE_CTRL)) { std::string s = GetSelectedText(); #if defined(NUX_OS_WINDOWS) inlCopyTextToClipboard(s.c_str()); #endif } // CTRL+V if ((virtual_code == NUX_VK_V) && (state & NUX_STATE_CTRL)) { #if defined(NUX_OS_WINDOWS) std::string s = inlReadTextToClipboard(); #elif defined(NUX_OS_LINUX) std::string s = "Paste not implemented yet"; #endif unsigned int start = GetTextSelectionStart(); unsigned int end = GetTextSelectionEnd(); m_textline.replace(start, end - start, s); m_caret = start + (unsigned int) s.length(); UnselectAllText(); } if (virtual_code == NUX_VK_ESCAPE) { // If Text is selected, Unselect UnselectAllText(); } if (virtual_code == NUX_VK_ENTER) { SelectAllText(); } if (virtual_code == NUX_VK_BACKSPACE) { if ( m_caret != m_selection_start ) { DeleteSelectionText(); } else { // Deleting one character if ( m_caret > 0 ) { m_textline.erase(m_caret - 1, 1); PlaceCaret(m_caret - 1 ); m_selection_start = m_caret; } } } else if (virtual_code == NUX_VK_DELETE) { // Check if there is a text selection. if ( m_caret != m_selection_start ) { DeleteSelectionText(); } else { // Deleting one character if (m_caret < (int) m_textline.length()) { m_textline.erase(m_caret, 1); } } } else if (virtual_code == NUX_VK_LEFT) { if (IsTextSelected() && ((state & NUX_STATE_SHIFT) == 0)) { //m_caret = Min(m_caret, m_selection_start); if (m_caret) --m_caret; UnselectAllText(); } else { if ( state & NUX_STATE_CTRL ) { // Control is down. Move the caret to a new item // instead of a character. m_caret = PrevWordPosition( m_caret); PlaceCaret(m_caret ); } else if ( m_caret > 0 ) PlaceCaret(m_caret - 1 ); if ((state & NUX_STATE_SHIFT) == 0) { // Shift is not down. Update selection // start along with the caret. m_selection_start = m_caret; } } } else if (virtual_code == NUX_VK_RIGHT) { if (IsTextSelected() && ((state & NUX_STATE_SHIFT) == 0)) { m_caret = Max(m_caret, m_selection_start); UnselectAllText(); } else { if ( state & NUX_STATE_CTRL) { // Control is down. Move the caret to a new item // instead of a character. m_caret = NextWordPosition( m_caret); PlaceCaret(m_caret ); } else if (m_caret < (int) m_textline.length()) PlaceCaret(m_caret + 1 ); if ((state & NUX_STATE_SHIFT) == 0) { // Shift is not down. Update selection // start along with the caret. m_selection_start = m_caret; } } } else if (virtual_code == NUX_VK_HOME) { if ((state & NUX_STATE_SHIFT) == 0) { PlaceCaret(0); // Shift is not down. Update selection // start along with the caret. m_selection_start = m_caret; } else { PlaceCaret(0 ); } } else if (virtual_code == NUX_VK_END) { if ((state & NUX_STATE_SHIFT) == 0) { PlaceCaret((unsigned int) m_textline.length()); // Shift is not down. Update selection // start along with the caret. m_selection_start = m_caret; } else { PlaceCaret((unsigned int) m_textline.length()); } } else if (virtual_code == NUX_VK_ESCAPE) { return virtual_code; } else if (virtual_code == NUX_VK_ENTER) { return virtual_code; } else { m_need_redraw = false; } if (virtual_code == NUX_VK_HOME) { m_text_positionx = 0; } else if (virtual_code == NUX_VK_END) { unsigned int str_width = GetFont()->GetStringWidth(m_textline.c_str()); if (str_width + s_cursor_width > (unsigned int) m_clip_region.GetWidth()) m_text_positionx = m_clip_region.GetWidth() - (str_width + s_cursor_width); else m_text_positionx = 0; } else if (m_textline.length() != 0) { AdjustCursorAndTextPosition(); m_need_redraw = true; } else if (m_textline.length() == 0) { ClearText(); m_need_redraw = true; } return virtual_code; } void BaseKeyboardHandler::AdjustCursorAndTextPosition() { int str_width = GetFont()->GetStringWidth(m_textline.c_str()); std::string temp0; if (m_caret > 0) temp0 = m_textline.substr(0, m_caret - 1); else temp0 = ""; // 0 1 2 // 01234567|8901234567890123456789 // abcdefgh|ijklmn // // Caret pos = 8 // temp0 = "abcdefg" // temp1 = "abcdefgh" // temp2 = "abcdefghi" std::string temp1 = m_textline.substr(0, m_caret); std::string temp2 = m_textline.substr(0, m_caret + 1); int str_width0 = GetFont()->GetStringWidth(temp0); int str_width1 = GetFont()->GetStringWidth(temp1); int str_width2 = GetFont()->GetStringWidth(temp2); if ((m_text_positionx + str_width1 + s_cursor_width) > m_clip_region.GetWidth()) { // Hitting the end of the text box if (m_caret == (int) m_textline.length()) { m_text_positionx = - (str_width + (int) s_cursor_width - m_clip_region.GetWidth()); } else { int PreviousCharWidth = str_width1 - str_width0; int Offset = Min (s_jump_offset_at_borders, str_width + s_cursor_width - str_width1); while (Offset > m_clip_region.GetWidth()) { Offset /= 2; } if (Offset < PreviousCharWidth) Offset = PreviousCharWidth; m_text_positionx -= Offset; if (m_text_positionx + str_width + s_cursor_width < (int) m_clip_region.GetWidth()) { m_text_positionx = - (str_width + (int) s_cursor_width - m_clip_region.GetWidth()); } } } else if ((m_text_positionx + str_width1) <= 0) { // Hitting the start of the text box if (m_caret == 0) { m_text_positionx = 0; } else { int NextCharWidth = str_width2 - str_width1; int Offset = Min (s_jump_offset_at_borders, str_width1); while (Offset > m_clip_region.GetWidth()) { Offset /= 2; } if (Offset < NextCharWidth) Offset = NextCharWidth; if (Offset > str_width1) { m_text_positionx = 0; return; } m_text_positionx += Offset; if (m_text_positionx > 0) { m_text_positionx = 0; } } } } void BaseKeyboardHandler::MoveCursorAtStart() { m_previous_cursor_position = m_caret; m_caret = 0; } void BaseKeyboardHandler::MoveCursorAtEnd() { unsigned int StrLength = ( unsigned int) m_textline.length(); m_previous_cursor_position = m_caret; m_caret = StrLength; } void BaseKeyboardHandler::SetKeyEntryType(BaseKeyboardHandler::eKeyEntryType keytype) { m_KeyType = keytype; } BaseKeyboardHandler::eKeyEntryType BaseKeyboardHandler::GetKeyEntryType() { return m_KeyType; } void BaseKeyboardHandler::SetText(const char *str) { m_textline = str; // Every time we set the text, we reposition the cursor at the beginning of the text, // and the text position is set to zero with regard to the start of the geometry area. MoveCursorAtStart(); m_selection_start = Min (m_selection_start, (int) StringLength(str)); m_caret = Min (m_caret, (int) StringLength(str)); if (m_caret < m_selection_start) m_selection_start = Max (m_selection_start, (int) StringLength(str)); else if (m_caret > m_selection_start) m_caret = Max (m_caret, (int) StringLength(str)); m_text_positionx = 0; } void BaseKeyboardHandler::SetText(const std::string &s) { SetText(s.c_str()); } void BaseKeyboardHandler::SetClipRegion(const Geometry &g) { m_clip_region = g; } void BaseKeyboardHandler::GetTextSelection(int *start, int *end) const { *start = Min(m_selection_start, m_caret); *end = Max(m_selection_start, m_caret); } int BaseKeyboardHandler::GetTextSelectionStart() const { return Min(m_selection_start, m_caret); } int BaseKeyboardHandler::GetTextSelectionEnd() const { return Max(m_selection_start, m_caret); } void BaseKeyboardHandler::SelectAllText() { m_selection_start = 0; m_caret = (unsigned int) m_textline.length(); AdjustCursorAndTextPosition(); } void BaseKeyboardHandler::UnselectAllText() { m_selection_start = m_caret; } std::string BaseKeyboardHandler::GetSelectedText() const { if (m_selection_start == m_caret) { return std::string(""); } else { std::string s = m_textline.substr(GetTextSelectionStart(), GetTextSelectionEnd() - GetTextSelectionStart()); return s; } } bool BaseKeyboardHandler::IsTextSelected() { if (m_caret != m_selection_start) return true; return false; } void BaseKeyboardHandler::SetFont(ObjectPtr Font) { m_Font = Font; } ObjectPtr BaseKeyboardHandler::GetFont() const { return m_Font; } } nux-4.0.6+14.04.20140409/Nux/EditTextBox.h0000644000015301777760000001434412321344237020071 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef EDITTEXTBOX_H #define EDITTEXTBOX_H #include "KeyboardHandler.h" #include "TimerProc.h" namespace nux { class HLayout; class VLayout; class Layout; class BaseKeyboardHandler; class TextLine; class Validator; class EditTextBox : public View { public: EditTextBox(const char *Caption, NUX_FILE_LINE_PROTO); ~EditTextBox(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); //! Return True if the the area knows what to do with the key event. virtual bool InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character); void SetText(const char *Caption); void SetText(const std::string &Caption); const char *GetText() const; unsigned int GetTextSize() const { return (unsigned int) m_Text.length(); } void SetDoubleValue(double d); void SetIntegerValue(int i); //! Return a caption string striping out the prefix and the suffix virtual std::string GetCleanText() const; void SetTextBackgroundColor(const Color &color); Color GetTextBackgroundColor() const; void SetSelectedTextColor(Color color) { m_SelectedTextColor = color; } void SetSelectedTextBackgroundColor(Color color) { m_SelectedTextBackgroundColor = color; } void SetTextBlinkColor(Color color) { m_TextBlinkColor = color; } void SetCursorColor(Color color) { m_CursorColor = color; } Color GetSelectedTextColor() const { return m_SelectedTextColor; } Color GetSelectedTextBackgroundColor() const { return m_SelectedTextBackgroundColor; } Color GetTextBlinkColor() const { return m_TextBlinkColor; } Color GetCursorColor() const { return m_CursorColor; } void SetKeyEntryType(BaseKeyboardHandler::eKeyEntryType keytype) { m_KeyboardHandler.SetKeyEntryType(keytype); } BaseKeyboardHandler::eKeyEntryType GetKeyEntryType() { return m_KeyboardHandler.GetKeyEntryType(); } // Receivers void RecvMouseDoubleClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void RecvKeyEvent( unsigned long eventType , /*event type*/ unsigned long keysym , /*event keysym*/ unsigned long state , /*event state*/ const char* character , /*character*/ unsigned short keyCount /*key repeat count*/); void RecvStartKeyFocus(); void RecvEndKeyFocus(); void SetPrefix(const char *p) { m_Prefix = p; }; void SetPrefix(const char &p) { m_Prefix = p; }; void SetPrefix(const std::string &p) { m_Prefix = p; }; std::string GetPrefix() const { return m_Prefix; }; void SetSuffix(const char *s) { m_Suffix = s; }; void SetSuffix(const char &s) { m_Suffix = s; }; void SetSuffix(const std::string &s) { m_Suffix = s; }; std::string Getsuffix() const { return m_Suffix; }; void SetValidator(const Validator *validator); sigc::signal< void, EditTextBox *, unsigned int > sigCharacter; // Emitted every time a character typed sigc::signal< void, EditTextBox * > sigEditChange; // Emitted every time a character typed sigc::signal< void, EditTextBox *, const std::string &> sigValidateKeyboardEntry; sigc::signal< void, EditTextBox * > sigValidateEntry; // Emitted when the text is validated sigc::signal< void, EditTextBox * > sigSetText; // Emitted when text is set with setCaption sigc::signal< void, EditTextBox * > sigEscapeKeyboardFocus; sigc::signal< void, EditTextBox * > sigStartKeyboardFocus; sigc::signal< void, EditTextBox * > sigEndKeyboardFocus; bool IsTextSelected() { return m_KeyboardHandler.IsTextSelected(); } bool IsEmpty(); private: bool ValidateKeyboardEntry(const char *text) const; void EscapeKeyboardFocus(); void EnteringKeyboardFocus(); void QuitingKeyboardFocus(); virtual long PostLayoutManagement(long LayoutResult); std::string m_Text; HLayout *hlayout; Color m_BackgroundColor; Color m_SelectedTextColor; Color m_SelectedTextBackgroundColor; Color m_TextBlinkColor; Color m_CursorColor; BaseKeyboardHandler m_KeyboardHandler; std::string m_temporary_caption; BaseKeyboardHandler::eKeyEntryType m_keytype; Validator *m_Validator; std::string m_Suffix; std::string m_Prefix; bool BlinkCursor; void BlinkCursorTimerInterrupt(void *v); void StopBlinkCursor(bool BlinkState = false); void StartBlinkCursor(bool BlinkState = false); TimerFunctor *m_BlinkTimerFunctor; TimerHandle m_BlinkTimerHandler; void ScrollTimerInterrupt(void *v); TimerFunctor *m_ScrollTimerFunctor; TimerHandle m_ScrollTimerHandler; //! If true, blend the characters alpha value with the destination and write the result to the destination buffer. bool m_WriteAlpha; bool text_input_mode_; bool key_nav_mode_; friend class RGBValuator; }; } #endif // EDITTEXTBOX_H nux-4.0.6+14.04.20140409/Nux/Timeline.h0000644000015301777760000000711512321344237017432 0ustar pbusernogroup00000000000000/* * Copyright (C) 2010 Canonical, Ltd. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License * version 3.0 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3.0 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . * * Authored by Gordon Allott */ #ifndef TIMELINE_H #define TIMELINE_H namespace nux { class Timeline : public Object { public: Timeline(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL); ~Timeline(); void Stop(); void Start(); void Pause(); void Rewind(); double GetProgress(); //ranges from 0.0 -> 1.0 virtual double GetEasing(); // override to provide easing values void DoTick(unsigned long msecs); // If you use this, you make baby kittens cry bool Looping; unsigned long Duration; bool IsPlaying; sigc::signal NewFrame; sigc::signal Completed; sigc::signal Started; sigc::signal Paused; protected: unsigned long _ElapsedTime; }; // template // class PropertyAnimationContainer // { // }; // class AnimatedPropertyBase // { // public: // AnimatedPropertyBase(){}; // virtual void Animate(float t){}; // }; // // Explicit specialization. The explicit type could be float, int, Color.... // template <> // class PropertyAnimationContainer : public AnimatedPropertyBase // { // public: // PropertyAnimationContainer(Property& prop, float start_value, float end_value) // : prop_(prop) // { // start_value_ = start_value; // end_value_ = end_value; // } // virtual void Animate(float t) // { // float value = (1.0f - t) * start_value_ + t * end_value_; // prop_.set(value); // } // Property& prop_; // float start_value_; // float end_value_; // }; // template <> // class PropertyAnimationContainer : public AnimatedPropertyBase // { // public: // PropertyAnimationContainer(Property& prop, Color start_value, Color end_value) // : prop_(prop) // { // start_value_ = start_value; // end_value_ = end_value; // } // virtual void Animate(float t) // { // Color value = (1.0f - t) * start_value_ + t * end_value_; // prop_.set(value); // } // Property& prop_; // Color start_value_; // Color end_value_; // }; // class AnimationTimeline : public Object // { // public: // AnimationTimeline() {}; // template // void AddProperty(Property& prop, T start_value, T end_value) // { // PropertyAnimationContainer* a = new PropertyAnimationContainer (prop, start_value, end_value); // animated_properties_.push_back(a); // } // void Animate(float t) // { // std::list::iterator it; // // Go through all the properties and update them. // for (it = animated_properties_.begin(); it != animated_properties_.end(); ++it) // { // (*it)->Animate(t); // } // } // std::list animated_properties_; // }; } #endif // TIMELINE_H nux-4.0.6+14.04.20140409/Nux/KineticScrollView.h0000644000015301777760000000661412321344237021267 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_KINETIC_SCROLL_VIEW_H #define NUX_KINETIC_SCROLL_VIEW_H #include #include #include namespace nux { /* Used to scroll content that is bigger than the available space to display it. Unlike ScrollView, where scroll bars are used to move the content, here you directly drag the content with a mouse pointer or finger (in case of a touchscreen). Items inside a KineticScrollView should properly handle events of type EVENT_MOUSE_CANCEL. If an item inside a kinetic scroll view is pressed, it gets a EVENT_MOUSE_DOWN as usual. But if the user starts dragging it (instead of releasing it to generete a "click"), the KineticScrollView will get ownership of the mouse and that item will receive an EVENT_MOUSE_CANCEL signalling that it no longer has the mouse and won't get any further events from it. The mouse will then be used for scrolling or flicking the KineticScrollView contents until it's released. Usage example: VLayout *layout = new Layout; for (...) { ... layout->AddView(item ...); } KineticScrollView *kinetic_scroll_view = new KineticScrollView; kinetic_scroll_view->SetLayout(layout); */ class KineticScrollView : public View { NUX_DECLARE_OBJECT_TYPE(KineticScrollView, View); public: KineticScrollView(NUX_FILE_LINE_PROTO); virtual ~KineticScrollView(); void SetScrollableDirections(ScrollableDirections scrollable_directions); /*! Defines what happens when the viewport is about to go beyond content boundaries The default value is DragAndOvershootBounds. */ void SetBoundsBehavior(BoundsBehavior bounds_behavior); /* Reimplemented */ virtual bool ChildMouseEvent(const Event& event); protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual long PostLayoutManagement(long LayoutResult); virtual void PostResizeGeometry(); private: void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void SetLayoutTranslation(int x, int y); KineticScroller scroller_; /* Variables used to process events from ChildMouseEven() */ bool mouse_pressed_on_child_; int last_child_mouse_position_x_; int last_child_mouse_position_y_; }; } // namespace nux #endif // NUX_KINETIC_SCROLL_VIEW_H nux-4.0.6+14.04.20140409/Nux/GeisAdapter.cpp0000644000015301777760000004146212321344237020412 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #include #include #include "GeisAdapter.h" #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) #define NUX_USE_GLIB_LOOP #endif #define GEIS_CLASS_UNREF(c) if (c) {geis_gesture_class_unref(c); c = nullptr;} using namespace nux; DECLARE_LOGGER(logger, "nux.geisadapter"); namespace { #ifdef NUX_USE_GLIB_LOOP struct GeisAdapterEventSource { GSource source; GPollFD event_poll_fd; }; static gboolean geis_source_prepare(GSource * /* source */, gint *timeout) { *timeout = -1; return FALSE; } static gboolean geis_source_check(GSource *source) { gboolean retval; GeisAdapterEventSource *event_source = reinterpret_cast(source); if ((event_source->event_poll_fd.revents & G_IO_IN)) { retval = TRUE; } else { retval = FALSE; } return retval; } gboolean geis_source_dispatch(GSource * /* source */, GSourceFunc /* callback */, gpointer user_data) { GeisAdapter *geis_adapter = NUX_STATIC_CAST(GeisAdapter*, user_data); geis_adapter->ProcessGeisEvents(); return TRUE; } static GSourceFuncs geis_source_funcs = { geis_source_prepare, geis_source_check, geis_source_dispatch, NULL, NULL, NULL }; #endif } GeisAdapter::GeisAdapter() : geis_(nullptr) , class_drag_(nullptr) , class_pinch_(nullptr) , class_rotate_(nullptr) , class_tap_(nullptr) , class_touch_(nullptr) , is_init_complete_(false) { geis_ = geis_new(GEIS_INIT_NO_ATOMIC_GESTURES, GEIS_INIT_GRAIL_BACKEND, nullptr); if (!geis_) { LOG_WARNING(logger) << "Couldn't create a Geis instance." " Multitouch gesture support disabled."; } } GeisAdapter::~GeisAdapter() { GEIS_CLASS_UNREF(class_drag_) GEIS_CLASS_UNREF(class_pinch_) GEIS_CLASS_UNREF(class_rotate_) GEIS_CLASS_UNREF(class_tap_) GEIS_CLASS_UNREF(class_touch_) geis_delete(geis_); #ifdef NUX_USE_GLIB_LOOP g_source_remove_by_funcs_user_data(&geis_source_funcs, this); #endif } #ifdef NUX_USE_GLIB_LOOP void GeisAdapter::CreateGSource(GMainContext *context) { GSource *source = g_source_new(&geis_source_funcs, sizeof(GeisAdapterEventSource)); GeisAdapterEventSource *event_source = reinterpret_cast(source); g_source_set_priority(source, G_PRIORITY_DEFAULT); GeisStatus status = geis_get_configuration(geis_, GEIS_CONFIGURATION_FD, &event_source->event_poll_fd.fd); if (status != GEIS_STATUS_SUCCESS) { LOG_WARNING(logger) << "Failed to get geis file descriptor." " Multitouch gesture support disabled."; g_source_destroy(source); return; } event_source->event_poll_fd.events = G_IO_IN; g_source_add_poll(source, &event_source->event_poll_fd); g_source_set_callback(source, 0, this, 0); g_source_attach(source, context); } #endif // NUX_USE_GLIB_LOOP void GeisAdapter::ProcessGeisEvents() { GeisEvent event = nullptr; GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; GestureEvent nux_event; status = geis_dispatch_events(geis_); if (status != GEIS_STATUS_SUCCESS) { LOG_WARNING(logger) << "Failed to dispatch events! Status: " << status; } status = geis_next_event(geis_, &event); if (status != GEIS_STATUS_SUCCESS && status != GEIS_STATUS_CONTINUE && status != GEIS_STATUS_EMPTY) { LOG_WARNING(logger) << "Failed to get next event! Status: " << status; } while (status == GEIS_STATUS_CONTINUE || status == GEIS_STATUS_SUCCESS) { switch (geis_event_type(event)) { case GEIS_EVENT_GESTURE_BEGIN: FillNuxEvent(nux_event, event, EVENT_GESTURE_BEGIN); event_ready.emit(nux_event); break; case GEIS_EVENT_GESTURE_UPDATE: FillNuxEvent(nux_event, event, EVENT_GESTURE_UPDATE); if (nux_event.GetGestureClasses() == TAP_GESTURE) { // Geis sends a single Update event for a tap gesture and nothing more, // but it's better to be consistent with the rule that all gestures // must begin and end (with any number of updates in between). // Otherwise code in upper layers will have to add special cases just // for the tap gesture. nuxAssert(!pending_next_event_); SplitUpdateIntoBeginAndEnd(nux_event); nuxAssert(pending_next_event_); event_ready.emit(nux_event); event_ready.emit(*pending_next_event_); pending_next_event_.reset(); } else event_ready.emit(nux_event); break; case GEIS_EVENT_GESTURE_END: FillNuxEvent(nux_event, event, EVENT_GESTURE_END); event_ready.emit(nux_event); break; case GEIS_EVENT_CLASS_AVAILABLE: this->ProcessEventClassAvailable(event); break; case GEIS_EVENT_DEVICE_AVAILABLE: this->ProcessEventDeviceAvailable(event); break; case GEIS_EVENT_DEVICE_UNAVAILABLE: this->ProcessEventDeviceUnavailable(event); break; case GEIS_EVENT_INIT_COMPLETE: this->is_init_complete_ = true; this->init_complete.emit(); break; default: break; } geis_event_delete(event); status = geis_next_event(this->geis_, &event); } } void GeisAdapter::SplitUpdateIntoBeginAndEnd(GestureEvent &nux_event) { nux_event.type = EVENT_GESTURE_BEGIN; // Work around a bug in geis. A very quick gesture (e.g. a quick tap) // will end with its is_construction_finished still set to false. // https://bugs.launchpad.net/grail/+bug/1012315 nux_event.is_construction_finished_ = true; pending_next_event_.reset(new GestureEvent); *pending_next_event_ = nux_event; pending_next_event_->type = EVENT_GESTURE_END; } bool GeisAdapter::ProcessNextEvent(GestureEvent *nux_event) { if (pending_next_event_) { *nux_event = *pending_next_event_; pending_next_event_.reset(); return true; } GeisEvent event = nullptr; GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; bool filled_nux_event = false; status = geis_dispatch_events(geis_); if (status != GEIS_STATUS_SUCCESS) { LOG_WARNING(logger) << "Failed to dispatch events! Status: " << status; } status = geis_next_event(geis_, &event); if (status != GEIS_STATUS_SUCCESS && status != GEIS_STATUS_CONTINUE && status != GEIS_STATUS_EMPTY) { LOG_WARNING(logger) << "Failed to get next event! Status: " << status; } if (status == GEIS_STATUS_CONTINUE || status == GEIS_STATUS_SUCCESS) { switch (geis_event_type(event)) { case GEIS_EVENT_GESTURE_BEGIN: FillNuxEvent(*nux_event, event, EVENT_GESTURE_BEGIN); filled_nux_event = true; break; case GEIS_EVENT_GESTURE_UPDATE: FillNuxEvent(*nux_event, event, EVENT_GESTURE_UPDATE); if (nux_event->GetGestureClasses() == TAP_GESTURE) { // Geis sends a single Update event for a tap gesture and nothing more, // but it's better to be consistent with the rule that all gestures // must begin and end (with any number of updates in between). // Otherwise code in upper layers will have to add special cases just // for the tap gesture. SplitUpdateIntoBeginAndEnd(*nux_event); } filled_nux_event = true; break; case GEIS_EVENT_GESTURE_END: FillNuxEvent(*nux_event, event, EVENT_GESTURE_END); filled_nux_event = true; break; case GEIS_EVENT_CLASS_AVAILABLE: this->ProcessEventClassAvailable(event); break; case GEIS_EVENT_DEVICE_AVAILABLE: this->ProcessEventDeviceAvailable(event); break; case GEIS_EVENT_DEVICE_UNAVAILABLE: this->ProcessEventDeviceUnavailable(event); break; case GEIS_EVENT_INIT_COMPLETE: this->is_init_complete_ = true; this->init_complete.emit(); break; default: break; } geis_event_delete(event); } if (!filled_nux_event) nux_event->Reset(); return filled_nux_event; } void GeisAdapter::ProcessEventDeviceAvailable(GeisEvent event) { GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_DEVICE); if (!attr) { LOG_WARNING(logger) << "Missing device attr in \"Device Available\" event."; return; } GeisDevice geis_device = static_cast(geis_attr_value_to_pointer(attr)); if (!geis_device) { LOG_WARNING(logger) << "\"Device Available\" event contains a null device"; return; } Device device; attr = geis_device_attr_by_name(geis_device, GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH); if (!attr) { LOG_WARNING(logger) << "Missing \"direct touch\" attr in device."; return; } device.direct_touch = geis_attr_value_to_boolean(attr) == GEIS_TRUE; device.id = geis_device_id(geis_device); devices_[device.id] = device; } void GeisAdapter::ProcessEventDeviceUnavailable(GeisEvent event) { GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_DEVICE); if (!attr) { LOG_WARNING(logger) << "Missing device attr in \"Device Available\" event."; return; } GeisDevice geis_device = static_cast(geis_attr_value_to_pointer(attr)); if (!geis_device) { LOG_WARNING(logger) << "\"Device Available\" event contains a null device"; return; } devices_.erase(geis_device_id(geis_device)); } void GeisAdapter::FillNuxEvent(GestureEvent &nux_event, GeisEvent event, EventType nux_event_type) { GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_GROUPSET); GeisGroupSet group_set = static_cast(geis_attr_value_to_pointer(attr)); /* I expect only one group. */ if (geis_groupset_group_count(group_set) != 1) { LOG_WARNING(logger) << "Received a gesture event with " << geis_groupset_group_count(group_set) << " groups"; return; } GeisGroup group = geis_groupset_group(group_set, 0); /* I expect only one frame. */ if (geis_group_frame_count(group) != 1) { LOG_WARNING(logger) << "Received a gesture event with a group containing " << geis_group_frame_count(group) << " frames"; return; } nux_event.Reset(); nux_event.type = nux_event_type; nux_event.geis_ = geis_; nux_event.geis_group_ = group; GeisFrame frame = geis_group_frame(group, 0); FillNuxEventGestureAttributes(nux_event, frame); attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_CONSTRUCTION_FINISHED); nux_event.is_construction_finished_ = geis_attr_value_to_boolean(attr) == GEIS_TRUE; attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_TOUCHSET); GeisTouchSet touch_set = static_cast(geis_attr_value_to_pointer(attr)); FillNuxEventTouches(nux_event, touch_set); // OBS: A gesture may belong to more than one gesture class if (class_drag_ && geis_frame_is_class(frame, class_drag_)) { nux_event.gesture_classes_ |= DRAG_GESTURE; } if (class_pinch_ && geis_frame_is_class(frame, class_pinch_)) { nux_event.gesture_classes_ |= PINCH_GESTURE; } if (class_rotate_ && geis_frame_is_class(frame, class_rotate_)) { nux_event.gesture_classes_ |= ROTATE_GESTURE; } if (class_tap_ && geis_frame_is_class(frame, class_tap_)) { nux_event.gesture_classes_ |= TAP_GESTURE; } if (class_touch_ && geis_frame_is_class(frame, class_touch_)) { nux_event.gesture_classes_ |= TOUCH_GESTURE; } // Work around a bug in geis. A very quick gesture (e.g. a quick tap) // will end with its is_construction_finished still set to false. // https://bugs.launchpad.net/grail/+bug/1012315 if (nux_event_type == EVENT_GESTURE_END) nux_event.is_construction_finished_ = true; } void GeisAdapter::FillNuxEventGestureAttributes(GestureEvent &nux_event, GeisFrame frame) { GeisSize attr_count = geis_frame_attr_count(frame); GeisAttr attr = 0; nux_event.gesture_id_ = geis_frame_id(frame); // Idea: use a hash mapping string attribute names to their correponding // addresses in the GestureEvent class. for (GeisSize i = 0; i < attr_count; ++i) { attr = geis_frame_attr(frame, i); if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_DEVICE_ID)) { int device_id = geis_attr_value_to_integer(attr); nux_event.is_direct_touch_ = devices_[device_id].direct_touch; } else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_TIMESTAMP)) nux_event.timestamp_ = geis_attr_value_to_integer(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_FOCUS_X)) nux_event.focus_.x = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_FOCUS_Y)) nux_event.focus_.y = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_DELTA_X)) nux_event.delta_.x = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_DELTA_Y)) nux_event.delta_.y = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_ANGLE)) nux_event.angle_ = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_ANGLE_DELTA)) nux_event.angle_delta_ = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_ANGULAR_VELOCITY)) nux_event.angular_velocity_ = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_TAP_TIME)) nux_event.tap_duration_ = geis_attr_value_to_integer(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_VELOCITY_X)) nux_event.velocity_.x = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y)) nux_event.velocity_.y = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_RADIUS)) nux_event.radius_ = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_RADIUS_DELTA)) nux_event.radius_delta_ = geis_attr_value_to_float(attr); else if (g_str_equal(geis_attr_name(attr), GEIS_GESTURE_ATTRIBUTE_RADIAL_VELOCITY)) nux_event.radial_velocity_ = geis_attr_value_to_float(attr); } } void GeisAdapter::FillNuxEventTouches(GestureEvent &nux_event, GeisTouchSet touch_set) { GeisSize count = geis_touchset_touch_count(touch_set); TouchPoint point; for (GeisSize i = 0; i < count; ++i) { GeisTouch geis_touch = geis_touchset_touch(touch_set, i); point.id = geis_attr_value_to_integer( geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_ID)); point.x = geis_attr_value_to_float( geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_X)); point.y = geis_attr_value_to_float( geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_Y)); nux_event.touches_.push_back(point); } } void GeisAdapter::ProcessEventClassAvailable(GeisEvent event) { GeisGestureClass gesture_class; GeisAttr attr; attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_CLASS); gesture_class = static_cast(geis_attr_value_to_pointer(attr)); if (strcmp(GEIS_GESTURE_DRAG, geis_gesture_class_name(gesture_class)) == 0) { class_drag_ = gesture_class; geis_gesture_class_ref(gesture_class); } else if (strcmp(GEIS_GESTURE_PINCH, geis_gesture_class_name(gesture_class)) == 0) { class_pinch_ = gesture_class; geis_gesture_class_ref(gesture_class); } else if (strcmp(GEIS_GESTURE_ROTATE, geis_gesture_class_name(gesture_class)) == 0) { class_rotate_ = gesture_class; geis_gesture_class_ref(gesture_class); } else if (strcmp(GEIS_GESTURE_TAP, geis_gesture_class_name(gesture_class)) == 0) { class_tap_ = gesture_class; geis_gesture_class_ref(gesture_class); } else if (strcmp(GEIS_GESTURE_TOUCH, geis_gesture_class_name(gesture_class)) == 0) { class_touch_ = gesture_class; geis_gesture_class_ref(gesture_class); } } nux-4.0.6+14.04.20140409/Nux/GestureBroker.cpp0000644000015301777760000001314712321344237021004 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include "GestureBroker.h" #include "Gesture.h" using namespace nux; GestureBroker::GestureBroker() { } GestureBroker::~GestureBroker() { } void GestureBroker::ProcessGestureBegin(nux::GestureEvent &event) { std::vector target_list = FindGestureTargets(event); bool gesture_bound_to_target = false; for (auto target : target_list) { bool ok = BindNewGestureToTarget(event, target); gesture_bound_to_target |= ok; } if (!gesture_bound_to_target) event.Reject(); } bool GestureBroker::BindNewGestureToTarget(nux::GestureEvent &event, ShPtGestureTarget target) { bool successful; std::shared_ptr existing_gesture = gesture_set_.FindFromTarget(target); auto create_gesture_for_target = [&]() { std::shared_ptr gesture = gesture_set_.FindFromGestureId(event.GetGestureId()); if (!gesture) { gesture = std::shared_ptr(new Gesture(event)); gesture_lost_all_targets_connections_[gesture] = gesture->lost_all_targets.connect(sigc::mem_fun (&gesture_set_, &GestureSet::Remove)); } gesture->AddTarget(target); gesture_set_.Add(gesture); if (event.IsConstructionFinished()) { gesture->Accept(); gesture->EnableEventDelivery(); } }; if (existing_gesture) { // There's a conflict here. // The target for this new gesture already has a gesture. if (existing_gesture->IsDeliveringEvents()) { // A target can have only one gesture at a time. successful = false; } else { // Since the existing gesture hasn't been delivered to the target yet, // we can choose which will continue. // The rule is that the gesture with the most touches has precedence over // the other. int existing_num_touches = existing_gesture->GetTouches().size(); int new_num_touches = event.GetTouches().size(); if (new_num_touches < existing_num_touches) { successful = false; } else if (new_num_touches == existing_num_touches) { // It means that there are more fingers on the target area // than the target area can handle // (i.e. three fingers over an area that handles only two-fingers' // gestures) existing_gesture->RemoveTarget(*target); successful = false; } else // new_num_touches > existing_num_touches { existing_gesture->RemoveTarget(*target); create_gesture_for_target(); successful = true; } } } else { create_gesture_for_target(); successful = true; } return successful; } void GestureBroker::ProcessGestureUpdate(nux::GestureEvent &event) { std::shared_ptr gesture = gesture_set_.FindFromGestureId(event.GetGestureId()); if (!gesture) { return; } if (event.IsConstructionFinished() && !gesture->IsConstructionFinished()) { // This is the first update for this gesture signaling that // its construction has finished. gesture->Update(event); ResolveBufferedGestureThatFinishedConstruction(gesture); } else { gesture->Update(event); } } void GestureBroker::ProcessGestureEnd(nux::GestureEvent &event) { std::shared_ptr gesture = gesture_set_.FindFromGestureId(event.GetGestureId()); if (!gesture) return; if (event.IsConstructionFinished() && !gesture->IsConstructionFinished()) { // This is the first update for this gesture signaling that // its construction has finished. gesture->Update(event); ResolveBufferedGestureThatFinishedConstruction(gesture); } else { gesture->Update(event); } // We no longer have to keep track of it. auto connection_iterator = gesture_lost_all_targets_connections_.find(gesture); if (connection_iterator != gesture_lost_all_targets_connections_.end()) connection_iterator->second.disconnect(); gesture_set_.Remove(*gesture); // We cannot leave a gesture behing without making a decision on its acceptance. if (gesture->GetAcceptanceStatus() == Gesture::AcceptanceStatus::UNDECIDED) { // This will likely only happen if a geture is ending with its construction unfinished, // which is an odd situation, but just in case... gesture->Reject(); } } void GestureBroker::ResolveBufferedGestureThatFinishedConstruction( std::shared_ptr &gesture) { gesture->Accept(); gesture->EnableEventDelivery(); // will flush all queued events std::vector< std::shared_ptr > conflicting_gestures = gesture_set_.GetConflictingGestures(gesture); if (!conflicting_gestures.empty()) { // That shouldn't happen. All conflicting gestures should have been // dealt with when they begun. for (auto conflicting_gesture : conflicting_gestures) { conflicting_gesture->Reject(); gesture_set_.Remove(*conflicting_gesture); } } } nux-4.0.6+14.04.20140409/Nux/SpinBox_Logic.cpp0000644000015301777760000001436612321344237020724 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "TimerProc.h" #include "SpinBox_Logic.h" namespace nux { SpinBox_Logic::SpinBox_Logic(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_UpTimerHandler(0) , m_DownTimerHandler(0) { m_SpinnerUpBtn = new BasicView(NUX_TRACKER_LOCATION); m_SpinnerDownBtn = new BasicView(NUX_TRACKER_LOCATION); m_EditLine = new EditTextBox("", NUX_TRACKER_LOCATION); // Set Original State m_EditLine->SetSuffix(""); m_EditLine->SetPrefix(""); // Set Signals m_SpinnerUpBtn->mouse_down.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvIncrement)); m_SpinnerUpBtn->mouse_double_click.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvIncrement)); m_SpinnerUpBtn->mouse_up.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvSpinnerMouseUp)); m_SpinnerUpBtn->mouse_click.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvSpinnerMouseUp)); m_SpinnerUpBtn->mouse_enter.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvMouseEnter)); m_SpinnerUpBtn->mouse_leave.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvMouseLeave)); m_SpinnerDownBtn->mouse_down.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvDecrement)); m_SpinnerDownBtn->mouse_double_click.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvDecrement)); m_SpinnerDownBtn->mouse_up.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvSpinnerMouseUp)); m_SpinnerDownBtn->mouse_click.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvSpinnerMouseUp)); m_SpinnerDownBtn->mouse_enter.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvMouseEnter)); m_SpinnerDownBtn->mouse_leave.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvMouseLeave)); m_EditLine->sigValidateEntry.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvValidateEntry)); m_EditLine->sigStartKeyboardFocus.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvStartKeyboardFocus)); m_EditLine->sigEndKeyboardFocus.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvEndKeyboardFocus)); m_EditLine->sigEscapeKeyboardFocus.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvEscapeKeyboardFocus)); m_EditLine->sigEditChange.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvEditChange)); m_EditLine->mouse_enter.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvMouseEnter)); m_EditLine->mouse_leave.connect(sigc::mem_fun(this, &SpinBox_Logic::RecvMouseLeave)); m_UpTimerCallback = new TimerFunctor; m_UpTimerCallback->tick.connect(sigc::mem_fun(this, &SpinBox_Logic::TimerSpinUpBtn)); m_DownTimerCallback = new TimerFunctor; m_DownTimerCallback->tick.connect(sigc::mem_fun(this, &SpinBox_Logic::TimerSpinDownBtn)); } SpinBox_Logic::~SpinBox_Logic() { delete m_UpTimerCallback; delete m_DownTimerCallback; // m_SpinnerUpBtn->Dispose(); // m_SpinnerDownBtn->Dispose(); // m_EditLine->Dispose(); } void SpinBox_Logic::RecvIncrement(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { TimerSpinUpBtn(0); } void SpinBox_Logic::RecvSpinnerMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_UpTimerHandler.IsValid()) { GetTimer().RemoveTimerHandler(m_UpTimerHandler); m_UpTimerHandler = 0; } if (m_DownTimerHandler.IsValid()) { GetTimer().RemoveTimerHandler(m_DownTimerHandler); m_DownTimerHandler = 0; } QueueDraw(); } void SpinBox_Logic::RecvDecrement(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { TimerSpinDownBtn(0); } void SpinBox_Logic::TimerSpinUpBtn(void * /* v */) { ImplementIncrementBtn(); } void SpinBox_Logic::TimerSpinDownBtn(void * /* v */) { ImplementDecrementBtn(); } void SpinBox_Logic::RecvStartKeyboardFocus(EditTextBox * /* textbox */) { QueueDraw(); } void SpinBox_Logic::RecvEndKeyboardFocus(EditTextBox * /* textbox */) { QueueDraw(); } void SpinBox_Logic::RecvEscapeKeyboardFocus(EditTextBox * /* textbox */) { QueueDraw(); } void SpinBox_Logic::RecvMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void SpinBox_Logic::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void SpinBox_Logic::RecvMouseMove(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void SpinBox_Logic::RecvMouseDrag(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void SpinBox_Logic::RecvEditChange(EditTextBox * /* textbox */) { QueueDraw(); } void SpinBox_Logic::RecvValidateEntry(EditTextBox * /* textbox */) { ImplementValidateEntry(); // int ret = 0; // if (inlCharToInteger(m_EditLine->GetCleanCaption().GetTChar(), ret)) // { // m_iValue = ret; // if (m_iValue < m_IntValidator.GetMinimum()) // { // m_iValue = m_IntValidator.GetMinimum(); // m_EditLine->setCaption(std::string::Printf("%d", m_iValue)); // } // if (m_iValue > m_IntValidator.GetMaximum()) // { // m_iValue = m_IntValidator.GetMaximum(); // m_EditLine->setCaption(std::string::Printf("%d", m_iValue)); // } // } // else // { // m_EditLine->setCaption(std::string::Printf("%d", m_iValue)); // } } } nux-4.0.6+14.04.20140409/Nux/NuxGlobalInitializer.h0000644000015301777760000000444312321344237021764 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUXGLOBALINITIALIZER_H #define NUXGLOBALINITIALIZER_H #define NUX_NUX_GLOBAL_OBJECT_INIT_SEQUENCE() // // NUX_GLOBAL_OBJECT_VARIABLE(RenderingStats); namespace nux { class NuxGlobalSingletonInitializer { NUX_DISABLE_OBJECT_COPY(NuxGlobalSingletonInitializer); NuxGlobalSingletonInitializer *operator & (); const NuxGlobalSingletonInitializer *operator & () const; public: NuxGlobalSingletonInitializer(); ~NuxGlobalSingletonInitializer(); static bool Ready(); private: static bool m_NuxGlobalObjectsReady; NUX_NUX_GLOBAL_OBJECT_INIT_SEQUENCE(); }; // Nifty Counter idiom. See http://www-d0.fnal.gov/KAI/doc/tutorials/static_initialization.html class NuxGlobalInitializer { public: NuxGlobalInitializer(); ~NuxGlobalInitializer(); private: static int m_Count; }; // Every compilation unit that includes this file will have its own instance of sGlobalInitializer. sGlobalInitializer is initialized // before the main function of the program is called. The first time sGlobalInitializer is initialized, it calls SystemStart() to create // our global object singleton. In SystemStart() we have a change to create our singletons in any order we like. // When the program exits, every instance of sGlobalInitializer will be destroyed. The last instance destroyed will call SystemShutdown(). // In SystemShutdown() we can destroy our global objects in any order we like. static NuxGlobalInitializer sNuxGlobalInitializer; } #endif // NUXGLOBALINITIALIZER_H nux-4.0.6+14.04.20140409/Nux/ScrollView.h0000644000015301777760000001360012321344237017751 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2010-2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef SCROLLVIEW_H #define SCROLLVIEW_H #include "Nux.h" #include "View.h" namespace nux { class HScrollBar; class VScrollBar; // Rename it to ScrollArea or ScrollWindow class ScrollView: public View { NUX_DECLARE_OBJECT_TYPE(ScrollView, View); public: ScrollView(NUX_FILE_LINE_PROTO); virtual ~ScrollView(); // API void EnableVerticalScrollBar(bool b); void EnableHorizontalScrollBar(bool b); virtual bool SetLayout(Layout *layout); ///////////////// // EMITERS // ///////////////// void OnSizeGrigMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnSizeGrigMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void EmitMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); //void EmitInternalResize(int x, int y, int w, int h); ///////////////// // RECEIVERS // ///////////////// virtual void ScrollLeft(float stepx, int mousedx); virtual void ScrollRight(float stepx, int mousedx); virtual void ScrollUp(float stepy, int mousedy); virtual void ScrollDown(float stepy, int mousedy); virtual void ResetScrollToLeft(); virtual void ResetScrollToRight(); virtual void ResetScrollToUp(); virtual void ResetScrollToDown(); // amount to scroll by for each mouse wheel event int m_MouseWheelScrollSize; // Geometry of the layout that encompass the child layouts. //! X Position of the content int m_ViewContentX; //! Y Position of the content int m_ViewContentY; //! Width of content int m_ViewContentWidth; //! Height of content int m_ViewContentHeight; //Client View Area //! X position of the scroll view content area int m_ViewX; //! Y position of the scroll view content area int m_ViewY; //! Width of the scroll view content area int m_ViewWidth; //! Height of the scroll view content area int m_ViewHeight; Geometry m_ViewGeometry; Geometry m_ContentGeometry; // signals /*! Emitted when scrolling happens. the parameters to the signals are: int: value of the horizontal translation of the layout. int: value of the vertical translation of the layout. This signal is emitted only if the scroll view has a layout. */ sigc::signal scrolling; public: void SetViewContentLeftMargin(int margin) { m_ViewContentLeftMargin = margin; } int GetViewContentLeftMargin() const { return m_ViewContentLeftMargin; } void SetViewContentRightMargin(int margin) { m_ViewContentRightMargin = margin; } int GetViewContentRightMargin() const { return m_ViewContentRightMargin; } void SetViewContentTopMargin(int margin) { m_ViewContentTopMargin = margin; } int GetViewContentTopMargin() const { return m_ViewContentTopMargin; } void SetViewContentBottomMargin(int margin) { m_ViewContentBottomMargin = margin; } int GetViewContentBottomMargin() const { return m_ViewContentBottomMargin; } protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); void RecvMouseWheel(int x, int y, int wheel_delta, long button_flags, unsigned long key_flags); //! Change Vertical Scrollbar in the ScrollView. /*! For styling purpose, allow the classes that inherit from ScrollView to change the vertical scrollbar. */ void SetVScrollBar(VScrollBar* newVScrollBar); // Backup texture to speed up scrolling ObjectPtr m_FrameBufferObject; void SwapTextureIndex() { m_TextureIndex = (m_TextureIndex == 0) ? 1 : 0; } void SetTextureIndex(int index) { m_TextureIndex = index; } int GetTextureIndex() { return m_TextureIndex; } int m_TextureIndex; bool m_ReformatTexture; // ScrollBars HScrollBar *_hscrollbar; VScrollBar *_vscrollbar; bool m_horizontal_scrollbar_enable; bool m_vertical_scrollbar_enable; int m_top_border; int m_border; //! Horizontal scrollbar offsets. int _delta_x; //! Vertical scrollbar offsets. int _delta_y; void FormatContent(); virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void ComputeContentPosition(float offsetX, float offsetY); private: virtual bool AcceptKeyNavFocus(); /** If True, the scrollbar size will be adjusted to match the size of the content. This is useful for the ComboBoxComplex widget. */ bool m_bSizeMatchContent; int m_ViewContentLeftMargin; int m_ViewContentRightMargin; int m_ViewContentTopMargin; int m_ViewContentBottomMargin; }; } #endif // SCROLLVIEW_H nux-4.0.6+14.04.20140409/Nux/ToggleButton.cpp0000644000015301777760000000306712321344237020636 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * Gordon Allott * */ #include "Nux.h" #include "ToggleButton.h" #include "HLayout.h" namespace nux { ToggleButton::ToggleButton(TextureArea *image, NUX_FILE_LINE_DECL) : Button(image, NUX_FILE_LINE_PARAM) { persistent_active_state_ = true; } ToggleButton::ToggleButton(const std::string label, NUX_FILE_LINE_DECL) : Button(label, NUX_FILE_LINE_PARAM) { persistent_active_state_ = true; } ToggleButton::ToggleButton(const std::string label, TextureArea *image, NUX_FILE_LINE_DECL) : Button(label, image, NUX_FILE_LINE_PARAM) { persistent_active_state_ = true; } ToggleButton::ToggleButton(NUX_FILE_LINE_DECL) : Button(NUX_FILE_LINE_PARAM) { persistent_active_state_ = true; } ToggleButton::~ToggleButton() { } } nux-4.0.6+14.04.20140409/Nux/Utils.cpp0000644000015301777760000000202012321344237017305 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Utils.h" namespace nux { // bool gMouseOwned = false; // // bool IsMouseOwned() // { // if (gMouseOwned) // { // return true; // } // else // { // return false; // } // } } nux-4.0.6+14.04.20140409/Nux/PangoText.cpp0000644000015301777760000003323712321344237020134 0ustar pbusernogroup00000000000000#include "Nux.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "Validator.h" #include "cairo/cairo.h" #include "pango/pango.h" #include "pango/pangocairo.h" #include "NuxGraphics/CairoGraphics.h" #include "PangoText.h" namespace nux { PangoText::PangoText(const char* text, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { _pango_font_map = pango_ft2_font_map_new(); _pango_context = pango_font_map_create_context(PANGO_FONT_MAP(_pango_font_map)); _pango_layout = pango_layout_new(_pango_context); _pango_font_desc = pango_font_description_from_string("Sans, 20"); _size_match_text = true; _textColor = color::White; _texture2D = 0; SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); SetText(text); } PangoText::~PangoText() { if (_cairoGraphics == 0) delete(_cairoGraphics); if (_texture2D == 0) delete(_texture2D); } void PangoText::PreLayoutManagement() { int textWidth = 0; int textHeight = 0; GetTextExtents("Ubuntu", textWidth, textHeight); _pre_layout_width = GetBaseWidth(); _pre_layout_height = GetBaseHeight(); SetBaseSize(textWidth, textHeight); if (_texture2D == 0) { UpdateTextLayout(); } View::PreLayoutManagement(); } long PangoText::PostLayoutManagement(long layoutResult) { // long result = View::PostLayoutManagement(layoutResult); long result = 0; int w = GetBaseWidth(); int h = GetBaseHeight(); if (_pre_layout_width < w) result |= eLargerWidth; else if (_pre_layout_width > w) result |= eSmallerWidth; else result |= eCompliantWidth; if (_pre_layout_height < h) result |= eLargerHeight; else if (_pre_layout_height > h) result |= eSmallerHeight; else result |= eCompliantHeight; return result; } void PangoText::SetSizeMatchText(bool size_match_text) { _size_match_text = size_match_text; } bool PangoText::GetSizeMatchText() const { return _size_match_text; } void PangoText::Draw(GraphicsEngine& gfxContext, bool forceDraw) { Geometry base = GetGeometry(); gfxContext.PushClippingRectangle(base); TexCoordXForm texxform; texxform.SetWrap(TEXWRAP_REPEAT, TEXWRAP_REPEAT); texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); gfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); gfxContext.QRP_1Tex(base.x, base.y, base.width, base.height, _texture2D->GetDeviceTexture(), texxform, _textColor); gfxContext.GetRenderStates().SetBlend(false); gfxContext.PopClippingRectangle(); } void PangoText::DrawContent(GraphicsEngine& gfxContext, bool forceDraw) { } void PangoText::SetText(std::string text) { if (_text != text) { _text = text; UpdateTextLayout(); sigTextChanged.emit(this); } } void PangoText::SetTextColor(Color textColor) { if (_textColor != textColor) { _textColor = textColor; sigTextColorChanged.emit(this); } } void PangoText::GetTextExtents(int &width, int &height) { GetTextExtents("Ubuntu", width, height); } void PangoText::GetTextExtents(const char* font, int& width, int& height) { cairo_surface_t* surface = NULL; cairo_t* cr = NULL; PangoLayout* layout = NULL; PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; PangoRectangle logRect = {0, 0, 0, 0}; int dpi = 96; // sanity check if (!font) return; surface = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1); cr = cairo_create(surface); CairoFontOptions font_options; cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_DEFAULT); cairo_font_options_set_subpixel_order(font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_set_font_options(cr, font_options); layout = pango_cairo_create_layout(cr); desc = pango_font_description_from_string(font); pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL); pango_layout_set_font_description(layout, desc); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_text(layout, _text.c_str(), -1); pangoCtx = pango_layout_get_context(layout); // is not ref'ed pango_cairo_context_set_font_options(pangoCtx, font_options); // use some default DPI-value pango_cairo_context_set_resolution(pangoCtx, dpi); pango_layout_context_changed(layout); pango_layout_get_extents(layout, NULL, &logRect); width = logRect.width / PANGO_SCALE; height = logRect.height / PANGO_SCALE; // clean up pango_font_description_free(desc); g_object_unref(layout); cairo_destroy(cr); cairo_surface_destroy(surface); } void PangoText::DrawText(void* cairo_context, int width, int height, Color color) { cairo_t* cr = (cairo_t*) cairo_context; int textWidth = 0; int textHeight = 0; PangoLayout* layout = NULL; PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; int dpi = 0; GetTextExtents("Ubuntu", textWidth, textHeight); CairoFontOptions font_options; cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_DEFAULT); cairo_font_options_set_subpixel_order(font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_set_font_options(cr, font_options); layout = pango_cairo_create_layout(cr); desc = pango_font_description_from_string("Ubuntu"); pango_layout_set_font_description(layout, desc); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_text(layout, _text.c_str(), -1); pangoCtx = pango_layout_get_context(layout); pango_cairo_context_set_font_options(pangoCtx, font_options); pango_cairo_context_set_resolution(pangoCtx, dpi); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.0f); cairo_paint(cr); cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); pango_layout_context_changed(layout); cairo_move_to(cr, 0.0f, 0.0f); pango_cairo_show_layout(cr, layout); // clean up pango_font_description_free(desc); g_object_unref(layout); } void PangoText::UpdateTextLayout() { pango_layout_set_text(_pango_layout, _text.c_str(), -1); // reset the glyph string if (_glyph_text) delete(_glyph_text); _glyph_text = 0; _glyph_length = 0; int max_g = 0; double pango_to_ink = (1.0/((double) PANGO_SCALE)); PangoLayoutIter* pIter = pango_layout_get_iter(_pango_layout); // and go! do { // typedef struct { // PangoLayout *layout; // gint start_index; // start of line as byte index into layout->text. // gint length; // length of line in bytes. // GSList *runs; // a list containing the runs of the line in visual order. // guint is_paragraph_start : 1; // TRUE if this is the first line of the paragraph. // guint resolved_dir : 3; // Resolved direction of line. // } PangoLayoutLine; PangoLayoutLine* pLine = pango_layout_iter_get_line(pIter); // no need for unref int plOffset = pLine->start_index; // start of the line in the uni32_text PangoRectangle ink_r; PangoRectangle log_r; pango_layout_iter_get_line_extents(pIter, &ink_r, &log_r); double plY = (1.0 / ((double) PANGO_SCALE)) * ((double) log_r.y); // start position of this line of the layout double plX = (1.0 / ((double) PANGO_SCALE)) * ((double) log_r.x); GSList* curR = pLine->runs; // Iterate over the runs of this line while (curR) { // typedef struct { // PangoItem *item; // a PangoItem structure that provides information about a segment of text. // PangoGlyphString *glyphs; // the glyphs obtained by shaping the text corresponding to item. // } PangoLayoutRun, PangoGlyphItem; // // typedef struct { // gint offset; // the offset of the segment from the beginning of the string in bytes. // gint length; // the length of the segment in bytes. // gint num_chars; // the length of the segment in characters. // PangoAnalysis analysis; // the properties of the segment. // } PangoItem; // typedef struct { // gint num_glyphs; // // PangoGlyphInfo *glyphs; // // /* This is a memory inefficient way of representing the information // * here - each value gives the byte index within the text // * corresponding to the glyph string of the start of the cluster to // * which the glyph belongs. // */ // gint *log_clusters; // } PangoGlyphString; PangoLayoutRun* pRun = (PangoLayoutRun*) curR->data; int prOffset = pRun->item->offset; // the offset of the segment from the beginning of the line in bytes if (pRun) { // a run has uniform font/directionality/etc... int o_g_l = _glyph_length; // save the index of the first glyph we'll add for (int i = 0; i < pRun->glyphs->num_glyphs; i++) { // add glyph sequentially, reading them from the run. realloc space for the glyphs if (_glyph_length >= max_g) { max_g = 2 * _glyph_length + 1; pango_glyph* temp = new pango_glyph [max_g + 1]; if (_glyph_length == 0) { _glyph_text = temp; } else { std::memcpy(temp, _glyph_text, _glyph_length * sizeof(pango_glyph)); delete _glyph_text; _glyph_text = temp; } } // fill the glyph info _glyph_text[_glyph_length].font = pRun->item->analysis.font; _glyph_text[_glyph_length].gl = pRun->glyphs->glyphs[i].glyph; _glyph_text[_glyph_length].uni_st = plOffset + prOffset + pRun->glyphs->log_clusters[i]; // depending on the directionality, the last uni32 codepoint for this glyph is the first of the next char // or the first of the previous if (pRun->item->analysis.level == 1) { // rtl if (i < pRun->glyphs->num_glyphs - 1) { _glyph_text[_glyph_length + 1].uni_en = _glyph_text[_glyph_length].uni_st; } _glyph_text[_glyph_length].uni_dir = 1; _glyph_text[_glyph_length + 1].uni_dir = 1; // set the directionality for the next too, so that the last glyph in // the array has the correct direction } else { // ltr if (i > 0) { _glyph_text[_glyph_length - 1].uni_en = _glyph_text[_glyph_length].uni_st; } _glyph_text[_glyph_length].uni_dir = 0; _glyph_text[_glyph_length + 1].uni_dir = 0; } // set the position // the layout is an infinite line _glyph_text[_glyph_length].x = plX + pango_to_ink * ((double) pRun->glyphs->glyphs[i].geometry.x_offset); _glyph_text[_glyph_length].y = plY + pango_to_ink * ((double) pRun->glyphs->glyphs[i].geometry.y_offset); // advance to the next glyph plX += pango_to_ink * ((double) pRun->glyphs->glyphs[i].geometry.width); // and set the next glyph's position, in case it's the terminating glyph _glyph_text[_glyph_length+1].x = plX; _glyph_text[_glyph_length+1].y = plY; _glyph_length++; } // and finish filling the info // notably, the uni_en of the last char in ltr text and the uni_en of the first in rtl are still not set if (pRun->item->analysis.level == 1) { // rtl if (_glyph_length > o_g_l) _glyph_text[o_g_l].uni_en=plOffset+prOffset+pRun->item->length; } else { if (_glyph_length > 0) _glyph_text[_glyph_length-1].uni_en=plOffset+prOffset+pRun->item->length; } // the terminating glyph has glyph_id=0 because it means 'no glyph' _glyph_text[_glyph_length].gl = 0; // and is associated with no text(but you cannot set uni_st=uni_en=0, because the termination // is expected to be the glyph for the termination of the uni32_text) _glyph_text[_glyph_length].uni_st = _glyph_text[_glyph_length].uni_en = plOffset + prOffset + pRun->item->length; } curR = curR->next; } } while ( pango_layout_iter_next_line(pIter)); pango_layout_iter_free(pIter); } void PangoText::ComputeTextLayout() { PangoLayout* layout = NULL; PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; PangoRectangle logRect = {0, 0, 0, 0}; int dpi = 96; } } nux-4.0.6+14.04.20140409/Nux/GroupBox.h0000644000015301777760000000346212321344237017432 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GROUPBOX_H #define GROUPBOX_H namespace nux { class Layout; /*! A stretch factor of 0 or 1 for the GroupBox has no effect because the GroupBox is designed to tightly adjust to the size of its composition layout. This unlike the Panel widget for instance who does not force itself to adjust to the size of its composition layout. */ class GroupBox : public View { public: GroupBox(const char *Caption = "", NUX_FILE_LINE_PROTO); ~GroupBox(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual bool SetLayout(Layout *layout); void SetCaption(const char *Caption); protected: virtual bool AcceptKeyNavFocus(); private: virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void ComputeContentPosition(float offsetX, float offsetY); BasicView m_CaptionArea; Layout *m_layout; }; } #endif // GROUPBOX_H nux-4.0.6+14.04.20140409/Nux/FileSelector.h0000644000015301777760000000362512321344237020246 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef FILE_SELECTOR_H #define FILE_SELECTOR_H namespace nux { class Button; class EditTextBox; class FileSelector: public View { public: FileSelector(NUX_FILE_LINE_PROTO); ~FileSelector(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); //void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); //void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); //void RecvMouseMove(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvOpenButtonClick(int x, int y, unsigned long button_flags, unsigned long key_flags); sigc::signal sigClick; private: EditTextBox *m_FileEditTextBox; InputArea *m_OpenButton; HLayout *m_hlayout; BaseTexture *m_Texture; }; } #endif // FILE_SELECTOR_H nux-4.0.6+14.04.20140409/Nux/NuxTimerTickSource.h0000644000015301777760000000224612321344237021433 0ustar pbusernogroup00000000000000#ifndef NUX_TIMER_TICK_SOURCE_H #define NUX_TIMER_TICK_SOURCE_H #include "NuxCore/Animation.h" #include "NuxCore/AnimationController.h" #include "Nux/Nux.h" #include "Nux/TimerProc.h" namespace nux { // Everything inline, but should be extracted. class NuxTimerTickSource: public animation::TickSource { public: NuxTimerTickSource() : foo(0) { timer_.tick.connect(sigc::mem_fun(this, &NuxTimerTickSource::Tick)); timer_.expired.connect(sigc::mem_fun(this, &NuxTimerTickSource::TimerExpired)); unsigned int period = 16; // ms int duration = -1; // run forever timer_handle_ = nux::GetTimer().AddDurationTimer(period, duration, &timer_, NULL); } ~NuxTimerTickSource() { if (timer_handle_.Activated()) nux::GetTimer().RemoveTimerHandler(timer_handle_); } private: void Tick(void*) { tick.emit(g_get_monotonic_time()); if (++foo % 60 == 0) { // LOG_WARN(logger) << "tick..."; } } void TimerExpired(void*) { //LOG_WARN(logger) << "Timer expired."; } private: int foo; TimerFunctor timer_; TimerHandle timer_handle_; }; } #endif // NUX_TIMER_TICK_SOURCE_H nux-4.0.6+14.04.20140409/Nux/VLayout.h0000644000015301777760000000354312321344237017270 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef VLAYOUT_H #define VLAYOUT_H #include "LinearLayout.h" namespace nux { class VLayout: public LinearLayout { NUX_DECLARE_OBJECT_TYPE(VLayout, LinearLayout); public: VLayout(NUX_FILE_LINE_PROTO); VLayout(std::string name, NUX_FILE_LINE_PROTO); ~VLayout(); virtual long ComputeContentSize(); virtual void ComputeContentPosition(float offsetX, float offsetY); virtual void VLayoutManagement(int width, int height); virtual unsigned int GetMaxStretchFactor(); virtual void GetCompositeList(std::list *ViewList); //! Compute the how elements are spread inside the layout /*! @param remaining_height Size that remains after subtracting elements height, inner and outer margins from the content height. @param offset_space The space at the top of all elements. @param element_margin The margin between elements. */ void ComputeStacking(int length, int &offset_space, int &element_margin); protected: virtual Area* KeyNavIteration(KeyNavDirection direction); }; } #endif // VLAYOUT_H nux-4.0.6+14.04.20140409/Nux/AbstractCheckedButton.h0000644000015301777760000000632712321344237022076 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ABSTRACTCHECKEDBUTTON_H #define ABSTRACTCHECKEDBUTTON_H #include "AbstractButton.h" namespace nux { class HLayout; class InputArea; class StaticText; //! AbstractCheckedButton class /*! Acts as a base class for CheckBox and radioButton.\n */ class AbstractCheckedButton: public AbstractButton { NUX_DECLARE_OBJECT_TYPE(AbstractCheckedButton, AbstractButton); public: AbstractCheckedButton(const std::string &str, bool state = false, NUX_FILE_LINE_PROTO); virtual ~AbstractCheckedButton(); //! Emitted when the button is clicked. sigc::signal click; //! Emitted when the active state changes. /*! Emitted when the active state changes, as a result of a mouse click or an API call.\n \sa Activate, Deactivate. */ sigc::signal state_change; //! Set the label. /*! Set the label of this AbstractCheckedButton. If the \a label argument is an empty string, then the the AbstractCheckedButton label is destroyed, and the content of the AbstractCheckedButton is re-arranged accordingly. @param label The label of the AbstractCheckedButton. */ void SetLabel(const std::string &checkbox_label); //!Return the label of this AbstractCheckedButton. /*! Return the label of this AbstractCheckedButton. @return The AbstractCheckedButton label string. */ std::string GetLabel() const; //! Activate the check box. /*! Activate the check box. */ virtual void Activate() = 0; //! Deactivate the check box. /*! Deactivate the check box. */ virtual void Deactivate() = 0; virtual void SetLabelFontSize(int point); protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw) = 0; virtual void RecvClick(int x, int y, unsigned long button_flags, unsigned long key_flags) = 0; virtual long ComputeContentSize(); HLayout *hlayout_; InputArea *check_area_; private: //! Override of Area::SetMinimumHeight and made private. /*! Prevent changing the minimum height of the StaticText view. */ virtual void SetMinimumHeight(int h){}; //! Override of Area::SetMaximumHeight and made private. /*! Prevent changing the maximum height of the StaticText view. */ virtual void SetMaximumHeight(int h){}; }; } #endif // ABSTRACTCHECKEDBUTTON_H nux-4.0.6+14.04.20140409/Nux/DoubleValidator.cpp0000644000015301777760000000601112321344237021271 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "DoubleValidator.h" #include #include namespace nux { DoubleValidator::DoubleValidator(double Minimum, double Maximum) : m_Minimum(Minimum) , m_Maximum(Maximum) , m_Decimals(3) { _regexp_str = "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$"; InitRegExp(); if (m_Minimum > m_Maximum) { double temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } DoubleValidator::DoubleValidator(const DoubleValidator ©) { m_Minimum = copy.m_Minimum; m_Maximum = copy.m_Maximum; _regexp_str = copy._regexp_str; InitRegExp(); } DoubleValidator &DoubleValidator::operator= (const DoubleValidator &rhs) { if (&rhs != this) { m_Minimum = rhs.m_Minimum; m_Maximum = rhs.m_Maximum; _regexp_str = rhs._regexp_str; InitRegExp(); } return *this; } DoubleValidator::~DoubleValidator() { } Validator *DoubleValidator::Clone() const { return new DoubleValidator(*this); } void DoubleValidator::SetMinimum(double value) { m_Minimum = value; if (m_Minimum > m_Maximum) { double temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } double DoubleValidator::GetMinimum() const { return m_Minimum; } void DoubleValidator::SetMaximum(double value) { m_Maximum = value; if (m_Minimum > m_Maximum) { double temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } double DoubleValidator::GetMaximum() const { return m_Maximum; } double DoubleValidator::GetClampedValue(double d) const { if (d < m_Minimum) return m_Minimum; if (d > m_Maximum) return m_Maximum; return d; } void DoubleValidator::Alternative(const char * /* str */) { } void DoubleValidator::SetDecimals(int dec) { m_Decimals = Clamp (dec, 0, 13); } std::string DoubleValidator::ToString(double d) { std::stringstream s; s << std::setprecision(m_Decimals) << d; return s.str(); } double DoubleValidator::ToDouble(const char *str) { if (Validate(str) == Acceptable) return CharToDouble(str); else return 0.0; } } nux-4.0.6+14.04.20140409/Nux/MenuPage.h0000644000015301777760000002521012321344237017361 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef MENUPAGE_H #define MENUPAGE_H #include "ActionItem.h" #include "FloatingWindow.h" namespace nux { class StaticText; class MenuPage; class VLayout; class MenuBar; class MenuItem: public View { NUX_DECLARE_OBJECT_TYPE(MenuItem, View); public: MenuItem(const char *label, int UserValue, NUX_FILE_LINE_PROTO); ~MenuItem(); void DrawAsMenuItem(GraphicsEngine &graphics_engine, const Color &textcolor, bool is_highlighted, bool isFirstItem, bool isLastItem, bool draw_icone); //const ActionItem& GetItem() const {return m_ActionItem;} ActionItem *GetActionItem() const; //ActionItem* GetActionItem(); int GetTextWidth(); int GetTextHeight(); StaticText * GetStaticText() { return _pango_static_text; } private: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) {}; void SetChildMenu(MenuPage *menu); MenuPage *GetChildMenu() const; void SetActionItem(ActionItem *menu); MenuPage *_child_menu; ActionItem *_action_item; StaticText *_pango_static_text; friend class MenuPage; }; class MenuSeparator: public View { NUX_DECLARE_OBJECT_TYPE(MenuSeparator, View); public: MenuSeparator(NUX_FILE_LINE_PROTO); ~MenuSeparator(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) {}; private: friend class MenuPage; }; class MenuPage: public View { NUX_DECLARE_OBJECT_TYPE(MenuPage, View); public: MenuPage(const char *title = "", NUX_FILE_LINE_PROTO); ~MenuPage(); // void SetName(const char* name); const char *GetName() const; ActionItem *AddAction(const char *label = 0, int UserValue = 0); //void AddActionItem(ActionItem* actionItem); void AddSeparator(); MenuPage *AddMenu(const char *label); ActionItem *AddSubMenu(const char *label, MenuPage *menu); void RemoveItem(ActionItem *item); void RemoveAllItem(); bool CanClose() const; // emitters void EmitMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void EmitMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void EmitMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void EmitMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); //private: //! Start the MenuPage iteration and show it. /* Start the MenuPage iteration and show it. When this function is called, the menu becomes visible and appear at position(MenuXPosition, MenuYPosition). The menu also assumes it has received a mouse down event at coordinates(x, y). \param MenuXPosition: the position of the menu. \param MenuYPosition: the position of the menu. \param x: the simulate position where the mouse down happened on the menu area. \param y: the simulate position where the mouse down happened on the menu area. \param TakeMousefocus: if true, the MenuPage area will take the mouse focus. */ void StartMenu(int MenuXPosition, int MenuYPosition, int x = 0, int y = 0, bool OverrideCurrentMenuChain = true); //! Stop the MenuPage iteration and hide it. /* Stop the MenuPage iteration and hide it. \param x: the simulate position where the mouse down happened on the menu area. \param y: the simulate position where the mouse down happened on the menu area. */ void StopMenu(int x = 0, int y = 0); void SetFontName(char *font_name); //! Let regular widgets process a mouse down event that closes the menu chain without a menu item selection. /*! When a menu chain closes as a result of a mouse down event outside of the menu chain, there is still the possibility to let regular widgets process the event. The flag is tested on the top level MenuPage of the menu chain. @param propagate_when_closing_without_action Set to True to propagate the event to regular widgets if the menu chain closes as a result of a mouse down event outside the menu chain. */ void SetOnClosureContinueEventCycle(bool on_closure_continue_with_event); //! Returns True if a mouse down that closes the menu chain can be processed by regular widgets. /*! When a menu chain closes as a result of a mouse down event outside of the menu chain, there is still the possibility to let regular widgets process the event. The flag is tested on the top level MenuPage of the menu chain. @return True is a mouse down event that closes a menu chain without an item selection, can be passed down the event cycle. */ bool OnClosureContinueEventCycle() const; public: void StopActionSubMenu(); void ExecuteActionItem(MenuItem *menuItem); void NotifyActionTriggeredToParent(MenuPage *, MenuItem *menuItem); void NotifyTerminateMenuCascade(); void NotifyMouseDownOutsideMenuCascade(int x, int y); void SetParentMenu(MenuPage *); MenuPage *GetParentMenu(); void setShowItemIcon(bool b) { m_show_item_icon = b; } bool ShowItemIcon() { return m_show_item_icon; } bool TestMouseDown(); bool TestMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, bool &hit_inside_a_menu); // Never call this function directly void Terminate(int x, int y, unsigned long button_flags, unsigned long key_flags); // signals sigc::signal sigItemSelected; //! Send an action Signal. /* The MenuPage object sends this signal when an action is triggered. \param MenuPage the menu object sending the signal. \param ActionItem the action object that was triggered in the menu. */ sigc::signal sigActionTriggered; //! Terminate the menu and its sub menu cascade. /* The MenuPage object send this signal to inform that it needs to be close. The receiving object must close the MenuPage by calling the member function StopMenu(). Any object that controls a menu should intercept sigTerminateMenuCascade and sigMouseDownOutsideMenuCascade. */ sigc::signal sigTerminateMenuCascade; //! Notify that a mouse down event happened outside the menu cascade. /* Notify that a mouse down event happened outside the menu cascade. This event is processed by the MenuPage bar. The menu bar checks if the mouse down happened on one of its menu bar item. If yes, it let the menu bar item process the event. if no, it will initiate the closure of the menu cascade. Any object that controls a menu should intercept sigTerminateMenuCascade and sigMouseDownOutsideMenuCascade. */ sigc::signal sigMouseDownOutsideMenuCascade; sigc::signal sigOpeningMenu; sigc::signal sigClosingMenu; void SetActive(bool b) { m_IsActive = b; if (b) /*m_PopupArea.*/CaptureMouseDownAnyWhereElse(true); else /*m_PopupArea.*/CaptureMouseDownAnyWhereElse(false); } bool IsActive() const { return m_IsActive; } /*! Return the number of items in the menu. */ int GetNumItem() const { return m_numItem; } ActionItem *GetActionItem(int i) const; /*! Get the index of and item in the menu. @return the index of the ActionItem in the menu. -1 if the Action Item is not found. */ int GetActionItemIndex(ActionItem *action) const; //! Return the position of this object with regard to its top left corner of the physical window. /*! Return the position of the Area inside the physical window. For the main layout set in WindowThread, The following functions are equivalent: \li GetGeometry() \li GetRootGeometry() \li GetAbsoluteGeometry() */ virtual Geometry GetAbsoluteGeometry() const; //! Return the position of this object with regard to its top level parent(the main layout or a BaseWindow). /*! Return the position of the Area inside the physical window. For the main layout set in WindowThread or for a BaseWindow, GetRootGeometry() is equivalent to GetGeometry(). */ virtual Geometry GetRootGeometry() const; protected: virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); private: bool on_closure_continue_with_event_; int m_numItem; int m_HighlightedItem; bool m_IsActive; VLayout* _vlayout; bool m_NextMouseUpMeanStop; MenuItem *m_SubMenuAction; std::string m_Name; bool m_Action_Triggered; MenuPage *m_Parent; // Set to TRUE if one of the MenuItem processed the mouse event. bool m_MouseEventProcessed; int m_item_width; int m_item_height; bool m_show_item_icon; std::vector m_MenuItemVector; std::vector< MenuSeparator * > m_MenuSeparatorVector; BaseWindow *m_MenuWindow; //! This parameter is True if this MenuPage is at the top of a menu chain attached to a MenuBar. bool m_IsTopOfMenuChain; char *_font_name; public: /////////////////////////////////////////////////////// // AbstractInterfaceObject /////////////////////////////////////////////////////// virtual long ComputeContentSize(); virtual void SetGeometry(const Geometry &geo); friend class MenuBar; friend class WindowCompositor; }; } #endif // MENUPAGE_H nux-4.0.6+14.04.20140409/Nux/StaticTextBox.h0000644000015301777760000000632212321344237020430 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef STATICTEXTBOX_H #define STATICTEXTBOX_H namespace nux { class Validator; class StaticTextBox : public View //public InputArea { NUX_DECLARE_OBJECT_TYPE(StaticTextBox, View); public: StaticTextBox(const char *Caption, NUX_FILE_LINE_PROTO); ~StaticTextBox(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); // API void SetText(const char *Caption); void SetText(const std::string &Caption); const char *GetText() const; unsigned int GetTextSize() const { return (unsigned int) m_Text.length(); } //! Change the widget minimum width whenever the text is set. /*! Change the widget minimum width whenever the text is set. @param b If true, the widget minimum width is set to match the size of the text */ void SetMinWidthMatchText(bool b); //! Return true if the widget with changes to match the text width. bool GetMinWidthMatchText() const; void SetTextColor(const Color &color) { m_TextColor = color; }; Color GetTextColor() const { return m_TextColor; }; void SetTextBackgroundColor(const Color &color) { m_BackgroundColor = color; } Color GetTextBackgroundColor() const { return m_BackgroundColor; } void SetTextAlignment(TextAlignment alignment) { m_TextAlignment = alignment; } TextAlignment GetTextAlignment() { return m_TextAlignment; } void SetDrawBackground(bool b) { m_bDrawBackground = b; } void SetBackground(AbstractPaintLayer *bkg); ///////////////// // SIGNALS // ///////////////// virtual void SetFont(ObjectPtr Font); protected: virtual bool AcceptKeyNavFocus(); void AdjustMinWidthToMatchText(); std::string m_Text; Color m_TextColor; Color m_BackgroundColor; tstring m_temporary_caption; Validator *m_validator; TextAlignment m_TextAlignment; AbstractPaintLayer *m_Background; bool m_bMinimumWidthMatchText; bool m_bDrawBackground; //! If true, blend the characters alpha value with the destination and write the result to the destination buffer. bool m_WriteAlpha; public: virtual void SetGeometry(const Geometry &geo) { Area::SetGeometry(geo); ComputeContentSize(); } }; } #endif // STATICTEXTBOX_H nux-4.0.6+14.04.20140409/Nux/StaticText.h0000644000015301777760000001414012321344237017754 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef STATICTEXT_H #define STATICTEXT_H #include "NuxCore/Size.h" #if defined(NUX_OS_WINDOWS) #define NUX_STATIC_TEXT_USE_DIRECT_WRITE #elif defined(NUX_OS_LINUX) #define NUX_STATIC_TEXT_USE_CAIRO #else #error Not implemented. #endif namespace nux { class CairoGraphics; /*! A View that renders as static text. */ class StaticText: public View { NUX_DECLARE_OBJECT_TYPE(StaticText, View); public: //! Text alignment inside the view. /*! When the text width is smaller than the view width, the text may be aligned inside the view. The options are: Left Right Center The default alignment is centered. */ enum TextAlignment { ALIGN_CENTER = 0, ALIGN_LEFT, ALIGN_RIGHT, }; StaticText(const std::string& text, NUX_FILE_LINE_PROTO); virtual ~StaticText(); //! Set size of widget according to the text extent. /*! @param size_match_text If true, the widget size is set to match the size of the text on the screen. */ void SetSizeMatchText(bool size_match_text); //! Return true if the widget with changes to match the text width. bool GetSizeMatchText() const; //! Set the text string. void SetText(const std::string& text); //! Get the text string. std::string GetText() const; //! Set text color. /*! Set the text color. The default color is white. @param text_color The text color. */ void SetTextColor(const Color& text_color); //! Get text color. /*! Get the text color. @return The text color. */ Color GetTextColor() const; //! Set the font name. /*! Set the font name. On Ubuntu, the default is "Ubuntu". @param font_name The font name. */ void SetFontName(const std::string& font_name); //! Get the font name. /*! Get the font name. @return The font name. */ std::string GetFontName() const; //! Set text point size. /* Set the text point size. The value should be greater than 0. Otherwise, the text point size is not changed. \n The default value is 10. @param size The text point size. */ void SetFontSize(int size); void SetTextPointSize(int size); //deprecated: use SetFontSize //! Get text point size. int GetFontSize() const; int GetTextPointSize() const; //deprecated: use GetFontSize void GetTextLayoutSize(int& width, int& height) const; Size GetTextLayoutSize() const; //! Set text alignment inside the view. /*! @param alignment The text alignment inside the view. */ void SetTextAlignment(TextAlignment alignment); //! Return the text alignment /*! @return The text alignment inside the view. */ TextAlignment GetTextAlignment() const; //! Returns the device texture for the text. /*! Returns the device texture for the text. The device texture may be used \n for direct rendering. @return A smart point for the device texture. */ ObjectPtr GetTextTexture(); sigc::signal text_changed; protected: virtual void ApplyMinWidth(); virtual long ComputeContentSize(); virtual void Draw(GraphicsEngine& graphics_engine, bool forceDraw); int text_width_; //!< Rasterized text width. int text_height_; //!< Rasterized text height. std::string text_; Color text_color_; BaseTexture* rasterized_text_texture_; bool size_match_text_; int clip_to_width_; //!< Wrapping of line. float font_size_; std::string font_name_; bool update_text_rendering_; ObjectPtr dw_texture_; TextAlignment text_alignment_; void SetClipping(int clipping); int GetClipping() const; #if defined(NUX_STATIC_TEXT_USE_DIRECT_WRITE) Size ComputeTextSize(bool assign = true, bool with_clipping = true); void RasterizeText(Color color); void UpdateTextRendering(); float layout_left_; float layout_top_; float dpi_scale_x; float dpi_scale_y; #elif defined (NUX_STATIC_TEXT_USE_CAIRO) float dpy_; std::string pango_font_name_; //!< Input to pango_font_description_from_string. Size ComputeTextSize(bool assign = true, bool with_clipping = true); void RasterizeText(void* cairo_context, Color color); void UpdateTextRendering(); CairoGraphics* cairo_graphics_; #endif private: //! Override of Area::SetMinimumHeight and made private. /*! Prevent changing the minimum height of the StaticText view. */ virtual void SetMinimumHeight(int h){}; //! Override of Area::SetMaximumHeight and made private. /*! Prevent changing the maximum height of the StaticText view. */ virtual void SetMaximumHeight(int h){}; //! Compute the full text size. /*! Compute the full text size, but do not change the parameters of this class. @return The full text size. */ Size GetTextSizeNoClip(); float padding_x_; //!< Adds a padding around the entire text box. float padding_y_; //!< Adds a padding around the entire text box. Size no_clip_size_; //! Cache of the GetTextSizeNoClip results so we don't recompute them constantly. }; } #endif // STATICTEXT_H nux-4.0.6+14.04.20140409/Nux/RGBValuator.h0000644000015301777760000001450212321344237020012 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RGBGEVALUATOR_H #define RGBGEVALUATOR_H #include "NuxCore/Color.h" #include "HexRegExpValidator.h" #include "IntegerValidator.h" #include "DoubleValidator.h" namespace nux { class ToggleButton; class VLayout; class HLayout; class EditTextBox; class AbstractButton; class RGBValuator : public View //public ValuatorAbstraction { NUX_DECLARE_OBJECT_TYPE(RGBValuator, View); public: RGBValuator(NUX_FILE_LINE_PROTO); RGBValuator(Color const& color, NUX_FILE_LINE_PROTO); /*! Create an initialize the widget with the appropriate color model and value. @param ColorModel The color model(CM_RGB, CM_HSV, CM_HLS) @param x Red if CM_RGB, Hue if CM_HSV, Hue if CM_HLS @param y Green if CM_RGB, Saturation if CM_HSV, Light if CM_HLS @param z Blue if CM_RGB, Value if CM_HSV, Saturation if CM_HLS @param alpha */ RGBValuator(color::Model colorModel, float x, float y, float z, float alpha, NUX_FILE_LINE_PROTO); ~RGBValuator(); // API void SetColorModel(color::Model cm); void SetColorFormat(color::Format cf); Color GetColor() const; void SetRGB(Color const& color); void SetRGB(float r, float g, float b); void SetAlpha(float alpha); void SetRGBA(Color const& color); void SetRGBA(float r, float g, float b, float a); void SetHSV(float h, float s, float v); void SetHLS(float h, float l, float s); // emitters void OnReceiveMouseDown_Red (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDown_Green (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDown_Blue (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDown_Alpha (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDrag_Red (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDrag_Green (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDrag_Blue (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDrag_Alpha (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnChangeColorModel(AbstractButton* button); void OnChangeColorFormat(AbstractButton* button); void RecvMouseDownColorModel(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseUp_Red (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseUp_Green (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseUp_Blue (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnComponentInput (EditTextBox *textbox, const std::string &s, int componentIndex); void OnChannelKeyboardFocus(); void OnChannelLostKeyboardFocus(); void OnChannelValidateKeyboardEntry(); void OnChannelCharacter(unsigned int character, int componentIndex); //! Cause the widget to emit sigColorChanged signal. /*! Cause the widget to emit sigColorChanged signal. Useful for initialization of the signal receivers. */ void EmitColorChangedSignal(); // signals //sigc::signal sigSetRGB; sigc::signal sigColorChanged; protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void PreLayoutManagement(); void InitializeWidgets(); void InitializeLayout(); virtual bool AcceptKeyNavFocus(); private: //! Override of Area::SetMinimumHeight and made private. /*! Prevent changing the minimum height of the RGBValuator view. */ virtual void SetMinimumHeight(int h){}; //! Override of Area::SetMaximumHeight and made private. /*! Prevent changing the maximum height of the RGBValuator view. */ virtual void SetMaximumHeight(int h){}; void DrawRedMarker(GraphicsEngine &graphics_engine); void DrawGreenMarker(GraphicsEngine &graphics_engine); void DrawBlueMarker(GraphicsEngine &graphics_engine); void DrawAlphaMarker(GraphicsEngine &graphics_engine); void DrawRGB(GraphicsEngine &graphics_engine); void DrawHSV(GraphicsEngine &graphics_engine); void DrawHLS(GraphicsEngine &graphics_engine); HLayout *hlayout; HLayout *redlayout; HLayout *greenlayout; HLayout *bluelayout; HLayout *alphalayout; VLayout *vlayout; VLayout *colormodel_layout; EditTextBox *red_caption_; EditTextBox *green_caption_; EditTextBox *blue_caption_; EditTextBox *alpha_caption_; BasicView *red_valuator_; BasicView *green_valuator_; BasicView *blue_valuator_; BasicView *alpha_valuator_; BasicView *color_square_; BasicView *m_ComponentLabel0; BasicView *m_ComponentLabel1; BasicView *m_ComponentLabel2; BasicView *m_ComponentAlpha; TextureLayer *m_CheckboardLayer; color::RedGreenBlue rgb_; color::HueSaturationValue hsv_; color::HueLightnessSaturation hls_; float alpha_; ToggleButton *m_ColorModel; ToggleButton *m_ColorFormat; color::Model m_color_model; color::Format m_color_format; HexRegExpValidator m_HexRegExp; IntegerValidator m_IntRegExp; DoubleValidator m_DoubleRegExp; }; } #endif // RGBGEVALUATOR_H nux-4.0.6+14.04.20140409/Nux/TextureArea.cpp0000644000015301777760000001232412321344237020446 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "TextureArea.h" #include "NuxGraphics/ImageSurface.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(TextureArea); TextureArea::TextureArea(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { mouse_down.connect(sigc::mem_fun(this, &TextureArea::RecvMouseDown)); mouse_up.connect(sigc::mem_fun(this, &TextureArea::RecvMouseUp)); mouse_enter.connect(sigc::mem_fun(this, &TextureArea::RecvMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &TextureArea::RecvMouseLeave)); mouse_click.connect(sigc::mem_fun(this, &TextureArea::RecvMouseClick)); mouse_drag.connect(sigc::mem_fun(this, &TextureArea::RecvMouseDrag)); paint_layer_ = new ColorLayer(nux::color::Black); rotation_2d_.Identity(); } TextureArea::~TextureArea() { if (paint_layer_) delete paint_layer_; } void TextureArea::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { // Ability to rotate the widget around its center graphics_engine.PushModelViewMatrix(Matrix4::TRANSLATE(-GetBaseX() - GetBaseWidth() / 2, -GetBaseY() - GetBaseHeight() / 2, 0)); graphics_engine.PushModelViewMatrix(Get2DRotation()); graphics_engine.PushModelViewMatrix(Matrix4::TRANSLATE(GetBaseX() + GetBaseWidth() / 2, GetBaseY() + GetBaseHeight() / 2, 0)); // The TextureArea should not render the accumulated background. That is left to the caller. // GetPainter().PaintBackground(graphics_engine, GetGeometry()); if (paint_layer_) { paint_layer_->SetGeometry(GetGeometry()); GetPainter().RenderSinglePaintLayer(graphics_engine, GetGeometry(), paint_layer_); } graphics_engine.PopModelViewMatrix(); graphics_engine.PopModelViewMatrix(); graphics_engine.PopModelViewMatrix(); } void TextureArea::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void TextureArea::SetTexture(BaseTexture *texture) { NUX_RETURN_IF_NULL(texture); delete paint_layer_; TexCoordXForm texxform; texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); texxform.SetWrap(TEXWRAP_REPEAT, TEXWRAP_REPEAT); paint_layer_ = new TextureLayer(texture->GetDeviceTexture(), texxform, color::White); QueueDraw(); } void TextureArea::SetColor(const Color &color) { delete paint_layer_; paint_layer_ = new ColorLayer(color); QueueDraw(); } void TextureArea::LoadImageFile(const std::string &filename) { if (paint_layer_) { delete paint_layer_; paint_layer_ = NULL; } BaseTexture *texture = LoadTextureFromFile(filename); if (texture) { TexCoordXForm texxform; ROPConfig rop; rop.Blend = true; rop.SrcBlend = GL_SRC_ALPHA; rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; paint_layer_ = new TextureLayer(texture->GetDeviceTexture(), texxform, color::White, true, rop); texture->UnReference(); } else { paint_layer_ = new ColorLayer(nux::color::Black); } } void TextureArea::SetPaintLayer(AbstractPaintLayer *layer) { NUX_SAFE_DELETE(paint_layer_); paint_layer_ = layer->Clone(); QueueDraw(); } AbstractPaintLayer* TextureArea::GetPaintLayer() const { if (paint_layer_ == NULL) return NULL; return paint_layer_->Clone(); } // void TextureArea::SetTexture(const char* TextureFilename) // { // // Who should delete the texture? This class or the user? // m_UserTexture = CreateTextureFromFile(TextureFilename); // QueueDraw(); // } void TextureArea::RecvMouseDown(int x, int y, long /* button_flags */, long /* key_flags */) { sigMouseDown.emit(x, y); QueueDraw(); } void TextureArea::RecvMouseClick(int /* x */, int /* y */, long /* button_flags */, long /* key_flags */) { } void TextureArea::RecvMouseUp(int /* x */, int /* y */, long /* button_flags */, long /* key_flags */) { QueueDraw(); } void TextureArea::RecvMouseEnter(int /* x */, int /* y */, long /* button_flags */, long /* key_flags */) { } void TextureArea::RecvMouseLeave(int /* x */, int /* y */, long /* button_flags */, long /* key_flags */) { } void TextureArea::RecvMouseDrag(int x, int y, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { sigMouseDrag.emit(x, y); } void TextureArea::Set2DRotation(float angle) { rotation_2d_.Rotate_z(angle); QueueDraw(); } Matrix4 TextureArea::Get2DRotation() const { return rotation_2d_; } } nux-4.0.6+14.04.20140409/Nux/Readme.txt0000644000015301777760000001151412321344237017447 0ustar pbusernogroup00000000000000Wednesday, May 10, 2006 -------------------------- Implemented RTTI with ObjectType. class InterfaceControl now inherits from BaseArea. remove m_BackgroundArea from InterfaceControl. Tuesday, November 23, 2005 -------------------------- I have reach a milestone. I am no longer concern about the feasibility of the GUI. For the most part, it is completed. Many things have been implemented: - file menu - status bar - modal window dialog - ... At this stage, I am cleaning the project in order to package the GUI in a library. From there, I will start designing some applications. Monday, August 1, 2005 ---------------------- The ComboBox is done. For that purpose, the third parameter of OnEvent and ProcessEvent was designed: ProcessEventInfo. ProcessEventInfo allow each base area OnEvent function to receive the event but not to process it. Previously if a mouse down was not inside a window, that window wouldn't propagate the event. Now, the event is propagated up to the OnEvent function and this one won't process the event if ProcessEventInfo = eDoNotProcess. If ProcessEventInfo = eDoNotProcess, only some check about m_CaptureMouseDownAnyWhereElse are done if needed. This feature can also be use to update timer on dynamic drawing objet attached to the widget (progressive appearance or dissapearance of a popup window for instance). If a BaseArea object has m_CaptureMouseDownAnyWhereElse = true, then that object want to receive notification every time a mouse down happens outside of its geometry. PushButton is working. ToolButton is on the way. Friday, july 15, 2005 -------------------- Rearranged the the OpenGL window Client (moved to OpenGLEngine) and GfxServer. New Table widget (later list box, tree list) Added DevIL as the texture file reader. Replace the FreeType code with Font.cpp and Fonts.hpp. This solution is more efficient and better regarding performance. Various clean Up Friday, may 20, 2005 -------------------- Fixed some text entry inconsistencies. Cleanup of signals. Added Signals and Functions for keyboard entry focus. Sunday, May 15, 2005 -------------------- Vertical and Horizontal scrollbars are working. Some minor inconsistencies still remain, but they will be fixed. Added debug feature for layout: - fixed margins - drawing of layouts borders with #define DEBUG_LAYOUT Friday, May 13, 2005 --------------------- Integers and Scrollbar don't fit together. All coordinates and width/height will be converted to float. Wednesday, May 11, 2005 ----------------------- - Addd vertical and horizontal scrollbar. 2005-05-07 ------------ - Added Drawing clipping region stack. This is a feature that clips a region against its parent before the region is drawn. This is needed for the GUI interface. The GUI Areas are stacked inside other Areas. At the highest level, a window set the clipping region to its size. And area inside the Window will then set the clipping region to its own side before it is drawn(PushClippingRectangle). What the clipping features does is, it clips the new region against the previous one and pushes the resulting region on the stack and uses it to set glScissor. If the result of the intersection is null, the clipping region is set to a null rectangle (nothing is drawn). After drawing the area, call PopClippingRectangle to pop the current clipping region and restore the previous clipping region. PushClippingRectangle - If(there is a current clipping region on the stack) compute the intersection between the input region and the region on the stack. Else clip the input region against the full window size. - If(the intersection is not null) set the glScissor to the size and position of the intersection region. Else set glScissor(0, 0, 0, 00 (nothing is drawn) PushClippingRectangle - If(there is a current clipping region on the stack) - pop it - If(the stack is not empty) set the clipping region to the size and position of the region on top of the stack Else set glScissor to the full window size. - The original generic template design provided by Loki is no longer par of the design. It has been replaced by a more classic architecture featuring inheritance and virtual functions. Also, A new layout design has been implemented. It took some time and effort before a suitable design could be achieved. I call this design "Follow, Rebel then Lead" or FRL. A design document is definitely needed here. At least so I can remember what I did latter. Some new widget have been implemented, most notably, the RGB color selector. 2005-04-05 ------------ I am getting ride of the generic interface for BaseArea. I don't think I need it anymore. BaseArea as enough functionality and I can handle it directly to composite widget. The free List feature comming with template is not tht useful since there are only few BaseArea that compose a widget. I will refactor the ValuatorImpl first.nux-4.0.6+14.04.20140409/Nux/MenuBar.cpp0000644000015301777760000003413212321344237017547 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "WindowCompositor.h" #include "HLayout.h" #include "MenuBar.h" namespace nux { static const unsigned int MENU_MINIMUM_WIDTH = 10; static const unsigned int MENU_MINIMUM_HEIGHT = 16; static const unsigned int MENUBAR_ICON_WIDTH = 24; static const unsigned int MENUBAR_ICON_HEIGHT = 24; NUX_IMPLEMENT_ROOT_OBJECT_TYPE(MenuBarItem); NUX_IMPLEMENT_OBJECT_TYPE(MenuBar); MenuBarItem::MenuBarItem(NUX_FILE_LINE_DECL) : Object(true, NUX_FILE_LINE_PARAM) { // This area is added to the layout of the MenuBar. The Menubar will will ref/unref it. area = new BasicView(NUX_TRACKER_LOCATION); icon = 0; } MenuBarItem::~MenuBarItem() { if (menu) menu->UnReference(); if (icon) icon->UnReference(); // The Area is owned by the MenuBar: do nothing for area. } MenuBar::MenuBar(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_MenuIsActive(false) //, m_CurrentMenu(0) , m_IsOpeningMenu(false) { m_CurrentMenu = NULL; m_MenuBarWindow = NULL; m_hlayout = new HLayout(NUX_TRACKER_LOCATION); m_hlayout->SetHorizontalInternalMargin(4); m_hlayout->SetHorizontalExternalMargin(2); SetMinimumSize(24, 24); SetMaximumSize(AREA_MAX_WIDTH, 24); SetGeometry(Geometry(0, 0, 200, 20)); m_hlayout->SetHorizontalInternalMargin(4); m_hlayout->SetVerticalExternalMargin(0); m_hlayout->SetContentDistribution(eStackLeft); SetCompositionLayout(m_hlayout); } MenuBar::~MenuBar() { std::list< MenuBarItem * >::iterator it; for (it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++) { (*it)->UnReference(); } m_MenuBarItemList.clear(); } void MenuBar::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); Geometry item_geometry; std::list< MenuBarItem * >::iterator it; for (it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++) { BasicView *area = (*it)->area; item_geometry = area->GetGeometry(); if (area->IsMouseInside()) { GetPainter().PaintBackground(graphics_engine, item_geometry); if (!m_MenuIsActive) { GetPainter().Paint2DQuadColor(graphics_engine, item_geometry, Color(0xFF000000)); //GetPainter().PaintShape(graphics_engine, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2); } else { GetPainter().Paint2DQuadColor(graphics_engine, item_geometry, Color(0xFF000000)); //GetPainter().PaintShapeCorner(graphics_engine, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2, //eCornerTopLeft|eCornerTopRight, false); } if ((*it)->icon) { graphics_engine.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); GetPainter().Draw2DTexture(graphics_engine, (*it)->icon, item_geometry.x, item_geometry.y); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); graphics_engine.GetRenderStates().SetBlend(GL_FALSE); } else { GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), item_geometry, area->GetBaseString(), GetTextColor(), true, eAlignTextCenter); } } else { GetPainter().PaintBackground(graphics_engine, item_geometry); if ((*it)->icon) { graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); graphics_engine.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GetPainter().Draw2DTexture(graphics_engine, (*it)->icon, item_geometry.x, item_geometry.y); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); graphics_engine.GetRenderStates().SetBlend(GL_FALSE); } else { GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), item_geometry, area->GetBaseString(), GetTextColor(), true, eAlignTextCenter); } } } if (m_MenuIsActive) { BasicView *area = m_CurrentMenu->area; item_geometry = area->GetGeometry(); GetPainter().PaintBackground(graphics_engine, item_geometry); GetPainter().Paint2DQuadColor(graphics_engine, item_geometry, Color(0xFF000000)); //GetPainter().PaintShapeCorner(graphics_engine, item_geometry, Color(0xFF000000), eSHAPE_CORNER_ROUND2, eCornerTopLeft|eCornerTopRight, true); if (m_CurrentMenu->icon) { graphics_engine.GetRenderStates().SetBlend(TRUE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); GetPainter().Draw2DTexture(graphics_engine, m_CurrentMenu->icon, item_geometry.x, item_geometry.y); graphics_engine.GetRenderStates().SetColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); graphics_engine.GetRenderStates().SetBlend(GL_FALSE); } else { GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), item_geometry, area->GetBaseString(), GetTextColor(), true, eAlignTextCenter); } } graphics_engine.PopClippingRectangle(); } void MenuBar::DrawContent(GraphicsEngine &graphics_engine, bool /* force_draw */) { graphics_engine.PushClippingRectangle(GetGeometry()); graphics_engine.PopClippingRectangle(); } void MenuBar::AddMenu(const char *MenuLabel, MenuPage *menu) { NUX_RETURN_IF_NULL(menu); AddMenu(MenuLabel, menu, 0); } void MenuBar::AddMenu(const char *MenuLabel, MenuPage *menu, BaseTexture *icon) { NUX_RETURN_IF_NULL(menu); // MenuBarItem inherits from Object: no need to Sink the reference. MenuBarItem *menubar_item(new MenuBarItem(NUX_TRACKER_LOCATION)); menu->m_IsTopOfMenuChain = true; menubar_item->area->SetBaseString(MenuLabel); menubar_item->menu = menu; if (menubar_item->menu) menubar_item->menu->Reference(); menubar_item->icon = icon; if (menubar_item->icon) menubar_item->icon->Reference(); m_MenuBarItemList.push_back(menubar_item); //menubar_item->area->SetMinimumSize(DEFAULT_WIDGET_WIDTH, 40); if (!icon) { menubar_item->area->SetMinimumSize(Max(MENU_MINIMUM_WIDTH, (unsigned int) (10 + GetFont()->GetStringWidth(MenuLabel))), Max(MENU_MINIMUM_WIDTH, (unsigned int) 16)); } else { menubar_item->area->SetMinMaxSize(MENUBAR_ICON_WIDTH, MENUBAR_ICON_HEIGHT); } menubar_item->area->mouse_enter.connect(sigc::bind(sigc::mem_fun(this, &MenuBar::EmitItemMouseEnter), menubar_item)); menubar_item->area->mouse_leave.connect(sigc::bind(sigc::mem_fun(this, &MenuBar::EmitItemMouseLeave), menubar_item)); menubar_item->area->mouse_down.connect(sigc::bind(sigc::mem_fun(this, &MenuBar::EmitItemMouseDown), menubar_item)); menubar_item->area->mouse_drag.connect(sigc::bind(sigc::mem_fun(this, &MenuBar::RecvItemMouseDrag), menubar_item)); menubar_item->area->mouse_up.connect(sigc::bind(sigc::mem_fun(this, &MenuBar::EmitItemMouseUp), menubar_item)); menubar_item->menu->SetParentMenu(0); menubar_item->menu->sigActionTriggered.connect(sigc::mem_fun(this, &MenuBar::RecvSigActionTriggered)); menubar_item->menu->sigTerminateMenuCascade.connect(sigc::mem_fun(this, &MenuBar::RecvSigTerminateMenuCascade)); menubar_item->menu->sigMouseDownOutsideMenuCascade.connect(sigc::mem_fun(this, &MenuBar::RecvSigMouseDownOutsideMenuCascade)); m_hlayout->AddView(menubar_item->area, 0, eCenter); GetWindowThread()->ComputeElementLayout(m_hlayout); } void MenuBar::EmitItemMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */, MenuBarItem *menubar_item) { if (m_MenuIsActive) { if (m_CurrentMenu && (m_CurrentMenu->menu != menubar_item->menu)) m_CurrentMenu->menu->StopMenu(0, 0); menubar_item->menu->m_MenuWindow = m_MenuBarWindow; menubar_item->menu->StartMenu(menubar_item->area->GetBaseX(), menubar_item->area->GetBaseY() + menubar_item->area->GetBaseHeight(), 0, 0); m_CurrentMenu = menubar_item; m_IsOpeningMenu = true; } QueueDraw(); } void MenuBar::EmitItemMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */, MenuBarItem * /* menubar_item */) { QueueDraw(); } void MenuBar::EmitItemMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */, MenuBarItem *menubar_item) { m_MenuBarWindow = GetWindowThread()->GetWindowCompositor().GetProcessingTopView(); if (m_MenuIsActive == false) { // Open the corresponding MenuPage if (m_CurrentMenu) { // This should never happen nuxAssert(0); m_CurrentMenu->menu->StopMenu(); } m_MenuIsActive = true; m_CurrentMenu = menubar_item; m_CurrentMenu->menu->m_MenuWindow = m_MenuBarWindow; m_IsOpeningMenu = true; m_CurrentMenu->menu->StartMenu(menubar_item->area->GetBaseX(), menubar_item->area->GetBaseY() + menubar_item->area->GetBaseHeight(), 0, 0); } else { // If the mouse up that follows happen inside the area, then it is going to close the menu. m_IsOpeningMenu = false; } QueueDraw(); } void MenuBar::EmitItemMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, MenuBarItem * /* menubar_item */) { if (m_MenuIsActive) { if (m_CurrentMenu->area->IsMouseInside()) { if (m_IsOpeningMenu == false) { // close the MenuPage that is Open if (m_CurrentMenu) m_CurrentMenu->menu->StopMenu(0, 0); m_MenuIsActive = false; m_CurrentMenu = 0; } else { // The MousePress before this MouseRelease, caused the MenuPage to open. // Set m_IsOpeningMenu so the next mouse release will close the menu. m_IsOpeningMenu = false; } } else { bool hit_inside_a_menu = false; bool b = m_CurrentMenu->menu->TestMouseUp(x, y, button_flags, key_flags, hit_inside_a_menu); if (b || (hit_inside_a_menu == false)) { RecvSigTerminateMenuCascade(); } } } QueueDraw(); } void MenuBar::RecvItemMouseDrag(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */, MenuBarItem * /* menubar_item */) { // TODO: Port to new event architecture // // Transition between one menu bar item to another // if (GetWindowThread()->GetWindowCompositor().GetMouseFocusArea() == menubar_item->area) // { // if (!menubar_item->area->IsMouseInside()) // can also test GetWindowThread()->GetWindowCompositor().GetMouseOverArea() != &menubar_item->area // { // std::list< MenuBarItem * >::iterator it; // // compute window coordinates x and y; // int winx = menubar_item->area->GetBaseX() + x; // int winy = menubar_item->area->GetBaseY() + y; // // for (it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++) // { // BasicView *area = (*it)->area; // Geometry geometry = area->GetGeometry(); // // if (geometry.IsPointInside(winx, winy)) // { // // Close the menu below menubar_item(the one that has the focus // menubar_item->area->ForceStopFocus(0, 0); // // // EmitItemMouseEnter is going to open the menu below(*it) // { // EmitItemMouseEnter(winx, winy, button_flags, key_flags, (*it)); // m_IsOpeningMenu = true; // area->ForceStartFocus(0, 0); // // GetWindowThread()->GetWindowCompositor().SetMouseFocusArea(area); // GetWindowThread()->GetWindowCompositor().SetMouseOverArea(area); // } // // break; // } // } // } // } } void MenuBar::RecvSigActionTriggered(MenuPage * /* menu */, ActionItem * /* action */) { m_MenuIsActive = false; if (m_CurrentMenu) { m_CurrentMenu->menu->StopMenu(); QueueDraw(); } m_CurrentMenu = 0; m_IsOpeningMenu = false; // You can do something if you want with the menu* and the action* } void MenuBar::RecvSigTerminateMenuCascade() { m_MenuIsActive = false; if (m_CurrentMenu) { m_CurrentMenu->menu->StopMenu(); } m_CurrentMenu = 0; m_IsOpeningMenu = false; QueueDraw(); } void MenuBar::RecvSigMouseDownOutsideMenuCascade(MenuPage * /* menu */, int x, int y) { Geometry geometry; std::list< MenuBarItem * >::iterator it; bool TerminateMenuCascade = 1; for (it = m_MenuBarItemList.begin(); it != m_MenuBarItemList.end(); it++) { BasicView *area = (*it)->area; geometry = area->GetGeometry(); if (geometry.IsPointInside(x, y)) { // The event landed on one of the MenuBar item. // Do nothing. This will be handled in the ProcessEvent of the MenuBar item where the mouse down landed. TerminateMenuCascade = 0; break; } } if (TerminateMenuCascade) RecvSigTerminateMenuCascade(); } } nux-4.0.6+14.04.20140409/Nux/Gesture.h0000644000015301777760000001304112321344237017275 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_GESTURE_H #define NUX_GESTURE_H #include "Features.h" #ifdef NUX_GESTURES_SUPPORT #include #include "NuxGraphics/GestureEvent.h" /* A collection of helper classes used by WindowCompositor for the task of delivering GestureEvents to their correct target InputAreas and in the decision of whether a gesture should be accepted or rejected. */ namespace nux { class InputArea; /* Interface for gesture targets. */ class GestureTarget { public: /*! Called whenever there's a new gesture event for this target. \param event GestureEvent to be processed by the target. \return A request about the delivery of events for the related gesture. */ virtual GestureDeliveryRequest GestureEvent(const GestureEvent &event) = 0; bool operator ==(const GestureTarget& other) const { return Equals(other); } /*** * We might not have ownership of every single object that we create * implementations of GestureTarget's to wrap around so this signal * indicates to the owner of the GestureTarget that the underlying * object is no longer available, and this target should be removed */ sigc::signal died; private: /*! For some types of target, different instances may wrap the same actual target, in which case reimplementing this method is necessary. */ virtual bool Equals(const GestureTarget& other) const { return this == &other; } }; typedef std::shared_ptr ShPtGestureTarget; class InputAreaTarget : public GestureTarget { public: InputAreaTarget(InputArea *input_area); virtual GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event); private: virtual bool Equals(const GestureTarget& other) const; ObjectWeakPtr input_area_; }; //! A class that relates a multitouch gesture to its target entity /*! It relates a gesture to its target, which can be either a window or unity. It's fed with GestureEvents via Update(). It stores those GestureEvents in a queue until EnableEventDelivery() is called, when all queued events are finally acted upon. After that, further events fed via Update() will have an immediate effect over its target instead of being queued. */ class Gesture { public: Gesture(const GestureEvent &event); void AddTarget(ShPtGestureTarget target); void RemoveTarget(const GestureTarget &target); const std::list &GetTargetList() const {return target_list_;} void EnableEventDelivery(); void Update(const GestureEvent& event); bool IsConstructionFinished() const; bool IsDeliveringEvents() const {return event_delivery_enabled_;} int GetId() const; const std::vector &GetTouches() const; //! Returns whether the given gesture has any touches in common with this one. bool HasTouchesInCommon(const std::shared_ptr &other_gesture) const; //! Rejects the gesture. /* After rejection a gesture is no longer valid */ void Reject(); //! Accepts the gesture void Accept(); enum class AcceptanceStatus { UNDECIDED, ACCEPTED, REJECTED }; AcceptanceStatus GetAcceptanceStatus() const {return acceptance_status_;} /*** * This signal is emitted when a Gesture loses all of its targets and * can no longer be delivered to anything. This might provide a hint * to the owner to stop tracking the gesture */ sigc::signal lost_all_targets; private: const GestureEvent &GetLatestEvent() const; GestureEvent &GetLatestEvent(); void DeliverEvent(const GestureEvent &event); void ExecuteTargetExclusivityRequest(const GestureEvent &event, std::list::iterator &it_requestor); std::list target_list_; std::map target_died_connections_; // events that are waiting to be delivered std::vector queued_events_; // last event delivered GestureEvent last_event_; bool event_delivery_enabled_; AcceptanceStatus acceptance_status_; }; /* Stores information on all curently active gestures. */ class GestureSet { public: void Add(Gesture *gesture); void Add(std::shared_ptr &gesture); std::shared_ptr FindFromGestureId(int gesture_id); std::shared_ptr FindFromTarget(ShPtGestureTarget target); void Remove(const Gesture &gesture); std::vector< std::shared_ptr > GetConflictingGestures(std::shared_ptr &gesture); private: std::map > map_id_to_gesture_; }; } // namespace nux #endif // NUX_GESTURES_SUPPORT #endif // NUX_GESTURE_H nux-4.0.6+14.04.20140409/Nux/Timeline.cpp0000644000015301777760000000421512321344237017763 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by Gordon Allott * */ #include "Nux.h" #include "Timeline.h" namespace nux { Timeline::Timeline(unsigned int msecs, const char * /* Caption */, NUX_FILE_LINE_DECL) : Object(true, NUX_FILE_LINE_PARAM) { Looping = false; IsPlaying = false; Duration = msecs; Rewind(); SinkReference(); // get rid of our floating reference nux::GetWindowThread()->AddTimeline(this); } Timeline::~Timeline() { } void Timeline::Stop() { Pause(); Rewind(); } void Timeline::Start() { IsPlaying = true; Started.emit(); } void Timeline::Pause() { IsPlaying = false; Paused.emit(); } void Timeline::Rewind() { _ElapsedTime = 0; } double Timeline::GetProgress() { return (float)_ElapsedTime / Duration; } double Timeline::GetEasing() { // no easing for the base class return GetProgress(); } void Timeline::DoTick(unsigned long msecs) { if (msecs < 1) return; _ElapsedTime += msecs; if (Looping) _ElapsedTime %= Duration; unsigned long remainder = 0; if (_ElapsedTime > Duration) { remainder = _ElapsedTime - Duration; _ElapsedTime = Duration; } NewFrame.emit(msecs); if (remainder > 0) { nux::GetWindowThread()->RemoveTimeline(this); IsPlaying = false; Completed.emit(); UnReference(); } } } nux-4.0.6+14.04.20140409/Nux/AbstractThread.h0000644000015301777760000000441412321344237020556 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ABSTRACTTHREAD_H #define ABSTRACTTHREAD_H namespace nux { typedef void(*ThreadUserInitFunc) (NThread *, void *InitData); typedef void(*ThreadUserExitFunc) (NThread *, void *ExitData); typedef void(*ThreadMainFunc) (NThread *, void *MainData); class AbstractThread: public NThread, public sigc::trackable { NUX_DECLARE_OBJECT_TYPE(AbstractThread, NThread); public: AbstractThread(AbstractThread *Parent); virtual ~AbstractThread(); protected: virtual int Run(void *) = 0; virtual ThreadState StartChildThread(AbstractThread *thread, bool Modal) = 0; virtual void AddChildThread(AbstractThread *) = 0; virtual void RemoveChildThread(AbstractThread *) = 0; virtual void ChildHasFinished(AbstractThread *app) = 0; virtual void TerminateChildThreads() = 0; void TerminateChildWindows(); void JoinChildThreads(); std::list children_thread_list_; AbstractThread *parent_; ThreadUserInitFunc user_init_func_; ThreadUserExitFunc user_exit_func_; /*! This pointer maybe set by the user in ThreadInitFunc and reused in ThreadExitFunc */ void *initialization_data_; std::list m_ThreadList; private: AbstractThread(const AbstractThread &); // Does not make sense for a singleton. This is a self assignment. AbstractThread &operator= (const AbstractThread &); // Declare operator adress-of as private AbstractThread *operator &(); }; } #endif // ABSTRACTTHREAD_H nux-4.0.6+14.04.20140409/Nux/Theme.cpp0000644000015301777760000002563612321344237017271 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Theme.h" #if defined(NUX_OS_WINDOWS) #include "tinyxml/tinyxml.h" #endif namespace nux { #define INT_TO_ENUM_ELEMENT(a) {a, #a} // --->>> {a, "a"} typedef struct { UXStyleImageRef value; const char *style; } UXStyle; UXStyle UXStyleArray [] = { INT_TO_ENUM_ELEMENT(eIMAGE_STYLE_NONE), INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_SQUARE), INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND1), INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND2), INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND4), INT_TO_ENUM_ELEMENT(eSTROKE_CORNER_ROUND10), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND1), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND2), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND4), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND5), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND6), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND10), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND10_SHADOW), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_ROUND4_SHADOW), INT_TO_ENUM_ELEMENT(eSHAPE_CORNER_SHADOW), INT_TO_ENUM_ELEMENT(eTRIANGLE_UP), INT_TO_ENUM_ELEMENT(eTRIANGLE_DOWN), INT_TO_ENUM_ELEMENT(eTRIANGLE_LEFT), INT_TO_ENUM_ELEMENT(eTRIANGLE_RIGHT), INT_TO_ENUM_ELEMENT(eWINDOW_SIZEGRIP), INT_TO_ENUM_ELEMENT(eSHAPE_CHECK_MARK), INT_TO_ENUM_ELEMENT(eSHAPE_CHECK_BOX), INT_TO_ENUM_ELEMENT(eCHECKBOX_NORMAL_ON), INT_TO_ENUM_ELEMENT(eCHECKBOX_NORMAL_OFF), INT_TO_ENUM_ELEMENT(eCHECKBOX_FOCUS_ON), INT_TO_ENUM_ELEMENT(eCHECKBOX_FOCUS_OFF), INT_TO_ENUM_ELEMENT(eCHECKBOX_PRELIGHT_ON), INT_TO_ENUM_ELEMENT(eCHECKBOX_PRELIGHT_OFF), INT_TO_ENUM_ELEMENT(eRADIO_NORMAL_ON), INT_TO_ENUM_ELEMENT(eRADIO_NORMAL_OFF), INT_TO_ENUM_ELEMENT(eRADIO_FOCUS_ON), INT_TO_ENUM_ELEMENT(eRADIO_FOCUS_OFF), INT_TO_ENUM_ELEMENT(eRADIO_PRELIGHT_ON), INT_TO_ENUM_ELEMENT(eRADIO_PRELIGHT_OFF), INT_TO_ENUM_ELEMENT(eBUTTON_NORMAL), INT_TO_ENUM_ELEMENT(eBUTTON_FOCUS), INT_TO_ENUM_ELEMENT(eBUTTON_PRELIGHT), INT_TO_ENUM_ELEMENT(eSPINNERUP), INT_TO_ENUM_ELEMENT(eSPINNERDOWN), INT_TO_ENUM_ELEMENT(eCOMBOBOX_OPEN_BUTTON), INT_TO_ENUM_ELEMENT(eTAB_LEFT), INT_TO_ENUM_ELEMENT(eTAB_RIGHT), INT_TO_ENUM_ELEMENT(eSPINER_UP), INT_TO_ENUM_ELEMENT(eSPINER_DOWN), INT_TO_ENUM_ELEMENT(eTREE_NODE_OPEN), INT_TO_ENUM_ELEMENT(eTREE_NODE_CLOSE), INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_UP), INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_DOWN), INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_LEFT), INT_TO_ENUM_ELEMENT(eSCROLLBAR_TRIANGLE_RIGHT), INT_TO_ENUM_ELEMENT(eVALUATORVERTICALMOVE), INT_TO_ENUM_ELEMENT(eVALUATORHORIZONTALMOVE), INT_TO_ENUM_ELEMENT(eVALUATORMOVE), INT_TO_ENUM_ELEMENT(eVECTORXLABEL), INT_TO_ENUM_ELEMENT(eVECTORYLABEL), INT_TO_ENUM_ELEMENT(eVECTORZLABEL), INT_TO_ENUM_ELEMENT(eVECTORWLABEL), INT_TO_ENUM_ELEMENT(eHSCROLLBAR), INT_TO_ENUM_ELEMENT(eVSCROLLBAR), INT_TO_ENUM_ELEMENT(eMATRIX3PREVIEW), INT_TO_ENUM_ELEMENT(eMATRIX4PREVIEW), INT_TO_ENUM_ELEMENT(eDOT6x6), INT_TO_ENUM_ELEMENT(eGraphIcon), INT_TO_ENUM_ELEMENT(eGraphBarIcon), INT_TO_ENUM_ELEMENT(eWindowCloseButton), {eIMAGE_STYLE_NONE, 0} }; static UXStyleImageRef GetStyleImageRef(const char *style_name) { int i = 0; while (UXStyleArray[i].style != 0) { if (strcmp(UXStyleArray[i].style, style_name) == 0) { return UXStyleArray[i].value; } i++; } return eIMAGE_STYLE_NONE; } UXTheme::UXTheme() { LoadPainterImages(); } UXTheme::~UXTheme() { std::list::iterator it; for (it = painter_image_list_.begin(); it != painter_image_list_.end(); it++) { if ((*it)->texture) { (*it)->texture->UnReference(); } delete(*it); } painter_image_list_.clear(); } #if defined(NUX_OS_LINUX) void UXTheme::ParseStartImage(GMarkupParseContext* /* context */, const gchar* element_name, const gchar** attribute_names, const gchar** attribute_values, gpointer user_data, GError** /* error */) { if (strcmp(element_name, "Image") != 0) { return; } const gchar** name_cursor = attribute_names; const gchar** value_cursor = attribute_values; UXTheme* theme = static_cast(user_data); PainterImage* pimage = new PainterImage; while (*name_cursor) { if (strcmp(*name_cursor, "style") == 0) { pimage->style = GetStyleImageRef(*value_cursor); } if (strcmp(*name_cursor, "border_left") == 0) { pimage->border_left = CharToInteger(*value_cursor); } if (strcmp(*name_cursor, "border_right") == 0) { pimage->border_right = CharToInteger(*value_cursor); } if (strcmp(*name_cursor, "border_top") == 0) { pimage->border_top = CharToInteger(*value_cursor); } if (strcmp(*name_cursor, "border_bottom") == 0) { pimage->border_bottom = CharToInteger(*value_cursor); } if (strcmp(*name_cursor, "Name") == 0) { BaseTexture* device_texture; std::string texture_filename = NUX_FIND_RESOURCE_LOCATION_NOFAIL(*value_cursor); device_texture = theme->Load2DTextureFile(texture_filename.c_str()); pimage->texture = device_texture; } name_cursor++; value_cursor++; } theme->painter_image_list_.push_back(pimage); } void UXTheme::ParseEndImage(GMarkupParseContext* /* context */, const gchar* /* element_name */, gpointer /* user_data */, GError** /* error */) { } #endif void UXTheme::LoadPainterImages() { std::string file_search = "Painter.xml"; std::string painter_filename = NUX_FIND_RESOURCE_LOCATION_NOFAIL(file_search.c_str()); if (painter_filename == "") { nuxCriticalMsg("[GraphicsEngine::LoadPainterImages] Can't find Painter.xml file."); return; } #if defined(NUX_OS_LINUX) /* The list of what handler does what. */ GMarkupParser parser = { UXTheme::ParseStartImage, UXTheme::ParseEndImage, NULL, NULL, NULL }; GMarkupParseContext* context = g_markup_parse_context_new ( &parser, G_MARKUP_TREAT_CDATA_AS_TEXT, this, NULL); std::string str; LoadFileToString(str, painter_filename.c_str()); if (g_markup_parse_context_parse(context, str.c_str(), str.length(), NULL) == FALSE) { nuxCriticalMsg("[GraphicsEngine::LoadPainterImages] Failed to parse data."); return; } #else TiXmlDocument doc(painter_filename.c_str()); doc.LoadFile(); TiXmlHandle docHandle( &doc ); TiXmlElement *data = docHandle.FirstChild(TCHARToUTF8("PaintData")).Element(); TiXmlElement *image = 0; for (image = data->FirstChildElement(TCHARToUTF8("Image")); image; image = image->NextSiblingElement(TCHARToUTF8("Image"))) { PainterImage* pimage = new PainterImage; Memset(pimage, 0, sizeof(PainterImage)); std::string style = image->Attribute(TCHARToUTF8("style")); pimage->style = GetStyleImageRef(style.c_str()); // If the attributes border_left, border_right, border_top, border_bottom are not present, assume they are equal to 0; pimage->border_left = pimage->border_right = pimage->border_top = pimage->border_bottom = 0; image->Attribute(TCHARToUTF8("border_left"), &pimage->border_left); image->Attribute(TCHARToUTF8("border_right"), &pimage->border_right); image->Attribute(TCHARToUTF8("border_top"), &pimage->border_top); image->Attribute(TCHARToUTF8("border_bottom"), &pimage->border_bottom); const char *draw_borders_only = image->Attribute(TCHARToUTF8("border_only")); if (draw_borders_only == 0) { pimage->draw_borders_only = true; } else { if (strcmp(TCHARToUTF8("false"), draw_borders_only) == 0) { pimage->draw_borders_only = false; } else { pimage->draw_borders_only = true; } } if (1) { std::string filename = image->Attribute(TCHARToUTF8("Name")); std::string texture_filename = NUX_FIND_RESOURCE_LOCATION_NOFAIL(filename.c_str()); pimage->texture = 0; pimage->filename = texture_filename; } else { std::string filename = image->Attribute(TCHARToUTF8("Name")); std::string texture_filename = NUX_FIND_RESOURCE_LOCATION_NOFAIL(filename.c_str()); pimage->texture = Load2DTextureFile(texture_filename.c_str()); } painter_image_list_.push_back(pimage); } #endif } const PainterImage *UXTheme::GetImage(UXStyleImageRef style) { std::list::iterator it; for (it = painter_image_list_.begin(); it != painter_image_list_.end(); it++) { if (!(*it)->texture) { BaseTexture* device_texture = Load2DTextureFile((*it)->filename.c_str()); (*it)->texture = device_texture; } if ((*it)->style == style) { return (*it); } } return 0; } Rect UXTheme::GetImageGeometry(UXStyleImageRef style) { std::list::iterator it; for (it = painter_image_list_.begin(); it != painter_image_list_.end(); it++) { if (!(*it)->texture) { BaseTexture* device_texture = Load2DTextureFile((*it)->filename.c_str()); (*it)->texture = device_texture; } if ((*it)->style == style) { unsigned int width = (*it)->texture->GetWidth(); unsigned int height = (*it)->texture->GetHeight(); return Rect(0, 0, width, height); } } nuxDebugMsg("[GraphicsEngine::GetImageGeometry] Cannot find UXStyleImageRef"); return Rect(0, 0, 0, 0); } BaseTexture *UXTheme::Load2DTextureFile(const char *filename) { BaseTexture* texture2D = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); NBitmapData *BitmapData = LoadImageFile(filename); if (BitmapData) { texture2D->Update(BitmapData); delete BitmapData; } return texture2D; } BaseTexture *UXTheme::Load2DTextureFileGenerateAlpha(const char * /* filename */, int /* red */, int /* green */, int /* blue */) { return 0; } } nux-4.0.6+14.04.20140409/Nux/TimerProc.cpp0000644000015301777760000004717512321344237020135 0ustar pbusernogroup00000000000000/* * Copyright 2010-2013 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * Marco Trevisan * */ #include "Nux.h" #include "TimerProc.h" #include "WindowCompositor.h" #include "WindowThread.h" class BaseWindow; namespace nux { typedef struct { long sec; // seconds long usec; // and microseconds } TimeStruct; /** Return true if t1 is a time reference that will happen after time t2 has expired. */ static bool TimeIsGreater(TimeStruct t1, TimeStruct t2); static void TimeRightNow(TimeStruct *tv); //static unsigned int TimeDiff(TimeStruct t1, TimeStruct t2); static NThreadSafeCounter TimerUID = 0x01234567; class TimerObject { public: TimerObject(); bool operator == (const TimerObject &timer_object); //! Delay before the callback expires TimeStruct when; int Type; gint64 ms_time; // milliseconds void *CallbackData; TimeOutSignal *timeout_signal; //! time progression factor between [0.0, 1.0] float Param; float ProgressDelta; int Period; //!< The periode of the timer interuption(in milliseconds). int Duration; //!< How long the timer will be running from start to finish(in milliseconds); int ElapsedTime; //!< Elapsed time during execution(in milliseconds). int ScheduledIteration; //!< The number of scheduled iterations. int ProgressIterationCount; //!< Number of times the timer has been executed. bool marked_for_removal_; BaseWindow *Window; //!< BaseWindow from where the timer was created. unsigned int glibid; unsigned int uid; TimerHandler::TimerState state_; }; TimerObject::TimerObject() : Type(0) , ms_time(0) , CallbackData(nullptr) , timeout_signal(nullptr) , Param(0) , ProgressDelta(0) , Period(0) , Duration(0) , ElapsedTime(0) , ScheduledIteration(0) , ProgressIterationCount(0) , marked_for_removal_(0) , Window(nullptr) , glibid(0) , uid(0) , state_(TimerHandler::TIMER_STATE_STOPED) {} TimerHandle::TimerHandle() {} TimerHandle::TimerHandle(TimerObject *timer_object) : m_d(timer_object) {} TimerHandle::TimerHandle(const TimerHandle &timer_handle) : m_d(timer_handle.m_d) {} TimerHandle& TimerHandle::operator = (const TimerHandle &timer_handle) { TimerHandle copy(timer_handle); std::swap(m_d, copy.m_d); return *this; } std::shared_ptr const& TimerHandle::operator->() const { return m_d; } bool TimerHandle::operator==(TimerHandle const& h) const { bool equal = (m_d == h.m_d); if (equal && m_d) equal = (m_d->uid == h.m_d->uid); return equal; } bool TimerHandle::IsValid() const { return Activated(); } bool TimerHandle::Activated() const { return m_d != nullptr; } float TimerHandle::GetProgress() const { if (m_d) return m_d->Param; return 0.0f; } float TimerHandle::GetProgressDelta() const { if (m_d) return m_d->ProgressDelta; return 0; } int TimerHandle::GetScheduledIterationCount() const { if (m_d) return m_d->ScheduledIteration; return 0; } int TimerHandle::GetProgressIterationCount() const { if (m_d) return m_d->ProgressIterationCount; return 0; } int TimerHandle::GetElapsedTimed() const { if (m_d) return m_d->ElapsedTime; return 0; } //////////////////////////////////////////////////// TimerHandler::TimerHandler(WindowThread* window_thread) : window_thread_(window_thread) , is_processing_timers_(false) {} void TimerHandler::StartEarlyTimerObjects() { for (auto const& timer_object : early_timer_handlers_) { timer_object->ms_time = g_get_monotonic_time() / 1000; #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) timer_object->glibid = GetWindowThread()->AddTimeout(timer_object->Period); #endif } early_timer_handlers_.clear(); } TimerHandle TimerHandler::AddOneShotTimer(unsigned int Period, TimeOutSignal* timeout_signal, void* Data, WindowThread* window_thread) { TimerHandle timer_object(new TimerObject); timer_object->ms_time = g_get_monotonic_time() / 1000; timer_object->CallbackData = Data; timer_object->timeout_signal = timeout_signal; timer_object->Period = Period; timer_object->Type = TIMERTYPE_PERIODIC; timer_object->state_ = TimerHandler::TIMER_STATE_RUNNING; if (window_thread) timer_object->Window = window_thread->GetWindowCompositor().GetProcessingTopView(); else timer_object->Window = GetWindowThread()->GetWindowCompositor().GetProcessingTopView(); AddHandle(timer_object); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) { if (window_thread) timer_object->glibid = window_thread->AddTimeout(Period); else timer_object->glibid = GetWindowThread()->AddTimeout(Period); if (timer_object->glibid == 0) { early_timer_handlers_.push_back(timer_object); // Probably trying to set a timeout before Glib main context and loop have been created. // Sometimes later, this timer will be examined when ExecTimerHandler is called. // This happens when trying to set a callback before the main loop has been initialized. } //nuxDebugMsg("[TimerHandler::AddOneShotTimer] Adding Timeout ID: %d", timer_object->glibid); } #endif return timer_object; } TimerHandle TimerHandler::AddDurationTimer(unsigned int Period, int Duration, TimeOutSignal *timeout_signal, void *Data) { TimerHandle timer_object(new TimerObject); timer_object->ms_time = g_get_monotonic_time() / 1000; timer_object->CallbackData = Data; timer_object->timeout_signal = timeout_signal; timer_object->Period = Period; timer_object->Duration = (Duration < 0) ? -1 : Duration; timer_object->Type = TIMERTYPE_DURATION; timer_object->state_ = TimerHandler::TIMER_STATE_RUNNING; AddHandle(timer_object); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) { timer_object->glibid = GetWindowThread()->AddTimeout(Period); if (timer_object->glibid == 0) { early_timer_handlers_.push_back(timer_object); // Probably trying to set a timeout before Glib main context and loop have been created. // Sometimes later, this timer will be examined when ExecTimerHandler is called. // This happens when trying to set a callback before the mainloop has been initialized. } //nuxDebugMsg("[TimerHandler::AddOneShotTimer] Adding Timeout ID: %d", timer_object->glibid); } #endif return timer_object; } TimerHandle TimerHandler::AddIterativeTimer(unsigned int Period, int NumberOfIterations, TimeOutSignal *timeout_signal, void *Data) { TimerHandle timer_object(new TimerObject); timer_object->ms_time = g_get_monotonic_time() / 1000; timer_object->CallbackData = Data; timer_object->timeout_signal = timeout_signal; timer_object->Period = Period; timer_object->ScheduledIteration = (NumberOfIterations < 0) ? -1 : NumberOfIterations; timer_object->Type = TIMERTYPE_ITERATION; timer_object->state_ = TimerHandler::TIMER_STATE_RUNNING; AddHandle(timer_object); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) { timer_object->glibid = GetWindowThread()->AddTimeout(Period); if (timer_object->glibid == 0) { early_timer_handlers_.push_back(timer_object); // Probably trying to set a timeout before Glib main context and loop have been created. // Sometimes later, this timer will be examined when ExecTimerHandler is called. // This happens when trying to set a callback before the mainloop has been initialized. } //nuxDebugMsg("[TimerHandler::AddOneShotTimer] Adding Timeout ID: %d", timer_object->glibid); } #endif return timer_object; } // Sort timers and add them to the queue void TimerHandler::AddHandle(TimerHandle const& timer_handle) { if (!timer_handle.Activated()) return; // Give the Timer a unique ID; timer_handle->uid = TimerUID.GetValue(); TimerUID.Increment(); auto tmp = timer_handler_queue_.begin(); while (tmp != timer_handler_queue_.end() && timer_handle->ms_time >= (*tmp)->ms_time) ++tmp; timer_handler_queue_.insert(tmp, timer_handle); } unsigned int TimerHandler::GetNumPendingHandler() { return timer_handler_queue_.size(); } bool TimerHandler::RemoveTimerHandler(TimerHandle &handle) { if (!handle.Activated() || timer_handler_queue_.empty()) return false; for (auto it = timer_handler_queue_.begin(); it != timer_handler_queue_.end(); ++it) { if (*it == handle) { if (!is_processing_timers_) { handle = nullptr; timer_handler_queue_.erase(it); return true; } else { handle->marked_for_removal_ = true; } } } return false; } bool TimerHandler::PauseTimer(TimerHandle& handle) { if (!handle.Activated() || timer_handler_queue_.empty()) return false; if (handle->state_ != TimerHandler::TIMER_STATE_RUNNING) return false; for (auto const& h : timer_handler_queue_) { if (h == handle) { handle->state_ = TimerHandler::TIMER_STATE_PAUSED; if (!is_processing_timers_) { gint64 ms_time_now = g_get_monotonic_time() / 1000; if (handle->Type == TIMERTYPE_PERIODIC) { handle->ElapsedTime += (ms_time_now - handle->ms_time); handle->ProgressDelta = float(handle->ElapsedTime) / float(handle->Period); if (handle->Param + handle->ProgressDelta > 1.0f) handle->ProgressDelta = 1.0f - handle->Param; handle->Param = float(handle->ElapsedTime) / float(handle->Period); } } return true; } } return false; } bool TimerHandler::ResumeTimer(TimerHandle& handle) { if (handle.Activated() || timer_handler_queue_.empty()) return false; if (handle->state_ != TimerHandler::TIMER_STATE_PAUSED) return false; for (auto const& h : timer_handler_queue_) { if (h == handle) { handle->state_ = TimerHandler::TIMER_STATE_RUNNING; if (handle->Type == TIMERTYPE_PERIODIC) { handle->glibid = GetWindowThread()->AddTimeout(handle->Period * (1.0f - handle->Param)); } else { handle->glibid = GetWindowThread()->AddTimeout(handle->Period); } handle->ms_time = g_get_monotonic_time() / 1000; if (handle->glibid == 0) early_timer_handlers_.push_back(handle); return true; } } return false; } int TimerHandler::ExecTimerHandler(unsigned int timer_id) { if (timer_handler_queue_.empty()) return 0; bool repeat = false; is_processing_timers_ = true; for (auto it = timer_handler_queue_.begin(); it != timer_handler_queue_.end(); ++it) { auto const& timer_object = *it; if (timer_object->glibid == timer_id && !timer_object->marked_for_removal_) { if (timer_object->state_ != TIMER_STATE_RUNNING) { return false; } // Find the first timer object that timer_object->ElapsedTime += timer_object->Period; if (timer_object->Type == TIMERTYPE_PERIODIC) { timer_object->ProgressDelta = float(timer_object->ElapsedTime) / float(timer_object->Period) - timer_object->Param; // Clamp progress delta so(timer_object->Param + timer_object->ProgressDelta) <= 1.0f if (timer_object->Param + timer_object->ProgressDelta > 1.0f) timer_object->ProgressDelta = 1.0f - timer_object->Param; timer_object->Param = float(timer_object->ElapsedTime) / float(timer_object->Period); } else if (timer_object->Type == TIMERTYPE_DURATION) { timer_object->ProgressDelta = float(timer_object->ElapsedTime) / float(timer_object->Duration) - timer_object->Param; // Clamp progress delta so(timer_object->Param + timer_object->ProgressDelta) <= 1.0f if (timer_object->Param + timer_object->ProgressDelta > 1.0f) timer_object->ProgressDelta = 1.0f - timer_object->Param; if (timer_object->ProgressDelta < 0.0f) timer_object->ProgressDelta = 0.0f; timer_object->Param = float(timer_object->ElapsedTime) / float(timer_object->Duration); } else if (timer_object->Type == TIMERTYPE_ITERATION) { timer_object->ProgressIterationCount += 1; int duration = timer_object->Period * timer_object->ScheduledIteration; timer_object->ProgressDelta = float(timer_object->ElapsedTime) / float(duration) - timer_object->Param; // Clamp progress delta so(timer_object->Param + timer_object->ProgressDelta) <= 1.0f if (timer_object->Param + timer_object->ProgressDelta > 1.0f) timer_object->ProgressDelta = 1.0f - timer_object->Param; timer_object->Param = float(timer_object->ElapsedTime) / float(duration); } else { nuxAssertMsg(0, "[TimerHandler::ExecTimerHandler] Unknown timer type."); } if (timer_object->Param > 1.0f) { // correction. timer_object->Param = 1.0f; } timer_object->marked_for_removal_ = false; if (timer_object->timeout_signal) { // Execute the signal GetWindowThread()->GetWindowCompositor().SetProcessingTopView(timer_object->Window); timer_object->timeout_signal->tick.emit(timer_object->CallbackData); GetWindowThread()->GetWindowCompositor().SetProcessingTopView(NULL); // Reset glibid to 0. glibid is not null, if this element ever happened to be at the head of the queue // and we set a timer for it. //nuxDebugMsg("[TimerHandler::ExecTimerHandler] Executed Timeout ID: %d", timer_object->glibid); //timer_object->glibid = 0; } bool expired_handler = false; if (timer_object->marked_for_removal_) { // RemoveTimerHandler was called during the callback execution expired_handler = true; } else if (timer_object->Type == TIMERTYPE_PERIODIC) { // A one shot timer expires after the first execution. expired_handler = true; } else if ((timer_object->Type == TIMERTYPE_DURATION) && (timer_object->Param >= 1.0f)) { // A timer delay timer expires after the duration of the timer as expired. expired_handler = true; } else if ((timer_object->Type == TIMERTYPE_ITERATION) && (timer_object->ProgressIterationCount >= timer_object->ScheduledIteration)) { // An iterative timer expires after the timer as been executedN times. expired_handler = true; } if (!expired_handler && (timer_object->state_ == TIMER_STATE_PAUSED)) { // The state has been changed to "paused". return false; } if (expired_handler) { if (timer_object->timeout_signal) { GetWindowThread()->GetWindowCompositor().SetProcessingTopView(timer_object->Window); timer_object->timeout_signal->expired.emit(timer_object->CallbackData); GetWindowThread()->GetWindowCompositor().SetProcessingTopView(NULL); } timer_object->state_ = TIMER_STATE_STOPED; timer_handler_queue_.erase(it); } else { repeat = true; } break; } } // Purge handles that have been marked for removal for (auto it = timer_handler_queue_.begin(); it != timer_handler_queue_.end();) { auto const& timer_object = *it; if (timer_object->marked_for_removal_) { it = timer_handler_queue_.erase(it); continue; } ++it; } is_processing_timers_ = false; return repeat; } bool TimerHandler::FindTimerHandle(TimerHandle &timer_object) { auto it = std::find(timer_handler_queue_.begin(), timer_handler_queue_.end(), timer_object); return (it != timer_handler_queue_.end()); } //---------------------------------------------------------------------------- int TimerHandler::DelayUntilNextTimerExpires() { if (timer_handler_queue_.empty()) return 0; TimeStruct now; TimeStruct delay; TimeRightNow(&now); auto const& first = timer_handler_queue_.front(); if (TimeIsGreater(now, first->when)) { return 0; } else { delay.sec = first->when.sec - now.sec; delay.usec = first->when.usec - now.usec; // make sure that usec cannot be less than -1000000 before applying this code if (delay.usec < 0) { delay.usec += 1000000; delay.sec--; } return (delay.sec * 1000000 + delay.usec) / 1000; // return delay in milliseconds } } /*unsigned int TimeDiff( TimeStruct t1, TimeStruct t2) { int sec; int usec; if (t1.sec >= t2.sec) { sec = t1.sec - t2.sec; usec = t1.usec - t2.usec; while ((usec < 0) && (sec > 0)) { usec += 1000000; sec -= 1; } if (usec < 0) usec = -usec; } if (t1.sec < t2.sec) { sec = t2.sec - t1.sec; usec = t2.usec - t1.usec; while ((usec < 0) && (sec > 0)) { usec += 1000000; sec -= 1; } if (usec < 0) usec = -usec; } return sec*1000 + usec/1000; // time diff is millisecond }*/ bool TimeIsGreater( TimeStruct t1, TimeStruct t2) { if ((t1.sec > t2.sec) || ((t1.sec == t2.sec) && (t1.usec > t2.usec))) return true; if ((t1.sec == t2.sec) && (t1.usec == t2.usec)) return true; return false; } void TimeRightNow(TimeStruct *tv) { #if defined(NUX_OS_WINDOWS) struct _timeb timebuffer; // Time in seconds since midnight(00:00:00), January 1, 1970, coordinated universal time(UTC). _ftime(&timebuffer); tv->sec = timebuffer.time; tv->usec = timebuffer.millitm * 1000; #elif defined(NUX_OS_LINUX) timeval unix_timeval; gettimeofday(&unix_timeval, NULL); tv->sec = unix_timeval.tv_sec; tv->usec = unix_timeval.tv_usec; #else #error TimeRightNow is not implemented for this platform. #endif } } nux-4.0.6+14.04.20140409/Nux/TextureArea.h0000644000015301777760000000735212321344237020120 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef TEXTUREAREA_H #define TEXTUREAREA_H #include "NuxGraphics/GraphicsEngine.h" namespace nux { //! Represent a rectangular area painted with a color or a texture layer. /*! By default TextureArea contains a ColorLayer with the color set to Black. */ class TextureArea: public View { NUX_DECLARE_OBJECT_TYPE(TextureArea, View); public: TextureArea(NUX_FILE_LINE_PROTO); virtual ~TextureArea(); /*! Use the provided BaseTexture to create a TextureLayer. The current layer is destroyed. If the \a texture argument is invalid the function returns without changing this object. @param texture Pointer to a BaseTexture class. */ void SetTexture(BaseTexture *texture); /*! Use the provided \a color argument to create a ColorLayer. The current layer is destroyed. @param texture Pointer to a BaseTexture class. */ void SetColor(const Color &color); /*! Set the paint layer of this area. The layer argument to this function is cloned. \sa AbstractPaintLayer, ColorLayer, ShapeLayer, SliceScaledTextureLayer, TextureLayer; @param layer A pointer to a concrete class that inherit from AbstractPaintLayer. */ void SetPaintLayer(AbstractPaintLayer *layer); void LoadImageFile(const std::string &filename); /*! Get a copy of the paint layer of this area. The layer must be destroyed with delete when it is no longer needed. \sa AbstractPaintLayer, ColorLayer, ShapeLayer, SliceScaledTextureLayer, TextureLayer; @return A copy of the layer inside this object. */ AbstractPaintLayer* GetPaintLayer() const; //! Convenience function to set a 2D rotation when rendering the area. /*! The rotation is only used for rendering. It should not be used for something else. */ void Set2DRotation(float angle); Matrix4 Get2DRotation() const; sigc::signal sigMouseDown; //!< Signal emmitted when a mouse button is pressed over this area. sigc::signal sigMouseDrag; //!< Signal emmitted when the mouse is dragged over this area. protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); void RecvMouseDown(int x, int y, long button_flags, long key_flags); void RecvMouseUp(int x, int y, long button_flags, long key_flags); void RecvMouseEnter(int x, int y, long button_flags, long key_flags); void RecvMouseLeave(int x, int y, long button_flags, long key_flags); void RecvMouseClick(int x, int y, long button_flags, long key_flags); void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); private: AbstractPaintLayer *paint_layer_; Matrix4 rotation_2d_; //!< 2D rotation matrix for this area. Used for rendering only. }; typedef TextureArea Image; } #endif // TEXTUREAREA_H nux-4.0.6+14.04.20140409/Nux/LayeredLayout.h0000644000015301777760000002354112321344237020450 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Neil Jagdish Patel * */ #ifndef LAYERED_LAYOUT_H #define LAYERED_LAYOUT_H #include "Layout.h" namespace nux { //! An layered layout. /*! LayeredLayout works either as a bin layout, showing only one layer at a time, or it works as a composite layout, drawing all children in order(and you are able to modify the order). The layout also allows two modes of input. In INPUT_MODE_ACTIVE, the layout will only send events to the active layer, even if in composite drawing mode. In INPUT_MODE_COMPOSITE, the layout will send events to all the layers, in the stacking order from top to bottom. This allows creation of complex widgets more easily than implementing the drawing and input modes manually. */ class LayeredLayout: public Layout { NUX_DECLARE_OBJECT_TYPE(LayeredLayout, Layout); public: class LayeredChildProperties // : public LayeredLayout::LayoutProperties { public: LayeredChildProperties(bool expand, int x, int y, int width, int height); ~LayeredChildProperties(); void Update(bool expand, int x, int y, int width, int height); bool m_expand; int m_x; int m_y; int m_width; int m_height; sigc::signal::iterator m_vis_it; }; typedef enum { INPUT_MODE_ACTIVE = 0, INPUT_MODE_COMPOSITE } InputMode; LayeredLayout(NUX_FILE_LINE_PROTO); ~LayeredLayout(); //! Add a layer to the layout /*! This method will add the layer with layout specific options \param area the Area, Layout or View \param expand area should be expanded to all the available space of the layout. If this is set to false, all the following parameters must be set \param x the horizontal position of the layer, expand must be false \param y the vertical position of the layer, expand must be false \param width the width of the layer inside the layout, expand must be false \param height the height of the layer inside the layout, expand must be false */ void AddLayer (Area *area, bool expand=true, int x=0, int y=0, int width=0, int height=0); //! Update properties of a layer in the layout /*! Allows updating properties of a layer after it has been added to the layout \param area the Area, Layout or View to update \param expand area should be expanded to all the available space of the layout. If this is set to false, all the following parameters must be set \param x the horizontal position of the layer, expand must be false \param y the vertical position of the layer, expand must be false \param width the width of the layer inside the layout, expand must be false \param height the height of the layer inside the layout, expand must be false */ void UpdateLayer(Area *area, bool expand=true, int x=0, int y=0, int width=0, int height=0); //! Remove a layer /*! This method will remove a layer from the layout. It is here for completeness. \param area the Area, Layout or View to remove */ void RemoveLayer(Area *area); //! Set the active layer of the layout /*! The active layer will receives input in the input mode is INPUT_MODE_ACTIVE. \param index_ The index of the layer to make active */ void SetActiveLayerN(int index_); //! Get the active layer of the layout /*! Returns the index of the active layer of the layout. This is only useful if input mode is INPUT_MODE_ACTIVE. \return the index of the active layer */ int GetActiveLayerN(); //! Set the active layer of the layout /*! The active layer will receives input in the input mode is INPUT_MODE_ACTIVE. \param area The area of the layer to make active */ void SetActiveLayer(Area *area); //! Get the active layer of the layout /*! Returns the the active layer of the layout. This is only useful if input mode is INPUT_MODE_ACTIVE. \return the active layer */ Area * GetActiveLayer (); //! Set whether the layout will paint all the layers it contains. Default is false. /*! Normally, the layout will only paint the active layer. However, if you are using the layout in INPUT_COMPOSITE, or have just sized and positioned the layers that you'd like them to be drawn so that they they are composited inside the layout, this should be set to true. \param paint_all whether to paint all the layers in the layout */ void SetPaintAll(bool paint_all); //! Get whether the layout is drawing all the layers it contains /*! Returns whether the layout is drawing all the layers it contains. See SetPaintAll. \return whether the layout is drawing all the layers */ bool GetPaintAll(); //! Sets the input mode of the layout /*! The layout is able to operate in two modes. INPUT_MODE_ACTIVE means that the layout will send events only to the active layout. In INPUT_MODE_COMPOSITE, the layout sends events to all the layouts it contains, starting from the topmost down to the bottom. A layer can stop propagation by returning the appropriate value in ProcessEvent. This can be mixed and matched with SetPaintAll depending on what you want to achieve. For instance, having paint all set to true but input_mode set to INPUT_MODE_ACTIVE allows you to create a composite view with one or many backgrounds, but with only one active view. \param input_mode the input mode */ void SetInputMode(LayeredLayout::InputMode input_mode); //! Raise the paint and input depth of an area /*! Raises the paint and input depth of the area in the layout \param area area to raise \param above area to raise above */ void Raise(Area *area, Area *above); //! Lower the paint and input depth of an area /*! Lowers the paint and input depth of the area in the layout \param area area to raise \param below area to lower below */ void Lower(Area *area, Area *below); //! Raises the paint and input depth of area to the top of the layout /*! Area will be drawn above all other layers and will be the first receive events \param area area to raise */ void RaiseTop(Area *area); //! Lowers the paint and input depth of area to the bottom of the layout /*! Area will be drawn below all other layers and will be the last receive events \param area area to lower */ void LowerBottom(Area *area); //! Get which input mode is set on the layout /*! Returns the current input mode on the layout. \return the current input mode on the layout */ LayeredLayout::InputMode GetInputMode(); // //! Set the layout properties for this area // /*! // Allows the Layout managing this area to store the properties specifc to this area. Layouts // should create a sub-class of LayoutProperties. The LayoutProperties of an area will // be deleted upon destruction. // @param properties the LayoutProperties sub-class associated with this area. Can be NULL to // unset. // */ // void SetLayoutProperties(LayoutProperties *properties); // // //! Get the layout properties for this area // /*! // Retrieves the LayoutProperties sub-class with this area. See SetLayoutProperties // @return LayoutProperties sub-class associated with this area. // */ // LayoutProperties * GetLayoutProperties(); void AddLayout(Layout *layouy, unsigned int stretch_factor = 1, MinorDimensionPosition position = eAbove, MinorDimensionSize extend = eFull, float percentage = 100.0f, LayoutPosition = NUX_LAYOUT_END); void AddView(Area *view, unsigned int stretch_factor = 1, MinorDimensionPosition positioning = eAbove, MinorDimensionSize extend = eFull, float percentage = 100.0f, LayoutPosition = NUX_LAYOUT_END); void RemoveChildObject(Area *area); void Clear(); protected: // // Overrides // long ComputeContentSize(); void GetCompositeList(std::list *ViewList); void ProcessDraw(GraphicsEngine &gfx_context, bool force_draw); Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual Area* KeyNavIteration(KeyNavDirection direction); void OnLayerGeometryChanged(Area* area, Geometry geo); private: void PaintOne(Area *area, GraphicsEngine &graphics_engine, bool force_draw); void ChildQueueDraw(Area *area); void ChildVisibilityChanged(Area *area, bool visible); private: typedef std::map > AreaPropertyMap; AreaPropertyMap area_property_map_; int m_active_index; Area *m_active_area; bool m_paint_all; LayeredLayout::InputMode m_input_mode; bool m_child_draw_queued; }; } #endif // LAYERED_LAYOUT_H nux-4.0.6+14.04.20140409/Nux/NumericValuator.cpp0000644000015301777760000001120612321344237021333 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HLayout.h" #include "EditTextBox.h" #include "DoubleValidator.h" #include "NumericValuator.h" #include namespace nux { const int BTN_WIDTH = 14; const int BTN_HEIGHT = 14; NumericValuator::NumericValuator() : m_DoubleValidator(0.0, 100.0) , m_Step(0.1f) { InitializeLayout(); InitializeWidgets(); } NumericValuator::~NumericValuator() { } void NumericValuator::InitializeWidgets() { m_EditLine->SetValidator(&m_DoubleValidator); m_EditLine->SetText(std::to_string((long double)m_DoubleValidator.GetMinimum())); m_EditLine->SetMinimumSize(2 * DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); m_EditLine->SetGeometry(Geometry(0, 0, 2 * DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT)); m_SpinnerDownBtn->SetMinimumSize(BTN_WIDTH, BTN_HEIGHT); m_SpinnerDownBtn->SetGeometry(Geometry(0, 0, BTN_WIDTH, BTN_HEIGHT)); m_SpinnerUpBtn->SetMinimumSize(BTN_WIDTH, BTN_HEIGHT); m_SpinnerUpBtn->SetGeometry(Geometry(0, 0, BTN_WIDTH, BTN_HEIGHT)); hlayout->AddView(m_SpinnerDownBtn, 0); hlayout->AddView(m_EditLine, 1); hlayout->AddView(m_SpinnerUpBtn, 0); hlayout->SetContentDistribution(eStackLeft); SetCompositionLayout(hlayout); } void NumericValuator::InitializeLayout() { hlayout = new HLayout(NUX_TRACKER_LOCATION); } void NumericValuator::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { GeometryPositioning gp(eHALeft, eVACenter); Geometry GeoPo = ComputeGeometryPositioning(m_SpinnerUpBtn->GetGeometry(), GetTheme().GetImageGeometry(eTRIANGLE_RIGHT), gp); GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eTRIANGLE_RIGHT); GeoPo = ComputeGeometryPositioning(m_SpinnerDownBtn->GetGeometry(), GetTheme().GetImageGeometry(eTRIANGLE_LEFT), gp); GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eTRIANGLE_LEFT); m_EditLine->QueueDraw(); } void NumericValuator::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { m_EditLine->ProcessDraw(graphics_engine, force_draw); } void NumericValuator::SetValue(float value) { m_fValue = value; if (m_fValue < m_DoubleValidator.GetMinimum()) m_fValue = m_DoubleValidator.GetMinimum(); if (m_fValue > m_DoubleValidator.GetMaximum()) m_fValue = m_DoubleValidator.GetMaximum(); m_EditLine->SetText(std::to_string((long double)m_fValue)); } float NumericValuator::GetValue() const { return m_fValue; } void NumericValuator::SetStep(float f) { m_Step = f; } float NumericValuator::GetStep() { return m_Step; } void NumericValuator::ImplementIncrementBtn() { SetValue(m_fValue + m_Step); sigIncrement.emit(); sigValueChanged.emit(m_fValue); if (m_fValue < m_DoubleValidator.GetMaximum()) { m_UpTimerHandler = GetTimer().AddOneShotTimer(100, m_UpTimerCallback, 0); QueueDraw(); } } void NumericValuator::ImplementDecrementBtn() { SetValue(m_fValue - m_Step); sigDecrement.emit(); sigValueChanged.emit(m_fValue); if (m_fValue > m_DoubleValidator.GetMinimum()) { m_DownTimerHandler = GetTimer().AddOneShotTimer(100, m_DownTimerCallback, 0); QueueDraw(); } } void NumericValuator::ImplementValidateEntry() { double ret = 0; ret = CharToDouble(m_EditLine->GetCleanText().c_str()); { m_fValue = ret; if (m_fValue < m_DoubleValidator.GetMinimum()) { m_fValue = m_DoubleValidator.GetMinimum(); m_EditLine->SetText(std::to_string((long double)m_fValue)); } if (m_fValue > m_DoubleValidator.GetMaximum()) { m_fValue = m_DoubleValidator.GetMaximum(); m_EditLine->SetText(std::to_string((long double)m_fValue)); } } // else // { // m_EditLine->SetText(std::string::Printf("%f", m_fValue)); // } } } nux-4.0.6+14.04.20140409/Nux/ActionItem.h0000644000015301777760000000405612321344237017721 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ACTIONITEM_H #define ACTIONITEM_H #include "NuxGraphics/GraphicsEngine.h" namespace nux { class MenuBar; class MenuPage; class ActionItem: public Object { public: NUX_DECLARE_OBJECT_TYPE (ActionItem, Object); ActionItem (const TCHAR *label = 0, int UserValue = 0, NUX_FILE_LINE_PROTO); ~ActionItem(); void Activate (bool b); void Trigger() const; void DrawAsMenuItem (GraphicsEngine &GfxContext, InputArea &area, bool is_highlighted, bool draw_icone); void DrawAsToolButton (GraphicsEngine &GfxContext, InputArea &area); void Enable (bool b); bool isEnabled() const; void SetLabel (const TCHAR *label); const TCHAR *GetLabel() const; int GetUserValue() const { return m_UserValue; } // void SetMenu(MenuPage* menu); // MenuPage* GetMenu() const; void SetFont (ObjectPtr font); void SetIcon (const BaseTexture* icon); const BaseTexture* GetIcon(); sigc::signal sigAction; private: //! A value defined by the user at construction time. int m_UserValue; BaseTexture* m_Icon; std::string m_Label; bool m_IsActivated; MenuPage *m_Menu; bool m_Enable; friend class MenuBar; friend class MenuPage; }; } #endif // ACTIONITEM_H nux-4.0.6+14.04.20140409/Nux/IntegerValidator.cpp0000644000015301777760000000542412321344237021463 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "IntegerValidator.h" namespace nux { IntegerValidator::IntegerValidator(int Minimum, int Maximum) : m_Minimum(Minimum) , m_Maximum(Maximum) { _regexp_str = "^[-+]?[0-9]+$"; InitRegExp(); if (m_Minimum > m_Maximum) { int temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } IntegerValidator::IntegerValidator(const IntegerValidator ©) { m_Minimum = copy.m_Minimum; m_Maximum = copy.m_Maximum; _regexp_str = copy._regexp_str; InitRegExp(); } IntegerValidator &IntegerValidator::operator= (const IntegerValidator &rhs) { if (&rhs != this) { m_Minimum = rhs.m_Minimum; m_Maximum = rhs.m_Maximum; _regexp_str = rhs._regexp_str; InitRegExp(); } return *this; } IntegerValidator::~IntegerValidator() { } Validator *IntegerValidator::Clone() const { return new IntegerValidator(*this); } void IntegerValidator::SetMinimum(int value) { m_Minimum = value; if (m_Minimum > m_Maximum) { int temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } int IntegerValidator::GetMinimum() const { return m_Minimum; } void IntegerValidator::SetMaximum(int value) { m_Maximum = value; if (m_Minimum > m_Maximum) { int temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } int IntegerValidator::GetMaximum() const { return m_Maximum; } int IntegerValidator::GetClampedValue(int i) const { if (i < m_Minimum) return m_Minimum; if (i > m_Maximum) return m_Maximum; return i; } void IntegerValidator::Alternative(const char * /* str */) { } std::string IntegerValidator::ToString(int i) { return std::to_string((long long)i); } int IntegerValidator::ToInteger(const char *str) { if (Validate(str) == Acceptable) return CharToInteger(str); else return 0; } } nux-4.0.6+14.04.20140409/Nux/Utils.h0000644000015301777760000000560612321344237016767 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef UTILS_H #define UTILS_H // check if a value lies within a closed interval #ifndef IN_BOUNDS #define IN_BOUNDS( x, lo, hi ) ((x) >= (lo) && (x) <= (hi)) #endif //check if a 2D point lies within a 2D box #ifndef PT_IN_BOX #define PT_IN_BOX( x, y, lo_x, hi_x, lo_y, hi_y ) ( IN_BOUNDS(x,lo_x,hi_x) && IN_BOUNDS(y,lo_y,hi_y)) #endif namespace nux { typedef enum { eSolveNone = (0L), eMouseEventSolved = (1L), eKeyEventSolved = (1L) << 1, eDoNotProcess = (1L) << 2, EVENT_CYCLE_EXCLUSIVE = (1L) << 3, //!< Value of ProcessEventInfo when processing the event cycle of the input area that has the exclusivity. EVENT_CYCLE_EXCLUSIVE_CONTINUE = (1L) << 4, //!< Return value of the cycle of the exclusive input area. If it is returned, allow other areas to process the event. EVENT_CYCLE_SOLVED = (1L) << 5, EVENT_CYCLE_DO_NOT_PROCESS = (1L) << 6, EVENT_CYCLE_RESET_AREA_STATE = (1L) << 7, //!< Reset the mouse event processor of an InputArea. } EventCycleStatus; enum PositionPolicy { ePositionLeft, ePositionRight, ePositionCenter, ePositionFull, ePositionProportional, }; enum SizePolicy { eSizeFixed, eSizeResizeable, }; typedef enum /*RectangleShapeCorners*/ { eCornerNone = 0, eCornerTopLeft = (1L), eCornerTopRight = (1L << 1), eCornerBottomLeft = (1L << 2), eCornerBottomRight = (1L << 3), eAllCorners = eCornerTopLeft | eCornerTopRight | eCornerBottomLeft | eCornerBottomRight, } ShapeCornerType; enum TextureAlignment { eTACenter, eTALeft, eTARight, eTATop, eTABottom }; enum VerticalAlignment { eVACenter, eVATop, eVABottom }; enum HorizontalAlignment { eHACenter, eHALeft, eHARight, }; typedef struct { int x; int y; int width; int height; int x_clipregion; int y_clipregion; int width_clipregion; int height_clipregion; } DrawAreaContext; bool IsMouseOwned(); } #endif // UTILS_H nux-4.0.6+14.04.20140409/Nux/ActionItem.cpp0000644000015301777760000001035312321344237020251 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "ActionItem.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(ActionItem); ActionItem::ActionItem(const char *label, int UserValue, NUX_FILE_LINE_DECL) : Object(true, NUX_FILE_LINE_PARAM) , m_UserValue(UserValue) , m_Label("") , m_IsActivated(true) , m_Menu(0) , m_Enable(true) { m_Icon = 0; SetLabel(label); } ActionItem::~ActionItem() { if (m_Icon) m_Icon->UnReference(); } void ActionItem::DrawAsMenuItem(GraphicsEngine &graphics_engine, InputArea &area, bool is_highlighted, bool /* draw_icone */) { Geometry geo = area.GetGeometry(); Geometry icon_geo(0, 0, 20, 20); Geometry text_geo = geo; text_geo.OffsetPosition(24, 2); text_geo.OffsetSize(2 * 24, 2 * 2); icon_geo.SetX(geo.x + 2); icon_geo.SetY(geo.y + 2); const char *label = GetLabel(); if (is_highlighted) { GetPainter().Paint2DQuadColor(graphics_engine, geo, Color(COLOR_FOREGROUND_SECONDARY)); } if (m_Icon) GetPainter().Draw2DTextureAligned(graphics_engine, m_Icon, icon_geo, TextureAlignmentStyle(eTACenter, eTACenter)); GetPainter().PaintTextLineStatic(graphics_engine, GetSysFont(), text_geo, std::string(label), Color(0xFF000000), eAlignTextLeft); } void ActionItem::DrawAsToolButton(GraphicsEngine &graphics_engine, InputArea &area) { Geometry base = area.GetGeometry(); if (area.IsMouseOwner()) { if (area.IsMouseInside()) { GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BACKGROUND_SECONDARY), eSHAPE_CORNER_ROUND2); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BLACK), eSTROKE_CORNER_ROUND2); } else { GetPainter().PaintShape(graphics_engine, base, Color(COLOR_FOREGROUND_PRIMARY), eSHAPE_CORNER_ROUND2); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BLACK), eSTROKE_CORNER_ROUND2); } } else { if (area.IsMouseInside() /*TODO: && (!area.MouseFocusOnOtherArea())*/) { GetPainter().PaintShape(graphics_engine, base, Color(COLOR_FOREGROUND_PRIMARY), eSHAPE_CORNER_ROUND2); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BLACK), eSTROKE_CORNER_ROUND2); } else { GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BACKGROUND_SECONDARY), eSHAPE_CORNER_ROUND2); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BLACK), eSTROKE_CORNER_ROUND2); } } GetPainter().Draw2DTextureAligned(graphics_engine, m_Icon, base, TextureAlignmentStyle(eTACenter, eTACenter)); } void ActionItem::Activate(bool b) { m_IsActivated = b; } void ActionItem::Trigger() const { sigAction.emit(); } void ActionItem::Enable(bool b) { m_Enable = b; } bool ActionItem::isEnabled() const { return m_Enable; } void ActionItem::SetLabel(const char *label) { m_Label = label; } const char *ActionItem::GetLabel() const { return m_Label.c_str(); } void ActionItem::SetIcon(const BaseTexture* icon) { if (m_Icon) m_Icon->UnReference(); m_Icon = icon->Clone(); } // NUXTODO: should return the bitmap data instead or a const pointer?. const BaseTexture* ActionItem::GetIcon() { return m_Icon; } //void ActionItem::SetMenu(Menu* menu) //{ // m_Menu = menu; //} //Menu* ActionItem::GetMenu() const //{ // return m_Menu; //} } nux-4.0.6+14.04.20140409/Nux/Theme.h0000644000015301777760000000727712321344237016737 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef UXTHEME_H #define UXTHEME_H namespace nux { enum UXStyleImageRef { eIMAGE_STYLE_NONE = 0, eSTROKE_CORNER_SQUARE, eSTROKE_CORNER_ROUND1, eSTROKE_CORNER_ROUND2, eSTROKE_CORNER_ROUND4, eSTROKE_CORNER_ROUND10, eSHAPE_CORNER_SQUARE, eSHAPE_CORNER_ROUND1, eSHAPE_CORNER_ROUND2, eSHAPE_CORNER_ROUND4, eSHAPE_CORNER_ROUND5, eSHAPE_CORNER_ROUND6, eSHAPE_CORNER_ROUND10, eSHAPE_CORNER_ROUND10_SHADOW, eSHAPE_CORNER_ROUND4_SHADOW, eSHAPE_CORNER_SHADOW, eTRIANGLE_UP, eTRIANGLE_DOWN, eTRIANGLE_LEFT, eTRIANGLE_RIGHT, eWINDOW_SIZEGRIP, eSHAPE_CHECK_MARK, eSHAPE_CHECK_BOX_FOCUS, eSHAPE_CHECK_BOX_PRELIGHT, eSHAPE_CHECK_BOX, eCHECKBOX_NORMAL_ON, eCHECKBOX_NORMAL_OFF, eCHECKBOX_FOCUS_ON, eCHECKBOX_FOCUS_OFF, eCHECKBOX_PRELIGHT_ON, eCHECKBOX_PRELIGHT_OFF, eRADIO_NORMAL_ON, eRADIO_NORMAL_OFF, eRADIO_FOCUS_ON, eRADIO_FOCUS_OFF, eRADIO_PRELIGHT_ON, eRADIO_PRELIGHT_OFF, eBUTTON_NORMAL, eBUTTON_FOCUS, eBUTTON_PRELIGHT, eSPINNERUP, eSPINNERDOWN, eCOMBOBOX_OPEN_BUTTON, eTAB_LEFT, eTAB_RIGHT, eSPINER_UP, eSPINER_DOWN, eTREE_NODE_OPEN, eTREE_NODE_CLOSE, eSCROLLBAR_TRIANGLE_UP, eSCROLLBAR_TRIANGLE_DOWN, eSCROLLBAR_TRIANGLE_LEFT, eSCROLLBAR_TRIANGLE_RIGHT, eVECTORXLABEL, eVECTORYLABEL, eVECTORZLABEL, eVECTORWLABEL, eVALUATORVERTICALMOVE, eVALUATORHORIZONTALMOVE, eVALUATORMOVE, eHSCROLLBAR, eVSCROLLBAR, eMATRIX3PREVIEW, eMATRIX4PREVIEW, eDOT6x6, eGraphIcon, eGraphBarIcon, eWindowCloseButton, }; struct PainterImage { BaseTexture* texture; UXStyleImageRef style; int border_left; int border_right; int border_top; int border_bottom; bool draw_borders_only; std::string filename; PainterImage() { texture = NULL; } }; //! Load textures and other data for user interface rendering. /*! Load textures and other data for user interface rendering. */ class UXTheme { public: UXTheme(); ~UXTheme(); const PainterImage *GetImage(UXStyleImageRef style); Rect GetImageGeometry(UXStyleImageRef style); private: #if defined(NUX_OS_LINUX) static void ParseStartImage(GMarkupParseContext* context, const gchar* element_name, const gchar** attribute_names, const gchar** attribute_values, gpointer user_data, GError** error); static void ParseEndImage(GMarkupParseContext* context, const gchar* element_name, gpointer user_data, GError** error); #endif void LoadPainterImages(); BaseTexture* Load2DTextureFile(const char* filename); BaseTexture* Load2DTextureFileGenerateAlpha(const char* filename, int red, int green, int blue); std::list painter_image_list_; }; } #endif // UXTHEME_H nux-4.0.6+14.04.20140409/Nux/Features.h.in0000644000015301777760000000052212321344237020042 0ustar pbusernogroup00000000000000/* This file specifies which optional features are available on this specific build of NUX libraries Generated from Features.h.in by configure. */ #ifndef NUX_FEATURES_H #define NUX_FEATURES_H // Whether NUX was built with gestures support. I.e., whether the gestures // API is available. #define @NUX_GESTURES_SUPPORT@ #endif nux-4.0.6+14.04.20140409/Nux/InputMethodIBus.h0000644000015301777760000001524012321344237020705 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * Jay Taoko * */ #ifndef INPUTMETHODIBUS_H #define INPUTMETHODIBUS_H #include #include namespace nux { class IBusIMEContext; class TextEntry; // FIXME This class should be reworked to replace the mouse_state // with the hardware key_code. class KeyEvent { public: KeyEvent(NuxEventType type, unsigned int key_sym, unsigned int key_code, unsigned int event_flags, const char* character) : type_(type) , key_sym_(key_sym) , key_code_(key_code) , key_modifiers_(event_flags) , character_(character ? character : "") { } NuxEventType type() const {return type_;} unsigned int key_sym() const {return key_sym_;} unsigned int key_code() const {return key_code_;} unsigned int flags() const {return key_modifiers_;} std::string character() const {return character_;} bool IsShiftDown() const { return (key_modifiers_ & KEY_MODIFIER_SHIFT) != 0; } bool IsControlDown() const { return (key_modifiers_ & KEY_MODIFIER_CTRL) != 0; } bool IsCapsLockDown() const { return (key_modifiers_ & KEY_MODIFIER_CAPS_LOCK) != 0; } bool IsAltDown() const { return (key_modifiers_ & KEY_MODIFIER_ALT) != 0; } private: EventType type_; unsigned int key_sym_; unsigned int key_code_; unsigned int key_modifiers_; std::string character_; KeyEvent(const KeyEvent&); void operator = (const KeyEvent&); }; // Used for passing data to ProcessKeyEventDone function() class ProcessKeyEventData { public: ProcessKeyEventData(IBusIMEContext* context, const KeyEvent& event) : context(context) , event(event.type(), event.key_sym(), event.key_code(), event.flags(), event.character().c_str()) { } IBusIMEContext* context; KeyEvent event; }; // Implements IMEContext to integrate ibus input method framework class IBusIMEContext { public: explicit IBusIMEContext(TextEntry* text_entry); virtual ~IBusIMEContext(); // views::IMEContext implementations: virtual void Focus(); virtual void Blur(); virtual void Reset(); virtual bool FilterKeyEvent(const KeyEvent& event); virtual void SetSurrounding(const std::wstring& text, int cursor_pos); bool IsConnected() const; bool IsHotkeyEvent(EventType type, unsigned long keysym, unsigned long modifiers) const; protected: static std::vector ParseIBusHotkeys(const gchar** keybindings); private: void CreateContext(); void DestroyContext(); void UpdateCursorLocation(); static void UpdateHotkeys(); // Event handlers for IBusBus: //CHROMEG_CALLBACK_0(IBusIMEContext, void, OnConnected, IBusBus*); static void OnConnected_(IBusBus* bus, void* data) {nuxDebugMsg("***IBusIMEContext::OnConnected***"); static_cast(data)->OnConnected(bus);} void OnConnected(IBusBus *bus); //CHROMEG_CALLBACK_0(IBusIMEContext, void, OnDisconnected, IBusBus*); static void OnDisconnected_(IBusBus* bus, void* data) {static_cast(data)->OnDisconnected(bus);} void OnDisconnected(IBusBus *bus); static void OnConfigChanged_(IBusConfig* config, gchar* section, gchar* name, GVariant* value, gpointer data) {static_cast(data)->OnConfigChanged(config, section, name, value);} void OnConfigChanged(IBusConfig* config, gchar* section, gchar* name, GVariant* value); // // Event handlers for IBusIMEContext: //CHROMEG_CALLBACK_1(IBusIMEContext, void, OnCommitText, IBusInputContext*, IBusText*); static void OnCommitText_(IBusInputContext* context, IBusText* text, void* data) {static_cast(data)->OnCommitText(context, text);} void OnCommitText(IBusInputContext *context, IBusText* text); //CHROMEG_CALLBACK_3(IBusIMEContext, void, OnUpdatePreeditText, IBusInputContext*, IBusText*, guint, gboolean); static void OnUpdatePreeditText_(IBusInputContext* context, IBusText* text, guint cursor_pos, gboolean visible, void* data) {reinterpret_cast(data)->OnUpdatePreeditText(context, text, cursor_pos, visible);} void OnUpdatePreeditText(IBusInputContext *context, IBusText* text, guint cursor_pos, gboolean visible); //CHROMEG_CALLBACK_0(IBusIMEContext, void, OnShowPreeditText, IBusInputContext*); static void OnShowPreeditText_(IBusInputContext* context, void* data) {static_cast(data)->OnShowPreeditText(context);} void OnShowPreeditText(IBusInputContext *context); // CHROMEG_CALLBACK_0(IBusIMEContext, void, OnHidePreeditText, IBusInputContext*); static void OnHidePreeditText_(IBusInputContext* context, void* data) {static_cast(data)->OnHidePreeditText(context);} void OnHidePreeditText(IBusInputContext *context); // CHROMEG_CALLBACK_0(IBusIMEContext, void, OnEnable, IBusInputContext*); static void OnEnable_(IBusInputContext* context, void* data) {static_cast(data)->OnEnable(context);} void OnEnable(IBusInputContext *context); // CHROMEG_CALLBACK_0(IBusIMEContext, void, OnDisable, IBusInputContext*); static void OnDisable_(IBusInputContext* context, void* data) {static_cast(data)->OnDisable(context);} void OnDisable(IBusInputContext *context); // CHROMEG_CALLBACK_0(IBusIMEContext, void, OnDestroy, IBusInputContext*); static void OnDestroy_(IBusInputContext* context, void* data) {static_cast(data)->OnDestroy(context);} void OnDestroy(IBusInputContext *context); static void ProcessKeyEventDone(IBusInputContext* context, GAsyncResult* res, ProcessKeyEventData* data); TextEntry* text_entry_; IBusInputContext* context_; GCancellable* cancellable_; bool is_focused_; static IBusBus* bus_; static std::vector hotkeys_; IBusIMEContext(const IBusIMEContext&); void operator = (const IBusIMEContext&); }; } #endif // INPUTMETHODIBUS_H nux-4.0.6+14.04.20140409/Nux/LinearLayout.cpp0000644000015301777760000001631212321344237020626 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "LinearLayout.h" #include "View.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(LinearLayout); LinearLayout::LinearLayout(NUX_FILE_LINE_DECL) : Layout(NUX_FILE_LINE_PARAM) { } LinearLayout::~LinearLayout() { } // If(stretchfactor == 0): the WidgetLayout geometry will be set to SetGeometry(0,0,1,1); // and the children will take their natural size by expending WidgetLayout. // If the parent of WidgetLayout offers more space, it won't be used by WidgetLayout. void LinearLayout::AddLayout(Layout *layout, unsigned int stretchFactor, MinorDimensionPosition minor_position, MinorDimensionSize minor_size, float percentage, LayoutPosition index) { nuxAssertMsg(layout != 0, "[Layout::AddView] Invalid parameter."); NUX_RETURN_IF_TRUE(layout == 0); // Should never happen nuxAssertMsg(layout != this, "[Layout::AddLayout] Error: Trying to add a layout to itself."); NUX_RETURN_IF_FALSE(layout != 0); Area *parent = layout->GetParentObject(); nuxAssertMsg(parent == 0, "[Layout::AddLayout] Trying to add an object that already has a parent."); NUX_RETURN_IF_TRUE(parent != 0); nuxAssertMsg(index >= 0, "[Layout::AddLayout] Invalid index position. Adding at the beginning of the list.."); layout->SetScaleFactor(stretchFactor); layout->SetPositioning(minor_position); layout->SetExtend(minor_size); if (percentage < 1.0f) { layout->SetPercentage(1.0f); } else if (percentage > 100.0f) { layout->SetPercentage(100.0f); } else { layout->SetPercentage(percentage); } layout->SetParentObject(this); layout->child_queue_draw.connect(sigc::mem_fun(this, &Layout::ChildQueueDraw)); layout->queue_draw.connect(sigc::mem_fun(this, &Layout::ChildQueueDraw)); if (index < 0) index = NUX_LAYOUT_BEGIN; if (index == NUX_LAYOUT_END || index >= _layout_element_list.size()) { _layout_element_list.push_back(layout); } else { std::list::iterator pos = _layout_element_list.begin(); int idx = index; while (pos != _layout_element_list.end() && idx > 0) { idx--; pos++; } _layout_element_list.insert(pos, layout); } ViewAdded.emit(this, layout); } //! Add an object to the layout. /*! Add an object to the layout. A baseobject minor dimension with respect to a layout object is the dimension opposite to the layout flow. A baseobject major dimension with respect to a layout object is the dimension aligned with the layout flow. A layout object minor dimension is the dimension opposite to the layout flow. A layout object major dimension is the dimension aligned with the layout flow. Add an object to the layout. The added object get its size and position managed by the layout. When a baseobject is added with a stretches factor equal to 0, its major dimension assumes its minimum value. For instance, if the layout is a vertical layout and the added object has a stretch factor equal 0, then during the layout, the added object height will be set to its minimum value using ApplyMinHeight(). The minor_position parameter controls how the layout will place the object within itself. A vertical layout object controls the horizontal positioning of its children baseobjects, While an horizontal layout object controls the vertical positioning of its children baseobjects. The minor_size parameter controls how much size the baseobject minor dimension gets from the layout minor dimension. See MinorDimensionSize. /param baseobject The object that is being added. /param stretchFactor This value controls how the layout object share space between its children baseobject. /param minor_position Controls how the layout position the object. /param minor_size Controls the object minor dimension size. /param percentage Controls the object minor dimension size in percentage of the layout minor dimension size. /param index Controls the object position in the layout children. */ void LinearLayout::AddView(Area *bo, unsigned int stretchFactor, MinorDimensionPosition minor_position, MinorDimensionSize minor_size, float percentage, LayoutPosition index) { nuxAssertMsg(bo != 0, "[Layout::AddView] Invalid parameter."); NUX_RETURN_IF_TRUE(bo == 0); Area *parent = bo->GetParentObject(); nuxAssertMsg(parent == 0, "[Layout::AddView] Trying to add an object that already has a parent."); NUX_RETURN_IF_TRUE(parent != 0); nuxAssertMsg(index >= 0, "[Layout::AddView] Invalid index position. Adding at the beginning of the list.."); bo->SetScaleFactor(stretchFactor); bo->SetPositioning(minor_position); bo->SetExtend(minor_size); if (percentage < 1.0f) { bo->SetPercentage(1.0f); } else if (percentage > 100.0f) { bo->SetPercentage(100.0f); } else { bo->SetPercentage(percentage); } bo->SetParentObject(this); if (bo->IsView()) (static_cast (bo))->queue_draw.connect(sigc::mem_fun(this, &Layout::ChildQueueDraw)); //if(HasFocusControl() && HasFocusableEntries() == false) //{ //bo->SetFocused(true); //ChildFocusChanged(this, bo); //} if (index < 0) index = NUX_LAYOUT_BEGIN; if (index == NUX_LAYOUT_END || index >= _layout_element_list.size()) { _layout_element_list.push_back(bo); } else { #if defined(NUX_OS_WINDOWS) && !defined(NUX_VISUAL_STUDIO_2010) std::list::iterator pos = _layout_element_list.begin(); #else auto pos = _layout_element_list.begin(); #endif int idx = index; while (pos != _layout_element_list.end() && idx > 0) { idx--; pos++; } _layout_element_list.insert(pos, bo); } ViewAdded.emit(this, bo); //--->> Removed because it cause problem with The splitter widget: ComputeContentSize(); } void LinearLayout::AddSpace(unsigned int /* width */, unsigned int stretchFactor, LayoutPosition /* index */) { AddLayout(new SpaceLayout(), stretchFactor); } void LinearLayout::SetHorizontalInternalMargin(int space) { SetSpaceBetweenChildren(space); } void LinearLayout::SetVerticalInternalMargin(int space) { SetSpaceBetweenChildren(space); } void LinearLayout::SetSpaceBetweenChildren(int space) { #if DEBUG_LAYOUT return; #endif space_between_children_ = space >= 0 ? space : 0; } } nux-4.0.6+14.04.20140409/Nux/ABI.h.in0000644000015301777760000000053212321344237016660 0ustar pbusernogroup00000000000000#ifndef ABI_H #define ABI_H // Increase the number (to the current date) everytime you propose a branch that breaks the API or ABI // The number format is : year/month/day // e.g.: december 1st, 2011 is: 20111201 // So far there is no provision for more than one break in a day. #define NUX_ABIVERSION @NUX_ABI_VERSION@ #endif // ABI_H nux-4.0.6+14.04.20140409/Nux/RangeValue.cpp0000644000015301777760000001747612321344237020263 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "EditTextBox.h" #include "HLayout.h" #include "RangeValue.h" #include #include namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(RangeValue); RangeValue::RangeValue(float Value, float MinValue, float MaxValue, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { m_min = MinValue; m_max = MaxValue; m_StartColor = Color(0xff202020); m_EndColor = Color(0xff202020); m_ProgressColor = Color(0xff606060); m_EnableDrawProgress = true; m_CTRL_KEY = 0; InitializeLayout(); InitializeWidgets(); SetValue(Value); } RangeValue::~RangeValue() { } void RangeValue::InitializeWidgets() { ////////////////// // Set Signals // ////////////////// m_Percentage->mouse_down.connect(sigc::mem_fun(this, &RangeValue::OnReceiveMouseDown)); m_Percentage->mouse_up.connect(sigc::mem_fun(this, &RangeValue::OnReceiveMouseUp)); m_Percentage->mouse_drag.connect(sigc::mem_fun(this, &RangeValue::OnReceiveMouseDrag)); m_ValueString->sigValidateKeyboardEntry.connect(sigc::mem_fun(this, &RangeValue::OnValidateKeyboardEntry)); ////////////////// // Set Geometry // ////////////////// m_ValueString->SetMinimumSize(DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT); m_ValueString->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT)); m_Percentage->SetMinimumSize(2 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT); m_Percentage->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT)); // Set the minimum size of this widget. // This is use by RangeValuePropertyItem::GetItemBestHeight SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); hlayout->AddView(m_ValueString, 0, eCenter, eFull); hlayout->AddView(m_Percentage, 4, eCenter, eFull); //hlayout->AddLayout(&vlayout, 4); hlayout->SetHorizontalExternalMargin(0); hlayout->SetHorizontalInternalMargin(2); hlayout->SetVerticalExternalMargin(0); SetCompositionLayout(hlayout); } void RangeValue::InitializeLayout() { hlayout = new HLayout(NUX_TRACKER_LOCATION); m_Percentage = new BasicView(NUX_TRACKER_LOCATION); m_ValueString = new EditTextBox("", NUX_TRACKER_LOCATION); } void RangeValue::DrawMarker(GraphicsEngine &graphics_engine) { int marker_position_x; int marker_position_y; graphics_engine.PushClippingRectangle(m_Percentage->GetGeometry()); marker_position_x = m_Percentage->GetBaseX() + (m_Value - m_min) * m_Percentage->GetBaseWidth() * 1 / (m_max - m_min); marker_position_y = m_Percentage->GetBaseY() + m_Percentage->GetBaseHeight(); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y, marker_position_x, marker_position_y - 5, marker_position_x + 5, marker_position_y, Color(0.0f, 0.0f, 0.0f, 1.0f)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 4, marker_position_y, marker_position_x, marker_position_y - 4, marker_position_x + 4, marker_position_y, Color(0.7f, 0.7f, 0.7f, 1.0f)); graphics_engine.PopClippingRectangle(); } void RangeValue::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { // Percentage Geometry P = m_Percentage->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, m_StartColor, m_StartColor, m_EndColor, m_EndColor); if (m_EnableDrawProgress) { P.SetWidth((m_Value - m_min) * (float) P.GetWidth() / (m_max - m_min)); GetPainter().Paint2DQuadColor(graphics_engine, P, m_ProgressColor); } m_ValueString->ProcessDraw(graphics_engine, true); DrawMarker(graphics_engine); } void RangeValue::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { m_ValueString->ProcessDraw(graphics_engine, force_draw); } ///////////////// // RECEIVERS // ///////////////// void RangeValue::SetRange(float min_value, float max_value) { if (min_value < max_value) { m_min = min_value; m_max = max_value; } else { m_min = max_value; m_max = min_value; } if (m_Value < m_min) m_Value = m_min; else if (m_Value > m_max) m_Value = m_max; SetValue(m_Value); } void RangeValue::SetValue(float value) { if (value < m_min) m_Value = m_min; else if (value > m_max) m_Value = m_max; else m_Value = value; m_ValueString->SetText(std::to_string((long double)m_Value)); QueueDraw(); } float RangeValue::GetValue() const { return m_Value; } //////////////// // EMITTERS // //////////////// void RangeValue::OnReceiveMouseDown(int x, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (x < 0) m_Value = m_min; else if (x > m_Percentage->GetBaseWidth()) m_Value = m_max; else m_Value = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); m_ValueString->SetText(std::to_string((long double)m_Value)); sigValueChanged.emit(this); sigFloatChanged.emit(m_Value); sigMouseDown.emit(m_Value); QueueDraw(); } void RangeValue::OnReceiveMouseUp(int x, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (x < 0) m_Value = m_min; else if (x > m_Percentage->GetBaseWidth()) m_Value = m_max; else m_Value = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); std::stringstream s; s << std::setprecision(3) << m_Value; m_ValueString->SetText(s.str()); sigValueChanged.emit(this); sigFloatChanged.emit(m_Value); sigMouseUp.emit(m_Value); QueueDraw(); } void RangeValue::OnReceiveMouseDrag(int x, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (x < 0) m_Value = m_min; else if (x > m_Percentage->GetBaseWidth()) m_Value = m_max; else m_Value = m_min + (m_max - m_min) * (float) x / (float) m_Percentage->GetBaseWidth(); std::stringstream s; s << std::setprecision(3) << m_Value; m_ValueString->SetText(s.str()); sigValueChanged.emit(this); sigFloatChanged.emit(m_Value); sigMouseDrag.emit(m_Value); QueueDraw(); } void RangeValue::OnKeyboardFocus() { } void RangeValue::OnLostKeyboardFocus() { } void RangeValue::OnValidateKeyboardEntry(EditTextBox* /* textbox */, const std::string &text) { float f; f = CharToDouble(text.c_str()); SetValue(f); sigValueChanged.emit(this); sigFloatChanged.emit(m_Value); sigSetTypedValue.emit(f); QueueDraw(); } void RangeValue::EmitFloatChangedSignal() { sigFloatChanged.emit(m_Value); } void RangeValue::SetBackgroundColor(const Color &color) { m_ValueString->SetTextBackgroundColor(color); } const Color RangeValue::GetBackgroundColor() const { return m_ValueString->GetTextBackgroundColor(); } } nux-4.0.6+14.04.20140409/Nux/VLayout.cpp0000644000015301777760000007302612321344237017626 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "View.h" #include "VLayout.h" #include "HLayout.h" namespace nux { static const int VERROR = 0; NUX_IMPLEMENT_OBJECT_TYPE(VLayout); VLayout::VLayout(NUX_FILE_LINE_DECL) : LinearLayout(NUX_FILE_LINE_PARAM) { #if DEBUG_LAYOUT m_h_in_margin = 10; left_padding_ = 10; right_padding_ = 10; space_between_children_ = 10; top_padding_ = 10; bottom_padding_ = 10; #endif // Start packing the elements from the left size. Is the layout has more space than the elements can use, // leave that space on the right side of the VLayout. m_ContentStacking = eStackTop; } VLayout::VLayout(std::string name, NUX_FILE_LINE_DECL) : LinearLayout(NUX_FILE_LINE_PARAM) { m_name = name; #if DEBUG_LAYOUT m_h_in_margin = 10; left_padding_ = 10; right_padding_ = 10; space_between_children_ = 10; top_padding_ = 10; bottom_padding_ = 10; #endif m_ContentStacking = eStackTop; } VLayout::~VLayout() { } void VLayout::GetCompositeList(std::list *ViewList) { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if ((*it)->IsView()) { View *ic = NUX_STATIC_CAST(View *, (*it)); ViewList->push_back(ic); } else if ((*it)->IsLayout()) { Layout *layout = NUX_STATIC_CAST(Layout *, (*it)); layout->GetCompositeList(ViewList); } } } //! Compute the how elements are spread inside the layout /*! @param remaining_height Height that remains after subtracting elements height, inner and outer margins from the content height. @param offset_space The space at the top of all elements. @param element_margin The margin between elements. */ void VLayout::ComputeStacking(int remaining_height, int &offset_space, int &element_margin) { int per_element_space = 0; int total_used_space = 0; int n_elements = 0; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { // gather all the space used by elements if ((*it)->IsVisible()) { total_used_space += (*it)->GetBaseHeight(); n_elements++; } } if (n_elements != 0) { // Compute the space available for each element per_element_space = (remaining_height - total_used_space) / int(n_elements); } if (per_element_space < 0) { per_element_space = 0; } int margin; if (per_element_space > 0) { margin = (per_element_space) / 2; } else { margin = 0; } LayoutContentDistribution stacking = GetContentDistribution(); switch(stacking) { case MAJOR_POSITION_START: { offset_space = 0; element_margin = 0; } break; case MAJOR_POSITION_END: { offset_space = (remaining_height - total_used_space); if (offset_space < 0) offset_space = 0; element_margin = 0; } break; case eStackCenter: { offset_space = (remaining_height - total_used_space) / 2; if (offset_space < 0) offset_space = 0; element_margin = 0; } break; case eStackExpand: default: { offset_space = 0; element_margin = margin; } break; } } long VLayout::ComputeContentSize() { if (_layout_element_list.size() == 0) { return eCompliantHeight | eCompliantWidth; } std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { (*it)->SetLayoutDone(false); } int original_width = GetBaseWidth(); if (GetScaleFactor() == 0) { // The size must exactly fit the children. The parent cannot be larger or smaller // than the total height of its children(+ margins). // So set the parent size to Geometry(0,0,1,1) and let the children force it to extend. if (GetParentObject() && GetParentObject()->Type().IsObjectType(HLayout::StaticObjectType)) { // The parent if a HLayout. Then a Stretch factor of 0 means this layout has its width set to 1. Area::SetBaseWidth(1); } else if (GetParentObject() && GetParentObject()->Type().IsObjectType(VLayout::StaticObjectType)) { // The parent if a VLayout(same type). Then a Stretch factor of 0 means this layout has its height set to 1. Area::SetBaseHeight(1); } else { // This is for when a layout is set as a composition layout of an View and its stretch factor is explicitly set to 0. Area::SetBaseWidth(1); Area::SetBaseHeight(1); } //The children will all assume their minimum size. } else { // The total size of the children(+ margins) may be smaller or equal to parent size. } bool unadjusted_layout = false; size_t num_element = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if ((*it)->IsVisible()) num_element++; } do { // Get layout Width and Height int width = GetBaseWidth(); int height = GetBaseHeight(); // Remove the margins. This is the real width and height available to the children. width -= (left_padding_ + right_padding_); height -= (int) (num_element - 1) * space_between_children_ + (top_padding_ + bottom_padding_); // Size the children according to their stretch factor. VLayoutManagement(width, height); // Objects have been resized, now position them. int current_x = GetBaseX() + left_padding_; int current_y = GetBaseY() + top_padding_; //int per_element_space = 0; //int total_used_space = 0; int offset_space = 0; int space_after_element = 0; ComputeStacking(height, offset_space, space_after_element); current_y += offset_space; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; current_y += space_after_element; (*it)->SetBaseX(current_x); (*it)->SetBaseY(current_y); MinorDimensionSize extend = (*it)->GetExtend(); MinorDimensionPosition positioning = (*it)->GetPositioning(); float percentage = (*it)->GetPercentage(); // Compute the size of an element in the minor dimension(horizontal) switch(extend) { case MINOR_SIZE_PERCENTAGE: { // The size of the element in the minor dimension is a percentage of layout minor dimension size. // Note that children of the processed element may force it to have a bigger size. int percentage_width = (width * percentage) / 100.0f; (*it)->SetBaseWidth(percentage_width); break; } case MINOR_SIZE_MATCHCONTENT: { // Force the element width to be the minimum has defined with SetMinimumWidth. // The children of this element can force it to get larger. (*it)->ApplyMinWidth(); break; } case eFix: { //do nothing break; } case MINOR_SIZE_FULL: default: { (*it)->SetBaseWidth(width); break; } } // Compute the position of an element in the minor dimension. if ((*it)->GetBaseWidth() < width) { int widget_width = (*it)->GetBaseWidth(); switch(positioning) { case MINOR_POSITION_START: { // do nothing (*it)->SetBaseX(current_x); break; } case MINOR_POSITION_END: { if (widget_width < width) (*it)->SetBaseX(current_x + width - widget_width); else (*it)->SetBaseX(current_x); break; } case MINOR_POSITION_CENTER: default: { if (widget_width < width) (*it)->SetBaseX(current_x + (width - widget_width) / 2); else (*it)->SetBaseX(current_x); } } } current_y += (*it)->GetBaseHeight() + space_after_element + space_between_children_; } // Manage child layout m_contentWidth = GetBaseWidth() - (left_padding_ + right_padding_); // Set to the size of the layout. if (num_element == 0) m_fittingHeight = (int) (top_padding_ + bottom_padding_); else m_fittingHeight = (int) (num_element - 1) * space_between_children_ + (top_padding_ + bottom_padding_); int element_width; unadjusted_layout = false; // This array is meant to store the sizes of some of the elements width. These elements must have MINOR_SIZE_FULL as extent and // they have not been not been constrained smaller after ComputeContentSize is called. Because the layout may have a stretch factor of 0 // and therefore its size has been set to 1x1 at the start of this function, there is a possibility that some of the elements don't have // the full width of the layout(these elements uses their minimum width because the layout was set to a size 1x1). // We check if that is the case and force a recompute. std::vector FullSizeUnadjusted; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; int ret = 0; if (((*it)->IsLayout() || (*it)->IsView()) /*&& ((*it)->IsLayoutDone() == false)*/ /*&& ((*it)->GetScaleFactor() != 0)*/) { Geometry pre_geo = (*it)->GetGeometry(); ret = (*it)->ComputeContentSize(); Geometry post_geo = (*it)->GetGeometry(); bool larger_width = pre_geo.width < post_geo.width; bool smaller_width = pre_geo.width > post_geo.width; bool larger_height = pre_geo.height < post_geo.height; bool smaller_height = pre_geo.height > post_geo.height; if ((larger_height || smaller_height) && ((*it)->IsLayoutDone() == false)) { // Stop computing the size of this layout. Its size was not convenient to its children. So the children size take priority // over the layout. In ComputeContentSize, the dimension of the layout has been set so it encompasses its children(and the margins). // Now the parent layout cannot be touched again: layout_done_ = true. In VLayoutManagement, it is as if the stretchfactor // of this layout is now 0. // This is the only place where a layout can have layout_done_ set to "true". // If(smaller_height == true) the layout takes less space than anticipated. // Set unadjusted_layout = true, so another pass will allow its sibling to claim more space. { unadjusted_layout = true; (*it)->SetLayoutDone(true); } } if ((smaller_width == false) && ((*it)->GetExtend() == MINOR_SIZE_FULL) && ((*it)->GetBaseWidth() < (*it)->GetMaximumWidth())) { // Catch all object whose size is possibly larger than the layout. Check their size at the end and // recompute the layout if necessary. // For layout elements, make sure that the stretch factor is not 0. If it is, it means it will not use the // size provided by the parent layout. Its size will be adjusted to the minimum size of the layout content. if (!((*it)->IsLayout() && (*it)->GetScaleFactor() == 0)) FullSizeUnadjusted.push_back((*it)->GetBaseWidth()); } if ((smaller_width || larger_width) && ((*it)->GetExtend() == MINOR_SIZE_MATCHCONTENT)) { (*it)->SetMinimumWidth((*it)->GetBaseWidth()); unadjusted_layout = true; } // Should be reactivate so that if the parent Layout does not call // ComputeContentPosition, at least it is done here to arrange the internal // element of the children. //(*it)->ComputeContentPosition(0,0); } m_fittingHeight += (*it)->GetBaseHeight(); element_width = (*it)->GetBaseWidth(); if ((*it)->IsSpaceLayout() == false) { if ((GetScaleFactor() != 0) && (ret & eSmallerWidth)) { if (m_contentWidth < element_width) { if (m_contentWidth < GetMaximumWidth()) { // An element is larger than the layout width and the layout has not reach its maximum width yet. m_contentWidth = element_width; unadjusted_layout = true; } } } else { if (m_contentWidth <= element_width) { m_contentWidth = element_width; } // else if ((*it)->GetExtend() == MINOR_SIZE_FULL) // { // unadjusted_layout = true; // } } } } // Set the width of the layout to be equal to the largest width it controls. // m_contentWidth is the largest width of an element within this layout. The layout size is then // m_contentWidth + (left_padding_ + right_padding_); SetBaseWidth(m_contentWidth + (left_padding_ + right_padding_)); // Get back the Width after it has been bounded by [minWidth, maxWidth] in the preceeding call to SetBaseWidth. // Then deduce the width of the content. int temp = GetWidth() - (left_padding_ + right_padding_); std::vector::iterator IntIterator = FullSizeUnadjusted.begin(); for (IntIterator = FullSizeUnadjusted.begin(); IntIterator != FullSizeUnadjusted.end(); ++IntIterator) { if ((*IntIterator) < temp) { unadjusted_layout = true; } } } while (unadjusted_layout); // m_fittingWidth is sum of the largest element width plus the outer margin. m_fittingWidth = m_contentWidth + (left_padding_ + right_padding_); // m_fittingHeight is sum of the element height plus the inner and outer margin. // If the stretch factor is 0 then, the layout height has been set to 1 and need to grow with the elements within. // If the stretch factor is not 0, then the layout height is set to m_fittingHeight only if the its height is less than m_fittingHeight; // This way, if the layout height is greater than m_fittingHeight there is space to compute the content stacking(ComputeStacking). if (GetBaseHeight() < m_fittingHeight) { SetBaseHeight(m_fittingHeight); } m_contentHeight = m_fittingHeight; long size_compliance = 0L; ComputeContentPosition(0, 0); if (GetBaseWidth() > original_width + VERROR) { #if DEBUG_LAYOUT_COMPUTATION // The layout has been resized larger in WIDTH to tightly pack its content. // Or you can say that the layout refuse to be smaller than total WIDTH of its elements. std::cout << "ComputeContentSize: VLayout Width block at " << GetWidth() << std::endl; #endif size_compliance |= eLargerWidth; // need scrollbar } else if (GetBaseWidth() + VERROR < original_width) { #if DEBUG_LAYOUT_COMPUTATION // The layout is smaller. std::cout << "ComputeContentSize: VLayout Width smaller = " << GetWidth() << std::endl; #endif size_compliance |= eSmallerWidth; } else { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: VLayout Width compliant = " << GetWidth() << std::endl; #endif size_compliance |= eCompliantWidth; } { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: VLayout Height compliant = " << m_fittingHeight << std::endl; #endif size_compliance |= eCompliantHeight; } return size_compliance; } void VLayout::VLayoutManagement(int /* width */, int height) { bool need_recompute = false; do { int available_height = height; int max_stretchfactor = GetMaxStretchFactor(); std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() == 0) && ((*it)->IsLayoutDone() != true)) { (*it)->ApplyMinHeight(); } } if (max_stretchfactor == 0) { // It means all object are fixed sized or all re-sizable object have been sized to there max or there min. if (GetScaleFactor() == 0) { // It is unlikely that we get here! int h = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; ++it) { if (!(*it)->IsVisible()) continue; h += (*it)->GetBaseHeight(); } SetBaseHeight(h); } return; } for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; if ((*it)->GetScaleFactor() == 0 || (*it)->IsLayoutDone() == true) { available_height -= (*it)->GetBaseHeight(); } } if (available_height <= 2) { for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() != 0) && (*it)->IsArea()) { // If it is not an object of type eInputArea, do not set layout_done_ to true, // so, the layout management function will later be called on the object. (*it)->ApplyMinHeight(); (*it)->SetLayoutDone(true); } else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayout()) && ((*it)->IsLayoutDone() == false)) { // The out of bound must be reset to false. (*it)->ApplyMinHeight(); (*it)->SetLayoutDone(false); } else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) { (*it)->ApplyMinHeight(); // A layout must never have layout_done_ set to true "here" because it must continue // doing the layout of its children and finally resize itself to fit them. // The same way, A layout size factor should never be set to 0. } } return; } float cumul = 0; Area *LastElementThatCanBeResized = 0; int total_distributed_size = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) { float sf = (float) (*it)->GetScaleFactor(); cumul += sf / max_stretchfactor; LastElementThatCanBeResized = (*it); } else { total_distributed_size += (*it)->GetBaseWidth(); } } // -- // \ factor // Ref_Size * \ ------------ = available_height // / max_factor // / // -- // all element with stretchfactor != 0 int ref_height = available_height / cumul; // need_recompute = false;; for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; ++it) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) { int sf = (*it)->GetScaleFactor(); int new_height; if (sf == max_stretchfactor) { new_height = ref_height; } else { new_height = ref_height * sf / max_stretchfactor; } total_distributed_size += new_height; if (LastElementThatCanBeResized == (*it)) { // Redistribute the remaining size to the last element(at the bottom). // This is necessary because of imprecision. For instance if available_height = 451 and we have 2 elements // with the same stretch factor than each one will have a size of 225. With is correction, the first element will have a size of // 225 while the second one will have a size of 226. if (available_height - total_distributed_size > 0) { new_height += available_height - total_distributed_size; total_distributed_size = available_height; } } int elemt_max_height = (*it)->GetMaximumSize().height; int elemt_min_height = (*it)->GetMinimumSize().height; // A layout must never have layout_done_ set to true "here" because it must continue // doing the layout of its children and finally resize itself to fit them. // The same way, A layout size factor should never be set to 0. // Q: How about SpaceLayout? Should we treat them the same as layout or widget in this particular case? // A: SapceLayout are treated like widgets in this case if (new_height < elemt_min_height) { // assume the minimum width (*it)->SetBaseHeight(elemt_min_height); if (((*it)->IsLayout() == false) || (*it)->IsSpaceLayout()) { (*it)->SetLayoutDone(true); need_recompute = true; } } else if (new_height > elemt_max_height) { // assume the maximum width (*it)->SetBaseHeight(elemt_max_height); if (((*it)->IsLayout() == false) || (*it)->IsSpaceLayout()) { (*it)->SetLayoutDone(true); need_recompute = true; } // else // { // // set the extra space back in the pool // total_distributed_size -= (new_height - elemt_max_height); // } } else { (*it)->SetBaseHeight(new_height); } } else { // For fixed element, reset their size to the same so it is checked against // the min and max. This is necessary in case you have set the size of the element first then latter, // you define its MinimumSize and/or MaximumSize size. unsigned int w = (*it)->GetBaseWidth(); unsigned int h = (*it)->GetBaseHeight(); (*it)->SetBaseWidth(w); (*it)->SetBaseHeight(h); } } } while (need_recompute); } unsigned int VLayout::GetMaxStretchFactor() { unsigned int value = 0; unsigned int sf; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; // In the recursive process, make sure we get always the highest stretch factor // of an element that has not been bounded. if ((*it)->IsLayoutDone() == false) { sf = (*it)->GetScaleFactor(); if (sf >= value) { value = sf; } } } return value; } void VLayout::ComputeContentPosition(float offsetX, float offsetY) { std::list::iterator it; { unsigned int num_element = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if ((*it)->IsVisible()) num_element++; } // Get layout Width and Height int width = GetBaseWidth(); int height = GetBaseHeight(); // remove the margins width -= (left_padding_ + right_padding_); height -= (int) (num_element - 1) * space_between_children_ + (top_padding_ + bottom_padding_); // Objects have been resized, now position them. int current_x = GetBaseX() + left_padding_ + offsetX; // add base offset in X(used for scrolling) int current_y = GetBaseY() + top_padding_ + offsetY; // add base offset in Y(used for scrolling) int offset_space = 0; int element_margin = 0; ComputeStacking(height, offset_space, element_margin); current_y += offset_space; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; current_y += element_margin; (*it)->SetBaseX(current_x); (*it)->SetBaseY(current_y); MinorDimensionPosition positioning = (*it)->GetPositioning(); if ((*it)->GetBaseWidth() < width) { int widget_width = (*it)->GetBaseWidth(); switch(positioning) { case MINOR_POSITION_START: { // do nothing (*it)->SetBaseX(current_x); break; } case MINOR_POSITION_END: { if (widget_width < width) (*it)->SetBaseX(current_x + width - widget_width); else (*it)->SetBaseX(current_x); break; } case MINOR_POSITION_CENTER: default: { if (widget_width < width) (*it)->SetBaseX(current_x + (width - widget_width) / 2); else (*it)->SetBaseX(current_x); } } } current_y += (*it)->GetBaseHeight() + element_margin + space_between_children_; } } for (it = _layout_element_list.begin(); it != _layout_element_list.end(); ++it) { if (!(*it)->IsVisible()) continue; if ((*it)->Type().IsDerivedFromType(Layout::StaticObjectType)) { (*it)->ComputeContentPosition(offsetX, offsetY); } else if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { (*it)->ComputeContentPosition(offsetX, offsetY); } } } Area* VLayout::KeyNavIteration(KeyNavDirection direction) { if (_layout_element_list.size() == 0) return NULL; if (IsVisible() == false) return NULL; if (next_object_to_key_focus_area_) { if ((direction == KEY_NAV_LEFT) || (direction == KEY_NAV_RIGHT)) { // Don't know what to do with this return NULL; } std::list::iterator it; std::list::iterator it_next; it = std::find(_layout_element_list.begin(), _layout_element_list.end(), next_object_to_key_focus_area_); if (it == _layout_element_list.end()) { // Should never happen nuxAssert(0); return NULL; } it_next = it; ++it_next; if ((direction == KEY_NAV_UP) && (it == _layout_element_list.begin())) { // can't go further return NULL; } if ((direction == KEY_NAV_DOWN) && (it_next == _layout_element_list.end())) { // can't go further return NULL; } if (direction == KEY_NAV_UP) { --it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { if (it == _layout_element_list.begin()) break; --it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_DOWN) { ++it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == _layout_element_list.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } } else { Area* key_nav_focus = NULL; if (direction == KEY_NAV_UP) { std::list::reverse_iterator it = _layout_element_list.rbegin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == _layout_element_list.rend()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } else { std::list::iterator it = _layout_element_list.begin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == _layout_element_list.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } return key_nav_focus; } return NULL; } } nux-4.0.6+14.04.20140409/Nux/SpinBoxDouble.cpp0000644000015301777760000001721712321344237020740 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "TimerProc.h" #include "HLayout.h" #include "VLayout.h" #include "DoubleValidator.h" #include "SpinBox_Logic.h" #include "SpinBoxDouble.h" namespace nux { const Color SPINBOX_DOUBLE_BUTTON_COLOR = Color(0xFF4D4D4D); const Color SPINBOX_DOUBLE_BUTTON_MOUSEOVER_COLOR = Color(0xFF222222); SpinBoxDouble::SpinBoxDouble(double Value, double Step, double MinValue, double MaxValue, NUX_FILE_LINE_DECL) : SpinBox_Logic(NUX_FILE_LINE_PARAM) , m_DoubleValidator(MinValue, MaxValue) , m_Step(Step) { InitializeLayout(); InitializeWidgets(); SetValue(Value); } SpinBoxDouble::~SpinBoxDouble() { } void SpinBoxDouble::InitializeWidgets() { m_EditLine->SetValidator(&m_DoubleValidator); m_EditLine->SetSuffix(""); m_EditLine->SetPrefix(""); m_EditLine->SetText(std::to_string((long double)m_DoubleValidator.GetMinimum())); m_EditLine->SetMinimumSize(1.5 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT); m_EditLine->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); m_SpinnerUpBtn->SetMinimumSize(15, 10); m_SpinnerUpBtn->SetGeometry(Geometry(0, 0, 15, 10)); m_SpinnerDownBtn->SetMinimumSize(15, 10); m_SpinnerDownBtn->SetGeometry(Geometry(0, 0, 15, 10)); // Set the minimum size of this widget. // This is use by TextLineEditPropertyItem::GetItemBestHeight SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); m_hlayout->AddView(m_EditLine, 1); m_vlayout->AddView(m_SpinnerUpBtn, 1); m_vlayout->AddView(m_SpinnerDownBtn, 1); m_hlayout->AddLayout(m_vlayout, 0); SetCompositionLayout(m_hlayout); } void SpinBoxDouble::InitializeLayout() { m_hlayout = new HLayout(NUX_TRACKER_LOCATION); m_vlayout = new VLayout(NUX_TRACKER_LOCATION); } void SpinBoxDouble::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); GetPainter().PaintBackground(graphics_engine, base); if (m_EditLine->IsMouseInside() || m_SpinnerUpBtn->IsMouseInside() || m_SpinnerDownBtn->IsMouseInside()) { GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerUpBtn->GetGeometry(), SPINBOX_DOUBLE_BUTTON_MOUSEOVER_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopRight, false); GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerDownBtn->GetGeometry(), SPINBOX_DOUBLE_BUTTON_MOUSEOVER_COLOR, eSHAPE_CORNER_ROUND4, eCornerBottomRight, false); } else { GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerUpBtn->GetGeometry(), SPINBOX_DOUBLE_BUTTON_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopRight, false); GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerDownBtn->GetGeometry(), SPINBOX_DOUBLE_BUTTON_COLOR, eSHAPE_CORNER_ROUND4, eCornerBottomRight, false); } GeometryPositioning gp(eHACenter, eVACenter); Geometry GeoPo = ComputeGeometryPositioning(m_SpinnerUpBtn->GetGeometry(), GetTheme().GetImageGeometry(eSPINER_UP), gp); if (m_SpinnerUpBtn->IsMouseInside()) GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_UP); else GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_UP); gp.SetAlignment(eHACenter, eVACenter); GeoPo = ComputeGeometryPositioning(m_SpinnerDownBtn->GetGeometry(), GetTheme().GetImageGeometry(eSPINER_DOWN), gp); if (m_SpinnerDownBtn->IsMouseInside()) GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_DOWN); else GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_DOWN); m_EditLine->QueueDraw(); } void SpinBoxDouble::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { m_EditLine->ProcessDraw(graphics_engine, force_draw); } void SpinBoxDouble::SetValue(double value) { m_Value = m_DoubleValidator.GetClampedValue(value); // if (m_Value < m_DoubleValidator.GetMinimum()) // m_Value = m_DoubleValidator.GetMinimum(); // if (m_Value > m_DoubleValidator.GetMaximum()) // m_Value = m_DoubleValidator.GetMaximum(); m_EditLine->SetText(std::to_string((long double)m_Value)); sigValueChanged.emit(this); sigValue.emit(m_Value); QueueDraw(); } double SpinBoxDouble::GetValue() const { return m_Value; } void SpinBoxDouble::SetStep(double d) { m_Step = d; if (m_Step <= 0) m_Step = 1.0; QueueDraw(); } double SpinBoxDouble::GetStep() const { return m_Step; } double SpinBoxDouble::GetMinValue() const { return m_DoubleValidator.GetMinimum(); } double SpinBoxDouble::GetMaxValue() const { return m_DoubleValidator.GetMaximum(); } void SpinBoxDouble::SetRange(double MinValue, double Maxvalue) { m_DoubleValidator.SetMinimum(MinValue); m_DoubleValidator.SetMaximum(Maxvalue); m_Value = m_DoubleValidator.GetClampedValue(m_Value); sigValueChanged.emit(this); sigValue.emit(m_Value); QueueDraw(); } void SpinBoxDouble::ImplementIncrementBtn() { SetValue(m_Value + m_Step); if (m_Value < m_DoubleValidator.GetMaximum()) { if (m_UpTimerHandler.IsValid()) m_UpTimerHandler = GetTimer().AddOneShotTimer(100, m_UpTimerCallback, 0); else m_UpTimerHandler = GetTimer().AddOneShotTimer(800, m_UpTimerCallback, 0); QueueDraw(); } sigValueChanged.emit(this); sigIncrement.emit(this); sigValue.emit(m_Value); } void SpinBoxDouble::ImplementDecrementBtn() { SetValue(m_Value - m_Step); if (m_Value > m_DoubleValidator.GetMinimum()) { if (m_DownTimerHandler.IsValid()) m_DownTimerHandler = GetTimer().AddOneShotTimer(100, m_DownTimerCallback, 0); else m_DownTimerHandler = GetTimer().AddOneShotTimer(800, m_DownTimerCallback, 0); QueueDraw(); } sigValueChanged.emit(this); sigDecrement.emit(this); sigValue.emit(m_Value); } void SpinBoxDouble::ImplementValidateEntry() { double ret = 0; ret = CharToDouble(m_EditLine->GetCleanText().c_str()); { m_Value = m_DoubleValidator.GetClampedValue(ret); m_EditLine->SetText(std::to_string((long double)m_Value)); sigValueChanged.emit(this); sigValue.emit(m_Value); // // if (m_Value < m_DoubleValidator.GetMinimum()) // { // m_Value = m_DoubleValidator.GetMinimum(); // m_EditLine->SetText(std::string::Printf("%.3f", m_Value)); // } // if (m_Value > m_DoubleValidator.GetMaximum()) // { // m_Value = m_DoubleValidator.GetMaximum(); // m_EditLine->SetText(std::string::Printf("%.3f", m_Value)); // } } // else // { // m_EditLine->SetText(std::string::Printf("%.3f", m_Value)); // sigValueChanged.emit(this); // sigValue.emit(m_Value); // } } } nux-4.0.6+14.04.20140409/Nux/Canvas.h0000644000015301777760000000327312321344237017100 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller #include "Nux/Nux.h" #include "Nux/View.h" namespace nux { class Canvas : public View { public: Canvas (NUX_FILE_LINE_DECL); ~Canvas (); protected: void Draw (GraphicsEngine& graphics_engine, bool forceDraw); void DrawContent (GraphicsEngine& graphics_engine, bool forceDraw); virtual void Paint (); void Invalidate (); cairo_surface_t* GetCairoSurface (); cairo_t* GetCairoContext (); int GetLastWidth (); int GetLastHeight (); private: void PreLayoutManagement (); long PostLayoutManagement (long layoutResult); void Recreate (); NBitmapData* GetBitmap (); private: cairo_t* _cr; cairo_surface_t* _surface; int _last_width; int _last_height; bool _invalid; BaseTexture* _texture; }; } #endif // CANVAS_H nux-4.0.6+14.04.20140409/Nux/Layout.h0000644000015301777760000003213412321344237017140 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef LAYOUT_H #define LAYOUT_H namespace nux { #define DEBUG_LAYOUT 0 #define DEBUG_LAYOUT_COMPUTATION 0 typedef enum { NUX_LAYOUT_BEGIN = 0, NUX_LAYOUT_END = 0x7fffffff } LayoutPosition; class Layout: public Area { NUX_DECLARE_OBJECT_TYPE(Layout, Area); public: Layout(NUX_FILE_LINE_PROTO); virtual ~Layout(); virtual void AddLayout(Layout *, unsigned int stretchFactor = 1, MinorDimensionPosition = eAbove, MinorDimensionSize extend = eFull, float percentage = 100.0f, LayoutPosition = NUX_LAYOUT_END); //! Add an object to the layout. /*! Add an object to the layout. A baseobject minor dimension with respect to a layout object is the dimension opposite to the layout flow. A baseobject major dimension with respect to a layout object is the dimension aligned with the layout flow. A layout object minor dimension is the dimension opposite to the layout flow. A layout object major dimension is the dimension aligned with the layout flow. Add an object to the layout. The added object get its size and position managed by the layout. When a baseobject is added with a stretches factor equal to 0, its major dimension assumes its minimum value. For instance, if the layout is a vertical layout and the added object has a stretch factor equal 0, then during the layout, the added object height will be set to its minimum value using ApplyMinHeight(). The positioning parameter controls how the layout will place the object within itself. A vertical layout object controls the horizontal positioning of its children baseobject, While an horizontal layout object controls the vertical positioning of its children baseobject. The extend parameter controls how much size the baseobject minor dimension gets from the layout minor dimension. See MinorDimensionSize. /param baseobject The object that is being added. /param stretchFactor This value controls how the layout object share space between its children baseobject. /param positioning Controls how the layout position the object. /param extend Controls the object minor dimension size. /param percentage Controls the object minor dimension size in percentage of the layout minor dimension size. /param index Controls the object position in the layout. */ virtual void AddView(Area *baseobject, unsigned int stretchFactor = 1, MinorDimensionPosition positioning = eAbove, MinorDimensionSize extend = eFull, float percentage = 100.0f, LayoutPosition index = NUX_LAYOUT_END); virtual void AddSpace(unsigned int width, unsigned int stretchFactor = 0, LayoutPosition index = NUX_LAYOUT_END); virtual void Clear(); //! Set the left/right padding with the same value. /*! Set the left/right padding of the layout. \n Valid only for HLayout, VLayouts, HGridLayouts and VGridLayout. @param padding The left/right padding value of the layout. */ void SetLeftAndRightPadding(int padding); //! Set the left/right padding independently. /*! Set the left/right padding of the layout. \n Valid only for HLayout, VLayouts, HGridLayouts and VGridLayout. @param left Left padding value of the layout. @param right Right padding value of the layout. */ void SetLeftAndRightPadding(int left, int right); //! Set the top/bottom padding with the same value. /*! Set the top/bottom padding of the layout. \n Valid only for HLayout, VLayouts, HGridLayouts and VGridLayout. @param padding The top/bottom padding value of the layout. */ void SetTopAndBottomPadding(int padding); //! Set the top/bottom padding independently. /*! Set the top/bottom padding of the layout. \n Valid only for HLayout, VLayouts, HGridLayouts and VGridLayout. @param top Top padding value of the layout. @param bottom Bottom padding value of the layout. */ void SetTopAndBottomPadding(int top, int bottom); //! Set the left/right and top/bottom padding of the layout. /*! Set the left/right and top/bottom padding of the layout. \n Valid only for HLayout, VLayouts, HGridLayouts and VGridLayout. @param top_bottom_padding The top/bottom padding value of the layout. @param left_right_padding The left/right padding value of the layout. */ void SetPadding(int top_bottom_padding, int left_right_padding); virtual unsigned int GetMaxStretchFactor(); unsigned int GetMinStretchFactor(); unsigned int GetNumStretchFactor(unsigned int sf); int GetContentWidth() const { return m_contentWidth; }; int GetContentHeight() const { return m_contentHeight; }; //! Deprecated. Use SetLeftAndRightPadding. void SetHorizontalExternalMargin(int m); //! Deprecated. Use SetTopAndBottomPadding, void SetVerticalExternalMargin(int m); //! Set the left/right/top/bottom padding of the layout. /*! Set the left/right and top/bottom padding of the layout. \n Valid only for HLayout, VLayouts, HGridLayouts and VGridLayout. @param top The top padding value of the layout. @param right The right padding value of the layout. @param bottom The bottom padding value of the layout. @param left The left padding value of the layout. */ void SetPadding(int top, int right, int bottom, int left); //! Set the left/right/top/bottom padding of the layout. /*! Set the left/right/top/bottom padding of the layout. \n Valid only for HLayout, VLayouts, HGridLayouts and VGridLayout. @param padding The top/right/bottom/left padding value of the layout. */ void SetPadding(int padding); int GetLeftPadding() const; int GetRightPadding() const; int GetTopPadding() const; int GetBottomPadding() const; public: virtual void GetCompositeList(std::list * /* ViewList */) { } virtual void Draw() {} void DoneRedraw(); bool SearchInAllSubNodes(Area *bo); bool SearchInFirstSubNodes(Area *bo); Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); //! Draw Element /*! Draw all elements inside the layout. If force_draw is true then the system requests that all objects redraw themselves completely. \param force_draw \param TraverseInfo \param ProcessEventInfo \return The state of the Process Event. */ virtual void ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw); //! Mark all element in the layout as dirty. /*! Mark all element in the layout as dirty. This will also mark all sub elements as dirty. InputArea element are not marked as dirty(they don't have the flags). Emits the signal \i queue_draw. */ virtual void QueueDraw(); //! Return true if a draw has been scheduled for this layout /*! @return True if a draw has been scheduled for this layout. */ bool IsQueuedForDraw(); //! Return true if a draw has been scheduled for a child of this layout /*! @return True if a draw has been scheduled for a child of this layout. */ bool ChildQueuedForDraw(); //! Define how elements are spread out inside the layout. /*! Typically, a layout stacks it elements from left to right(HLayout) or top to bottom(VLayout). When the elements don't uses all the space that is available, the content stacking policy allows alternatives ways to position the elements. This does not affect the elements size, only their position inside the layout. @param stacking_order */ virtual void SetContentDistribution(LayoutContentDistribution stacking_order); virtual LayoutContentDistribution GetContentDistribution(); virtual bool FindWidget(Area *WidgetObject) const; virtual bool IsEmpty() const; /* This function is reimplemented in Layout and View classes they need to perform some special operations. It does nothing for Area classes(this class cannot have children). */ virtual void RemoveChildObject(Area *); //! Request a Layout recompute after a change of size /* When an object size changes, it is necessary for its parent structure to initiate a layout re computation in order preserve the layout structure defined by the user through the API. */ virtual void RequestBottomUpLayoutComputation(Area *bo_initiator); std::list& GetChildren() { return _layout_element_list; } virtual void ChildQueueDraw(Area* area); sigc::signal queue_draw; //!< Signal emitted when a layout is scheduled for a draw. sigc::signal child_queue_draw; sigc::signal ViewAdded; sigc::signal ViewRemoved; #ifdef NUX_GESTURES_SUPPORT virtual Area* GetInputAreaHitByGesture(const GestureEvent &event); #endif /*! When a layout goes through Layout::ProcessDraw, this call isn't necessary. Otherwise, call it to set the value of draw_cmd_queued_ to false. */ virtual void ResetQueueDraw(); protected: void BeginBackupTextureRendering(GraphicsEngine& graphics_engine, bool force_draw); void EndBackupTextureRendering(GraphicsEngine& graphics_engine, bool force_draw); virtual void GeometryChangePending(bool position_about_to_change, bool size_about_to_change); virtual void GeometryChanged(bool position_has_changed, bool size_has_changed); virtual bool AcceptKeyNavFocus(); bool draw_cmd_queued_; // _layout_element_list; std::string m_name; LayoutContentDistribution m_ContentStacking; }; // The Space layout is a layout object that is used to create fixed or re-sizable empty space. class SpaceLayout: public Layout { NUX_DECLARE_OBJECT_TYPE(SpaceLayout, Layout); public: SpaceLayout(NUX_FILE_LINE_PROTO) : Layout(NUX_FILE_LINE_PARAM) { }; SpaceLayout(int minWidth, int maxWidth, int minHeight, int maxHeight, NUX_FILE_LINE_PROTO) : Layout(NUX_FILE_LINE_PARAM) { SetMinimumSize(minWidth, minHeight); SetMaximumSize(maxWidth, maxHeight); }; ~SpaceLayout() { }; virtual bool FindWidget(Area * /* WidgetObject */) const { return false; } virtual bool IsEmpty() const { return true; } virtual void AddLayout(Layout *, unsigned int /* stretchFactor */ = 1, MinorDimensionPosition /* minor_position */ = eAbove, MinorDimensionSize /* minor_size */ = eFull, float /* percentage */ = 100.0f, LayoutPosition /* index */ = NUX_LAYOUT_END) { // Do not allow a WidgetLayout to encapsulate an object of type layout } virtual void AddView(Area * /* baseobject */, unsigned int /* stretchFactor */ = 1, MinorDimensionPosition /* positioning */ = eAbove, MinorDimensionSize /* extend */ = eFull, float /* percentage */ = 100.0f, LayoutPosition /* index */ = NUX_LAYOUT_END) { // the baseObject is provided via the constructor. }; virtual void AddSpace(unsigned int /* width */, unsigned int /* stretchFactor */ = 0, LayoutPosition /* index */ = NUX_LAYOUT_END) { // Do not allow a WidgetLayout to encapsulate an object of type layout } virtual bool CanFocus() { return false; } // Begin: Abstract virtual function member(inherited from class Layout) that must be implemented virtual long ComputeContentSize() { return 0; } virtual void ComputeContentPosition(float /* offsetX */, float /* offsetY */) { } // End: Abstract virtual function member(inherited from class Layout) that must be implemented protected: Area *Find(long handle); }; } #endif // LAYOUT_H nux-4.0.6+14.04.20140409/Nux/SpinBox.h0000644000015301777760000000371612321344237017251 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef SPINBOX_H #define SPINBOX_H #include "IntegerValidator.h" #include "SpinBox_Logic.h" namespace nux { class SpinBox: public SpinBox_Logic { public: SpinBox(int Value = 0, int Step = 1, int MinValue = 0, int MaxValue = 100, NUX_FILE_LINE_PROTO); virtual ~SpinBox(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void ImplementIncrementBtn(); virtual void ImplementDecrementBtn(); virtual void ImplementValidateEntry(); void SetValue(int value); int GetValue() const; void SetStep(int i); int GetStep() const; int GetMinValue() const; int GetMaxValue() const; void SetRange(int MinValue, int Maxvalue); sigc::signal sigIncrement; sigc::signal sigDecrement; sigc::signal sigValueChanged; sigc::signal sigValue; protected: void InitializeWidgets(); void InitializeLayout(); private: HLayout *hlayout; VLayout *vlayout; IntegerValidator m_IntValidator; int m_iValue; int m_Step; }; } #endif // SPINBOX_H nux-4.0.6+14.04.20140409/Nux/ComboBoxSimple.cpp0000644000015301777760000002272112321344237021101 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "ComboBoxSimple.h" #include "MenuPage.h" #include "ActionItem.h" #include "StaticText.h" namespace nux { ComboBoxSimple::ComboBoxSimple(NUX_FILE_LINE_DECL) : AbstractComboBox(NUX_FILE_LINE_PARAM) { m_SelectedAction = 0; m_CurrentMenu = 0; m_CurrentMenu = new MenuPage("", NUX_TRACKER_LOCATION); m_CurrentMenu->SinkReference(); m_CurrentMenu->SetParentObject(this); // Set Signals _combo_box_opening_area->mouse_down.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvMouseDown)); _combo_box_opening_area->mouse_up.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvMouseUp)); _combo_box_area->mouse_down.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvMouseDown)); _combo_box_area->mouse_up.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvMouseUp)); //m_Popup.sigPopupStop.connect(sigc::mem_fun(this, &ComboBox::OnPopupStop)); // Set Geometry _combo_box_opening_area->SetGeometry(Geometry(0, 0, 20, DEFAULT_WIDGET_HEIGHT)); //_combo_box_opening_area->SetMaximumSize(20, DEFAULT_WIDGET_HEIGHT); _combo_box_opening_area->SetMinimumSize(20, DEFAULT_WIDGET_HEIGHT); _combo_box_area->SetMinimumSize(2 * DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); _combo_box_area->SetGeometry(Geometry(0, 0, 3 * DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT)); //_pango_static_text->SetClipping(_combo_box_area->GetBaseWidth()); _combo_box_area->geometry_changed.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvGeometryChanged)); //m_CurrentMenu = new MenuPage; m_CurrentMenu->SetParentMenu(0); m_CurrentMenu->sigActionTriggered.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvSigActionTriggered)); m_CurrentMenu->sigTerminateMenuCascade.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvSigTerminateMenuCascade)); m_CurrentMenu->sigClosingMenu.connect(sigc::mem_fun(this, &ComboBoxSimple::RecvClosingMenuSignal)); } ComboBoxSimple::~ComboBoxSimple() { m_CurrentMenu->UnParentObject(); m_CurrentMenu->UnReference(); } Area* ComboBoxSimple::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; NUX_RETURN_VALUE_IF_TRUE(_combo_box_opening_area->TestMousePointerInclusion(mouse_position, event_type), _combo_box_opening_area); NUX_RETURN_VALUE_IF_TRUE(_combo_box_area->TestMousePointerInclusion(mouse_position, event_type), _combo_box_area); if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } void ComboBoxSimple::MoveSelectionUp() { int current_index = GetSelectionIndex(); SetSelectionIndex(current_index - 1); } void ComboBoxSimple::MoveSelectionDown() { int current_index = GetSelectionIndex(); SetSelectionIndex(current_index + 1); } ActionItem *ComboBoxSimple::AddItem(const char *label, int Uservalue) { if (m_CurrentMenu->GetNumItem() == 0) { // The first element added is the element featured on the combo box when it is closed. m_SelectedAction = m_CurrentMenu->AddAction(label, Uservalue); _combo_box_area->SetBaseString(m_SelectedAction->GetLabel()); _pango_static_text->SetText(m_SelectedAction->GetLabel()); return m_SelectedAction; } else { return m_CurrentMenu->AddAction(label, Uservalue); } } void ComboBoxSimple::RemoveItem(ActionItem *item) { } void ComboBoxSimple::RemoveAllItem() { m_CurrentMenu->RemoveAllItem(); } void ComboBoxSimple::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags) { if (m_MenuIsActive == false) { // Open the MenuPage m_MenuIsActive = true; m_IsOpeningMenu = true; Geometry geo = m_CurrentMenu->GetGeometry(); geo.SetX(_combo_box_area->GetAbsoluteX()); geo.SetY(_combo_box_area->GetAbsoluteY() + _combo_box_area->GetBaseHeight()); geo.SetWidth(_combo_box_area->GetBaseWidth()); //m_CurrentMenu->SetMinimumWidth(geo.width); //m_CurrentMenu->SetMaximumWidth(geo.width); m_CurrentMenu->SetGeometry(geo); m_CurrentMenu->ComputeContentSize(); m_CurrentMenu->StartMenu(_combo_box_area->GetAbsoluteX(), _combo_box_area->GetAbsoluteY() + _combo_box_area->GetBaseHeight(), 0, 0); } else { // If the mouse up that follows happen inside the area, then it is going to close the menu. m_IsOpeningMenu = false; } QueueDraw(); } void ComboBoxSimple::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags) { if (m_MenuIsActive) { if (_combo_box_area->IsMouseInside() || _combo_box_opening_area->IsMouseInside()) { if (m_IsOpeningMenu == false) { // close the MenuPage that is Open m_CurrentMenu->StopMenu(0, 0); m_MenuIsActive = false; } else { // The MousePress before this MouseRelease, caused the MenuPage to open. // Set m_IsOpeningMenu so the next mouse release will close the menu. m_IsOpeningMenu = false; m_MenuIsActive = true; } } else { bool hit_inside_a_menu = false; bool b = m_CurrentMenu->TestMouseUp(x, y, button_flags, key_flags, hit_inside_a_menu); if (b || (hit_inside_a_menu == false)) { RecvSigTerminateMenuCascade(); m_MenuIsActive = false; } } } QueueDraw(); } void ComboBoxSimple::RecvSigActionTriggered(MenuPage *menu, ActionItem *action) { m_MenuIsActive = false; m_CurrentMenu->StopMenu(); m_SelectedAction = action; _combo_box_area->SetBaseString(m_SelectedAction->GetLabel()); m_IsOpeningMenu = false; _pango_static_text->SetText(m_SelectedAction->GetLabel()); sigTriggered.emit(this); sigActionTriggered.emit(m_SelectedAction); QueueDraw(); // You can do something if you want with the menu* and the action* } void ComboBoxSimple::RecvSigActionTriggered2(TableCtrl *table, TableItem *item, unsigned int row, unsigned int column) { m_MenuIsActive = false; m_CurrentMenu->StopMenu(); m_IsOpeningMenu = false; QueueDraw(); // You can do something if you want with the menu* and the action* } void ComboBoxSimple::RecvSigTerminateMenuCascade() { //m_MenuIsActive = false; m_CurrentMenu->StopMenu(); m_IsOpeningMenu = false; } void ComboBoxSimple::RecvClosingMenuSignal(MenuPage* menu_page) { nuxAssert(menu_page == m_CurrentMenu); m_IsOpeningMenu = false; m_MenuIsActive = false; // When the menu is closing check if the mouse is still inside the combo box surface // and set the _current_mouse_in flag accordingly. if (!_combo_box_area->TestMousePointerInclusion(GetWindowThread()->GetWindowCompositor().GetMousePosition(), NUX_NO_EVENT)) { _combo_box_area->mouse_in_ = false; } if (!_combo_box_opening_area->TestMousePointerInclusion(GetWindowThread()->GetWindowCompositor().GetMousePosition(), NUX_NO_EVENT)) { _combo_box_opening_area->mouse_in_ = false; } QueueDraw(); } void ComboBoxSimple::RecvGeometryChanged(Area *area, Geometry &geo) { //_pango_static_text->SetClipping(geo.width); } const char *ComboBoxSimple::GetSelectionLabel() const { if (m_SelectedAction) return m_SelectedAction->GetLabel(); return 0; } int ComboBoxSimple::GetSelectionUserValue() const { if (m_SelectedAction) return m_SelectedAction->GetUserValue(); return 0; } int ComboBoxSimple::GetNumItem() const { return m_CurrentMenu->GetNumItem(); } ActionItem *ComboBoxSimple::GetItem(int index) const { return m_CurrentMenu->GetActionItem(index); } int ComboBoxSimple::GetSelectionIndex() const { if (m_SelectedAction) return m_CurrentMenu->GetActionItemIndex(m_SelectedAction); return -1; } void ComboBoxSimple::SetSelectionIndex(int index) { if ((index >= 0) && (index < m_CurrentMenu->GetNumItem())) { m_SelectedAction = m_CurrentMenu->GetActionItem(index); _combo_box_area->SetBaseString(m_SelectedAction->GetLabel()); _pango_static_text->SetText(m_SelectedAction->GetLabel()); QueueDraw(); } else if (m_CurrentMenu->GetNumItem() > 0) { // index is negative m_SelectedAction = m_CurrentMenu->GetActionItem(0); _combo_box_area->SetBaseString(m_SelectedAction->GetLabel()); _pango_static_text->SetText(m_SelectedAction->GetLabel()); QueueDraw(); } else { m_SelectedAction = 0; } } } nux-4.0.6+14.04.20140409/Nux/MouseAreaCtrl.h0000644000015301777760000000422712321344237020373 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef MOUSEAREACTRL_H #define MOUSEAREACTRL_H #include "EditTextBox.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" namespace nux { //replace MouseAreaCtrl with GfxViewCtrl class MouseAreaCtrl: public View { public: MouseAreaCtrl(NUX_FILE_LINE_PROTO); ~MouseAreaCtrl(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); int getAreaPosY(); int getAreaPosX(); int getAreaWidth(); int getAreaHeight(); ///////////////// // EMITERS // ///////////////// void MouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void MouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void MouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); ///////////////// // SIGNALS // ///////////////// sigc::signal sigMouseDown; sigc::signal sigMouseUp; sigc::signal sigMouseDrag; sigc::signal sigDraw; private: VLayout *m_vlayout; BasicView *m_Area; public: virtual void SetGeometry(const Geometry &geo) { Area::SetGeometry(geo); ComputeContentSize(); } }; } #endif // MOUSEAREACTRL_H nux-4.0.6+14.04.20140409/Nux/ColorPreview.h0000644000015301777760000000367712321344237020315 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef COLORPREVIEW_H #define COLORPREVIEW_H #include "NuxCore/Color.h" #include "NuxGraphics/GpuDevice.h" #include "NuxGraphics/GLDeviceObjects.h" #include "TimerProc.h" namespace nux { class HLayout; class StaticTextBox; class ColorEditor; class TimerHandle; class ColorDialogProxy; class ColorPreview : public View { public: ColorPreview(Color const& c = nux::color::Transparent, NUX_FILE_LINE_PROTO); ~ColorPreview(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); sigc::signal< void, ColorEditor * > sigColorChanged; void SetColor(Color const& rgb); Color const& GetRGBColor() const; private: void RecvTimer(void *v); void RecvClick(int x, int y, unsigned long button_flags, unsigned long key_flags); TimerFunctor *m_ChangeDetectionTimer; TimerHandle m_ChangeTimerHandler; Color m_Color; HLayout *m_hlayout; InputArea *m_ColorArea; StaticTextBox *m_ColorValue; ColorDialogProxy *m_DialogThreadProxy; }; } #endif // COLORPREVIEW_H nux-4.0.6+14.04.20140409/Nux/RadioButton.cpp0000644000015301777760000000767712321344237020466 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HLayout.h" #include "RadioButton.h" #include "StaticText.h" #include "RadioButtonGroup.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(RadioButton); RadioButton::RadioButton(const std::string& str, bool state, NUX_FILE_LINE_DECL) : AbstractCheckedButton(str, state, NUX_FILE_LINE_PARAM) { block_changed_signal_ = false; radio_group_index_ = -1; } RadioButton::~RadioButton() { if (radio_button_group_.IsValid() && radio_group_index_ != -1) { radio_button_group_->DisconnectButton(this); if (radio_button_group_->GetNumButtons() == 0) { // The last button in the group calls UnReference on the RadioButtonGroup. radio_button_group_->UnReference(); } } } void RadioButton::Draw(GraphicsEngine& graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); InteractState is; is.is_on = active_; if (visual_state_ == VISUAL_STATE_PRESSED) { is.is_focus = true; } else if (visual_state_ == VISUAL_STATE_PRELIGHT) { is.is_prelight = true; } else { is.is_focus = false; is.is_prelight = false; } GetPainter().PushPaintLayerStack(); { GetPainter().PaintRadioButton(graphics_engine, check_area_->GetGeometry(), is, Color(0xff000000)); static_text_->ProcessDraw(graphics_engine, true); } GetPainter().PopPaintLayerStack(); graphics_engine.PopClippingRectangle(); } void RadioButton::RecvClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (radio_button_group_.IsValid()) { block_changed_signal_ = true; radio_button_group_->NotifyClick(this); block_changed_signal_ = false; state_change.emit(this); click.emit(this); } else { active_ = !active_; click.emit(this); } QueueDraw(); } void RadioButton::Activate() { if (radio_button_group_.IsValid()) { radio_button_group_->SetActiveButton(this, true); return; } SetStatePrivate(true); } void RadioButton::Deactivate() { if (radio_button_group_.IsValid()) { // The RadioButton is part of a group. To deactivate it, activate another radio button in that group."; return; } SetStatePrivate(false); } void RadioButton::SetRadioButtonGroup(RadioButtonGroup* radio_button_group) { if (radio_button_group_.IsValid() && radio_button_group_.GetPointer() == radio_button_group) return; if (radio_button_group_.IsValid()) { radio_button_group_.Release(); } if (radio_button_group) { radio_button_group_ = ObjectWeakPtr(radio_button_group); } } ObjectWeakPtr RadioButton::GetRadioButtonGroup() { return radio_button_group_; } void RadioButton::SetStatePrivate(bool state) { active_ = state; QueueDraw(); } void RadioButton::SetStatePrivate(bool state, bool emit_signal) { active_ = state; if (emit_signal && !block_changed_signal_) { state_change.emit(this); } QueueDraw(); } } nux-4.0.6+14.04.20140409/Nux/TabView.h0000644000015301777760000001071312321344237017223 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef TABVIEW_H #define TABVIEW_H #include "Nux.h" #include "View.h" #include "TimerProc.h" #include "HLayout.h" namespace nux { class TabView : public View { public: TabView(NUX_FILE_LINE_PROTO); ~TabView(); virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); void AddTab(const char *tab_name, Layout *tab_layout); void SetActiveTad(int index); //! Return true if this object can break the layout. /* Return true if this object can break the layout, meaning, the layout can be done on the composition layout only without recomputing the whole window layout. Inherited from View */ virtual bool CanBreakLayout() { return false; } sigc::signal< void, TabView * > sigTabChanged; sigc::signal< void, int > sigTabIndexChanged; private: class TabElement { public: TabElement(std::string TabName, Layout *TabLayout); ~TabElement(); void SetIndex(int index); int GetIndex() const; void SetGeometry(const Geometry &geo); Geometry const& GetGeometry() const; const std::string &GetName() const; std::string _tab_name; Layout *_tab_content_layout; BasicView *_tab_area; int _index; }; public: void RecvTabMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags, TabElement *); void RecvTabMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, TabElement *); void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); protected: virtual bool AcceptKeyNavFocus(); private: void RecvTabRightTimerExpired(void *v); void RecvTabLeftTimerExpired(void *v); void RecvTabRightMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTabLeftMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTabButtonMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void ComputeContentPosition(float offsetX, float offsetY); void TranslateLeft(int x, int y, unsigned long button_flags, unsigned long key_flags); void TranslateRight(int x, int y, unsigned long button_flags, unsigned long key_flags); void TranslateTabLayout(int offset); BasicView *_scroll_right; BasicView *_scroll_left; Layout *_visible_tab_content_layout; HLayout *_tabview_heads_layout; HLayout *_tabview_scroll_button_layout; int m_TabPositionOffset; int m_FocusTabIndex; TimerFunctor *tabright_callback; TimerFunctor *tableft_callback; TimerHandle m_TabRightTimerHandler; TimerHandle m_TabLeftTimerHandler; std::vector _tab_array; static Color TAB_HEADER_BACKGROUND_COLOR; static Color TAB_BACKGROUND_COLOR; static Color TAB_HEADER_COLOR; static Color TAB_HEADER_FOCUS_COLOR; static int TAB_BUTTON_WIDTH; static int TAB_BUTTON_HEIGHT; static int TAB_HEIGHT; static int TAB_X_BORDER; static int TAB_Y_BORDER; // We need to draw the background on the previous size of the Table if its // size is set to match the content(IsSizeMatchContent) and an item is close. Geometry m_PreviousGeometry; bool m_DrawBackgroundOnPreviousGeometry; }; } #endif // TABVIEW_H nux-4.0.6+14.04.20140409/Nux/DoubleValidator.h0000644000015301777760000000336112321344237020743 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef DOUBLEVALIDATOR_H #define DOUBLEVALIDATOR_H #include "Validator.h" namespace nux { class DoubleValidator : public Validator { public: DoubleValidator(double Minimum = -1.7E308, double Maximum = 1.7E308); DoubleValidator(const DoubleValidator &validator); DoubleValidator &operator= (const DoubleValidator &rhs); virtual ~DoubleValidator(); virtual Validator *Clone() const; //Virtual Constructor Idiom /*! @return The input value clamped to the range [m_Minimum, m_Maximum]. */ double GetClampedValue(double d) const; virtual void Alternative(const char *str); void SetDecimals(int dec); void SetMinimum(double value); double GetMinimum() const; void SetMaximum(double value); double GetMaximum() const; std::string ToString(double d); double ToDouble(const char *str); private: double m_Minimum; double m_Maximum; int m_Decimals; }; } #endif // INTEGERVALIDATOR_H nux-4.0.6+14.04.20140409/Nux/KineticScrolling/0000755000015301777760000000000012321344711020747 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/Nux/KineticScrolling/KineticScrollingEnums.h0000644000015301777760000000460712321344237025405 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_KINETIC_SCROLLING_ENUMS_H #define NUX_KINETIC_SCROLLING_ENUMS_H namespace nux { enum BoundsBehavior { StopAtBounds, /*!< content can not be dragged beyond viewport boundaries, and flicks will not overshoot */ DragOverBounds, /*!< content can be dragged beyond viewport boundaries, but flicks will not overshoot. */ DragAndOvershootBounds /*!< content can be dragged beyond viewport boundaries and can overshoot it when flicked. */ }; enum ScrollableDirections { ScrollableDirectionsAuto, ScrollableDirectionsHorizontal, ScrollableDirectionsVertical, ScrollableDirectionsHorizontalAndVertical }; /*! Enumeration that describes the possible states of an axis of the kinetic scroller Kinetic scrolling works for each axis independently. Therefore each axis has its own separate state. */ enum KineticScrollerAxisState { /*!< It's not pressed and not moving. This is the initial state. This is also the state an axis will be if scrolling is not possible or enabled for it. */ KineticScrollerAxisStateIdle, /*!< It's pressed but not yet moving. */ KineticScrollerAxisStatePressed, /*!< It's pressed and moving to follow the user's finger */ KineticScrollerAxisStateFollowingFinger, /*!< It's not pressed anymore but it's still moving due to inertia. Reacheable from FollowingFinger. After it loses all its momentum it will stop and therefore move to the Idle state. */ KineticScrollerAxisStateMovingByInertia }; } // namespace nux #endif // NUX_KINETIC_SCROLLING_ENUMS_H nux-4.0.6+14.04.20140409/Nux/KineticScrolling/KineticAxisScroller.h0000644000015301777760000001236512321344237025053 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_KINETIC_AXIS_SCROLLER_H #define NUX_KINETIC_AXIS_SCROLLER_H #include "KineticScrollingEnums.h" namespace nux { namespace kinetic_scrolling { class TickSourceInterface; } /* Drives the scrolling of an entity based on user input, along an axis Given information on user input (e.g. touches and mouse events) it tells how a view/entity/object should react by scrolling in a kinetic fashion. The scroller moves the content and considers the viewport to be fixed. */ class KineticAxisScroller { public: /* Minimum flick speed, in axis units per millisecond. If the flick speed is lower than that there will be no kinetic scrolling. */ static const float MINIMUM_FLICK_SPEED; /* Multiplier for the flick speed, to make flicking more effective. */ static const float FLICK_BOOST; /*! Enumeration that describes the possible states of the kinetic scroller */ enum States { Idle, /*!< It's not pressed and not moving. This is the initial state */ Pressed, /*!< It's pressed but not yet moving. */ FollowingFinger, /*!< It's pressed and moving to follow the user's finger */ MovingByInertia /*!< It's not pressed anymore but it's still moving due to inertia. Reacheable from FollowingFinger. After it loses all its momentum it will stop and therefore move to the Idle state. */ }; /*! Minimum movement of the finger along an axis necessary for the scroller to start following it. I.e. to move from Pressed to FollowingFinger state. */ static const int MOVEMENT_THRESHOLD = 5; KineticAxisScroller(); virtual ~KineticAxisScroller(); /***** Initialization ******/ /*! Specifies the length of the viewport. Any existing momentum or movement is halted. You will usually call this method only during initialization. */ void SetViewportLength(int length); /*! Returns the viewport length set via SetViewportLength() */ int GetViewportLength() const; /*! Specifies the length of the content. Scrolling is only useful when the content is larger than the viewport. Any existing momentum or movement is halted. You will usually call this method only during initialization. */ void SetContentLength(int length); /*! Returns the content length set via SetViewportLength() */ int GetContentLength() const; /*! Sets the content position, relative to viewport's top/left corner. Any existing momentum or movement is halted. You will usually call this method only during initialization. */ void SetContentPosition(int pos); /*! Defines what happens when the viewport is about to be beyond content boundaries The default value is DragAndOvershootBounds. */ void SetBoundsBehavior(BoundsBehavior bounds_behavior); /***** input ******/ /*! Tells the scroller that a finger is touching the scrollable surface The scroller is interested only in single finger interactions. If subsequent fingers hit the surface they shouldn't be informed to the scroller. Thus calling this method twice, without a ProcessFingerUp() in between, is not supported. */ void ProcessFingerDown(); /*! Tells the scroller that a finger has left the scrollable surface \sa ProcessFingerDown() */ void ProcessFingerUp(); /*! Tells the scroller that a finger has moved along the scrollable surface \param movement How far it has moved along the axis. */ void ProcessFingerDrag(int movement); /*! Moves animations forward by delta_time milliseconds. After calling this method you will normally want to know the new position (GetPosition()) and whether the animation has finished (IsActive()), meaning that movement along that axis came to a halt. \param delta_time Time elapsed since the last call to Update() */ void UpdateTime(int delta_time); /***** Scrolling output ******/ int GetContentPosition() const; /*! Whether, in its current state, the scroller needs UpdateTime() to be called That happens in states where content position changes happen due to internal animations and not in direct response to user input like in ProcessFingerDrag() */ bool NeedTimeUpdates() const; /*! Returns the current state of the kinetic scroller. */ KineticScrollerAxisState GetState() const; private: class Private; Private *p; }; } // namespace nux #endif // NUX_KINETIC_AXIS_SCROLLER_H nux-4.0.6+14.04.20140409/Nux/KineticScrolling/AxisDecelerationAnimation.cpp0000644000015301777760000000613312321344237026544 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include "AxisDecelerationAnimation.h" using namespace nux; const float AxisDecelerationAnimation::MINIMUM_VELOCITY = 0.07f; void AxisDecelerationAnimation::SetOvershootBoundsEnabled(bool enable) { overshoot_bounds_ = enable; } void AxisDecelerationAnimation::SetMinimumPosition(float min_pos) { min_pos_ = min_pos; } void AxisDecelerationAnimation::SetMaximumPosition(float max_pos) { max_pos_ = max_pos; } void AxisDecelerationAnimation::SetStartPosition(float position) { start_pos_ = position; } void AxisDecelerationAnimation::SetStartVelocity(float velocity) { start_vel_ = velocity; } void AxisDecelerationAnimation::Start() { decay_constant_ = 0.01f; overshoot_constant_ = 0.007f; pos_ = start_pos_; vel_ = start_vel_; elapsed_time_ = 0; } void AxisDecelerationAnimation::Update(int delta_time) { // Exponential decay elapsed_time_ += delta_time; vel_ = start_vel_ * expf(-(decay_constant_ * elapsed_time_)); pos_ += vel_ * delta_time; if (overshoot_bounds_) { PullBackIfBeyondBoundaries(delta_time); } else { StopIfBeyondBoundaries(); } } void AxisDecelerationAnimation::PullBackIfBeyondBoundaries(int delta_time) { // If we overshot, apply a spring acceleration to bring position // back to its max/min limit. if (pos_ > max_pos_) { float dt = delta_time; float acceleration = -overshoot_constant_ * (pos_ - max_pos_); pos_ += (vel_*dt) + (acceleration*dt*dt/2.0f); vel_ += acceleration*dt; if (fabs(pos_ - max_pos_) < 1.5f) { pos_ = max_pos_; vel_ = 0.0f; } } else if (pos_ < min_pos_) { float dt = delta_time; float acceleration = -overshoot_constant_ * (pos_ - min_pos_); pos_ += (vel_*dt) + (acceleration*dt*dt/2.0f); vel_ += acceleration*dt; if (fabs(pos_ - min_pos_) < 1.5f) { pos_ = min_pos_; vel_ = 0.0f; } } } float AxisDecelerationAnimation::GetPosition() const { return pos_; } bool AxisDecelerationAnimation::IsActive() const { if (pos_ < min_pos_ || pos_ > max_pos_) return true; else return (fabs(vel_) > MINIMUM_VELOCITY); } void AxisDecelerationAnimation::StopIfBeyondBoundaries() { if (pos_ > max_pos_) { pos_ = max_pos_; vel_ = 0.0f; } else if (pos_ < min_pos_) { pos_ = min_pos_; vel_ = 0.0f; } } nux-4.0.6+14.04.20140409/Nux/KineticScrolling/KineticScrollingTickSource.cpp0000644000015301777760000000342512321344237026721 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include "KineticScrollingTickSource.h" using namespace nux::kinetic_scrolling; TimerTickSource::TimerTickSource() { timer_functor_.tick.connect(sigc::mem_fun(this, &TimerTickSource::Tick)); timer_functor_.expired.connect(sigc::mem_fun(this, &TimerTickSource::TimerExpired)); } TimerTickSource::~TimerTickSource() { Stop(); } void TimerTickSource::Start() { timer_handle_ = nux::GetTimer().AddDurationTimer(UPDATE_PERIOD, 100000000 /* some arbitrarily long time */, &timer_functor_, NULL); last_elapsed_time_ = 0; } void TimerTickSource::Stop() { if (timer_handle_.IsValid()) { nux::GetTimer().RemoveTimerHandler(timer_handle_); } } void TimerTickSource::Tick(void*) { int delta_time = timer_handle_.GetElapsedTimed() - last_elapsed_time_; last_elapsed_time_ = timer_handle_.GetElapsedTimed(); tick.emit(delta_time); } void TimerTickSource::TimerExpired(void*) { } nux-4.0.6+14.04.20140409/Nux/KineticScrolling/KineticAxisScroller.cpp0000644000015301777760000001727512321344237025413 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include "KineticAxisScroller.h" #include "AxisDecelerationAnimation.h" #include "VelocityCalculator.h" #include #include "KineticScrollingTickSource.h" using namespace nux; /***************************************************************************** * Private class *****************************************************************************/ class KineticAxisScroller::Private : public sigc::trackable { public: Private(); void CalculateContentPosLimits(); void ProcessFingerDown(); void ProcessFingerUp(); void ProcessFingerDrag(int mov); void ProcessFingerDrag_Pressed(int mov); void ProcessFingerDrag_FollowingFinger(int mov); void UpdateAnimations(int time); int LimitOutOfBoundsMovement(int movement, int position, int min_position) const; float viewport_length_; float content_length_; float content_pos_; float min_content_pos_; BoundsBehavior bounds_behavior_; KineticScrollerAxisState state_; VelocityCalculator velocity_calculator_; AxisDecelerationAnimation deceleration_animation_; int accumulated_movement_; }; KineticAxisScroller::Private::Private() { viewport_length_ = 0.0f; content_length_ = 0.0f; content_pos_ = 0.0f; min_content_pos_ = 0.0f; bounds_behavior_ = DragAndOvershootBounds; state_ = KineticScrollerAxisStateIdle; } void KineticAxisScroller::Private::CalculateContentPosLimits() { if (content_length_ > viewport_length_) min_content_pos_ = -(content_length_ - viewport_length_); else min_content_pos_ = 0.0f; } void KineticAxisScroller::Private::ProcessFingerDown() { switch (state_) { case KineticScrollerAxisStateIdle: state_ = KineticScrollerAxisStatePressed; accumulated_movement_ = 0; break; case KineticScrollerAxisStateMovingByInertia: state_ = KineticScrollerAxisStatePressed; accumulated_movement_ = 0; break; default: /* Ignore it */ break; } } void KineticAxisScroller::Private::ProcessFingerUp() { // consider the elapsed time between the last drag update and now, that the // finger has been lifted (it could have been still for a while). velocity_calculator_.ProcessMovement(0); float velocity = velocity_calculator_.CalculateVelocity(); if (fabs(velocity) < MINIMUM_FLICK_SPEED) velocity = 0.0f; else velocity *= FLICK_BOOST; /* Always run the animation, even if there's no starting speed, as it will pull the content back to a valid position if it was dragged beyond valid boundaries */ deceleration_animation_.SetMinimumPosition(min_content_pos_); deceleration_animation_.SetMaximumPosition(0.0f); deceleration_animation_.SetStartPosition(content_pos_); deceleration_animation_.SetStartVelocity(velocity); deceleration_animation_.Start(); state_ = KineticScrollerAxisStateMovingByInertia; } void KineticAxisScroller::Private::ProcessFingerDrag(int movement) { movement = LimitOutOfBoundsMovement(movement, content_pos_, min_content_pos_); if (movement == 0) return; if (state_ == KineticScrollerAxisStatePressed) { ProcessFingerDrag_Pressed(movement); } else // KineticScrollerAxisState::FollowingFinger { ProcessFingerDrag_FollowingFinger(movement); } } void KineticAxisScroller::Private::ProcessFingerDrag_Pressed(int movement) { accumulated_movement_ += movement; if (abs(accumulated_movement_) > KineticAxisScroller::MOVEMENT_THRESHOLD) { state_ = KineticScrollerAxisStateFollowingFinger; velocity_calculator_.Reset(); ProcessFingerDrag_FollowingFinger(movement); } } void KineticAxisScroller::Private::ProcessFingerDrag_FollowingFinger(int movement) { /* TODO: Filter the input for a smoother movement. E.g.: make the content follow the finger with a small delay instead of exactly following it. That will remove the inherent jitter in input coming from a touchscreen. */ content_pos_ += movement; velocity_calculator_.ProcessMovement(movement); } void KineticAxisScroller::Private::UpdateAnimations(int delta_time) { if (deceleration_animation_.IsActive()) { deceleration_animation_.Update(delta_time); content_pos_ = deceleration_animation_.GetPosition(); if (!deceleration_animation_.IsActive()) state_ = KineticScrollerAxisStateIdle; } else { state_ = KineticScrollerAxisStateIdle; } } int KineticAxisScroller::Private::LimitOutOfBoundsMovement(int movement, int position, int min_position) const { int new_position = position + movement; if (new_position > 0) { if (bounds_behavior_ == StopAtBounds) { return 0 - position; } else { /* hinder movement to hint user that he's dragging content beyound its boundaries*/ return movement / 2; } } else if (new_position < min_position) { if (bounds_behavior_ == StopAtBounds) { return min_position - position; } else { return movement / 2; } } else { /* new_position is still within bounds */ return movement; } } /***************************************************************************** * Public class *****************************************************************************/ const float KineticAxisScroller::MINIMUM_FLICK_SPEED = 0.003f; const float KineticAxisScroller::FLICK_BOOST = 2.0f; KineticAxisScroller::KineticAxisScroller() : p(new Private) { } KineticAxisScroller::~KineticAxisScroller() { delete p; } void KineticAxisScroller::SetViewportLength(int length) { p->viewport_length_ = length; p->CalculateContentPosLimits(); } int KineticAxisScroller::GetViewportLength() const { return p->viewport_length_; } void KineticAxisScroller::SetContentLength(int length) { p->content_length_ = length; p->CalculateContentPosLimits(); } int KineticAxisScroller::GetContentLength() const { return p->content_length_; } void KineticAxisScroller::SetContentPosition(int pos) { p->content_pos_ = pos; } void KineticAxisScroller::SetBoundsBehavior(BoundsBehavior bounds_behavior) { p->bounds_behavior_ = bounds_behavior; p->deceleration_animation_.SetOvershootBoundsEnabled( bounds_behavior != BoundsBehavior::StopAtBounds); } void KineticAxisScroller::ProcessFingerDown() { p->ProcessFingerDown(); } void KineticAxisScroller::ProcessFingerUp() { p->ProcessFingerUp(); } void KineticAxisScroller::ProcessFingerDrag(int movement) { p->ProcessFingerDrag(movement); } void KineticAxisScroller::UpdateTime(int delta_time) { p->UpdateAnimations(delta_time); } bool KineticAxisScroller::NeedTimeUpdates() const { return p->state_ == KineticScrollerAxisStateMovingByInertia && p->deceleration_animation_.IsActive(); } KineticScrollerAxisState KineticAxisScroller::GetState() const { return p->state_; } int KineticAxisScroller::GetContentPosition() const { return p->content_pos_; } nux-4.0.6+14.04.20140409/Nux/KineticScrolling/VelocityCalculator.h0000644000015301777760000000444412321344237024741 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_VELOCITY_CALCULATOR_H #define NUX_VELOCITY_CALCULATOR_H #include namespace nux { /* Estimates the current velocity of a finger based on recent movement Taking an estimate from a reasonable number of samples, instead of only from its last movement, removes wild variations in velocity caused by the jitter normally present in input from a touchscreen. */ class VelocityCalculator { public: VelocityCalculator(); /* How much the finger has moved since ProcessMovement() was last called. */ void ProcessMovement(int movement); /* Calculates the finger velocity, in axis units/millisecond */ float CalculateVelocity() const; /* Removes all stored movements from previous calls to ProcessMovement() */ void Reset(); /* Maximum number of movement samples stored */ static const int MAX_SAMPLES = 10; /* Age of the oldest sample considered in the velocity calculations, in milliseconds, compared to the most recent one. */ static const int AGE_OLDEST_SAMPLE = 200; private: int NumSamples() const; class Sample { public: int mov; /* movement distance since last sample */ int64_t time; /* time, in milliseconds */ }; /* a circular buffer of samples */ Sample samples_[MAX_SAMPLES]; int samples_read_; /* index of the oldest sample available. -1 if buffer is empty */ int samples_write_; /* index where the next sample will be written */ }; } // namespace nux #endif // NUX_VELOCITY_CALCULATOR_H nux-4.0.6+14.04.20140409/Nux/KineticScrolling/KineticScroller.h0000644000015301777760000001042612321344237024222 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_KINETIC_SCROLLER_H #define NUX_KINETIC_SCROLLER_H #include "KineticScrollingEnums.h" namespace nux { namespace kinetic_scrolling { class TickSourceInterface; } /* Drives the scrolling of an entity based on user input Given information on user input (e.g. touches and mouse events) it tells how a view/entity/object should react by scrolling in a kinetic fashion. Thus this class doesn't do anything by itself but must be attached or composed with the object that you want to have kinetic scrolling. The scroller moves the content and considers the viewport to be fixed. */ class KineticScroller { public: /*! Minimum movement of the finger along an axis necessary for the scroller to start following it. I.e. to move from Pressed to FollowingFinger state. */ static const int MOVEMENT_THRESHOLD = 5; KineticScroller(); /*! Constructor useful for testing purposes. When testing you would like to manually drive the animations */ KineticScroller(kinetic_scrolling::TickSourceInterface *tick_source); virtual ~KineticScroller(); /***** Initialization ******/ /*! Specifies the size of the viewport. Any existing momentum or movement is halted. You will usually call this method only during initialization. */ void SetViewportSize(int width, int height); /*! Specifies the size of the content. Scrolling is only useful when the content is larger than the viewport. Any existing momentum or movement is halted. You will usually call this method only during initialization. */ void SetContentSize(int width, int height); /*! Sets the content position, relative to viewport's top-left corner. Any existing momentum or movement is halted. You will usually call this method only during initialization. */ void SetContentPosition(int x, int y); /*! Defines what happens when the viewport is about to be beyond content boundaries The default value is DragAndOvershootBounds. */ void SetBoundsBehavior(BoundsBehavior bounds_behavior); /*! Defines which directions can be scrolled. The default value is Auto. */ void SetScrollableDirections(ScrollableDirections scrollable_directions); /***** input ******/ /*! Tells the scroller that a finger is touching the scrollable surface The scroller is interested only in single finger interactions. If subsequent fingers hit the surface they shouldn't be informed to the scroller. Thus calling this method twice, without a ProcessFingerUp() in between, is not supported. */ void ProcessFingerDown(); /*! Tells the scroller that a finger has left the scrollable surface \sa ProcessFingerDown() */ void ProcessFingerUp(); /*! Tells the scroller that a finger has moved along the scrollable surface \param dx How far it has moved along the X axis. \param dx How far it has moved along the Y axis. */ void ProcessFingerDrag(int dx, int dy); /***** Scrolling output ******/ //! Emitted when the content position changes /*! It won't be emitted due to a call to SetContentPosition(). @param int X coordinate of the new content position. @param int Y coordinate of the new content position. */ sigc::signal content_position_changed; KineticScrollerAxisState GetHorizontalAxisState() const; KineticScrollerAxisState GetVerticalAxisState() const; private: class Private; Private *p; }; } // namespace nux #endif // NUX_KINETIC_SCROLLER_H nux-4.0.6+14.04.20140409/Nux/KineticScrolling/AxisDecelerationAnimation.h0000644000015301777760000000620212321344237026206 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_AXIS_DECELERATION_ANIMATION_H #define NUX_AXIS_DECELERATION_ANIMATION_H namespace nux { /*! Animates the deceleration along an axis until it comes to a halt Usage: 1 - Setup the animation animation.SetMinimumPosition(0.0f); animation.SetMaximumPosition(100.0f); animation.SetStartPosition(34.0f); animation.SetStartVelocity(2.0f); 2 - Start it animation.Start(); 3 - Update it at regular intervals until it finishes animation.Update(delta_time); new_pos = animation.GetPosition(); if (!animation.IsActive()) Stop updating this animation */ class AxisDecelerationAnimation { public: /*! Sets whether position limits can be momentarily overshot */ void SetOvershootBoundsEnabled(bool enable); void SetMinimumPosition(float min_pos); void SetMaximumPosition(float max_pos); void SetStartPosition(float position); /*! \param velocity Initial velocity, in axis units per millisecond. */ void SetStartVelocity(float velocity); /*! Marks the end of the setup phase and sets the animation time to 0. After that, Update() should be called until IsActive() returns false. This method can also be used to restart an ongoing animation. */ void Start(); /*! Moves the animation forward by delta_time milliseconds. After calling this method you will normally want to know the new position (GetPosition()) and whether the animation has finished (IsActive()), meaning that movement along that axis came to a halt. \param delta_time Time elapsed since the last call to Update() */ void Update(int delta_time); /*! Current position along that axis. It changes by every call made to Update() while IsActive() is true. */ float GetPosition() const; /*! Returns whether the animation has finished, meaning that further calls to Update() will no longer change the position. I.e., movement reached a complete halt. */ bool IsActive() const; private: void PullBackIfBeyondBoundaries(int delta_time); void StopIfBeyondBoundaries(); static const float MINIMUM_VELOCITY; float start_pos_; float start_vel_; float pos_; float vel_; float min_pos_; float max_pos_; int elapsed_time_; float decay_constant_; float overshoot_constant_; bool overshoot_bounds_; }; } // namespace nux #endif // NUX_AXIS_DECELERATION_ANIMATION_H nux-4.0.6+14.04.20140409/Nux/KineticScrolling/VelocityCalculator.cpp0000644000015301777760000000565712321344237025303 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include "VelocityCalculator.h" #include using namespace nux; VelocityCalculator::VelocityCalculator() { Reset(); } #include void VelocityCalculator::ProcessMovement(int movement) { if (samples_read_ == -1) { samples_read_ = samples_write_; } else if (samples_read_ == samples_write_) { /* the oldest value is going to be overwritten. so now the oldest will be the next one. */ samples_read_ = (samples_read_ + 1) % MAX_SAMPLES; } samples_[samples_write_].mov = movement; samples_[samples_write_].time = g_get_monotonic_time() / 1000; samples_write_ = (samples_write_ + 1) % MAX_SAMPLES; } float VelocityCalculator::CalculateVelocity() const { if (NumSamples() < 2) return 0.0f; int last_index; if (samples_write_ == 0) last_index = MAX_SAMPLES - 1; else last_index = samples_write_ - 1; int64_t curr_time = samples_[last_index].time; int total_time = 0; int total_distance = 0; int sample_index = (samples_read_ + 1) % MAX_SAMPLES; int64_t previous_time = samples_[samples_read_].time; while (sample_index != samples_write_) { // Skip this sample if it's too old if (curr_time - samples_[sample_index].time <= AGE_OLDEST_SAMPLE) { int delta_time = samples_[sample_index].time - previous_time; total_distance += samples_[sample_index].mov; total_time += delta_time; } previous_time = samples_[sample_index].time; sample_index = (sample_index + 1) % MAX_SAMPLES; } return float(total_distance) / float(total_time); } void VelocityCalculator::Reset() { samples_read_ = -1; samples_write_ = 0; } int VelocityCalculator::NumSamples() const { if (samples_read_ == -1) { return 0; } else { if (samples_write_ == 0) { /* consider only what's to the right of samples_read_ (including himself) */ return MAX_SAMPLES - samples_read_; } else if (samples_write_ == samples_read_) return MAX_SAMPLES; /* buffer is full */ else if (samples_write_ < samples_read_) return (MAX_SAMPLES - samples_read_) + samples_write_; else return samples_write_ - samples_read_; } } nux-4.0.6+14.04.20140409/Nux/KineticScrolling/KineticScroller.cpp0000644000015301777760000001536512321344237024564 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include "KineticScroller.h" #include "KineticAxisScroller.h" #include "AxisDecelerationAnimation.h" #include "VelocityCalculator.h" #include #include "KineticScrollingTickSource.h" using namespace nux; /***************************************************************************** * Private class *****************************************************************************/ class KineticScroller::Private : public sigc::trackable { public: Private(); Private(kinetic_scrolling::TickSourceInterface *tick_source); void Init(); void SetViewportSize(int width, int height); void SetContentSize(int width, int height); void SetContentPosition(int x, int y); void ProcessFingerDown(); void ProcessFingerUp(); void ProcessFingerDrag(int dx, int dy); void UpdateAnimations(int time); void CheckChangesInContentPosition(); bool CanScrollHorizontally() const; bool CanScrollVertically() const; ScrollableDirections scrollable_directions_; std::unique_ptr tick_source_; sigc::signal *content_position_changed; KineticAxisScroller scroller_x_; KineticAxisScroller scroller_y_; int last_content_pos_x_; int last_content_pos_y_; }; KineticScroller::Private::Private() { tick_source_.reset(new kinetic_scrolling::TimerTickSource); Init(); } KineticScroller::Private::Private(kinetic_scrolling::TickSourceInterface *tick_source) { tick_source_.reset(tick_source); Init(); } void KineticScroller::Private::Init() { scrollable_directions_ = ScrollableDirectionsAuto; tick_source_->tick.connect( sigc::mem_fun(this, &KineticScroller::Private::UpdateAnimations)); } void KineticScroller::Private::SetViewportSize(int width, int height) { scroller_x_.SetViewportLength(width); scroller_y_.SetViewportLength(height); } void KineticScroller::Private::SetContentSize(int width, int height) { scroller_x_.SetContentLength(width); scroller_y_.SetContentLength(height); } void KineticScroller::Private::SetContentPosition(int x, int y) { scroller_x_.SetContentPosition(x); scroller_y_.SetContentPosition(y); last_content_pos_x_ = x; last_content_pos_y_ = y; } void KineticScroller::Private::ProcessFingerDown() { if (CanScrollHorizontally()) scroller_x_.ProcessFingerDown(); if (CanScrollVertically()) scroller_y_.ProcessFingerDown(); tick_source_->Stop(); } void KineticScroller::Private::ProcessFingerUp() { if (CanScrollHorizontally()) scroller_x_.ProcessFingerUp(); if (CanScrollVertically()) scroller_y_.ProcessFingerUp(); if (scroller_x_.NeedTimeUpdates() || scroller_y_.NeedTimeUpdates()) tick_source_->Start(); } void KineticScroller::Private::ProcessFingerDrag(int dx, int dy) { if (CanScrollHorizontally()) scroller_x_.ProcessFingerDrag(dx); if (CanScrollVertically()) scroller_y_.ProcessFingerDrag(dy); CheckChangesInContentPosition(); } void KineticScroller::Private::UpdateAnimations(int delta_time) { if (scroller_x_.NeedTimeUpdates()) scroller_x_.UpdateTime(delta_time); if (scroller_y_.NeedTimeUpdates()) scroller_y_.UpdateTime(delta_time); CheckChangesInContentPosition(); if (!scroller_x_.NeedTimeUpdates() && !scroller_y_.NeedTimeUpdates()) tick_source_->Stop(); } void KineticScroller::Private::CheckChangesInContentPosition() { if (last_content_pos_x_ != scroller_x_.GetContentPosition() || last_content_pos_y_ != scroller_y_.GetContentPosition()) { content_position_changed->emit(scroller_x_.GetContentPosition(), scroller_y_.GetContentPosition()); } last_content_pos_x_ = scroller_x_.GetContentPosition(); last_content_pos_y_ = scroller_y_.GetContentPosition(); } bool KineticScroller::Private::CanScrollHorizontally() const { return scrollable_directions_ == ScrollableDirectionsHorizontal || scrollable_directions_ == ScrollableDirectionsHorizontalAndVertical || (scrollable_directions_ == ScrollableDirectionsAuto && scroller_x_.GetViewportLength() < scroller_x_.GetContentLength()); } bool KineticScroller::Private::CanScrollVertically() const { return scrollable_directions_ == ScrollableDirectionsVertical || scrollable_directions_ == ScrollableDirectionsHorizontalAndVertical || (scrollable_directions_ == ScrollableDirectionsAuto && scroller_y_.GetViewportLength() < scroller_y_.GetContentLength()); } /***************************************************************************** * Public class *****************************************************************************/ KineticScroller::KineticScroller() : p(new Private) { p->content_position_changed = &content_position_changed; } KineticScroller::KineticScroller(kinetic_scrolling::TickSourceInterface *tick_source) : p(new Private(tick_source)) { p->content_position_changed = &content_position_changed; } KineticScroller::~KineticScroller() { delete p; } void KineticScroller::SetViewportSize(int width, int height) { p->SetViewportSize(width, height); } void KineticScroller::SetContentSize(int width, int height) { p->SetContentSize(width, height); } void KineticScroller::SetContentPosition(int x, int y) { p->SetContentPosition(x, y); } void KineticScroller::SetBoundsBehavior(BoundsBehavior bounds_behavior) { p->scroller_x_.SetBoundsBehavior(bounds_behavior); p->scroller_y_.SetBoundsBehavior(bounds_behavior); } void KineticScroller::SetScrollableDirections( ScrollableDirections scrollable_directions) { p->scrollable_directions_ = scrollable_directions; } void KineticScroller::ProcessFingerDown() { p->ProcessFingerDown(); } void KineticScroller::ProcessFingerUp() { p->ProcessFingerUp(); } void KineticScroller::ProcessFingerDrag(int dx, int dy) { p->ProcessFingerDrag(dx, dy); } KineticScrollerAxisState KineticScroller::GetHorizontalAxisState() const { return p->scroller_x_.GetState(); } KineticScrollerAxisState KineticScroller::GetVerticalAxisState() const { return p->scroller_y_.GetState(); } nux-4.0.6+14.04.20140409/Nux/KineticScrolling/KineticScrollingTickSource.h0000644000015301777760000000425712321344237026372 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_KS_TICK_SOURCE_H #define NUX_KS_TICK_SOURCE_H #include #include /***** * OBS: Would be good have animation::TickSource used instead of this, * but that's not posssible at the moment. ****/ namespace nux { namespace kinetic_scrolling { /*! A class that emits a signal at constant intervals. */ class TickSourceInterface { public: virtual ~TickSourceInterface() {} virtual void Start() = 0; virtual void Stop() = 0; /*! Emitted at a constant frequency. Its parameter is the time elapsed since the previous tick or, if this is the very first tick, since the tick source was started, in milliseconds. */ sigc::signal tick; }; /*! A TickSource implemented using nux::TimerHandler It's way more convenient and testable to use this than nux::TimerHandler if all you want is something that calls you at regular intervals. */ class TimerTickSource : public TickSourceInterface { public: TimerTickSource(); virtual ~TimerTickSource(); virtual void Start(); virtual void Stop(); private: /* update period in milliseconds */ static const int UPDATE_PERIOD = 16 /* 60 fps */; void Tick(void*); void TimerExpired(void*); TimerHandle timer_handle_; TimerFunctor timer_functor_; int64_t last_elapsed_time_; }; } // namespace kinetic_scrolling } // namespace nux #endif // NUX_KS_TICK_SOURCE_H nux-4.0.6+14.04.20140409/Nux/Nux.cpp0000644000015301777760000002620012321344237016765 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/NuxGraphics.h" namespace nux { static NCriticalSection ThreadArrayLock; std::vector ThreadArray; void NuxInitialize(const char * /* CommandLine */) { nux::NuxCoreInitialize(0); nux::NuxGraphicsInitialize(); // Register a thread local store for the WindowThreads. Each window thread will be able to access its own WindowThread pointer. inlRegisterThreadLocalIndex(0, ThreadLocal_InalogicAppImpl, NULL); } static WindowThread *_CreateModalWindowThread(const char *window_title, int width, int height, WindowThread *parent, ThreadUserInitFunc /* user_init_func */, void * /* data */, bool Modal) { // check that Parent exist WindowThread *w = new WindowThread(window_title, width, height, parent, Modal); if (w == 0) { nuxDebugMsg("[_CreateModalWindowThread] WindowThread creation failed."); return NULL; } return w; } WindowThread *CreateGUIThread(const char *window_title, int width, int height, WindowThread *parent, ThreadUserInitFunc user_init_func, void *data) { return CreateNuxWindow(window_title, width, height, WINDOWSTYLE_NORMAL, parent, false, user_init_func, data); } WindowThread *CreateNuxWindow(const char *window_title, int width, int height, WindowStyle window_border_style, AbstractThread *parent, bool modal, ThreadUserInitFunc user_init_func, void *data) { if (GetWindowThread()) { // An WindowThread already exist for this thread. nuxDebugMsg("[CreateGUIThread] You may have only one Nux window per system thread."); return NULL; } modal = (modal && parent && parent->Type().IsObjectType(WindowThread::StaticObjectType)); if (width <= WindowThread::MINIMUM_WINDOW_WIDTH) { width = WindowThread::MINIMUM_WINDOW_WIDTH; } if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT) { height = WindowThread::MINIMUM_WINDOW_HEIGHT; } WindowThread *w = new WindowThread(window_title, width, height, parent, modal); if (w == NULL) { nuxDebugMsg("[CreateGUIThread] WindowThread creation failed."); return NULL; } w->user_init_func_ = user_init_func; w->user_exit_func_ = 0; w->initialization_data_ = data; w->window_style_ = window_border_style; w->ThreadCtor(); return w; } WindowThread *CreateNuxWindowNewThread(const char *window_title, int width, int height, WindowStyle window_border_style, AbstractThread *parent, bool modal, ThreadUserInitFunc user_init_func, void *data) { modal = (modal && parent && parent->Type().IsObjectType(WindowThread::StaticObjectType)); if (width <= WindowThread::MINIMUM_WINDOW_WIDTH) { width = WindowThread::MINIMUM_WINDOW_WIDTH; } if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT) { height = WindowThread::MINIMUM_WINDOW_HEIGHT; } WindowThread *w = new WindowThread(window_title, width, height, parent, modal); if (w == NULL) { nuxDebugMsg("[CreateNuxWindowNewThread] WindowThread creation failed."); return NULL; } w->user_init_func_ = user_init_func; w->user_exit_func_ = 0; w->initialization_data_ = data; w->window_style_ = window_border_style; // Do not call WindowThread::ThreadCtor(); return w; } #if defined(NUX_OS_WINDOWS) WindowThread* CreateFromForeignWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext, ThreadUserInitFunc user_init_func, void *data) { if (GetWindowThread()) { // An WindowThread already exist for this thread. nuxDebugMsg("[CreateGUIThread] You may have only one Nux window per system thread."); return NULL; } WindowThread *w = new WindowThread("WindowTitle", 400, 300, 0, true); if (w == 0) { nuxDebugMsg("[CreateGUIThread] WindowThread creation failed."); return NULL; } w->user_init_func_ = user_init_func; w->user_exit_func_ = 0; w->initialization_data_ = data; w->window_style_ = WINDOWSTYLE_NORMAL; w->embedded_window_ = true; w->ThreadCtor(WindowHandle, WindowDCHandle, OpenGLRenderingContext); return w; } #elif defined(NO_X11) #elif defined(NUX_OS_LINUX) #ifdef NUX_OPENGLES_20 WindowThread *CreateFromForeignWindow (Window X11Window, EGLContext OpenGLContext, ThreadUserInitFunc user_init_func, void *data) #else WindowThread *CreateFromForeignWindow (Window X11Window, GLXContext OpenGLContext, ThreadUserInitFunc user_init_func, void *data) #endif { if (GetWindowThread()) { // An WindowThread already exist for this thread. nuxDebugMsg("[CreateGUIThread] You may have only one Nux window per system thread."); return 0; } WindowThread *w = new WindowThread("WindowTitle", 400, 300, 0, true); if (w == 0) { nuxDebugMsg("[CreateGUIThread] WindowThread creation failed."); return NULL; } w->user_init_func_ = user_init_func; w->user_exit_func_ = 0; w->initialization_data_ = data; w->window_style_ = WINDOWSTYLE_NORMAL; w->embedded_window_ = true; w->ThreadCtor(NULL, X11Window, OpenGLContext); return w; } #endif // Create a window thread that is a child of the Parent. This thread has a window. WindowThread *CreateWindowThread(WindowStyle WndStyle, const char *window_title, int width, int height, WindowThread *parent, ThreadUserInitFunc user_init_func, void *data) { if (width <= WindowThread::MINIMUM_WINDOW_WIDTH) { width = WindowThread::MINIMUM_WINDOW_WIDTH; } if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT) { height = WindowThread::MINIMUM_WINDOW_HEIGHT; } WindowThread *w = _CreateModalWindowThread(window_title, width, height, parent, user_init_func, data, false); if (w == 0) { nuxDebugMsg("[CreateWindowThread] WindowThread creation failed."); return NULL; } w->user_init_func_ = user_init_func; w->user_exit_func_ = 0; w->initialization_data_ = data; w->window_style_ = WndStyle; return w; } // Create modal graphics thread that is a child of the Parent. This thread has a window. WindowThread *CreateModalWindowThread(WindowStyle WndStyle, const char *window_title, int width, int height, WindowThread *parent, ThreadUserInitFunc user_init_func, void *data) { if (width <= WindowThread::MINIMUM_WINDOW_WIDTH) { width = WindowThread::MINIMUM_WINDOW_WIDTH; } if (height <= WindowThread::MINIMUM_WINDOW_HEIGHT) { height = WindowThread::MINIMUM_WINDOW_HEIGHT; } WindowThread *w = _CreateModalWindowThread(window_title, width, height, parent, user_init_func, data, true); if (w == 0) { nuxDebugMsg("[CreateWindowThread] WindowThread creation failed."); return NULL; } w->user_init_func_ = user_init_func; w->user_exit_func_ = 0; w->initialization_data_ = data; w->window_style_ = WndStyle; return w; } SystemThread *CreateSystemThread(AbstractThread *parent, ThreadUserInitFunc user_init_func, void *data) { SystemThread *system_thread = new SystemThread(parent); if (system_thread == 0) { nuxDebugMsg("[CreateSimpleThread] SystemThread creation failed."); return NULL; } system_thread->user_init_func_ = user_init_func; system_thread->user_exit_func_ = 0; system_thread->initialization_data_ = data; return system_thread; } bool RegisterNuxThread(NThread *ThreadPtr) { nuxAssert(ThreadPtr); NUX_RETURN_VALUE_IF_NULL(ThreadPtr, false); NScopeLock Scope(&ThreadArrayLock); std::vector::iterator it = find(ThreadArray.begin(), ThreadArray.end(), ThreadPtr); if (it == ThreadArray.end()) { ThreadArray.push_back(ThreadPtr); } return true; } void UnregisterNuxThread(NThread *ThreadPtr) { nuxAssert(ThreadPtr); NUX_RETURN_IF_NULL(ThreadPtr); NScopeLock Scope(&ThreadArrayLock); std::vector::iterator it = find(ThreadArray.begin(), ThreadArray.end(), ThreadPtr); if (it != ThreadArray.end()) { ThreadArray.erase(it); } } ObjectPtr GetSysFont() { return GetWindowThread()->GetGraphicsEngine().GetFont(); } ObjectPtr GetSysBoldFont() { return GetWindowThread()->GetGraphicsEngine().GetBoldFont(); } WindowCompositor &GetWindowCompositor() { NThread *thread = GetWindowThread(); if (thread && !thread->Type().IsObjectType(WindowThread::StaticObjectType)) { nuxDebugMsg("[GetWindowCompositor] You can't call GetWindowCompositor on this type of thread: s", thread->Type().name ); PrintOutputDebugString("[GetWindowCompositor] You can't call GetWindowCompositor on this type of thread: s", thread->Type().name ); NUX_HARDWARE_BREAK; } return (static_cast (thread))->GetWindowCompositor(); } WindowThread *GetWindowThread() { return GetThreadNuxWindow(); } WindowThread *GetThreadNuxWindow() { NThread *thread = static_cast (inlGetThreadLocalStorage(ThreadLocal_InalogicAppImpl)); return NUX_STATIC_CAST(WindowThread *, thread); } BasePainter& GetPainter() { NThread *thread = GetWindowThread(); return NUX_STATIC_CAST(WindowThread *, thread)->GetPainter(); } UXTheme& GetTheme() { NThread *thread = GetWindowThread(); return NUX_STATIC_CAST(WindowThread *, thread)->GetTheme(); } TimerHandler& GetTimer() { NThread *thread = GetWindowThread(); return NUX_STATIC_CAST(WindowThread *, thread)->GetTimerHandler(); } } nux-4.0.6+14.04.20140409/Nux/TextLoader.h0000644000015301777760000000245312321344237017737 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith */ #ifndef NUX_TEXTLOADER_H #define NUX_TEXTLOADER_H #include // FIXME namespace nux { class TextLoader { public: enum TextAlignment { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, }; TextLoader(); ~TextLoader(); Property alignment; Property color; Property font_name; Property text; Property font_size; Property width; Property minimum_width; Property lines; ObjectPtr CreateTexture(); private: struct Impl; Impl* pimpl; }; } #endifnux-4.0.6+14.04.20140409/Nux/GestureBroker.h0000644000015301777760000000357712321344237020457 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #ifndef NUX_GESTURE_BROKER_H #define NUX_GESTURE_BROKER_H #include "Features.h" #ifdef NUX_GESTURES_SUPPORT #include #include "Gesture.h" namespace nux { /*! Receives GestureEvents and delivers them to the appropriate gesture targets. */ class GestureBroker : public sigc::trackable { public: GestureBroker(); virtual ~GestureBroker(); void ProcessGestureBegin(nux::GestureEvent &event); void ProcessGestureUpdate(nux::GestureEvent &event); void ProcessGestureEnd(nux::GestureEvent &event); private: bool BindNewGestureToTarget(nux::GestureEvent &event, ShPtGestureTarget target); void ResolveBufferedGestureThatFinishedConstruction( std::shared_ptr &gesture); /*! Finds the targets of the gesture from the given gesture event. */ std::vector virtual FindGestureTargets(const nux::GestureEvent &event) = 0; GestureSet gesture_set_; std::map , sigc::connection> gesture_lost_all_targets_connections_; }; } // namespace nux #endif // NUX_GESTURES_SUPPORT #endif // NUX_GESTURE_BROKER_H nux-4.0.6+14.04.20140409/Nux/HScrollBar.cpp0000644000015301777760000003233212321344237020211 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "HScrollBar.h" namespace nux { const int HSCROLLBAR_WIDTH = 10; const int HSCROLLBAR_HEIGHT = 10; HScrollBar::HScrollBar(NUX_FILE_LINE_DECL) : ScrollBar(NUX_FILE_LINE_PARAM) { content_width_ = 0; content_height_ = 0; container_width_ = 0; container_height_ = 0; m_TrackWidth = 0; m_TrackHeight = 0; m_SlideBarOffsetX = 0; m_SlideBarOffsetY = 0; content_offset_x_ = 0; content_offset_y_ = 0; b_MouseUpTimer = false; b_MouseDownTimer = false; m_color_factor = 1.0f; m_LeftTimerHandler = 0; m_RightTimerHandler = 0; hlayout = new HLayout(NUX_TRACKER_LOCATION); _scroll_left_button = new BasicView(NUX_TRACKER_LOCATION); _track = new BasicView(NUX_TRACKER_LOCATION); _scroll_right_button = new BasicView(NUX_TRACKER_LOCATION); _slider = new BasicView(NUX_TRACKER_LOCATION); _slider->SetParentObject(this); // Set Original State SetMinimumSize(AREA_MIN_WIDTH, HSCROLLBAR_HEIGHT); SetMaximumSize(AREA_MAX_WIDTH, HSCROLLBAR_HEIGHT); // Set Signals _scroll_right_button->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::RecvStartScrollRight)); _scroll_right_button->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::RecvEndScrollRight)); _scroll_left_button->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::RecvStartScrollLeft)); _scroll_left_button->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::RecvEndScrollLeft)); _slider->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::OnSliderMouseDown)); _slider->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::OnSliderMouseUp)); _slider->mouse_drag.connect(sigc::mem_fun(this, &HScrollBar::OnSliderMouseDrag)); _track->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::RecvTrackMouseDown)); _track->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::RecvTrackMouseUp)); _track->mouse_drag.connect(sigc::mem_fun(this, &HScrollBar::RecvTrackMouseDrag)); // Set Geometry _scroll_right_button->SetMinimumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT); _scroll_right_button->SetMaximumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT); _scroll_right_button->SetGeometry(Geometry(0, 0, HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT)); _scroll_left_button->SetMinimumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT); _scroll_left_button->SetMaximumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT); _scroll_left_button->SetGeometry(Geometry(0, 0, HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT)); hlayout->AddView(_scroll_left_button, 0, eCenter, eFix); hlayout->AddView(_track, 1, eCenter, eFull); hlayout->AddView(_scroll_right_button, 0, eCenter, eFix); callback = new TimerFunctor; callback->tick.connect(sigc::mem_fun(this, &HScrollBar::HScrollBarHandler)); left_callback = new TimerFunctor; left_callback->tick.connect(sigc::mem_fun(this, &HScrollBar::ScrollLeft)); right_callback = new TimerFunctor; right_callback->tick.connect(sigc::mem_fun(this, &HScrollBar::ScrollRight)); trackleft_callback = new TimerFunctor; trackleft_callback->tick.connect(sigc::mem_fun(this, &HScrollBar::TrackLeft)); trackright_callback = new TimerFunctor; trackright_callback->tick.connect(sigc::mem_fun(this, &HScrollBar::TrackRight)); SetLayout(hlayout); SetAcceptMouseWheelEvent(true); } HScrollBar::~HScrollBar() { _slider->UnReference(); delete callback; delete left_callback; delete trackleft_callback; delete right_callback; delete trackright_callback; } void HScrollBar::HScrollBarHandler(void *v) { HScrollBar *scrollbar = static_cast (v); if (scrollbar->b_MouseUpTimer && scrollbar->m_color_factor < 1) { scrollbar->m_color_factor += 0.1f; if (scrollbar->m_color_factor >= 1) { scrollbar->m_color_factor = 1; scrollbar->b_MouseUpTimer = false; } else { scrollbar->QueueDraw(); GetTimer().AddOneShotTimer(10, callback, scrollbar); } } if (scrollbar->b_MouseDownTimer && scrollbar->m_color_factor > 0) { scrollbar->m_color_factor -= 0.09f; if (scrollbar->m_color_factor <= 0) { scrollbar->m_color_factor = 0; scrollbar->b_MouseUpTimer = false; } else { scrollbar->QueueDraw(); GetTimer().AddOneShotTimer(10, callback, scrollbar); } } } void HScrollBar::ScrollRight(void * /* v */) { OnScrollRight.emit(m_ScrollUnit, 1); if (AtMaximum()) RecvEndScrollRight(0, 0, 0, 0); else m_RightTimerHandler = GetTimer().AddOneShotTimer(10, right_callback, this); QueueDraw(); } void HScrollBar::ScrollLeft(void * /* v */) { OnScrollLeft.emit(m_ScrollUnit, 1); if (AtMaximum()) RecvEndScrollLeft(0, 0, 0, 0); else m_LeftTimerHandler = GetTimer().AddOneShotTimer(10, left_callback, this); QueueDraw(); } void HScrollBar::TrackLeft(void * /* v */) { if (m_TrackMouseCoord.x < _slider->GetBaseX() - _track->GetBaseX()) { OnScrollLeft.emit(container_width_, 1); m_TrackLeftTimerHandler = GetTimer().AddOneShotTimer(10, trackleft_callback, this); QueueDraw(); } } void HScrollBar::TrackRight(void * /* v */) { if (m_TrackMouseCoord.x > _slider->GetBaseX() + _slider->GetBaseWidth() - _track->GetBaseX()) { OnScrollRight.emit(container_width_, 1); m_TrackRightTimerHandler = GetTimer().AddOneShotTimer(10, trackright_callback, this); QueueDraw(); } } void HScrollBar::RecvStartScrollLeft(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (!AtMinimum()) ScrollLeft(this); } void HScrollBar::RecvStartScrollRight(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (!AtMaximum()) ScrollRight(this); } void HScrollBar::RecvEndScrollRight(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_RightTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_RightTimerHandler); m_RightTimerHandler = 0; } void HScrollBar::RecvEndScrollLeft(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_LeftTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_LeftTimerHandler); m_LeftTimerHandler = 0; } void HScrollBar::RecvTrackMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { m_TrackMouseCoord = Point(x, y); int X = _slider->GetBaseX() - _track->GetBaseX(); if (x < X) { // move the slide bar up TrackLeft(this); } else { TrackRight(this); // move the slide bar down } } void HScrollBar::RecvTrackMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_TrackLeftTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_TrackLeftTimerHandler); if (m_TrackRightTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_TrackRightTimerHandler); m_TrackLeftTimerHandler = 0; m_TrackRightTimerHandler = 0; } void HScrollBar::RecvTrackMouseDrag(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } Area* HScrollBar::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; NUX_RETURN_VALUE_IF_TRUE(_scroll_right_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_right_button); NUX_RETURN_VALUE_IF_TRUE(_scroll_left_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_left_button); NUX_RETURN_VALUE_IF_TRUE(_slider->TestMousePointerInclusion(mouse_position, event_type), _slider); NUX_RETURN_VALUE_IF_TRUE(_track->TestMousePointerInclusion(mouse_position, event_type), _track); if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } void HScrollBar::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); GetPainter().PaintBackground(graphics_engine, base); base.OffsetPosition(HSCROLLBAR_WIDTH, 0); base.OffsetSize(-2 * HSCROLLBAR_WIDTH, 0); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_SCROLLBAR_TRACK), eHSCROLLBAR, false); GetPainter().PaintShape(graphics_engine, _scroll_left_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_LEFT); GetPainter().PaintShape(graphics_engine, _scroll_right_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_RIGHT); GetPainter().PaintShape(graphics_engine, _slider->GetGeometry(), Color(0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f), eHSCROLLBAR, true); }; void HScrollBar::SetContainerSize(int /* x */, int /* y */, int w, int h) { // x and y are not needed container_width_ = w; container_height_ = h; ComputeScrolling(); } void HScrollBar::SetContentSize(int /* x */, int /* y */, int w, int h) { // x and y are not needed content_width_ = w; content_height_ = h; ComputeScrolling(); } void HScrollBar::SetContentOffset(float dx, float dy) { content_offset_x_ = dx; content_offset_y_ = dy; ComputeScrolling(); } void HScrollBar::ComputeScrolling() { if (content_width_ == 0) { visibility_percentage_ = 100.0f; } else { visibility_percentage_ = Clamp(100.0f * (float) container_width_ / (float) content_width_, 0.0f, 100.0f); } m_TrackWidth = _track->GetBaseWidth(); int slider_height = _scroll_left_button->GetBaseHeight(); int slider_width = m_TrackWidth * visibility_percentage_ / 100.0f; if (slider_width < 15) { slider_width = 15; } _slider->SetBaseWidth(slider_width); _slider->SetBaseHeight(slider_height); _slider->SetBaseY(_scroll_left_button->GetBaseY()); float pct; if (content_width_ - container_width_ > 0) pct = - (float) content_offset_x_ / (float) (content_width_ - container_width_); else pct = 0; int x = _track->GetBaseX() + pct * (m_TrackWidth - slider_width); _slider->SetBaseX(x); } ///////////////// // RECEIVERS // ///////////////// void HScrollBar::SetValue(float /* value */) { //m_ValueString.setCaption(value); } void HScrollBar::SetParameterName(const char * /* parameter_name */) { //m_ParameterName.setCaption(parameter_name); } //////////////// // EMITTERS // //////////////// void HScrollBar::OnSliderMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { m_SliderDragPositionX = x; m_SliderDragPositionY = y; //sigVScrollBarSliderMouseDown.emit(); b_MouseDownTimer = true; b_MouseUpTimer = false; GetTimer().AddOneShotTimer(10, callback, this); } void HScrollBar::OnSliderMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { b_MouseDownTimer = false; b_MouseUpTimer = true; GetTimer().AddOneShotTimer(10, callback, this); } void HScrollBar::OnSliderMouseDrag(int x, int /* y */, int dx, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (_track->GetBaseWidth() - _slider->GetBaseWidth() > 0) { stepX = (float) (content_width_ - container_width_) / (float) (_track->GetBaseWidth() - _slider->GetBaseWidth()); } else { return; } if ((dx > 0) && (x > m_SliderDragPositionX)) { OnScrollRight.emit(stepX, x - m_SliderDragPositionX); } if ((dx < 0) && (x < m_SliderDragPositionX)) { OnScrollLeft.emit(stepX, m_SliderDragPositionX - x); } } bool HScrollBar::AtMaximum() { if (_slider->GetBaseX() + _slider->GetBaseWidth() == _track->GetBaseX() + _track->GetBaseWidth()) return TRUE; return FALSE; } bool HScrollBar::AtMinimum() { if (_slider->GetBaseX() == _track->GetBaseX()) return TRUE; return FALSE; } long HScrollBar::PostLayoutManagement(long LayoutResult) { long ret = ScrollBar::PostLayoutManagement(LayoutResult); ComputeScrolling(); return ret; } } nux-4.0.6+14.04.20140409/Nux/SystemThread.cpp0000644000015301777760000000775112321344237020641 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #if defined(NUX_OS_WINDOWS) #include "NuxGraphics/GraphicsDisplay.h" #elif defined(NUX_OS_LINUX) #include "NuxGraphics/GraphicsDisplay.h" #endif #include "NuxGraphics/GraphicsEngine.h" #include "ClientArea.h" #include "WindowCompositor.h" #include "TimerProc.h" #include "WindowCompositor.h" #include "WindowThread.h" #include "SystemThread.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(SystemThread); SystemThread::SystemThread(AbstractThread *Parent/* = 0*/) : AbstractThread(Parent) { } SystemThread::~SystemThread() { } ThreadState SystemThread::Start(void * /* arg */) { if (!parent_) { return NThread::Start(); } else { if (parent_->Type().IsObjectType(SystemThread::StaticObjectType)) return static_cast (parent_)->StartChildThread(this, true); if (parent_->Type().IsObjectType(WindowThread::StaticObjectType)) return static_cast (parent_)->StartChildThread(this, true); nuxAssertMsg(0, "[WindowThread::Start] This should not happen."); return THREAD_START_ERROR; } } int SystemThread::Run(void * /* arg */) { if (user_init_func_) { (*user_init_func_) (this, initialization_data_); } if (parent_) { if (parent_->Type().IsObjectType(SystemThread::StaticObjectType)) static_cast (parent_)->ChildHasFinished(this); if (parent_->Type().IsObjectType(WindowThread::StaticObjectType)) static_cast (parent_)->ChildHasFinished(this); } SetThreadState(THREADSTOP); TerminateChildThreads(); return 0; } ThreadState SystemThread::StartChildThread(AbstractThread *thread, bool /* Modal */) { ThreadState state = thread->NThread::Start(); //if(state == THREADRUNNING) AddChildThread(thread); return state; } void SystemThread::AddChildThread(AbstractThread *thread) { nuxAssert(thread); std::list::iterator it; it = find(children_thread_list_.begin(), children_thread_list_.end(), thread); if (it == children_thread_list_.end()) { children_thread_list_.push_back(thread); } } void SystemThread::RemoveChildThread(AbstractThread *window) { nuxAssert(window); std::list::iterator it; it = find(children_thread_list_.begin(), children_thread_list_.end(), window); if (it != children_thread_list_.end()) { children_thread_list_.erase(it); } } void SystemThread::ChildHasFinished(AbstractThread *thread) { RemoveChildThread(thread); if (thread->Type().IsObjectType(WindowThread::StaticObjectType)) { //SuspendChildGraphics(static_cast(thread)); } thread->SetThreadState(THREADSTOP); } void SystemThread::TerminateChildThreads() { std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); it++) { (*it)->SetThreadState(THREADSTOP); } children_thread_list_.clear(); } bool SystemThread::ThreadCtor() { SetThreadState(THREADRUNNING); return true; } bool SystemThread::ThreadDtor() { return true; } } nux-4.0.6+14.04.20140409/Nux/VScrollBar.h0000644000015301777760000001076112321344237017676 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef VSCROLLBAR_H #define VSCROLLBAR_H #include "TimerProc.h" #include "ScrollBar.h" namespace nux { class VLayout; class VScrollBar: public ScrollBar { public: VScrollBar(NUX_FILE_LINE_PROTO); ~VScrollBar(); virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); void DrawDownTriangle(GraphicsEngine &graphics_engine, int width, int height, const Geometry &geo, BasePainter &painter); void DrawUpTriangle(GraphicsEngine &graphics_engine, int width, int height, const Geometry &geo, BasePainter &painter); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); private: virtual void DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) {}; void VScrollBarHandler(void *v); void ScrollDown(void *v); void ScrollUp(void *v); void TrackUp(void *v); void TrackDown(void *v); public: void SetContainerSize(int x, int y, int w, int h); void SetContentSize(int x, int y, int w, int h); void SetContentOffset(float dx, float dy); void ComputeScrolling(); ///////////////// // RECEIVERS // ///////////////// void SetValue(float value); void SetParameterName(const char *parameter_name); //////////////// // EMITTERS // //////////////// void RecvStartScrollDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvStartScrollUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvEndScrollDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvEndScrollUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTrackMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTrackMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTrackMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnSliderMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnSliderMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnSliderMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); /////////////// // SIGNALS // /////////////// sigc::signal sigClick; sigc::signal OnScrollUp; sigc::signal OnScrollDown; sigc::signal sigVScrollBarSliderMouseDown; bool b_MouseDownTimer; bool b_MouseUpTimer; float m_color_factor; protected: // When the Scrollbar is used standalone, it is necessary to call ComputeScrolling at the end of the layout. virtual long PostLayoutManagement(long LayoutResult); bool AtMinimum(); bool AtMaximum(); VLayout *vlayout; BasicView *_slider; BasicView *_scroll_up_button; BasicView *_scroll_down_button; BasicView *_track; int content_width_; int content_height_; float content_offset_x_; float content_offset_y_; int container_width_; int container_height_; int m_TrackWidth; int m_TrackHeight; int m_SlideBarOffsetX; int m_SlideBarOffsetY; float stepX; float stepY; int m_SliderDragPositionX; int m_SliderDragPositionY; TimerFunctor *callback; TimerFunctor *up_callback; TimerFunctor *down_callback; TimerFunctor *trackup_callback; TimerFunctor *trackdown_callback; TimerHandle m_UpTimerHandler; TimerHandle m_DownTimerHandler; TimerHandle m_TrackUpTimerHandler; TimerHandle m_TrackDownTimerHandler; Point m_TrackMouseCoord; friend class VLayout; friend class ScrollView; }; } #endif // HSCROLLBAR_H nux-4.0.6+14.04.20140409/Nux/EditTextBox.cpp0000644000015301777760000003424412321344237020425 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "EditTextBox.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "Validator.h" namespace nux { EditTextBox::EditTextBox(const char *Caption, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { m_Validator = NULL; BlinkCursor = false; m_ScrollTimerHandler = 0; m_BlinkTimerFunctor = 0; m_WriteAlpha = true; m_Prefix = ""; m_Suffix = ""; key_nav_mode_ = false; text_input_mode_ = false; SetGeometry(Geometry(0, 0, 3 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); SetGeometry(Geometry(0, 0, 3 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); mouse_down.connect(sigc::mem_fun(this, &EditTextBox::RecvMouseDown)); mouse_drag.connect(sigc::mem_fun(this, &EditTextBox::RecvMouseDrag)); mouse_up.connect(sigc::mem_fun(this, &EditTextBox::RecvMouseUp)); mouse_double_click.connect(sigc::mem_fun(this, &EditTextBox::RecvMouseDoubleClick)); key_down.connect(sigc::mem_fun(this, &EditTextBox::RecvKeyEvent)); begin_key_focus.connect(sigc::mem_fun(this, &EditTextBox::RecvStartKeyFocus)); end_key_focus.connect(sigc::mem_fun(this, &EditTextBox::RecvEndKeyFocus)); SetText(Caption); SetTextColor(color::White); m_BackgroundColor = Color(0xFF343434); //COLOR_TEXTEDIT_BACKGROUNG; m_SelectedTextColor = Color(0xFFFAFAFA); m_SelectedTextBackgroundColor = Color(0xFF777777); m_TextBlinkColor = Color(0xFF003D0A); m_CursorColor = Color(0xFFDDDDDD); hlayout = new HLayout(NUX_TRACKER_LOCATION); SetLayout(hlayout); m_BlinkTimerFunctor = new TimerFunctor(); m_BlinkTimerFunctor->tick.connect(sigc::mem_fun(this, &EditTextBox::BlinkCursorTimerInterrupt)); m_ScrollTimerFunctor = new TimerFunctor(); m_ScrollTimerFunctor->tick.connect(sigc::mem_fun(this, &EditTextBox::ScrollTimerInterrupt)); SetAcceptKeyboardEvent(true); EnableDoubleClick(true); } EditTextBox::~EditTextBox() { delete m_BlinkTimerFunctor; delete m_ScrollTimerFunctor; delete m_Validator; if (m_BlinkTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_BlinkTimerHandler); m_BlinkTimerHandler = 0; } void EditTextBox::ScrollTimerInterrupt(void * /* v */) { Geometry base = GetGeometry(); const Event& event = GetGraphicsDisplay()->GetCurrentEvent(); int X = event.x; m_KeyboardHandler.CaretAutoScroll(event.x, event.y, base); if (((X < base.x) && (m_KeyboardHandler.GetCursorPosition() > 0)) || ((X > base.x + base.GetWidth()) && (m_KeyboardHandler.GetCursorPosition() < m_KeyboardHandler.GetLength()))) { m_ScrollTimerHandler = GetTimer().AddOneShotTimer(50, m_ScrollTimerFunctor, this); } else { GetTimer().RemoveTimerHandler(m_BlinkTimerHandler); m_ScrollTimerHandler = 0; } // While the mouse is selecting the text, no blinking of cursor StopBlinkCursor(false); StartBlinkCursor(false); QueueDraw(); } void EditTextBox::BlinkCursorTimerInterrupt(void * /* v */) { GetTimer().RemoveTimerHandler(m_BlinkTimerHandler); m_BlinkTimerHandler = GetTimer().AddOneShotTimer(500, m_BlinkTimerFunctor, this); BlinkCursor = !BlinkCursor; QueueDraw(); } void EditTextBox::StopBlinkCursor(bool BlinkState) { GetTimer().RemoveTimerHandler(m_BlinkTimerHandler); m_BlinkTimerHandler = 0; BlinkCursor = BlinkState; QueueDraw(); } void EditTextBox::StartBlinkCursor(bool BlinkState) { m_BlinkTimerHandler = GetTimer().AddOneShotTimer(500, m_BlinkTimerFunctor, this); BlinkCursor = BlinkState; QueueDraw(); } void EditTextBox::SetValidator(const Validator *validator) { nuxAssert(validator != 0); delete m_Validator; m_Validator = validator->Clone(); } void EditTextBox::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); { graphics_engine.PushClippingRectangle(base); GetPainter().Paint2DQuadColor(graphics_engine, base, Color(m_BackgroundColor)); if (HasKeyboardFocus()) { GetPainter().PaintColorTextLineEdit(graphics_engine, GetGeometry(), m_KeyboardHandler.GetTextLine(), GetTextColor(), m_WriteAlpha, m_SelectedTextColor, m_SelectedTextBackgroundColor, m_TextBlinkColor, m_CursorColor, !BlinkCursor, m_KeyboardHandler.GetCursorPosition(), m_KeyboardHandler.GetPositionX(), m_KeyboardHandler.GetTextSelectionStart(), m_KeyboardHandler.GetTextSelectionEnd() ); } else { GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), GetGeometry(), m_KeyboardHandler.GetTextLine(), GetTextColor()); } } graphics_engine.PopClippingRectangle(); } void EditTextBox::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void EditTextBox::SetText(const char *Caption) { std::string s(Caption); SetText(s); } void EditTextBox::SetText(const std::string &Caption) { std::string s(Caption); size_t pos = s.find(m_Prefix, 0); if (pos == 0) { s.erase(0, m_Prefix.size()); } pos = s.rfind(m_Suffix); if (pos != std::string::npos && pos == s.size() - m_Suffix.size()) { s.erase(pos); } if (ValidateKeyboardEntry(s.c_str())) { m_Text = (m_Prefix + s) + m_Suffix; m_KeyboardHandler.SetText(m_Text); m_temporary_caption = m_Text; sigSetText.emit(this); } QueueDraw(); } const char *EditTextBox::GetText() const { return m_Text.c_str(); } //! Return a caption string striping out the prefix and the suffix std::string EditTextBox::GetCleanText() const { std::string CleanText(m_Text); size_t pos = CleanText.find(m_Prefix, 0); if (pos == 0) { CleanText.erase(0, m_Prefix.size()); } pos = CleanText.rfind(m_Suffix); if (pos != std::string::npos && pos == CleanText.size() - m_Suffix.size()) { CleanText.erase(pos); } return CleanText; } void EditTextBox::RecvMouseDoubleClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { m_KeyboardHandler.SelectAllText(); QueueDraw(); } void EditTextBox::RecvMouseUp(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { m_KeyboardHandler.MouseUp(x, y); if (m_ScrollTimerHandler.IsValid()) { GetTimer().RemoveTimerHandler(m_ScrollTimerHandler); m_ScrollTimerHandler = 0; } QueueDraw(); } void EditTextBox::RecvMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (HasKeyboardFocus() == false) { // First mouse down m_KeyboardHandler.EnterFocus(); } else { // Second mouse down and more m_KeyboardHandler.UnselectAllText(); m_KeyboardHandler.MouseDown(x, y); // Always make the cursor visible when a mouse down happens. StopBlinkCursor(false); StartBlinkCursor(false); } QueueDraw(); } void EditTextBox::RecvMouseDrag(int x, int y, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { Geometry base = GetGeometry(); int X = x + base.x; if ((!m_ScrollTimerHandler.IsValid()) && ((X < base.x) || (X > base.x + base.GetWidth()))) { m_ScrollTimerHandler = GetTimer().AddOneShotTimer(25, m_ScrollTimerFunctor, this); } else if ((X >= base.x) && (X < base.x + base.GetWidth())) { m_KeyboardHandler.MouseDrag(x, y); // While the mouse is selecting the text, no blinking of cursor StopBlinkCursor(false); StartBlinkCursor(false); } QueueDraw(); } long EditTextBox::PostLayoutManagement(long LayoutResult) { long ret = View::PostLayoutManagement(LayoutResult); m_KeyboardHandler.SetClipRegion(GetGeometry()); return ret; } void EditTextBox::RecvKeyEvent( unsigned long eventType , /*event type*/ unsigned long keysym , /*event keysym*/ unsigned long state , /*event state*/ const char* character , /*character*/ unsigned short /* keyCount */ /*key repeat count*/) { if (eventType == NUX_KEYDOWN) text_input_mode_ = true; m_KeyboardHandler.ProcessKey(eventType, keysym, state, character[0], GetGeometry()); // When a key event happens, show the cursor. StopBlinkCursor(false); // Start a new blink cycle with the cursor originally visible. StartBlinkCursor(false); if (character) { sigCharacter.emit(this, character[0]); sigEditChange.emit(this); } if (keysym == NUX_VK_ENTER || keysym == NUX_KP_ENTER) { std::string str(m_KeyboardHandler.GetTextLine()); size_t pos = str.rfind(m_Suffix); if (pos != std::string::npos && pos == str.size() - m_Suffix.size()) { str.erase(pos); } if (ValidateKeyboardEntry(str.c_str())) { m_Text = m_KeyboardHandler.GetTextLine(); m_temporary_caption = m_Text; sigValidateKeyboardEntry.emit(this, m_Text); sigValidateEntry.emit(this); m_KeyboardHandler.SelectAllText(); } else { m_Text = m_temporary_caption; m_KeyboardHandler.SetText(m_Text); m_KeyboardHandler.SelectAllText(); } } if (keysym == NUX_VK_ESCAPE) { text_input_mode_ = false; } QueueDraw(); } bool EditTextBox::ValidateKeyboardEntry(const char *text) const { if (m_Validator) { if (m_Validator->Validate(text) == Validator::Acceptable) { return true; } else { return false; } } return true; } void EditTextBox::EscapeKeyboardFocus() { // todo(jaytaoko): SetKeyboardFocus(false); // Revert back the caption text m_Text = m_temporary_caption; sigEscapeKeyboardFocus.emit(this); QueueDraw(); } void EditTextBox::EnteringKeyboardFocus() { m_KeyboardHandler.SetText(m_Text); m_KeyboardHandler.SelectAllText(); // Preserve the current caption text. If ESC is pressed while we have keyboard focus then // the previous caption text is restored m_temporary_caption = m_Text; sigStartKeyboardFocus.emit(this); QueueDraw(); } void EditTextBox::QuitingKeyboardFocus() { std::string CleanText(m_KeyboardHandler.GetTextLine()); size_t pos = CleanText.find(m_Prefix, 0); if (pos == 0) { CleanText.erase(0, m_Prefix.size()); } pos = CleanText.rfind(m_Suffix); if (pos != std::string::npos && pos == CleanText.size() - m_Suffix.size()) { CleanText.erase(pos); } if (ValidateKeyboardEntry(CleanText.c_str())) { CleanText = m_Prefix + CleanText; CleanText = CleanText + m_Suffix; m_Text = CleanText; //m_KeyboardHandler.GetTextLine(); m_KeyboardHandler.SetText(CleanText); m_temporary_caption = m_Text; sigValidateKeyboardEntry.emit(this, m_Text); sigValidateEntry.emit(this); } else { m_Text = m_temporary_caption; m_KeyboardHandler.SetText(m_Text); m_KeyboardHandler.SelectAllText(); } QueueDraw(); } void EditTextBox::RecvStartKeyFocus() { key_nav_mode_ = true; text_input_mode_ = false; EnteringKeyboardFocus(); m_BlinkTimerHandler = GetTimer().AddOneShotTimer(500, m_BlinkTimerFunctor, this); } void EditTextBox::RecvEndKeyFocus() { key_nav_mode_ = false; text_input_mode_ = false; QuitingKeyboardFocus(); GetTimer().RemoveTimerHandler(m_BlinkTimerHandler); m_BlinkTimerHandler = 0; BlinkCursor = false; } void EditTextBox::SetDoubleValue(double d) { SetText(std::to_string((long double)d)); } void EditTextBox::SetIntegerValue(int i) { SetText(std::to_string((long long)i)); } void EditTextBox::SetTextBackgroundColor(const Color &color) { m_BackgroundColor = color; QueueDraw(); } Color EditTextBox::GetTextBackgroundColor() const { return m_BackgroundColor; } bool EditTextBox::IsEmpty() { if (m_Text == "") { return true; } return false; } bool EditTextBox::InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* /* character */) { if ((eventType == NUX_KEYDOWN) && (key_nav_mode_ == true) && (text_input_mode_ == false)) { if (keysym == NUX_VK_ENTER || keysym == NUX_KP_ENTER || keysym == NUX_VK_UP || keysym == NUX_VK_DOWN || keysym == NUX_VK_LEFT || keysym == NUX_VK_RIGHT || keysym == NUX_VK_LEFT_TAB || keysym == NUX_VK_TAB) { return false; } } if ((eventType == NUX_KEYDOWN) && (key_nav_mode_ == false) && (text_input_mode_ == false)) { return false; } return true; } } nux-4.0.6+14.04.20140409/Nux/Layout.cpp0000644000015301777760000006303612321344237017500 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "View.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(Layout); NUX_IMPLEMENT_OBJECT_TYPE(SpaceLayout); Layout::Layout(NUX_FILE_LINE_DECL) : Area(NUX_FILE_LINE_PARAM) { space_between_children_ = 0; left_padding_ = 0; right_padding_ = 0; top_padding_ = 0; bottom_padding_ = 0; m_contentWidth = 0; m_contentHeight = 0; m_ContentStacking = eStackExpand; draw_cmd_queued_ = false; child_draw_cmd_queued_ = false; SetMinimumSize(1, 1); } Layout::~Layout() { // It is possible that this layout object is in the refresh list. Remove // it here before it is deleted. WindowThread* wt = GetWindowThread(); if (wt) wt->RemoveObjectFromLayoutQueue(this); std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { (*it)->UnParentObject(); } _layout_element_list.clear(); } int Layout::GetLeftPadding() const { return left_padding_; } int Layout::GetRightPadding() const { return right_padding_; } int Layout::GetTopPadding() const { return top_padding_; } int Layout::GetBottomPadding() const { return bottom_padding_; } void Layout::SetLeftAndRightPadding(int padding) { #if DEBUG_LAYOUT return; #endif left_padding_ = padding < 0 ? 0 : padding; right_padding_ = padding < 0 ? 0 : padding; } void Layout::SetLeftAndRightPadding(int left, int right) { #if DEBUG_LAYOUT return; #endif left_padding_ = left < 0 ? 0 : left; right_padding_ = right < 0 ? 0 : right; } void Layout::SetTopAndBottomPadding(int padding) { #if DEBUG_LAYOUT return; #endif top_padding_ = padding < 0 ? 0 : padding; bottom_padding_ = padding < 0 ? 0 : padding; } void Layout::SetTopAndBottomPadding(int top, int bottom) { #if DEBUG_LAYOUT return; #endif top_padding_ = top < 0 ? 0 : top; bottom_padding_ = bottom < 0 ? 0 : bottom; } void Layout::SetPadding(int padding) { top_padding_ = padding < 0 ? 0 : padding; bottom_padding_ = top_padding_; right_padding_ = top_padding_; left_padding_ = top_padding_; } void Layout::SetPadding(int top_bottom_padding, int left_right_padding) { top_padding_ = top_bottom_padding < 0 ? 0 : top_bottom_padding; bottom_padding_ = top_padding_; right_padding_ = left_right_padding < 0 ? 0 : left_right_padding; left_padding_ = right_padding_; } void Layout::SetPadding(int top, int right, int bottom, int left) { top_padding_ = top < 0 ? 0 : top; right_padding_ = right < 0 ? 0 : right; bottom_padding_ = bottom < 0 ? 0 : bottom; left_padding_ = left < 0 ? 0 : left; } //! Deprecated. Use SetLeftAndRightPadding. void Layout::SetHorizontalExternalMargin(int padding) { SetLeftAndRightPadding(padding); } //! Deprecated. Use SetTopAndBottomPadding, void Layout::SetVerticalExternalMargin(int padding) { SetTopAndBottomPadding(padding); } void Layout::RemoveChildObject(Area *bo) { std::list::iterator it; it = std::find(_layout_element_list.begin(), _layout_element_list.end(), bo); if (it != _layout_element_list.end()) { /* we need to emit the signal before the un-parent, just in case one of the callbacks wanted to use this object */ ViewRemoved.emit(this, bo); bo->UnParentObject(); _layout_element_list.erase(it); } } bool Layout::FindWidget(Area *WidgetObject) const { std::list::const_iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it) == WidgetObject) { return true; } } return false; } bool Layout::IsEmpty() const { return (_layout_element_list.size() == 0); } // If(stretchfactor == 0): the WidgetLayout geometry will be set to SetGeometry(0,0,1,1); // and the children will take their natural size by expending WidgetLayout. // If the parent of WidgetLayout offers more space, it won't be used by WidgetLayout. void Layout::AddLayout(Layout *layout, unsigned int stretchFactor, MinorDimensionPosition minor_position, MinorDimensionSize minor_size, float percentage, LayoutPosition index) { nuxAssertMsg(layout != 0, "[Layout::AddView] Invalid parameter."); NUX_RETURN_IF_TRUE(layout == 0); // Should never happen nuxAssertMsg(layout != this, "[Layout::AddLayout] Error: Trying to add a layout to itself."); NUX_RETURN_IF_FALSE(layout != 0); Area *parent = layout->GetParentObject(); nuxAssertMsg(parent == 0, "[Layout::AddLayout] Trying to add an object that already has a parent."); NUX_RETURN_IF_TRUE(parent != 0); nuxAssertMsg(index >= 0, "[Layout::AddLayout] Invalid index position. Adding at the beginning of the list.."); layout->SetScaleFactor(stretchFactor); layout->SetPositioning(minor_position); layout->SetExtend(minor_size); if (percentage < 1.0f) { layout->SetPercentage(1.0f); } else if (percentage > 100.0f) { layout->SetPercentage(100.0f); } else { layout->SetPercentage(percentage); } layout->SetParentObject(this); layout->child_queue_draw.connect(sigc::mem_fun(this, &Layout::ChildQueueDraw)); layout->queue_draw.connect(sigc::mem_fun(this, &Layout::ChildQueueDraw)); if (index < 0) index = NUX_LAYOUT_BEGIN; if (index == NUX_LAYOUT_END || index >= _layout_element_list.size()) { _layout_element_list.push_back(layout); } else { std::list::iterator pos = _layout_element_list.begin(); int idx = index; while (pos != _layout_element_list.end() && idx > 0) { idx--; pos++; } _layout_element_list.insert(pos, layout); } ViewAdded.emit(this, layout); } //! Add an object to the layout. /*! Add an object to the layout. A baseobject minor dimension with respect to a layout object is the dimension opposite to the layout flow. A baseobject major dimension with respect to a layout object is the dimension aligned with the layout flow. A layout object minor dimension is the dimension opposite to the layout flow. A layout object major dimension is the dimension aligned with the layout flow. Add an object to the layout. The added object get its size and position managed by the layout. When a baseobject is added with a stretches factor equal to 0, its major dimension assumes its minimum value. For instance, if the layout is a vertical layout and the added object has a stretch factor equal 0, then during the layout, the added object height will be set to its minimum value using ApplyMinHeight(). The minor_position parameter controls how the layout will place the object within itself. A vertical layout object controls the horizontal positioning of its children baseobjects, While an horizontal layout object controls the vertical positioning of its children baseobjects. The minor_size parameter controls how much size the baseobject minor dimension gets from the layout minor dimension. See MinorDimensionSize. /param baseobject The object that is being added. /param stretchFactor This value controls how the layout object share space between its children baseobject. /param minor_position Controls how the layout position the object. /param minor_size Controls the object minor dimension size. /param percentage Controls the object minor dimension size in percentage of the layout minor dimension size. /param index Controls the object position in the layout children. */ void Layout::AddView(Area *bo, unsigned int stretchFactor, MinorDimensionPosition minor_position, MinorDimensionSize minor_size, float percentage, LayoutPosition index) { nuxAssertMsg(bo != 0, "[Layout::AddView] Invalid parameter."); NUX_RETURN_IF_TRUE(bo == 0); if (!bo->IsView()) return; Area *parent = bo->GetParentObject(); nuxAssertMsg(parent == 0, "[Layout::AddView] Trying to add an object that already has a parent."); NUX_RETURN_IF_TRUE(parent != 0); nuxAssertMsg(index >= 0, "[Layout::AddView] Invalid index position. Adding at the beginning of the list.."); bo->SetScaleFactor(stretchFactor); bo->SetPositioning(minor_position); bo->SetExtend(minor_size); if (percentage < 1.0f) { bo->SetPercentage(1.0f); } else if (percentage > 100.0f) { bo->SetPercentage(100.0f); } else { bo->SetPercentage(percentage); } bo->SetParentObject(this); if (bo->IsView()) { static_cast (bo)->queue_draw.connect(sigc::mem_fun(this, &Layout::ChildQueueDraw)); static_cast (bo)->child_queue_draw.connect(sigc::mem_fun(this, &Layout::ChildQueueDraw)); } //if(HasFocusControl() && HasFocusableEntries() == false) //{ //bo->SetFocused(true); //ChildFocusChanged(this, bo); //} if (index < 0) index = NUX_LAYOUT_BEGIN; if (index == NUX_LAYOUT_END || index >= _layout_element_list.size()) { _layout_element_list.push_back(bo); } else { #if defined(NUX_OS_WINDOWS) && !defined(NUX_VISUAL_STUDIO_2010) std::list::iterator pos = _layout_element_list.begin(); #else auto pos = _layout_element_list.begin(); #endif int idx = index; while (pos != _layout_element_list.end() && idx > 0) { idx--; pos++; } _layout_element_list.insert(pos, bo); } ViewAdded.emit(this, bo); //--->> Removed because it cause problem with The splitter widget: ComputeContentSize(); } void Layout::AddSpace(unsigned int /* width */, unsigned int stretchFactor, LayoutPosition /* index */) { AddLayout(new SpaceLayout(), stretchFactor); } void Layout::Clear() { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { (*it)->UnParentObject(); } _layout_element_list.clear(); } bool Layout::SearchInAllSubNodes(Area *bo) { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it) == bo) { return true; } else if ((*it)->IsLayout()) { Layout *layout = NUX_STATIC_CAST(Layout *, (*it)); if (layout->SearchInAllSubNodes(bo)) { return true; } } } return false; } bool Layout::SearchInFirstSubNodes(Area *bo) { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it) == bo) { return true; } } return false; } unsigned int Layout::GetMaxStretchFactor() { unsigned int value = 0; unsigned int sf; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { sf = (*it)->GetScaleFactor(); if (sf >= value) { value = sf; } } return value; } unsigned int Layout::GetMinStretchFactor() { unsigned int value = 0xFFFFFFFF; unsigned int sf; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { sf = (*it)->GetScaleFactor(); if (sf <= value) { value = sf; } } return value; } unsigned int Layout::GetNumStretchFactor(unsigned int sf) { unsigned int count = 0; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->GetScaleFactor() == sf) { count++; } } return count; } void Layout::DoneRedraw() { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsView()) { View *ic = NUX_STATIC_CAST(View *, (*it)); ic->DoneRedraw(); } } } Area* Layout::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible() && (*it)->GetInputEventSensitivity()) { Area* hit_view = NUX_STATIC_CAST(Area*, (*it)->FindAreaUnderMouse(mouse_position, event_type)); if (hit_view) return hit_view; } } return NULL; } void Layout::ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw) { std::list::iterator it; if (RedirectRenderingToTexture()) { if (update_backup_texture_ || force_draw || draw_cmd_queued_) { GetPainter().PushPaintLayerStack(); BeginBackupTextureRendering(graphics_engine, force_draw); { graphics_engine.PushModelViewMatrix(Get2DMatrix()); for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; if ((*it)->IsView()) { View* view = static_cast(*it); view->ProcessDraw(graphics_engine, force_draw); } else if ((*it)->IsLayout()) { Layout* layout = static_cast(*it); layout->ProcessDraw(graphics_engine, force_draw); } } graphics_engine.PopModelViewMatrix(); } EndBackupTextureRendering(graphics_engine, force_draw); GetPainter().PopPaintLayerStack(); } if (PresentRedirectedView()) { unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; // Be a good citizen, get a copy of the current GPU sates according to Nux graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); TexCoordXForm texxform; //Geometry xform_geo = GetGraphicsDisplay()->GetGraphicsEngine()->ModelViewXFormRect(GetGeometry()); if ((force_draw || draw_cmd_queued_) && background_texture_.IsValid()) { graphics_engine.GetRenderStates().SetBlend(false); texxform.FlipVCoord(true); // Draw the background of this view. GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(GetX(), GetY(), background_texture_->GetWidth(), background_texture_->GetHeight(), background_texture_, texxform, color::White); } texxform.uwrap = TEXWRAP_CLAMP; texxform.vwrap = TEXWRAP_CLAMP; texxform.FlipVCoord(true); graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(GetX(), GetY(), GetWidth(), GetHeight(), backup_texture_, texxform, Color(color::White)); // Be a good citizen, restore the Nux blending states. graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } } else { graphics_engine.PushModelViewMatrix(Get2DMatrix()); // Clip against the padding region. Geometry clip_geo = GetGeometry(); clip_geo.OffsetPosition(left_padding_, top_padding_); clip_geo.OffsetSize(-left_padding_ - right_padding_, -top_padding_ - bottom_padding_); graphics_engine.PushClippingRectangle(clip_geo); for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; if ((*it)->IsView()) { View* view = static_cast(*it); view->ProcessDraw(graphics_engine, force_draw); } else if ((*it)->IsLayout()) { Layout* layout = static_cast(*it); layout->ProcessDraw(graphics_engine, force_draw); } } graphics_engine.PopClippingRectangle(); graphics_engine.PopModelViewMatrix(); } ResetQueueDraw(); } void Layout::BeginBackupTextureRendering(GraphicsEngine& graphics_engine, bool force_draw) { ObjectPtr active_fbo_texture; if (force_draw || draw_cmd_queued_) { // Get the active fbo color texture active_fbo_texture = GetGraphicsDisplay()->GetGpuDevice()->ActiveFboTextureAttachment(0); } Geometry xform_geo; // Compute position in the active fbo texture. xform_geo = graphics_engine.ModelViewXFormRect(GetGeometry()); // Get the current fbo... prev_fbo_ = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); // ... and the size of the view port rectangle. prev_viewport_ = graphics_engine.GetViewportRect(); const int width = GetWidth(); const int height = GetHeight(); // Compute intersection with active fbo. Geometry intersection = xform_geo; if (active_fbo_texture.IsValid()) { Geometry active_fbo_geo(0, 0, active_fbo_texture->GetWidth(), active_fbo_texture->GetHeight()); intersection = active_fbo_geo.Intersect(xform_geo); } if (backup_fbo_.IsNull()) { // Create the fbo before using it for the first time. backup_fbo_ = GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject(); } if (!backup_texture_.IsValid() || (backup_texture_->GetWidth() != width) || (backup_texture_->GetHeight() != height)) { // Create or resize the color and depth textures before using them. backup_texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); backup_depth_texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } if (!background_texture_.IsValid() || (background_texture_->GetWidth() != intersection.width) || (background_texture_->GetHeight() != intersection.height)) { background_texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(intersection.width, intersection.height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); } // Draw the background on the previous fbo texture if ((force_draw || draw_cmd_queued_) && background_texture_.IsValid()) { backup_fbo_->FormatFrameBufferObject(intersection.width, intersection.height, BITFMT_R8G8B8A8); backup_fbo_->EmptyClippingRegion(); graphics_engine.SetViewport(0, 0, intersection.width, intersection.height); graphics_engine.SetOrthographicProjectionMatrix(intersection.width, intersection.height); // Set the background texture in the fbo backup_fbo_->SetTextureAttachment(0, background_texture_, 0); backup_fbo_->SetDepthTextureAttachment(ObjectPtr(0), 0); backup_fbo_->Activate(); graphics_engine.SetViewport(0, 0, background_texture_->GetWidth(), background_texture_->GetHeight()); // Clear surface CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); CHECKGL(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); TexCoordXForm texxform; texxform.uoffset = xform_geo.x / (float) active_fbo_texture->GetWidth(); texxform.voffset = xform_geo.y / (float) active_fbo_texture->GetHeight(); texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); texxform.flip_v_coord = true; // Temporarily change the model-view matrix to copy the texture background texture. // This way we are not affceted by the regular model-view matrix. graphics_engine.SetModelViewMatrix(Matrix4::IDENTITY()); // Copy the texture from the previous fbo attachment into our background texture. if (copy_previous_fbo_for_background_) { graphics_engine.QRP_1Tex(0, 0, intersection.width, intersection.height, active_fbo_texture, texxform, color::White); } else { graphics_engine.QRP_Color(0, 0, intersection.width, intersection.height, Color(0.0f, 0.0f, 0.0f, 0.0f)); } // Restore the model-view matrix. graphics_engine.ApplyModelViewMatrix(); } backup_fbo_->FormatFrameBufferObject(width, height, BITFMT_R8G8B8A8); backup_fbo_->EmptyClippingRegion(); backup_fbo_->SetTextureAttachment(0, backup_texture_, 0); backup_fbo_->SetDepthTextureAttachment(backup_depth_texture_, 0); backup_fbo_->Activate(); if (force_draw || draw_cmd_queued_) { CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); CHECKGL(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); } graphics_engine.SetViewport(0, 0, width, height); graphics_engine.SetOrthographicProjectionMatrix(width, height); // Transform the geometry of this area through the current model view matrix. This gives the // the position of the view in the active fbo texture. Geometry offset_rect = graphics_engine.ModelViewXFormRect(GetGeometry()); int x_offset = -offset_rect.x; int y_offset = -offset_rect.y; graphics_engine.PushModelViewMatrix(Matrix4::TRANSLATE(x_offset, y_offset, 0)); } void Layout::EndBackupTextureRendering(GraphicsEngine& graphics_engine, bool /* force_draw */) { graphics_engine.PopModelViewMatrix(); if (prev_fbo_.IsValid()) { // Restore the previous fbo prev_fbo_->Activate(); prev_fbo_->ApplyClippingRegion(); } // Release the reference on the previous fbo prev_fbo_.Release(); // Restore the matrices and the view port. graphics_engine.ApplyModelViewMatrix(); graphics_engine.SetOrthographicProjectionMatrix(prev_viewport_.width, prev_viewport_.height); graphics_engine.SetViewport(prev_viewport_.x, prev_viewport_.y, prev_viewport_.width, prev_viewport_.height); } void Layout::QueueDraw() { if (draw_cmd_queued_) { // A draw has already been scheduled. return; } // Report to a parent view with redirect_rendering_to_texture_ set to true that one of its children // needs to be redrawn. PrepareParentRedirectedView(); std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsView()) { View* view = static_cast(*it); view->QueueDraw(); } else if ((*it)->IsLayout()) { Layout* layout = static_cast(*it); layout->QueueDraw(); } } draw_cmd_queued_ = true; queue_draw.emit(this); } bool Layout::IsQueuedForDraw() { return draw_cmd_queued_; } bool Layout::ChildQueuedForDraw() { return child_draw_cmd_queued_; } void Layout::SetContentDistribution(LayoutContentDistribution stacking) { m_ContentStacking = stacking; } LayoutContentDistribution Layout::GetContentDistribution() { return m_ContentStacking; } void Layout::RequestBottomUpLayoutComputation(Area * /* bo_initiator */) { } void Layout::ChildQueueDraw(Area* area) { if (child_draw_cmd_queued_) return; child_draw_cmd_queued_ = true; child_queue_draw.emit(area); } bool Layout::AcceptKeyNavFocus() { return false; } void Layout::ResetQueueDraw() { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsLayout()) { Layout* layout = NUX_STATIC_CAST(Layout*, (*it)); if (layout->ChildQueuedForDraw()) { layout->ResetQueueDraw(); } } else if ((*it)->IsView()) { View* view = NUX_STATIC_CAST(View*, (*it)); if (view->GetLayout()) { view->GetLayout()->ResetQueueDraw(); view->draw_cmd_queued_ = false; view->child_draw_cmd_queued_ = false; } } } draw_cmd_queued_ = false; child_draw_cmd_queued_ = false; update_backup_texture_ = false; } void Layout::GeometryChangePending(bool /* position_about_to_change */, bool /* size_about_to_change */) { if (IsLayoutDone()) QueueDraw(); } void Layout::GeometryChanged(bool /* position_has_changed */, bool size_has_changed) { if (RedirectedAncestor()) { if (size_has_changed) QueueDraw(); return; } if (IsLayoutDone()) QueueDraw(); } #ifdef NUX_GESTURES_SUPPORT Area* Layout::GetInputAreaHitByGesture(const GestureEvent &event) { if (!IsVisible()) return nullptr; if (!IsGestureInsideArea(event)) return nullptr; for (const auto area : _layout_element_list) { Area *area_hit = area->GetInputAreaHitByGesture(event); if (area_hit) return area_hit; } return nullptr; } #endif } nux-4.0.6+14.04.20140409/Nux/XIMCallbacks.cpp0000644000015301777760000001126212321344237020452 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2013 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * */ #include "Nux.h" #include "TextEntry.h" #include "XICClient.h" #include #include "NuxCore/Logger.h" DECLARE_LOGGER(logger, "xim.callbacks"); using namespace std; namespace nux { int const FEEDBACK_MASK = (XIMUnderline | XIMReverse); int XICClient::PreeditStartCallback(XIC xic, XPointer clientdata, XPointer call_data) { TextEntry* text_entry = (TextEntry*)clientdata; if (text_entry) { text_entry->PreeditStarted(); } return 0; } int XICClient::PreeditDoneCallback(XIC xic, XPointer clientdata, XPointer call_data) { TextEntry* text_entry = (TextEntry*)clientdata; if (text_entry) { text_entry->ClearPreedit(); } return 0; } void add_feedback_attr(PangoAttrList* attrs, char const* str, XIMFeedback feedback, int start, int end) { PangoAttribute* attr; int start_index = g_utf8_offset_to_pointer(str, start) - str; int end_index = g_utf8_offset_to_pointer(str, end) - str; if (feedback & XIMUnderline) { attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); attr->start_index = start_index; attr->end_index = end_index; pango_attr_list_insert (attrs, attr); } if (feedback & XIMReverse) { attr = pango_attr_foreground_new(0xFFFF, 0xFFFF, 0xFFFF); attr->start_index = start_index; attr->end_index = end_index; pango_attr_list_insert (attrs, attr); attr = pango_attr_background_new(0x0, 0x0, 0x0); attr->start_index = start_index; attr->end_index = end_index; pango_attr_list_insert (attrs, attr); } if (feedback & ~FEEDBACK_MASK) { LOG_WARN(logger) << "Unrenderer feedback: " << (feedback & ~FEEDBACK_MASK); } } void feedback_to_pango_list(PangoAttrList** attrs, char const* str, int nfeedbacks, XIMFeedback* feedbacks) { XIMFeedback last_feedback = 0; int start = -1; int i = 0; if (attrs) { *attrs = pango_attr_list_new(); for (i = 0; i < nfeedbacks; ++i) { XIMFeedback new_feedback = (feedbacks[i] & FEEDBACK_MASK); if (new_feedback != last_feedback) { last_feedback = new_feedback; start = i; } else { PangoAttribute* attr; int start_index = g_utf8_offset_to_pointer(str, start) - str; int end_index = g_utf8_offset_to_pointer(str, i) - str; attr = pango_attr_foreground_new(0x0, 0x0, 0x0); attr->start_index = start_index; attr->end_index = end_index; pango_attr_list_insert (*attrs, attr); attr = pango_attr_background_new(0xFFFF, 0xFFFF, 0xFFFF); attr->start_index = start_index; attr->end_index = end_index; pango_attr_list_insert (*attrs, attr); } } if (start >= 0) add_feedback_attr(*attrs, str, last_feedback, start, i); } } int XICClient::PreeditDrawCallback(XIC xic, XPointer clientdata, XIMPreeditDrawCallbackStruct* call_data) { TextEntry* text_entry = (TextEntry*)clientdata; if (call_data->text && text_entry) { string preedit; // TODO Actually handle this correctly... if (call_data->text->encoding_is_wchar) { preedit = string(""); } else { preedit = string(call_data->text->string.multi_byte); } PangoAttrList* preedit_attr; feedback_to_pango_list(&preedit_attr, preedit.c_str(), call_data->text->length, call_data->text->feedback); text_entry->UpdatePreeditAttribs(preedit_attr); text_entry->UpdatePreedit(preedit, call_data->caret); } return 0; } } nux-4.0.6+14.04.20140409/Nux/WindowThread.cpp0000644000015301777760000015077712321344237020633 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include #include "Nux.h" #include "Layout.h" #include "NuxCore/Logger.h" #include "NuxGraphics/GraphicsEngine.h" #include "ClientArea.h" #include "WindowCompositor.h" #include "TimerProc.h" #include "SystemThread.h" #include "FloatingWindow.h" #include "WindowThread.h" #include "MainLoopGLib.h" namespace nux { DECLARE_LOGGER(logger, "nux.windows.thread"); TimerFunctor *m_ScrollTimerFunctor; TimerHandle m_ScrollTimerHandler; // Thread registration call. Hidden from the users. Implemented in Nux.cpp bool RegisterNuxThread(NThread *ThreadPtr); void UnregisterNuxThread(NThread *ThreadPtr); const int WindowThread::MINIMUM_WINDOW_WIDTH = 1; const int WindowThread::MINIMUM_WINDOW_HEIGHT = 1; NUX_IMPLEMENT_OBJECT_TYPE(WindowThread); WindowThread::WindowThread(const char *WindowTitle, int width, int height, AbstractThread *Parent, bool Modal) : AbstractThread(Parent) , foreign_frame_frozen_(false) , window_initial_width_(width) , window_initial_height_(height) , window_title_(WindowTitle) , m_WidgetInitialized(false) , window_style_(WINDOWSTYLE_NORMAL) , embedded_window_(false) , window_size_configuration_event_(false) , force_rendering_(false) #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) , external_glib_sources_(new ExternalGLibSources) #endif #ifdef NUX_GESTURES_SUPPORT , geis_adapter_(new GeisAdapter) #endif { // Thread specific objects graphics_display_ = NULL; window_compositor_ = NULL; painter_ = NULL; timer_manager_ = NULL; theme_ = NULL; main_layout_ = NULL; queue_main_layout_ = false; // Protection for ThreadCtor and ThreadDtor; thread_ctor_called_ = false; thread_dtor_called_ = false; // wait_for_modal_window_ = false; modal_window_thread_ = 0; is_modal_window_ = Modal; _inside_layout_cycle = 0; _draw_requested_to_host_wm = false; first_pass_ = true; #if !defined(NUX_MINIMAL) _Timelines = new std::list (); gint64 micro_secs = g_get_real_time(); last_timeline_frame_time_sec_ = micro_secs / 1000000; last_timeline_frame_time_usec_ = micro_secs % 1000000; #endif _MasterClock = NULL; #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) main_loop_glib_ = 0; main_loop_glib_context_ = 0; #endif #if defined(USE_X11) x11display_ = NULL; ownx11display_ = false; #endif _pending_wake_up_timer = false; _inside_main_loop = false; _inside_timer_loop = false; async_wake_up_signal_ = new TimerFunctor(); async_wake_up_signal_->tick.connect(sigc::mem_fun(this, &WindowThread::AsyncWakeUpCallback)); } WindowThread::~WindowThread() { #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) xim_controller_.reset(); CleanupGlibLoop(); #endif ThreadDtor(); #if !defined(NUX_MINIMAL) std::list::iterator li; for (li=_Timelines->begin(); li!=_Timelines->end(); ++li) { (*li)->UnReference(); } delete _Timelines; #endif delete async_wake_up_signal_; #if defined(USE_X11) if (x11display_ && ownx11display_) { XCloseDisplay(x11display_); } #endif } void WindowThread::ExitMainLoop() { #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) StopGLibLoop(); #endif } unsigned int WindowThread::AddTimeout(unsigned int timeout_delay) { #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) return AddGLibTimeout(timeout_delay); #endif } TimerHandle WindowThread::SetAsyncTimerCallback(int time_ms, TimeOutSignal* timeout_signal, void *user_data) { if (timeout_signal == NULL) return TimerHandle(); // Use "this->" because if called from a different thread, GetTimer and GetWindowThread are invalid. TimerHandle handle = this->GetTimerHandler().AddOneShotTimer(time_ms, timeout_signal, user_data, this); return handle; } void WindowThread::AsyncWakeUpCallback(void* /* data */) { this->GetTimerHandler().RemoveTimerHandler(async_wake_up_timer_handle_); _pending_wake_up_timer = false; } void WindowThread::ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw) { if (main_layout_) { bool dirty = main_layout_->IsQueuedForDraw(); if (dirty) { // A main layout re computation has happen. It was not initiated physically by resizing the window. We need to draw the background to // clean any dirty region. int buffer_width = graphics_engine.GetWindowWidth(); int buffer_height = graphics_engine.GetWindowHeight(); GetPainter().PaintBackground(graphics_engine, Geometry(0, 0, buffer_width, buffer_height)); } main_layout_->ProcessDraw(graphics_engine, force_draw || dirty); } } void WindowThread::RequestRedraw() { _draw_requested_to_host_wm = true; RedrawRequested.emit(); if (!IsEmbeddedWindow()) { // If the system is not in embedded mode and an asynchronous request for a Draw is made, // and the system is not in a timer processing cycle(always followed by a draw cycle) // or not in the event processing cycle(also followed by a draw cycle), then we set a 0 delay // timer that will wake up the system and initiate a draw cycle. if ((_inside_main_loop == false) && (_inside_timer_loop == false) && (_pending_wake_up_timer == false)) { _pending_wake_up_timer = true; async_wake_up_timer_handle_ = this->GetTimerHandler().AddOneShotTimer(0, async_wake_up_signal_, this); } } } void WindowThread::ClearRedrawFlag() { _draw_requested_to_host_wm = false; } bool WindowThread::IsRedrawNeeded() const { return _draw_requested_to_host_wm; } void WindowThread::SetLayout(Layout *layout) { main_layout_ = layout; if (main_layout_) { int w = graphics_display_->GetGraphicsEngine()->GetContextWidth(); int h = graphics_display_->GetGraphicsEngine()->GetContextHeight(); main_layout_->Reference(); main_layout_->SetScaleFactor(1); StartLayoutCycle(); main_layout_->SetGeometry(0, 0, w, h); main_layout_->ComputeContentSize(); main_layout_->ComputeContentPosition(0, 0); StopLayoutCycle(); RemoveQueuedLayout(); } } Layout* WindowThread::GetLayout() { return main_layout_; } void WindowThread::QueueLayout() { queue_main_layout_ = true; RequestRedraw(); } void WindowThread::ReconfigureLayout() { int w = graphics_display_->GetGraphicsEngine()->GetWindowWidth(); int h = graphics_display_->GetGraphicsEngine()->GetWindowHeight(); if (main_layout_) { StartLayoutCycle(); main_layout_->SetGeometry(0, 0, w, h); main_layout_->ComputeContentSize(); main_layout_->ComputeContentPosition(0, 0); StopLayoutCycle(); } RemoveQueuedLayout(); queue_main_layout_ = false; } bool WindowThread::QueueObjectLayout(Area *area) { NUX_RETURN_VALUE_IF_NULL(area, false); std::list::iterator it; it = find(_queued_layout_list.begin(), _queued_layout_list.end(), area); if (it == _queued_layout_list.end()) { _queued_layout_list.push_back(area); } return true; } bool WindowThread::RemoveObjectFromLayoutQueue(Area *area) { NUX_RETURN_VALUE_IF_NULL(area, false); std::list::iterator it; it = find(_queued_layout_list.begin(), _queued_layout_list.end(), area); if (it != _queued_layout_list.end()) { _queued_layout_list.erase(it); return true; } return false; } void WindowThread::RemoveQueuedLayout() { _queued_layout_list.clear(); } void WindowThread::ComputeQueuedLayout() { StartLayoutCycle(); std::list::iterator it; for (it = _queued_layout_list.begin(); it != _queued_layout_list.end(); ++it) { Area *area = *it; if (area->Type().IsDerivedFromType(View::StaticObjectType)) { View *view = NUX_STATIC_CAST(View *, area); if (!view->CanBreakLayout()) view->QueueDraw(); } else if (area->Type().IsDerivedFromType(Layout::StaticObjectType)) { Layout *layout = NUX_STATIC_CAST(Layout *, area); layout->QueueDraw(); } else { continue; } (*it)->ComputeContentSize(); } StopLayoutCycle(); RemoveQueuedLayout(); } void WindowThread::StartLayoutCycle() { _inside_layout_cycle = true; } void WindowThread::StopLayoutCycle() { _inside_layout_cycle = false; } bool WindowThread::IsInsideLayoutCycle() const { return _inside_layout_cycle; } void WindowThread::ComputeElementLayout(Area *area, bool recurse_to_top_level_layout) { NUX_RETURN_IF_NULL(area); bool alreadyComputingLayout = IsInsideLayoutCycle(); if ((!alreadyComputingLayout) && (!recurse_to_top_level_layout)) { // When computing the layout, setting the size of widgets may cause the system to recurse // upward an look for the up most container which size is affected by its this area. // This happens in Area::InitiateResizeLayout(); // The search upward is not done if we are already in a layout cycle. StartLayoutCycle(); } if (area->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = NUX_STATIC_CAST(View *, area); ic->QueueDraw(); } else if (area->Type().IsDerivedFromType(Layout::StaticObjectType)) { Layout *layout = NUX_STATIC_CAST(Layout *, area); layout->QueueDraw(); } area->ComputeContentSize(); if (!alreadyComputingLayout) StopLayoutCycle(); } #if !defined(NUX_MINIMAL) void WindowThread::AddTimeline(Timeline *timeline) { _Timelines->push_back(timeline); _Timelines->unique(); StartMasterClock(); } void WindowThread::RemoveTimeline(Timeline *timeline) { _Timelines->remove(timeline); if (_Timelines->empty()) { StopMasterClock(); } } #endif int WindowThread::Run(void * /* ptr */) { if (GetWindowThread() != this) { nuxDebugMsg("Cannot run a several WindowThreads in the same window."); return 1; } if (!IsEmbeddedWindow() && (thread_ctor_called_ == false)) { nuxDebugMsg("Call WindowThread::Start to run this window in its own thread."); return 1; } // Setup the main loop first, so that user_init_func can add new sources // before running it SetupMainLoop(); if (user_init_func_ && (m_WidgetInitialized == false)) { (*user_init_func_) (this, initialization_data_); m_WidgetInitialized = true; } return MainLoop(); } void WindowThread::SetupMainLoop() { if (IsEmbeddedWindow()) { window_compositor_->FormatRenderTargets(graphics_display_->GetWindowWidth(), graphics_display_->GetWindowHeight()); InitGlibLoop(); } else { #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) InitGlibLoop(); #endif } // Called the first time so we can initialize the size of the render targets // At this stage, the size of the window is known. window_compositor_->FormatRenderTargets(graphics_display_->GetWindowWidth(), graphics_display_->GetWindowHeight()); } int WindowThread::MainLoop() { if (IsEmbeddedWindow()) { RunGlibLoop(); return 0; } else { graphics_display_->ShowWindow(); } while (GetThreadState() != THREADSTOP) { if (GetThreadState() == THREADRUNNING) { #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) RunGlibLoop(); #else ExecutionLoop(); #endif if (parent_) { if (parent_->Type().IsObjectType(SystemThread::StaticObjectType)) static_cast (parent_)->ChildHasFinished(this); if (parent_->Type().IsObjectType(WindowThread::StaticObjectType)) static_cast (parent_)->ChildHasFinished(this); { SetThreadState(THREADSTOP); // All children window must be terminated. TerminateChildWindows(); JoinChildThreads(); std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); ++it) { delete (*it); } children_thread_list_.clear(); } } else { SetThreadState(THREADSTOP); // All child window must be terminated. TerminateChildWindows(); JoinChildThreads(); std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); ++it) { delete (*it); } children_thread_list_.clear(); } } else { // Do not sleep. Just return and let the GraphicsDisplay::SwapBuffer do the sleep if necessary. } } return 0; } extern EventToNameStruct EventToName[]; Event WindowThread::GetNextEvent() { Event event; graphics_display_->GetSystemEvent(&event); #if defined(NUX_OS_LINUX) && defined(USE_X11) // Make sure the current xic is synced up with the current event window if ((event.type == KeyPress || event.type == KeyRelease) && event.x11_window && xim_controller_->GetCurrentWindow() != event.x11_window) { xim_controller_->SetFocusedWindow(event.x11_window); graphics_display_->SetCurrentXIC(xim_controller_->GetXIC()); } #endif return event; } #if (!defined(NUX_OS_LINUX) && !defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) || defined(NUX_DISABLE_GLIB_LOOP) #ifdef NUX_GESTURES_SUPPORT Event *WindowThread::FetchNextEvent() { Event *event; if (check_geis_first_) { if (geis_adapter_->ProcessNextEvent(&gesture_event_)) { event = &gesture_event_; } else { graphics_display_->GetSystemEvent(&input_event_); event = &input_event; } } else { if (graphics_display_->GetSystemEvent(&input_event_)) { event = &input_event_; } else { geis_adapter_->ProcessNextEvent(&gesture_event_); event = &gesture_event_; } } // If we are running in a loop and both event buffers (X and GEIS) happens // to have pending events, let's take one from each alternately so that no // buffer overflows. check_geis_first_ = !check_geis_first_; return event; } #endif // NUX_GESTURES_SUPPORT unsigned int WindowThread::ExecutionLoop() { #ifndef NUX_GESTURES_SUPPORT Event event; #endif if (!IsEmbeddedWindow() && graphics_display_->IsPauseThreadGraphicsRendering()) { // Do not sleep. Just return and let the GraphicsDisplay::SwapBuffer do the sleep if necessary. return 0; } while (true) { #ifdef NUX_GESTURES_SUPPORT int result = DoProcessEvent(*FetchNextEvent()); #else graphics_display_->GetSystemEvent(&event); int result = DoProcessEvent(event); #endif #if defined(NUX_OS_LINUX) // select on all of our external fds. We can't use poll () here because // ExectionLoop is designed to be a busy-wait system. In reality we should // probably just drop support for this codepath. // // See https://bugs.launchpad.net/nux/+bug/1111216 fd_set read_fds; FD_ZERO(&read_fds); for (std::list::iterator it = _external_fds.begin(); it != _external_fds.end(); ++it) { nuxAssertMsg(it->fd < FD_SETSIZE, "[nux::WindowThread::ExecutionLoop]"\ " file descriptor overflow, aborting"); FD_SET(it->fd, &read_fds); } // Wait 10 us struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 10; int select_result = select(_external_fds.size(), &read_fds, NULL, NULL, &timeout); nuxAssertMsg(select_result != -1, strerror ("select()")); // Dispatch any active external fds for (std::list::iterator it = _external_fds.begin(); it != _external_fds.end(); ++it) { if (FD_ISSET(it->fd, &read_fds)) it->cb(); } if (result != 1) return result; } return 1; } #else nuxAssertMsg(_external_fds.empty(), "[nux::WindowThread::ExecutionLoop]"\ " external fd support is not implemented on Windows"); #endif // NUX_OS_LINUX #endif // GLIB loop or not unsigned int WindowThread::ProcessEvent(Event &event) { if (!IsEmbeddedWindow() && graphics_display_->IsPauseThreadGraphicsRendering()) { // Do not sleep. Just return and let the GraphicsDisplay::SwapBuffer do the sleep if necessary. return 0; } return DoProcessEvent(event); } unsigned int WindowThread::DoProcessEvent(Event &event) { _inside_main_loop = true; if (first_pass_) { // Reset the timers that were called before the mainloop got initialized. GetTimer().StartEarlyTimerObjects(); } if ((event.type == NUX_DND_ENTER_WINDOW) || (event.type == NUX_DND_LEAVE_WINDOW)) { GetWindowCompositor().ResetDnDArea(); } // Call event inspectors. bool event_discarded = CallEventInspectors(&event); if (event_discarded) { return 1; } if ((event.type == NUX_TERMINATE_APP) || (this->GetThreadState() == THREADSTOP)) { return 0; } if (event.type == NUX_SIZE_CONFIGURATION) { window_size_configuration_event_ = true; Rect r = graphics_display_->GetWindowGeometry(); window_configuration.emit(r.x, r.y, r.width, r.height); } int w, h; // Call gGfx_OpenGL.getWindowSize after the gGfx_OpenGL.get_event. // Otherwise, w and h may not be correct for the current frame if a resizing happened. graphics_display_->GetWindowSize(w, h); if ((event.type == NUX_MOUSE_PRESSED) || (event.type == NUX_MOUSE_RELEASED) || (event.type == NUX_MOUSE_DOUBLECLICK) || (event.type == NUX_MOUSE_MOVE) || (event.type == NUX_SIZE_CONFIGURATION) || (event.type == NUX_KEYDOWN) || (event.type == NUX_KEYUP) || (event.type == NUX_NC_WINDOW_CONFIGURATION) || (event.type == NUX_WINDOW_ENTER_FOCUS) || (event.type == NUX_WINDOW_EXIT_FOCUS) || (event.type == NUX_WINDOW_MOUSELEAVE) || (event.type == NUX_DND_MOVE) || (event.type == NUX_DND_DROP) || (event.type == NUX_DND_ENTER) || (event.type == NUX_DND_LEAVE) || (event.type == NUX_MOUSE_WHEEL) || event.type == EVENT_GESTURE_BEGIN || event.type == EVENT_GESTURE_UPDATE || event.type == EVENT_GESTURE_END) { //DISPATCH EVENT HERE //event.Application = Application; window_compositor_->ProcessEvent(event); } if (event.type == NUX_SIZE_CONFIGURATION) { if (!graphics_display_->isWindowMinimized()) { graphics_display_->SetViewPort(0, 0, event.width, event.height); ReconfigureLayout(); window_compositor_->FormatRenderTargets(event.width, event.height); } window_compositor_->FloatingAreaConfigureNotify(event.width, event.height); window_size_configuration_event_ = true; } // Some action may have caused layouts and areas to request a recompute. // Process them here before the Draw section. if (!graphics_display_->isWindowMinimized() && !IsEmbeddedWindow()) { if (queue_main_layout_) { ReconfigureLayout(); } else { // Compute the layouts that have been queued. ComputeQueuedLayout(); } } _inside_main_loop = false; if (!graphics_display_->IsPauseThreadGraphicsRendering() || IsEmbeddedWindow()) { bool SwapGLBuffer = false; // Warn the host window manager to initiate a draw cycle. bool request_draw_cycle_to_host_wm = false; if (first_pass_) { if (IsEmbeddedWindow()) { request_draw_cycle_to_host_wm = true; force_rendering_ = true; } else { window_compositor_->Draw(window_size_configuration_event_, true); } first_pass_ = false; } else { bool b = (event.type == NUX_MOUSE_PRESSED) || (event.type == NUX_MOUSE_RELEASED) || (event.type == NUX_MOUSE_DOUBLECLICK) || //(event.type == NUX_MOUSE_MOVE) || (event.type == NUX_SIZE_CONFIGURATION) || (event.type == NUX_KEYDOWN) || (event.type == NUX_KEYUP) || (event.type == NUX_NC_WINDOW_CONFIGURATION) || (event.type == NUX_WINDOW_ENTER_FOCUS) || (event.type == NUX_WINDOW_EXIT_FOCUS) || (event.type == NUX_WINDOW_DIRTY); if (b && window_compositor_->IsTooltipActive()) { // Cancel the tooltip since an event that should cause the tooltip to disappear has occurred. window_compositor_->CancelTooltip(); b |= true; } if (!window_compositor_->ValidateMouseInsideTooltipArea(event.x, event.y) && window_compositor_->IsTooltipActive()) { // Cancel the tooltip since an event that should cause the tooltip to disappear has occurred. window_compositor_->CancelTooltip(); b |= true; } if (b || IsRedrawNeeded()) { if (IsEmbeddedWindow()) { request_draw_cycle_to_host_wm = true; } else { window_compositor_->Draw(window_size_configuration_event_, false); } SwapGLBuffer = true; } else if (window_compositor_->GetWidgetDrawingOverlay() != 0) { if (IsEmbeddedWindow()) { request_draw_cycle_to_host_wm = true; } else { window_compositor_->Draw(window_size_configuration_event_, false); } SwapGLBuffer = false; } } if (!IsEmbeddedWindow()) { if (SwapGLBuffer) { // Something was rendered! Swap the rendering buffer! graphics_display_->SwapBuffer(true); } ClearRedrawFlag(); GetWindowThread()->GetGraphicsEngine().ResetStats(); } else if (IsEmbeddedWindow() && (_draw_requested_to_host_wm == false) && request_draw_cycle_to_host_wm) { RequestRedraw(); } window_size_configuration_event_ = false; } return 1; } unsigned int SpawnThread(NThread & /* thread */) { return 0; } bool WindowThread::IsWaitingforModalWindow() const { return wait_for_modal_window_; } bool WindowThread::IsModalWindow() const { return is_modal_window_; } void WindowThread::AddChildThread(AbstractThread *window) { if (window == NULL) return; std::list::iterator it; it = find(children_thread_list_.begin(), children_thread_list_.end(), window); if (it == children_thread_list_.end()) { children_thread_list_.push_back(window); } } void WindowThread::RemoveChildThread(AbstractThread *window) { nuxAssert(window); std::list::iterator it; it = find(children_thread_list_.begin(), children_thread_list_.end(), window); if (it != children_thread_list_.end()) { children_thread_list_.erase(it); } } void WindowThread::ChildHasFinished(AbstractThread *thread) { RemoveChildThread(thread); if (thread->Type().IsObjectType(WindowThread::StaticObjectType)) { SuspendChildGraphics(static_cast (thread)); } thread->SetThreadState(THREADSTOP); } void WindowThread::TerminateChildThreads() { std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); ++it) { (*it)->SetThreadState(THREADSTOP); if ((*it)->Type().IsObjectType(WindowThread::StaticObjectType)) { // Terminate by shutting down the main loop static_cast(*it)->ExitMainLoop(); } if ((*it)->Type().IsObjectType(SystemThread::StaticObjectType)) { // Just kill the thread static_cast(*it)->Stop(true); } } } ThreadState WindowThread::Start(void * /* ptr */) { if (!parent_) { return NThread::Start(); } else { if (parent_->Type().IsObjectType(SystemThread::StaticObjectType)) { return static_cast (parent_)->StartChildThread(this, true); } else if (parent_->Type().IsObjectType(WindowThread::StaticObjectType)) { return static_cast (parent_)->StartChildThread(this, true); } nuxAssertMsg(0, "[WindowThread::Start] This should not happen."); return THREAD_START_ERROR; } } ThreadState WindowThread::StartChildThread(AbstractThread *thread, bool /* Modal */) { if (wait_for_modal_window_) { // This window is already waiting for a modal window. It cannot start another windows. return thread->GetThreadState(); } ThreadState state = thread->NThread::Start(); //if(state == THREADRUNNING) { if (thread->Type().IsObjectType(WindowThread::StaticObjectType)) { // While the child window is being created, the rendering is paused. // This is necessary to active OpenGL objects context sharing. // Cancel the pause by sending the message NUX_THREADMSG_START_RENDERING to this thread. //graphics_display_->PauseThreadGraphicsRendering(); if (static_cast (thread)->is_modal_window_) { DisableMouseKeyboardInput(); modal_window_thread_ = static_cast (thread); // std::list::iterator it; // for (it = children_thread_list_.begin(); it != children_thread_list_.end(); it++) // { // static_cast(*it)->wait_for_modal_window_ = true; // // WIN32: Disable Mouse and Keyboard inputs for all windows child of this window // ::EnableWindow(static_cast(*it)->graphics_display_->GetWindowHandle(), FALSE); // } // // WIN32 // ::EnableWindow(graphics_display_->GetWindowHandle(), FALSE); // wait_for_modal_window_ = true; } static_cast (thread)->wait_for_modal_window_ = false; AddChildThread(thread); } } return state; } ThreadState WindowThread::SuspendChildGraphics(WindowThread *thread) { if (wait_for_modal_window_) { if (modal_window_thread_ != thread) { nuxAssertMsg(0, "[WindowThread::SuspendChildGraphics] cannot supend thread that is not the modal window."); return thread->GetThreadState(); } } ThreadState state = thread->GetThreadState(); if (wait_for_modal_window_) { modal_window_thread_ = 0; EnableMouseKeyboardInput(); // std::list::iterator it; // for (it = children_thread_list_.begin(); it != children_thread_list_.end(); it++) // { // static_cast(*it)->wait_for_modal_window_ = false; // // // WIN32 // ::EnableWindow(static_cast(*it)->graphics_display_->GetWindowHandle(), TRUE); // } } // WIN32 #if defined(NUX_OS_WINDOWS) ::EnableWindow(graphics_display_->GetWindowHandle(), TRUE); #elif defined(NUX_OS_LINUX) #endif return state; } #if !defined(NUX_MINIMAL) bool WindowThread::ProcessTimelines(gint64 micro_secs) { // go through our timelines and tick them // return true if we still have active timelines long msecs; msecs = (micro_secs / 1000000 - last_timeline_frame_time_sec_) * 1000 + (micro_secs % 1000000 - last_timeline_frame_time_usec_) / 1000; if (msecs < 0) { last_timeline_frame_time_sec_ = micro_secs / 1000000; last_timeline_frame_time_usec_ = micro_secs % 1000000; return true; } if (msecs > 0) { last_timeline_frame_time_sec_ += msecs / 1000; last_timeline_frame_time_usec_ += msecs * 1000; } std::list::iterator li; std::list timelines_copy; for (li=_Timelines->begin(); li!=_Timelines->end(); ++li) { (*li)->Reference(); timelines_copy.push_back((*li)); } for(li=timelines_copy.begin(); li!=timelines_copy.end(); ++li) { (*li)->DoTick(msecs); } // unreference again for (li=timelines_copy.begin(); li!=timelines_copy.end(); ++li) (*li)->UnReference(); // return if we have any timelines left return (_Timelines->size() != 0); } #endif void WindowThread::EnableMouseKeyboardInput() { std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); ++it) { if (NUX_STATIC_CAST(WindowThread *, *it)->Type().IsObjectType(WindowThread::StaticObjectType)) { NUX_STATIC_CAST(WindowThread *, *it)->EnableMouseKeyboardInput(); } } // WIN32: Enable Mouse and Keyboard inputs for all windows child of this window #if defined(NUX_OS_WINDOWS) ::EnableWindow(graphics_display_->GetWindowHandle(), TRUE); #elif defined(NUX_OS_LINUX) #endif wait_for_modal_window_ = false; } void WindowThread::DisableMouseKeyboardInput() { std::list::iterator it; for (it = children_thread_list_.begin(); it != children_thread_list_.end(); ++it) { if (NUX_STATIC_CAST(WindowThread *, *it)->Type().IsObjectType(WindowThread::StaticObjectType)) { NUX_STATIC_CAST(WindowThread *, *it)->DisableMouseKeyboardInput(); } } // WIN32: Disable Mouse and Keyboard inputs for all windows child of this window #if defined(NUX_OS_WINDOWS) ::EnableWindow(graphics_display_->GetWindowHandle(), FALSE); #elif defined(NUX_OS_LINUX) #endif wait_for_modal_window_ = true; } bool WindowThread::ThreadCtor() { if(thread_ctor_called_) { nuxDebugMsg("[WindowThread::ThreadCtor] ThreadCtor should not be entered more than once per WindowThread."); return true; } #if defined(NUX_OS_WINDOWS) SetWin32ThreadName(GetThreadId(), window_title_.c_str()); #endif if (RegisterNuxThread(this) == FALSE) { nuxDebugMsg("[WindowThread::ThreadCtor] Failed to register the WindowThread."); return false; } inlSetThreadLocalStorage(ThreadLocal_InalogicAppImpl, this); GraphicsDisplay *parent_window = NULL; if (parent_ && static_cast (parent_)->Type().IsObjectType(WindowThread::StaticObjectType)) { parent_window = &static_cast (parent_)->GetGraphicsDisplay(); } else { parent_window = NULL; } graphics_display_ = gGLWindowManager.CreateGLWindow(window_title_.c_str(), window_initial_width_, window_initial_height_, window_style_, parent_window, false); if (graphics_display_ == NULL) { nuxDebugMsg("[WindowThread::ThreadCtor] Failed to create the window."); return false; } if (parent_ && parent_->Type().IsObjectType(WindowThread::StaticObjectType)) { // Cancel the effect of PauseThreadGraphicsRendering on the parent window. //PostThreadMessage(parent_->GetThreadId(), NUX_THREADMSG_START_RENDERING, (UINT_PTR)((void*)this), 0); } painter_ = new BasePainter(this); timer_manager_ = new TimerHandler(this); window_compositor_ = new WindowCompositor(this); xim_controller_ = std::make_shared(graphics_display_->GetX11Display()); SetThreadState(THREADRUNNING); thread_ctor_called_ = true; return true; } #if defined(NUX_OS_WINDOWS) bool WindowThread::ThreadCtor(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext) { nuxAssertMsg(thread_ctor_called_ == false, "[WindowThread::ThreadCtor] ThreadCtor should not be entered more than once per WindowThread."); if(thread_ctor_called_) { return true; } SetWin32ThreadName(GetThreadId(), window_title_.c_str()); if (RegisterNuxThread(this) == FALSE) { nuxDebugMsg("[WindowThread::ThreadCtor] Failed to register the WindowThread."); return false; } inlSetThreadLocalStorage(ThreadLocal_InalogicAppImpl, this); GraphicsDisplay *ParentWindow = 0; if (parent_ && static_cast (parent_)->Type().IsObjectType(WindowThread::StaticObjectType)) { ParentWindow = &static_cast (parent_)->GetGraphicsDisplay(); } else { ParentWindow = 0; } graphics_display_ = gGLWindowManager.CreateFromForeignWindow(WindowHandle, WindowDCHandle, OpenGLRenderingContext); if (graphics_display_ == 0) { nuxDebugMsg("[WindowThread::ThreadCtor] Failed to create the window."); return false; } if (parent_ && parent_->Type().IsObjectType(WindowThread::StaticObjectType)) { // Cancel the effect of PauseThreadGraphicsRendering on the parent window. //PostThreadMessage(parent_->GetThreadId(), NUX_THREADMSG_START_RENDERING, (UINT_PTR)((void*)this), 0); } painter_ = new BasePainter(this); timer_manager_ = new TimerHandler(this); window_compositor_ = new WindowCompositor(this); SetThreadState(THREADRUNNING); thread_ctor_called_ = true; // Set initial states int w = graphics_display_->GetWindowWidth(); int h = graphics_display_->GetWindowHeight(); graphics_display_->SetViewPort(0, 0, w, h); window_compositor_->FormatRenderTargets(w, h); window_compositor_->FloatingAreaConfigureNotify(w, h); return true; } #elif defined(NO_X11) #elif defined(NUX_OS_LINUX) #ifdef NUX_OPENGLES_20 bool WindowThread::ThreadCtor(Display *X11Display, Window X11Window, EGLContext OpenGLContext) #else bool WindowThread::ThreadCtor(Display *X11Display, Window X11Window, GLXContext OpenGLContext) #endif { nuxAssertMsg(thread_ctor_called_ == false, "[WindowThread::ThreadCtor] ThreadCtor should not be entered more than once per WindowThread."); if(thread_ctor_called_) { return true; } if (RegisterNuxThread(this) == FALSE) { nuxDebugMsg("[WindowThread::ThreadCtor] Failed to register the WindowThread."); return false; } inlSetThreadLocalStorage(ThreadLocal_InalogicAppImpl, this); if (X11Display) { x11display_ = X11Display; ownx11display_ = false; } else { x11display_ = XOpenDisplay(NULL); ownx11display_ = true; } graphics_display_ = gGLWindowManager.CreateFromForeignWindow(x11display_, X11Window, OpenGLContext); if (graphics_display_ == 0) { nuxDebugMsg("[WindowThread::ThreadCtor] Failed to create the window."); return false; } if (parent_ && parent_->Type().IsObjectType(WindowThread::StaticObjectType)) { // Cancel the effect of PauseThreadGraphicsRendering on the parent window. //PostThreadMessage(parent_->GetThreadId(), NUX_THREADMSG_START_RENDERING, (UINT_PTR)((void*)this), 0); } painter_ = new BasePainter(this); timer_manager_ = new TimerHandler(this); window_compositor_ = new WindowCompositor(this); xim_controller_ = std::make_shared(graphics_display_->GetX11Display()); SetThreadState(THREADRUNNING); thread_ctor_called_ = true; // Set initial states int w = graphics_display_->GetWindowWidth(); int h = graphics_display_->GetWindowHeight(); graphics_display_->SetViewPort(0, 0, w, h); window_compositor_->FormatRenderTargets(w, h); window_compositor_->FloatingAreaConfigureNotify(w, h); return true; } #endif bool WindowThread::ThreadDtor() { if(thread_dtor_called_) { return true; } // Cleanup RemoveQueuedLayout(); window_compositor_->BeforeDestructor(); if (main_layout_) { main_layout_->UnReference(); } NUX_SAFE_DELETE(window_compositor_); NUX_SAFE_DELETE(timer_manager_); NUX_SAFE_DELETE(painter_); NUX_SAFE_DELETE(theme_); NUX_SAFE_DELETE(graphics_display_); #if defined(NUX_OS_WINDOWS) PostThreadMessage(NUX_GLOBAL_OBJECT_INSTANCE(NProcess).GetMainThreadID(), NUX_THREADMSG_THREAD_TERMINATED, NUX_GLOBAL_OBJECT_INSTANCE(NProcess).GetCurrentThreadID(), 0); #elif defined(NUX_OS_LINUX) #else #error PostThreadMessage not implemented for this platform. #endif inlSetThreadLocalStorage(ThreadLocal_InalogicAppImpl, 0); UnregisterNuxThread(this); thread_dtor_called_ = true; return true; } void WindowThread::SetWindowSize(int width, int height) { if (graphics_display_) { if (IsEmbeddedWindow()) { // This is a passive way to set the window size through out the NuxGraphics system. This call gets the // current window size and sets its accordingly to all sub-system. graphics_display_->ResetWindowSize(); } else { graphics_display_->SetWindowSize(width, height); ReconfigureLayout(); } } } void WindowThread::SetWindowBackgroundPaintLayer(AbstractPaintLayer *background_layer) { if (background_layer == NULL) return; if (window_compositor_) { window_compositor_->SetBackgroundPaintLayer(background_layer); if (main_layout_) { main_layout_->QueueDraw(); } } } void WindowThread::AddToDrawList(View *view) { Area *parent; Geometry const& geo = view->GetAbsoluteGeometry(); parent = view->GetToplevel(); if (parent && (view != parent)) { // pgeo = parent->GetGeometry(); // geo.x += pgeo.x; // geo.y += pgeo.y; if (parent->Type().IsDerivedFromType(BaseWindow::StaticObjectType)) { BaseWindow* window = NUX_STATIC_CAST(BaseWindow*, parent); window->_child_need_redraw = true; } } if (view->Type().IsDerivedFromType(BaseWindow::StaticObjectType)) { // If the view is a BaseWindow, allow it to mark itself for redraw, as if it was its own child. BaseWindow* window = NUX_STATIC_CAST(BaseWindow*, view); window->_child_need_redraw = true; } dirty_areas_.push_back(geo); } void WindowThread::ClearDrawList() { dirty_areas_.clear(); } std::vector const& WindowThread::GetDrawList() const { return dirty_areas_; } bool WindowThread::AddToPresentationList(BaseWindow* bw, bool force) { if (!bw) return false; RequestRedraw(); bool force_or_not_frozen = (force || !foreign_frame_frozen_); std::vector& target_list = force_or_not_frozen ? presentation_list_embedded_ : presentation_list_embedded_next_frame_; if (std::find(target_list.begin(), target_list.end(), bw) != target_list.end()) return force_or_not_frozen; target_list.push_back(WeakBaseWindowPtr(bw)); return force_or_not_frozen; } std::vector WindowThread::GetPresentationListGeometries() const { std::vector presentation_geometries; for (auto const& base_window : presentation_list_embedded_) { if (base_window.IsValid()) { nux::Geometry const& abs_geom = base_window->GetAbsoluteGeometry(); nux::Geometry const& last_geom = base_window->LastPresentedGeometryInEmbeddedMode(); presentation_geometries.push_back(abs_geom); if (abs_geom != last_geom) { if (!last_geom.IsNull()) presentation_geometries.push_back(last_geom); } } } return presentation_geometries; } bool WindowThread::IsEmbeddedWindow() const { return embedded_window_; } #if defined(NUX_OS_WINDOWS) bool WindowThread::ProcessForeignEvent(HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, void *data) #elif defined(USE_X11) bool WindowThread::ProcessForeignEvent(XEvent *xevent, void * /* data */) #else bool WindowThread::ProcessForeignEvent() #endif { if (graphics_display_->IsPauseThreadGraphicsRendering()) { return false; } Event nux_event; memset(&nux_event, 0, sizeof(Event)); #if defined(NUX_OS_WINDOWS) graphics_display_->ProcessForeignWin32Event(hWnd, msg, wParam, lParam, &nux_event); #elif defined(USE_X11) graphics_display_->ProcessForeignX11Event(xevent, &nux_event); #endif if (nux_event.type == NUX_TERMINATE_APP || (this->GetThreadState() == THREADSTOP)) { return false; } if (nux_event.type == NUX_SIZE_CONFIGURATION) { window_size_configuration_event_ = true; } int w, h; // Call gGfx_OpenGL.getWindowSize after the gGfx_OpenGL.get_event. // Otherwise, w and h may not be correct for the current frame if a resizing happened. graphics_display_->GetWindowSize(w, h); if (nux_event.type == NUX_MOUSE_PRESSED || (nux_event.type == NUX_MOUSE_RELEASED) || (nux_event.type == NUX_MOUSE_DOUBLECLICK) || (nux_event.type == NUX_MOUSE_MOVE) || (nux_event.type == NUX_SIZE_CONFIGURATION) || (nux_event.type == NUX_KEYDOWN) || (nux_event.type == NUX_KEYUP) || (nux_event.type == NUX_NC_WINDOW_CONFIGURATION) || (nux_event.type == NUX_WINDOW_ENTER_FOCUS) || (nux_event.type == NUX_WINDOW_EXIT_FOCUS) || (nux_event.type == NUX_WINDOW_MOUSELEAVE) || (nux_event.type == NUX_MOUSE_WHEEL)) { //DISPATCH EVENT HERE //nux_event.Application = Application; window_compositor_->ProcessEvent(nux_event); } if (nux_event.type == NUX_SIZE_CONFIGURATION) { if (!graphics_display_->isWindowMinimized()) { graphics_display_->SetViewPort(0, 0, nux_event.width, nux_event.height); ReconfigureLayout(); window_compositor_->FormatRenderTargets(nux_event.width, nux_event.height); } window_compositor_->FloatingAreaConfigureNotify(nux_event.width, nux_event.height); window_size_configuration_event_ = true; } // Some action may have caused layouts and areas to request a recompute. // Process them here before the Draw section. if (!graphics_display_->isWindowMinimized()) { if (queue_main_layout_) { ReconfigureLayout(); } else { // Compute the layouts that have been queued. ComputeQueuedLayout(); } } // Warn the host window manager to initiate a draw cycle. bool request_draw_cycle_to_host_wm = false; if (this->first_pass_) { request_draw_cycle_to_host_wm = true; force_rendering_ = true; //window_compositor_->Draw(window_size_configuration_event_, true); this->first_pass_ = false; } else { bool b = (nux_event.type == NUX_MOUSE_PRESSED) || (nux_event.type == NUX_MOUSE_RELEASED) || (nux_event.type == NUX_MOUSE_DOUBLECLICK) || //(event.type == NUX_MOUSE_MOVE) || (nux_event.type == NUX_SIZE_CONFIGURATION) || (nux_event.type == NUX_KEYDOWN) || (nux_event.type == NUX_KEYUP) || (nux_event.type == NUX_NC_WINDOW_CONFIGURATION) || (nux_event.type == NUX_WINDOW_ENTER_FOCUS) || (nux_event.type == NUX_WINDOW_EXIT_FOCUS) || (nux_event.type == NUX_WINDOW_DIRTY); if (b && window_compositor_->IsTooltipActive()) { // Cancel the tooltip since an event that should cause the tooltip to disappear has occurred. window_compositor_->CancelTooltip(); b |= true; } if (!window_compositor_->ValidateMouseInsideTooltipArea(nux_event.x, nux_event.y) && window_compositor_->IsTooltipActive()) { // Cancel the tooltip since an event that should cause the tooltip to disappear has occurred. window_compositor_->CancelTooltip(); b |= true; } if (b || IsRedrawNeeded()) { request_draw_cycle_to_host_wm = true; } else if (window_compositor_->GetWidgetDrawingOverlay() != 0) { request_draw_cycle_to_host_wm = true; } } if (!_draw_requested_to_host_wm && request_draw_cycle_to_host_wm) RequestRedraw(); return request_draw_cycle_to_host_wm; } void WindowThread::PresentWindowsIntersectingGeometryOnThisFrame(Geometry const& rect) { nuxAssertMsg(IsEmbeddedWindow(), "[WindowThread::PresentWindowIntersectingGeometryOnThisFrame] " "can only be called inside an embedded window"); window_compositor_->ForEachBaseWindow([&rect] (WeakBaseWindowPtr const& w) { if (rect.IsIntersecting(w->GetAbsoluteGeometry())) w->PresentInEmbeddedModeOnThisFrame(true); }); } void WindowThread::RenderInterfaceFromForeignCmd(Geometry const& clip) { nuxAssertMsg(IsEmbeddedWindow() == true, "[WindowThread::RenderInterfaceFromForeignCmd] You can only call RenderInterfaceFromForeignCmd if the window was created with CreateFromForeignWindow."); if (!IsEmbeddedWindow()) return; IOpenGLShaderProgram::SetShaderTracking(true); // Set Nux opengl states. The other plugin in compiz have changed the GPU opengl states. // Nux keep tracks of its own opengl states and restore them before doing any drawing. GetWindowThread()->GetGraphicsEngine().GetRenderStates().SubmitChangeStates(); GetWindowThread()->GetGraphicsEngine().SetOpenGLClippingRectangle(0, 0, GetWindowThread()->GetGraphicsEngine().GetWindowWidth(), GetWindowThread()->GetGraphicsEngine().GetWindowHeight()); if (!graphics_display_->IsPauseThreadGraphicsRendering()) { ComputeQueuedLayout(); GetWindowThread()->GetGraphicsEngine().SetGlobalClippingRectangle(clip); window_compositor_->Draw(window_size_configuration_event_, force_rendering_); GetWindowThread()->GetGraphicsEngine().DisableGlobalClippingRectangle(); // When rendering in embedded mode, nux does not attempt to measure the frame rate... // Cleanup GetWindowThread()->GetGraphicsEngine().ResetStats(); ClearRedrawFlag(); window_size_configuration_event_ = false; force_rendering_ = false; } CHECKGL( glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)); IOpenGLShaderProgram::SetShaderTracking(false); } void WindowThread::ForeignFrameEnded() { nuxAssertMsg(IsEmbeddedWindow(), "[WindowThread::ForeignFrameEnded] " "can only be called inside an embedded window"); window_compositor_->ForEachBaseWindow([] (WeakBaseWindowPtr const& w) { w->MarkPresentedInEmbeddedMode(); }); presentation_list_embedded_.clear(); foreign_frame_frozen_ = false; /* Move all the BaseWindows in presentation_list_embedded_next_frame_ * to presentation_list_embedded_ and mark them for presentation */ for (auto const& win : presentation_list_embedded_next_frame_) { if (win.IsValid()) win->PresentInEmbeddedModeOnThisFrame(); } presentation_list_embedded_next_frame_.clear(); } void WindowThread::ForeignFrameCutoff() { foreign_frame_frozen_ = true; } int WindowThread::InstallEventInspector(EventInspector function, void* data) { NUX_RETURN_VALUE_IF_NULL(function, 0); std::map < int, EventInspectorStorage >::iterator it; for (it = _event_inspectors_map.begin(); it != _event_inspectors_map.end(); ++it) { if ((*it).second._function == function) { // The inspector has already been added. Return its unique id return (*it).second._uid; } } // This is a new Event Inspector EventInspectorStorage new_inspector; new_inspector._function = function; new_inspector._data = data; new_inspector._uid = NUX_GLOBAL_OBJECT_INSTANCE(UniqueIndex).GetUniqueIndex(); _event_inspectors_map [new_inspector._uid] = new_inspector; return new_inspector._uid; } bool WindowThread::RemoveEventInspector(int event_inspector_id) { NUX_RETURN_VALUE_IF_NULL(event_inspector_id, false); std::map < int, EventInspectorStorage >::iterator it; for (it = _event_inspectors_map.begin(); it != _event_inspectors_map.end(); ++it) { if ((*it).second._uid == event_inspector_id) { _event_inspectors_map.erase(it); return true; } } return false; } bool WindowThread::RemoveEventInspector(EventInspector function) { NUX_RETURN_VALUE_IF_NULL(function, false); std::map < int, EventInspectorStorage >::iterator it; for (it = _event_inspectors_map.begin(); it != _event_inspectors_map.end(); ++it) { if ((*it).second._function == function) { _event_inspectors_map.erase(it); return true; } } return false; } bool WindowThread::CallEventInspectors(Event* event) { int n = _event_inspectors_map.size(); if (n == 0) { // No event inspector installed. return false; } bool discard_event = false; std::map < int, EventInspectorStorage >::iterator it; for (it = _event_inspectors_map.begin(); it != _event_inspectors_map.end(); ++it) { EventInspector callback = (*it).second._function; if (callback == 0) continue; int ret = callback(0, event, (*it).second._data); if (ret) { discard_event = true; } } return discard_event; } bool WindowThread::FindDataByFd(const WindowThread::ExternalFdData &data, int fd) { return data.fd == fd; } void WindowThread::WatchFdForEvents(int fd, const WindowThread::FdWatchCallback &cb) { ExternalFdData data; data.fd = fd; data.cb = cb; _external_fds.push_back(data); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) AddFdToGLibLoop(fd, reinterpret_cast (&_external_fds.back()), WindowThread::ExternalSourceCallback); #endif } void WindowThread::UnwatchFd(int fd) { using namespace std::placeholders; std::list::iterator it = std::find_if (_external_fds.begin(), _external_fds.end(), std::bind(FindDataByFd, _1, fd)); if (it != _external_fds.end()) { #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) RemoveFdFromGLibLoop(&(*it)); #endif _external_fds.erase (it); } } #if defined(NUX_OS_LINUX) && defined(USE_X11) void WindowThread::XICFocus(TextEntry* text_entry) { xim_controller_->FocusInXIC(); xim_controller_->SetCurrentTextEntry(text_entry); graphics_display_->SetCurrentXIC(xim_controller_->GetXIC()); } void WindowThread::XICUnFocus() { xim_controller_->FocusOutXIC(); } #endif GraphicsDisplay& WindowThread::GetGraphicsDisplay() const { return *graphics_display_; } GraphicsEngine& WindowThread::GetGraphicsEngine() const { return *graphics_display_->GetGraphicsEngine(); } WindowCompositor& WindowThread::GetWindowCompositor() const { return *window_compositor_; } BasePainter& WindowThread::GetPainter() const { return *painter_; } TimerHandler& WindowThread::GetTimerHandler() const { return *timer_manager_; } UXTheme& WindowThread::GetTheme() const { if (!theme_) { LOG_INFO(logger) << "Lazily creating nux::UXTheme"; const_cast(this)->theme_ = new UXTheme(); } return *theme_; } std::string WindowThread::GetWindowTitle() const { return window_title_; } } nux-4.0.6+14.04.20140409/Nux/PopUpWindow.cpp0000644000015301777760000000237412321344237020454 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "WindowCompositor.h" #include "PopUpWindow.h" namespace nux { PopUpWindow::PopUpWindow() { EnableTitleBar(false); ShowWindow(false); SetTopBorder(0); SetBorder(0); SetWindowSizeMatchLayout(true); SetMinimumSize(20, 20); } PopUpWindow::~PopUpWindow() { } void PopUpWindow::Show() { //m_Window.ComputeContentSize(); ShowWindow(true); } void PopUpWindow::Hide() { ShowWindow(false); } } nux-4.0.6+14.04.20140409/Nux/Gesture.cpp0000644000015301777760000001740012321344237017633 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include "Gesture.h" #include "Nux/InputArea.h" using namespace nux; /***************************************************************************** * InputAreaTarget *****************************************************************************/ InputAreaTarget::InputAreaTarget(InputArea *input_area) : input_area_(input_area) { } GestureDeliveryRequest InputAreaTarget::GestureEvent(const nux::GestureEvent &event) { if (input_area_.IsValid()) return input_area_->GestureEvent(event); else return GestureDeliveryRequest::NONE; } bool InputAreaTarget::Equals(const GestureTarget& other) const { const InputAreaTarget *input_area_target = dynamic_cast(&other); if (input_area_target) { return input_area_ == input_area_target->input_area_; } else { return false; } } /***************************************************************************** * Gesture *****************************************************************************/ Gesture::Gesture(const nux::GestureEvent &event) : event_delivery_enabled_(false), acceptance_status_(AcceptanceStatus::UNDECIDED) { queued_events_.reserve(20); queued_events_.push_back(event); } void Gesture::AddTarget(ShPtGestureTarget target) { target_died_connections_[target] = target->died.connect(sigc::mem_fun (this, &Gesture::RemoveTarget)); target_list_.push_back(target); } void Gesture::RemoveTarget(const GestureTarget &target) { auto check_same_target = [&](const ShPtGestureTarget& other_target) { return *other_target == target; }; auto target_iterator = std::find_if(target_list_.begin(), target_list_.end(), check_same_target); if (target_iterator != target_list_.end()) { auto connection_iterator = target_died_connections_.find(*target_iterator); if (connection_iterator != target_died_connections_.end()) connection_iterator->second.disconnect(); target_list_.erase(target_iterator); } if (target_list_.empty()) { /* Reject this gesture if we can no longer accept it */ if (GetAcceptanceStatus() == Gesture::AcceptanceStatus::UNDECIDED) Reject (); lost_all_targets.emit (*this); } } void Gesture::EnableEventDelivery() { if (event_delivery_enabled_) return; event_delivery_enabled_ = true; if (queued_events_.empty()) return; // Deliver all queued events but keep the last one last_event_ = queued_events_[queued_events_.size()-1]; for (auto event : queued_events_) { DeliverEvent(event); } queued_events_.clear(); } void Gesture::Update(const nux::GestureEvent& event) { if (event_delivery_enabled_) { DeliverEvent(event); last_event_ = event; } else { queued_events_.push_back(event); } } void Gesture::DeliverEvent(const GestureEvent &event) { auto it = target_list_.begin(); while (it != target_list_.end()) { GestureDeliveryRequest request = (*it)->GestureEvent(event); switch(request) { case GestureDeliveryRequest::EXCLUSIVITY: ExecuteTargetExclusivityRequest(event, it); break; default: // NONE ++it; } } } void Gesture::ExecuteTargetExclusivityRequest(const GestureEvent &event, std::list::iterator &it_requestor) { // Don't send gesture lost events for a gesture begin. // Targets can't lose a gesture they never knew about. if (event.type != EVENT_GESTURE_BEGIN) { GestureEvent event_lost = event; event_lost.type = EVENT_GESTURE_LOST; auto other_it = target_list_.rbegin(); while (*other_it != *it_requestor) { (*other_it)->GestureEvent(event_lost); ++other_it; } } ++it_requestor; target_list_.erase(it_requestor, target_list_.end()); it_requestor = target_list_.end(); } nux::GestureEvent &Gesture::GetLatestEvent() { if (event_delivery_enabled_) { nuxAssert(queued_events_.size() == 0); return last_event_; } else { nuxAssert(queued_events_.size() > 0); return queued_events_[queued_events_.size()-1]; } } const nux::GestureEvent &Gesture::GetLatestEvent() const { if (event_delivery_enabled_) { nuxAssert(queued_events_.size() == 0); return last_event_; } else { nuxAssert(queued_events_.size() > 0); return queued_events_[queued_events_.size()-1]; } } bool Gesture::IsConstructionFinished() const { return GetLatestEvent().IsConstructionFinished(); } int Gesture::GetId() const { return GetLatestEvent().GetGestureId(); } const std::vector &Gesture::GetTouches() const { return GetLatestEvent().GetTouches(); } bool Gesture::HasTouchesInCommon( const std::shared_ptr &other_gesture) const { const std::vector &my_touches = GetTouches(); const std::vector &other_touches = other_gesture->GetTouches(); for (const auto other_touch : other_touches) { for (const auto my_touch : my_touches) { if (other_touch == my_touch) return true; } } return false; } void Gesture::Reject() { g_assert(acceptance_status_ == AcceptanceStatus::UNDECIDED); GetLatestEvent().Reject(); acceptance_status_ = AcceptanceStatus::REJECTED; } void Gesture::Accept() { g_assert(acceptance_status_ == AcceptanceStatus::UNDECIDED); GetLatestEvent().Accept(); acceptance_status_ = AcceptanceStatus::ACCEPTED; } /***************************************************************************** * GestureSet *****************************************************************************/ void GestureSet::Add(Gesture *gesture) { map_id_to_gesture_[gesture->GetId()] = std::shared_ptr(gesture); } void GestureSet::Add(std::shared_ptr &gesture) { map_id_to_gesture_[gesture->GetId()] = gesture; } std::shared_ptr GestureSet::FindFromGestureId(int gesture_id) { std::map >::iterator it = map_id_to_gesture_.find(gesture_id); if (it != map_id_to_gesture_.end()) return it->second; else return std::shared_ptr(); } std::shared_ptr GestureSet::FindFromTarget(ShPtGestureTarget wanted_target) { for (auto it : map_id_to_gesture_) { std::shared_ptr &gesture = it.second; const std::list &target_list = gesture->GetTargetList(); for (auto target : target_list) { if (*target == *wanted_target) return gesture; } } return nullptr; } std::vector< std::shared_ptr > GestureSet::GetConflictingGestures(std::shared_ptr &gesture) { std::vector< std::shared_ptr > conflicting_gestures; for (auto it : map_id_to_gesture_) { std::shared_ptr &other_gesture = it.second; if (other_gesture == gesture) continue; if (other_gesture->HasTouchesInCommon(gesture)) conflicting_gestures.push_back(other_gesture); } return conflicting_gestures; } void GestureSet::Remove(const Gesture &gesture) { map_id_to_gesture_.erase(gesture.GetId()); } nux-4.0.6+14.04.20140409/Nux/ColorEditor.cpp0000644000015301777760000011162712321344237020450 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/GLSh_ColorPicker.h" #include "VLayout.h" #include "HLayout.h" #include "CheckBox.h" #include "EditTextBox.h" #include "RadioButton.h" #include "RadioButtonGroup.h" #include "ToggleButton.h" #include "Layout.h" #include "ColorEditor.h" namespace nux { Size ColorEditor::picker_area_size = Size(200, 200); int ColorEditor::channel_area_width = 12; static void ThreadColorEditorDialog(NThread *thread, void *InitData) { VLayout *MainLayout(new VLayout(NUX_TRACKER_LOCATION)); ColorEditor *coloreditor(new ColorEditor()); coloreditor->ComputeContentSize(); // necessary so all element of the widget get their rightful size. ColorDialogProxy *coloreditorproxy = static_cast (InitData); if (coloreditorproxy) { coloreditor->SetRGB(coloreditorproxy->GetColor()); coloreditor->SetColorModel(coloreditorproxy->GetColorModel(), coloreditorproxy->GetColorChannel()); coloreditor->sigChange.connect(sigc::mem_fun(coloreditorproxy, &ColorDialogProxy::RecvDialogChange)); } HLayout *ButtonLayout(new HLayout("Dialog Buttons", NUX_TRACKER_LOCATION)); ToggleButton *OkButton(new ToggleButton("OK", NUX_TRACKER_LOCATION)); OkButton->SetMinimumWidth(60); OkButton->SetMinimumHeight(20); ToggleButton *CancelButton(new ToggleButton("Cancel", NUX_TRACKER_LOCATION)); CancelButton->SetMinimumWidth(60); CancelButton->SetMinimumHeight(20); //FIXME - OkButton->sigClick.connect(sigc::mem_fun(static_cast (thread), &WindowThread::TerminateThread)); //FIXME - OkButton->sigClick.connect(sigc::bind(sigc::mem_fun(coloreditorproxy, &ColorDialogProxy::RecvDialogOk), coloreditor)); //FIXME - CancelButton->sigClick.connect(sigc::bind(sigc::mem_fun(coloreditorproxy, &ColorDialogProxy::RecvDialogCancel), coloreditor)); //FIXME - CancelButton->sigClick.connect(sigc::mem_fun(static_cast (thread), &WindowThread::TerminateThread)); ButtonLayout->SetHorizontalInternalMargin(6); ButtonLayout->SetVerticalExternalMargin(2); ButtonLayout->AddView(OkButton, 0); ButtonLayout->AddView(CancelButton, 0); MainLayout->AddView(coloreditor); MainLayout->AddLayout(ButtonLayout, 0); static_cast (thread)->SetLayout(MainLayout); MainLayout->SetBaseWidth(1); MainLayout->SetBaseHeight(1); MainLayout->ComputeContentSize(); static_cast (thread)->SetWindowSize(MainLayout->GetBaseWidth(), MainLayout->GetBaseHeight()); // Call StopThreadMonitoring in case the dialog was close by clicking the window close button. //coloreditorproxy->StopThreadMonitoring(); } ColorDialogProxy::ColorDialogProxy(bool ModalWindow) { m_bDialogChange = false; m_bDialogRunning = false; m_ModalWindow = ModalWindow; m_RGBColor = Color(1.0f, 1.0f, 1.0f, 1.0f); m_ColorModel = color::RGB; color_channel_ = color::RED; } ColorDialogProxy::~ColorDialogProxy() { } void ColorDialogProxy::Start() { m_PreviousRGBColor = m_RGBColor; int Width = 290; int Height = 230; m_Thread = CreateModalWindowThread(WINDOWSTYLE_TOOL, "Color Editor", Width, Height, GetWindowThread(), ThreadColorEditorDialog, this); if (m_Thread) { //todo(jaytaoko): m_DialogThreadID = m_Thread->GetThreadId(); m_Thread->Start(0); } m_bDialogRunning = true; } bool ColorDialogProxy::IsActive() { return (m_Thread && (m_Thread->GetThreadState() != THREADSTOP) && m_bDialogRunning); } void ColorDialogProxy::RecvDialogOk(ColorEditor *coloreditor) { m_RGBColor = coloreditor->GetRGBColor(); m_PreviousRGBColor = m_RGBColor; m_bDialogChange = true; m_bDialogRunning = false; } void ColorDialogProxy::RecvDialogCancel(ColorEditor* /* coloreditor */) { m_RGBColor = m_PreviousRGBColor; m_bDialogChange = true; m_bDialogRunning = false; } void ColorDialogProxy::RecvDialogChange(ColorEditor *coloreditor) { m_RGBColor = coloreditor->GetRGBColor(); m_bDialogChange = true; } void ColorDialogProxy::StopThreadMonitoring() { m_RGBColor = m_PreviousRGBColor; m_bDialogChange = true; m_bDialogRunning = false; m_Thread = 0; m_DialogThreadID = 0; } void ColorDialogProxy::SetColor(Color color) { m_RGBColor = color; } Color ColorDialogProxy::GetColor() { return m_RGBColor; } void ColorDialogProxy::SetPreviousColor(Color color) { m_PreviousRGBColor = color; } Color ColorDialogProxy::GetPreviousColor() { return m_PreviousRGBColor; } void ColorDialogProxy::SetColorModel(color::Model color_model) { m_ColorModel = color_model; } color::Model ColorDialogProxy::GetColorModel() { return m_ColorModel; } void ColorDialogProxy::SetColorChannel(color::Channel color_channel) { color_channel_ = color_channel; } color::Channel ColorDialogProxy::GetColorChannel() { return color_channel_; } ColorEditor::ColorEditor(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , rgb_(1.0f, 1.0f, 0.0f) , hsv_(rgb_) { m_ColorModel = color::RGB; color_channel_ = color::RED; m_MarkerPosition = Point(0, 0); m_VertMarkerPosition = Point(0, 0); m_Validator.SetMinimum(0.0); m_Validator.SetMaximum(1.0); m_Validator.SetDecimals(2); picker_area_ = new BasicView(NUX_TRACKER_LOCATION); channel_area_ = new BasicView(NUX_TRACKER_LOCATION); selected_color_area_ = new BasicView(NUX_TRACKER_LOCATION); m_hlayout = new HLayout(NUX_TRACKER_LOCATION); channel_area_->mouse_down.connect(sigc::mem_fun(this, &ColorEditor::RecvMouseDown)); channel_area_->mouse_up.connect(sigc::mem_fun(this, &ColorEditor::RecvMouseUp)); channel_area_->mouse_drag.connect(sigc::mem_fun(this, &ColorEditor::RecvMouseDrag)); picker_area_->mouse_down.connect(sigc::mem_fun(this, &ColorEditor::RecvPickerMouseDown)); picker_area_->mouse_up.connect(sigc::mem_fun(this, &ColorEditor::RecvPickerMouseUp)); picker_area_->mouse_drag.connect(sigc::mem_fun(this, &ColorEditor::RecvPickerMouseDrag)); selected_color_area_->SetMinMaxSize(62, 32); picker_area_->SetMinMaxSize(picker_area_size.width, picker_area_size.height); channel_area_->SetMaximumHeight(picker_area_size.height); channel_area_->SetMinimumWidth(channel_area_width); channel_area_->SetMaximumWidth(channel_area_width); m_hlayout->AddView(picker_area_, 1); m_hlayout->AddLayout(new SpaceLayout(5, 5, 20, 20), 0); m_hlayout->AddView(channel_area_, 0, eAbove, eFull); SetCompositionLayout(m_hlayout); // RGB { redlayout = new HLayout(NUX_TRACKER_LOCATION); { //FIXME - change to radio button redcheck = new RadioButton("R"); redcheck->SetMinimumWidth(32); redtext = new EditTextBox("", NUX_TRACKER_LOCATION); redtext->SetMinimumWidth(36); redlayout->AddView(redcheck, 0); redlayout->AddView(redtext, 0); redcheck->click.connect(sigc::bind(sigc::bind(sigc::mem_fun(this, &ColorEditor::RecvCheckColorModel0), color::RED), color::RGB)); } greenlayout = new HLayout(NUX_TRACKER_LOCATION); { //FIXME - Change to radio button greencheck = new RadioButton("G"); greencheck->SetMinimumWidth(32); greentext = new EditTextBox("", NUX_TRACKER_LOCATION); greentext->SetMinimumWidth(36); greenlayout->AddView(greencheck, 0); greenlayout->AddView(greentext, 0); greencheck->click.connect(sigc::bind(sigc::bind(sigc::mem_fun(this, &ColorEditor::RecvCheckColorModel0), color::GREEN), color::RGB)); } bluelayout = new HLayout(NUX_TRACKER_LOCATION); { //FIXME - change to radio button bluecheck = new RadioButton("B"); bluecheck->SetMinimumWidth(32); bluetext = new EditTextBox("", NUX_TRACKER_LOCATION); bluetext->SetMinimumWidth(36); bluelayout->AddView(bluecheck, 0); bluelayout->AddView(bluetext, 0); bluecheck->click.connect(sigc::bind(sigc::bind(sigc::mem_fun(this, &ColorEditor::RecvCheckColorModel0), color::BLUE), color::RGB)); } } // HSV { huelayout = new HLayout(NUX_TRACKER_LOCATION); { huecheck = new RadioButton("H"); huecheck->SetMinimumWidth(32); hue_text_entry_ = new EditTextBox("", NUX_TRACKER_LOCATION); hue_text_entry_->SetMinimumWidth(36); huelayout->AddView(huecheck, 0); huelayout->AddView(hue_text_entry_, 0); huecheck->click.connect(sigc::bind(sigc::bind(sigc::mem_fun(this, &ColorEditor::RecvCheckColorModel0), color::HUE), color::HSV )); } saturationlayout = new HLayout(NUX_TRACKER_LOCATION); { saturationcheck = new RadioButton("S"); saturationcheck->SetMinimumWidth(32); saturation_text_entry_ = new EditTextBox("", NUX_TRACKER_LOCATION); saturation_text_entry_->SetMinimumWidth(36); saturationlayout->AddView(saturationcheck, 0); saturationlayout->AddView(saturation_text_entry_, 0); saturationcheck->click.connect(sigc::bind(sigc::bind(sigc::mem_fun(this, &ColorEditor::RecvCheckColorModel0), color::SATURATION), color::HSV )); } valuelayout = new HLayout(NUX_TRACKER_LOCATION); { valuecheck = new RadioButton("V"); valuecheck->SetMinimumWidth(32); value_text_entry_ = new EditTextBox("", NUX_TRACKER_LOCATION); value_text_entry_->SetMinimumWidth(36); valuelayout->AddView(valuecheck, 0); valuelayout->AddView(value_text_entry_, 0); valuecheck->click.connect(sigc::bind(sigc::bind(sigc::mem_fun(this, &ColorEditor::RecvCheckColorModel0), color::VALUE), color::HSV )); } } ctrllayout = new VLayout(NUX_TRACKER_LOCATION); ctrllayout->AddView(selected_color_area_); ctrllayout->AddView(new SpaceLayout(20, 20, 10, 10), 1); ctrllayout->AddLayout(redlayout, 0); ctrllayout->AddLayout(greenlayout, 0); ctrllayout->AddLayout(bluelayout, 0); ctrllayout->AddLayout(new SpaceLayout(10, 10, 10, 10)); ctrllayout->AddLayout(huelayout, 0); ctrllayout->AddLayout(saturationlayout, 0); ctrllayout->AddLayout(valuelayout, 0); ctrllayout->SetHorizontalExternalMargin(2); ctrllayout->SetVerticalInternalMargin(2); m_hlayout->AddLayout(ctrllayout, 0); radiogroup = new RadioButtonGroup(NUX_TRACKER_LOCATION); radiogroup->ConnectButton(redcheck); radiogroup->ConnectButton(greencheck); radiogroup->ConnectButton(bluecheck); radiogroup->ConnectButton(huecheck); radiogroup->ConnectButton(saturationcheck); radiogroup->ConnectButton(valuecheck); m_RedShader = new GLSh_ColorPicker(color::RED); m_GreenShader = new GLSh_ColorPicker(color::GREEN); m_BlueShader = new GLSh_ColorPicker(color::BLUE); m_HueShader = new GLSh_ColorPicker(color::HUE); m_SaturationShader = new GLSh_ColorPicker(color::SATURATION); m_ValueShader = new GLSh_ColorPicker(color::VALUE); redtext->SetText(m_Validator.ToString(255 * rgb_.red)); greentext->SetText(m_Validator.ToString(255 * rgb_.green)); bluetext->SetText(m_Validator.ToString(255 * rgb_.blue)); hue_text_entry_->SetText(m_Validator.ToString(360 * hsv_.hue)); saturation_text_entry_->SetText(m_Validator.ToString(100 * hsv_.saturation)); value_text_entry_->SetText(m_Validator.ToString(100 * hsv_.value)); } ColorEditor::~ColorEditor() { delete m_RedShader; delete m_GreenShader; delete m_BlueShader; delete m_HueShader; delete m_SaturationShader; delete m_ValueShader; radiogroup->UnReference(); } void ColorEditor::PreLayoutManagement() { View::PreLayoutManagement(); if (view_layout_) { // Constrain the vertical expansion of the color picker. view_layout_->SetBaseWidth(1); view_layout_->SetBaseHeight(1); } } void ColorEditor::Draw(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); base.OffsetPosition(1, 1); base.OffsetSize(-2, -2); graphics_engine.PushClippingRectangle(base); GetPainter().PushDrawShapeLayer(graphics_engine, base, eSHAPE_CORNER_ROUND4, Color(0xFF000000), eAllCorners, true); if (m_ColorModel == color::RGB) { DrawRGB(graphics_engine, force_draw); } else { DrawHSV(graphics_engine, force_draw); } GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } void ColorEditor::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); GetPainter().PushShapeLayer(graphics_engine, base, eSHAPE_CORNER_ROUND4, Color(0xFF000000), eAllCorners, true); bool force = force_draw || IsFullRedraw(); redcheck->ProcessDraw(graphics_engine, force); redtext->ProcessDraw(graphics_engine, force); greencheck->ProcessDraw(graphics_engine, force); greentext->ProcessDraw(graphics_engine, force); bluecheck->ProcessDraw(graphics_engine, force); bluetext->ProcessDraw(graphics_engine, force); huecheck->ProcessDraw(graphics_engine, force); hue_text_entry_->ProcessDraw(graphics_engine, force); saturationcheck->ProcessDraw(graphics_engine, force); saturation_text_entry_->ProcessDraw(graphics_engine, force); valuecheck->ProcessDraw(graphics_engine, force); value_text_entry_->ProcessDraw(graphics_engine, force); GetPainter().PopBackground(); } // Draw Marker on Base Chanel Area void ColorEditor::DrawBaseChannelMarker(GraphicsEngine &graphics_engine) { int marker_position_x; int marker_position_y; graphics_engine.PushClippingRectangle(channel_area_->GetGeometry()); marker_position_x = channel_area_->GetBaseX(); marker_position_y = channel_area_->GetBaseY() + m_VertMarkerPosition.y; GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x, marker_position_y - 5, marker_position_x + 5, marker_position_y, marker_position_x, marker_position_y + 5, Color(0.0f, 0.0f, 0.0f, 1.0f)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x, marker_position_y - 4, marker_position_x + 4, marker_position_y, marker_position_x, marker_position_y + 4, Color(0.7f, 0.7f, 0.7f, 1.0f)); marker_position_x = channel_area_->GetBaseX() + channel_area_->GetBaseWidth(); marker_position_y = channel_area_->GetBaseY() + m_VertMarkerPosition.y; GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x, marker_position_y - 5, marker_position_x - 5, marker_position_y, marker_position_x, marker_position_y + 5, Color(0.0f, 0.0f, 0.0f, 1.0f)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x, marker_position_y - 4, marker_position_x - 4, marker_position_y, marker_position_x, marker_position_y + 4, Color(0.7f, 0.7f, 0.7f, 1.0f)); graphics_engine.PopClippingRectangle(); } void ColorEditor::DrawRGB(GraphicsEngine &graphics_engine, bool /* force_draw */) { if (m_ColorModel == color::RGB) { GetPainter().Paint2DQuadColor(graphics_engine, selected_color_area_->GetGeometry(), Color(rgb_)); Color BaseChannelTop; Color BaseChannelBottom; if (color_channel_ == color::RED) { m_RedShader->SetColor(rgb_.red, rgb_.green, rgb_.blue, 1.0f); m_RedShader->SetScreenPositionOffset(graphics_engine.GetViewportX(), graphics_engine.GetViewportY()); BaseChannelTop = Color(1.0f, rgb_.green, rgb_.blue, 1.0f); BaseChannelBottom = Color(0.0f, rgb_.green, rgb_.blue, 1.0f); m_RedShader->Render( picker_area_->GetBaseX(), picker_area_->GetBaseY(), 0, picker_area_->GetBaseWidth(), picker_area_->GetBaseHeight(), graphics_engine.GetViewportWidth(), graphics_engine.GetViewportHeight() ); } else if (color_channel_ == color::GREEN) { m_GreenShader->SetColor(rgb_.red, rgb_.green, rgb_.blue, 1.0f); m_GreenShader->SetScreenPositionOffset(graphics_engine.GetViewportX(), graphics_engine.GetViewportY()); BaseChannelTop = Color(rgb_.red, 1.0f, rgb_.blue, 1.0f); BaseChannelBottom = Color(rgb_.red, 0.0f, rgb_.blue, 1.0f); m_GreenShader->Render( picker_area_->GetBaseX(), picker_area_->GetBaseY(), 0, picker_area_->GetBaseWidth(), picker_area_->GetBaseHeight(), graphics_engine.GetViewportWidth(), graphics_engine.GetViewportHeight() ); } else if (color_channel_ == color::BLUE) { m_BlueShader->SetColor(rgb_.red, rgb_.green, rgb_.blue, 1.0f); m_BlueShader->SetScreenPositionOffset(graphics_engine.GetViewportX(), graphics_engine.GetViewportY()); BaseChannelTop = Color(rgb_.red, rgb_.green, 1.0f, 1.0f); BaseChannelBottom = Color(rgb_.red, rgb_.green, 0.0f, 1.0f); m_BlueShader->Render( picker_area_->GetBaseX(), picker_area_->GetBaseY(), 0, picker_area_->GetBaseWidth(), picker_area_->GetBaseHeight(), graphics_engine.GetViewportWidth(), graphics_engine.GetViewportHeight() ); } Geometry pickermarker = Geometry(GetBaseX() + m_MarkerPosition.x - 2, GetBaseY() + m_MarkerPosition.y - 2, 5, 5); Color color(rgb_.red, rgb_.green, rgb_.blue); float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue; Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma); GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma); GetPainter().Paint2DQuadColor(graphics_engine, channel_area_->GetGeometry(), BaseChannelTop, BaseChannelBottom, BaseChannelBottom, BaseChannelTop); // Draw Marker on Base Chanel Area DrawBaseChannelMarker(graphics_engine); } } void ColorEditor::DrawHSV(GraphicsEngine &graphics_engine, bool /* force_draw */) { if (m_ColorModel == color::HSV) { color::RedGreenBlue rgb(hsv_); GetPainter().Paint2DQuadColor(graphics_engine, selected_color_area_->GetGeometry(), Color(rgb)); Color BaseChannelTop; Color BaseChannelBottom; if (color_channel_ == color::HUE) { m_HueShader->SetColor(hsv_.hue, hsv_.saturation, hsv_.value, 1.0f); m_HueShader->SetScreenPositionOffset(graphics_engine.GetViewportX(), graphics_engine.GetViewportY()); m_HueShader->Render( picker_area_->GetBaseX(), picker_area_->GetBaseY(), 0, picker_area_->GetBaseWidth(), picker_area_->GetBaseHeight(), graphics_engine.GetViewportWidth(), graphics_engine.GetViewportHeight() ); Geometry P = channel_area_->GetGeometry(); float s = 1.0f - 1.0f; float v = 1.0f; float fw = P.GetHeight() / 6; Geometry p = Geometry(P.x, P.y, P.GetWidth(), fw); GetPainter().Paint2DQuadVGradient(graphics_engine, p, Color(1.0f * v, s * v, s * v), Color(1.0f * v, s * v, 1.0f * v)); p.SetY(P.y + fw); GetPainter().Paint2DQuadVGradient(graphics_engine, p, Color(1.0f * v, s * v, 1.0f * v), Color(s * v, s * v, 1.0f * v)); p.SetY(P.y + 2 * fw); GetPainter().Paint2DQuadVGradient(graphics_engine, p, Color(s * v, s * v, 1.0f * v), Color(s * v, 1.0f * v, 1.0f * v)); p.SetY(P.y + 3 * fw); GetPainter().Paint2DQuadVGradient(graphics_engine, p, Color(s * v, 1.0f * v, 1.0f * v), Color(s * v, 1.0f * v, s * v)); p.SetY(P.y + 4 * fw); GetPainter().Paint2DQuadVGradient(graphics_engine, p, Color(s * v, 1.0f * v, s * v), Color(1.0f * v, 1.0f * v, s * v)); p.SetY(P.y + 5 * fw); p.SetHeight(P.GetHeight() - 5 * fw); // correct rounding errors GetPainter().Paint2DQuadVGradient(graphics_engine, p, Color(1.0f * v, 1.0f * v, s * v), Color(1.0f * v, s * v, s * v)); Geometry pickermarker = Geometry(GetBaseX() + m_MarkerPosition.x - 2, GetBaseY() + m_MarkerPosition.y - 2, 5, 5); float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue; Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma); GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma); } else if (color_channel_ == color::SATURATION) { float value = hsv_.value; if (value < 0.3f) value = 0.3f; m_SaturationShader->SetColor(hsv_.hue, hsv_.saturation, hsv_.value, 1.0f); m_SaturationShader->SetScreenPositionOffset(graphics_engine.GetViewportX(), graphics_engine.GetViewportY()); BaseChannelTop = Color(color::RedGreenBlue(color::HueSaturationValue(hsv_.hue, 1.0f, value))); BaseChannelBottom = Color(value, value, value, 1.0f); m_SaturationShader->Render( picker_area_->GetBaseX(), picker_area_->GetBaseY(), 0, picker_area_->GetBaseWidth(), picker_area_->GetBaseHeight(), graphics_engine.GetViewportWidth(), graphics_engine.GetViewportHeight() ); //Geometry pickermarker = Geometry(GetX() + x - 2, GetY() + y -2, 5, 5); Geometry pickermarker = Geometry(GetBaseX() + m_MarkerPosition.x - 2, GetBaseY() + m_MarkerPosition.y - 2, 5, 5); float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue; Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma); GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma); GetPainter().Paint2DQuadColor(graphics_engine, channel_area_->GetGeometry(), BaseChannelTop, BaseChannelBottom, BaseChannelBottom, BaseChannelTop); } else if (color_channel_ == color::VALUE) { m_ValueShader->SetColor(hsv_.hue, hsv_.saturation, hsv_.value, 1.0f); m_ValueShader->SetScreenPositionOffset(graphics_engine.GetViewportX(), graphics_engine.GetViewportY()); BaseChannelTop = Color(color::RedGreenBlue(color::HueSaturationValue(hsv_.hue, hsv_.saturation, 1.0f))); BaseChannelBottom = Color(color::RedGreenBlue(color::HueSaturationValue(hsv_.hue, hsv_.saturation, 0.0f))); m_ValueShader->Render( picker_area_->GetBaseX(), picker_area_->GetBaseY(), 0, picker_area_->GetBaseWidth(), picker_area_->GetBaseHeight(), graphics_engine.GetViewportWidth(), graphics_engine.GetViewportHeight() ); //Geometry pickermarker = Geometry(GetX() + x - 2, GetY() + y -2, 5, 5); Geometry pickermarker = Geometry(GetBaseX() + m_MarkerPosition.x - 2, GetBaseY() + m_MarkerPosition.y - 2, 5, 5); float luma = color::LumaRed * rgb_.red + color::LumaGreen * rgb_.green + color::LumaBlue * rgb_.blue; Color one_minus_luma(1.0f - luma, 1.0f - luma, 1.0f - luma); GetPainter().Paint2DQuadWireframe(graphics_engine, pickermarker, one_minus_luma); GetPainter().Paint2DQuadColor(graphics_engine, channel_area_->GetGeometry(), BaseChannelTop, BaseChannelBottom, BaseChannelBottom, BaseChannelTop); } // Draw Marker on Base Chanel Area DrawBaseChannelMarker(graphics_engine); } } void ColorEditor::RecvMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { float BaseValue; if (m_ColorModel == color::RGB) { if (y < 0) BaseValue = 1.0f; else if (y > channel_area_->GetBaseHeight()) BaseValue = 0.0f; else BaseValue = 1.0f - (float) y / (float) channel_area_->GetBaseHeight(); if (color_channel_ == color::RED) rgb_.red = BaseValue; else if (color_channel_ == color::GREEN) rgb_.green = BaseValue; else if (color_channel_ == color::BLUE) rgb_.blue = BaseValue; hsv_ = color::HueSaturationValue(rgb_); } if (m_ColorModel == color::HSV) { if (y < 0) BaseValue = 1.0f; else if (y > channel_area_->GetBaseHeight()) BaseValue = 0.0f; else BaseValue = 1.0f - (float) y / (float) channel_area_->GetBaseHeight(); if (color_channel_ == color::HUE) { hsv_.hue = BaseValue; if (hsv_.hue >= 1.0f) hsv_.hue = 0.0f; } else if (color_channel_ == color::SATURATION) hsv_.saturation = BaseValue; else if (color_channel_ == color::VALUE) hsv_.value = BaseValue; rgb_ = color::RedGreenBlue(hsv_); } redtext->SetText(m_Validator.ToString(255 * rgb_.red)); greentext->SetText(m_Validator.ToString(255 * rgb_.green)); bluetext->SetText(m_Validator.ToString(255 * rgb_.blue)); hue_text_entry_->SetText(m_Validator.ToString(360 * hsv_.hue)); saturation_text_entry_->SetText(m_Validator.ToString(100 * hsv_.saturation)); value_text_entry_->SetText(m_Validator.ToString(100 * hsv_.value)); m_VertMarkerPosition = Point(Clamp (x, 0, channel_area_->GetBaseWidth() - 1), Clamp (y, 0, channel_area_->GetBaseHeight() - 1)); sigChange.emit(this); QueueDraw(); } void ColorEditor::RecvMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void ColorEditor::RecvMouseDrag(int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { RecvMouseDown(x, y, button_flags, key_flags); } void ColorEditor::RecvPickerMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_ColorModel == color::RGB) { if (color_channel_ == color::RED) { if (y < 0) rgb_.green = 1.0f; else if (y > picker_area_->GetBaseHeight()) rgb_.green = 0.0f; else rgb_.green = 1.0f - (float) y / (float) picker_area_->GetBaseHeight(); if (x < 0) rgb_.blue = 0.0f; else if (x > picker_area_->GetBaseWidth()) rgb_.blue = 1.0f; else rgb_.blue = (float) x / (float) picker_area_->GetBaseWidth(); } if (color_channel_ == color::GREEN) { if (y < 0) rgb_.red = 1.0f; else if (y > picker_area_->GetBaseHeight()) rgb_.red = 0.0f; else rgb_.red = 1.0f - (float) y / (float) picker_area_->GetBaseHeight(); if (x < 0) rgb_.blue = 0.0f; else if (x > picker_area_->GetBaseWidth()) rgb_.blue = 1.0f; else rgb_.blue = (float) x / (float) picker_area_->GetBaseWidth(); } if (color_channel_ == color::BLUE) { if (x < 0) rgb_.red = 0.0f; else if (x > picker_area_->GetBaseWidth()) rgb_.red = 1.0f; else rgb_.red = (float) x / (float) picker_area_->GetBaseWidth(); if (y < 0) rgb_.green = 1.0f; else if (y > picker_area_->GetBaseHeight()) rgb_.green = 0.0f; else rgb_.green = 1.0f - (float) y / (float) picker_area_->GetBaseHeight(); } hsv_ = color::HueSaturationValue(rgb_); m_MarkerPosition = Point(Clamp (x, 0, picker_area_->GetBaseWidth() - 1), Clamp (y, 0, picker_area_->GetBaseHeight() - 1)); } if (m_ColorModel == color::HSV) { if (color_channel_ == color::HUE) { if (y < 0) hsv_.value = 1.0f; else if (y > picker_area_->GetBaseHeight()) hsv_.value = 0.0f; else hsv_.value = 1.0f - (float) y / (float) picker_area_->GetBaseHeight(); if (x < 0) hsv_.saturation = 0.0f; else if (x > picker_area_->GetBaseWidth()) hsv_.saturation = 1.0f; else hsv_.saturation = (float) x / (float) picker_area_->GetBaseWidth(); } if (color_channel_ == color::SATURATION) { if (y < 0) hsv_.value = 1.0f; else if (y > picker_area_->GetBaseHeight()) hsv_.value = 0.0f; else hsv_.value = 1.0f - (float) y / (float) picker_area_->GetBaseHeight(); if (x < 0) hsv_.hue = 0.0f; else if (x >= picker_area_->GetBaseWidth()) hsv_.hue = 0.0f; else hsv_.hue = (float) x / (float) picker_area_->GetBaseWidth(); } if (color_channel_ == color::VALUE) { if (x < 0) hsv_.hue = 0.0f; else if (x >= picker_area_->GetBaseWidth()) hsv_.hue = 0.0f; else hsv_.hue = (float) x / (float) picker_area_->GetBaseWidth(); if (y < 0) hsv_.saturation = 1.0f; else if (y > picker_area_->GetBaseHeight()) hsv_.saturation = 0.0f; else hsv_.saturation = 1.0f - (float) y / (float) picker_area_->GetBaseHeight(); } rgb_ = color::RedGreenBlue(hsv_); m_MarkerPosition = Point(Clamp (x, 0, picker_area_->GetBaseWidth() - 1), Clamp (y, 0, picker_area_->GetBaseHeight() - 1)); } redtext->SetText(m_Validator.ToString(255 * rgb_.red)); greentext->SetText(m_Validator.ToString(255 * rgb_.green)); bluetext->SetText(m_Validator.ToString(255 * rgb_.blue)); hue_text_entry_->SetText(m_Validator.ToString(360 * hsv_.hue)); saturation_text_entry_->SetText(m_Validator.ToString(100 * hsv_.saturation)); value_text_entry_->SetText(m_Validator.ToString(100 * hsv_.value)); sigChange.emit(this); QueueDraw(); } void ColorEditor::RecvPickerMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void ColorEditor::RecvPickerMouseDrag(int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { RecvPickerMouseDown(x, y, button_flags, key_flags); } void ColorEditor::RecvCheckColorModel0(AbstractButton * /* button */, color::Model color_mode, color::Channel color_channel) { RecvCheckColorModel(true, color_mode, color_channel); } void ColorEditor::RecvCheckColorModel(bool b, color::Model color_mode, color::Channel color_channel) { if (b) { if ((color_mode == color::HSV) && (m_ColorModel == color::RGB)) { hsv_ = color::HueSaturationValue(rgb_); } if ((color_mode == color::RGB) && (m_ColorModel == color::HSV)) { rgb_ = color::RedGreenBlue(hsv_); } m_ColorModel = color_mode; color_channel_ = color_channel; } if (b && (color_mode == color::RGB)) { int x = 0; int y = 0; int z = 1; if (color_channel_ == color::RED) { z = (1.0f - rgb_.red) * picker_area_->GetBaseHeight(); y = (1.0f - rgb_.green) * picker_area_->GetBaseHeight(); x = rgb_.blue * picker_area_->GetBaseWidth(); } if (color_channel_ == color::GREEN) { z = (1.0f - rgb_.green) * picker_area_->GetBaseHeight(); y = (1.0f - rgb_.red) * picker_area_->GetBaseHeight(); x = rgb_.blue * picker_area_->GetBaseWidth(); } if (color_channel_ == color::BLUE) { z = (1.0f - rgb_.blue) * picker_area_->GetBaseHeight(); y = (1.0f - rgb_.green) * picker_area_->GetBaseHeight(); x = rgb_.red * picker_area_->GetBaseWidth(); } m_VertMarkerPosition = Point(Clamp (0, 0, channel_area_->GetBaseWidth() - 1), Clamp (z, 0, channel_area_->GetBaseHeight() - 1)); m_MarkerPosition = Point(Clamp (x, 0, picker_area_->GetBaseWidth() - 1), Clamp (y, 0, picker_area_->GetBaseHeight() - 1)); redtext->SetText(m_Validator.ToString(255 * rgb_.red)); greentext->SetText(m_Validator.ToString(255 * rgb_.green)); bluetext->SetText(m_Validator.ToString(255 * rgb_.blue)); } if (b && (color_mode == color::HSV)) { int x = 0; int y = 0; int z = 1; if (color_channel_ == color::HUE) { z = (1.0f - hsv_.hue) * picker_area_->GetBaseHeight(); y = (1.0f - hsv_.value) * picker_area_->GetBaseHeight(); x = hsv_.saturation * picker_area_->GetBaseWidth(); } if (color_channel_ == color::SATURATION) { z = (1.0f - hsv_.saturation) * picker_area_->GetBaseHeight(); y = (1.0f - hsv_.value) * picker_area_->GetBaseHeight(); x = hsv_.hue * picker_area_->GetBaseWidth(); } if (color_channel_ == color::VALUE) { z = (1.0f - hsv_.value) * picker_area_->GetBaseHeight(); y = (1.0f - hsv_.saturation) * picker_area_->GetBaseHeight(); x = hsv_.hue * picker_area_->GetBaseWidth(); } m_VertMarkerPosition = Point(Clamp (0, 0, channel_area_->GetBaseWidth() - 1), Clamp (z, 0, channel_area_->GetBaseHeight() - 1)); m_MarkerPosition = Point(Clamp (x, 0, picker_area_->GetBaseWidth() - 1), Clamp (y, 0, picker_area_->GetBaseHeight() - 1)); hue_text_entry_->SetText(m_Validator.ToString(360 * hsv_.hue)); saturation_text_entry_->SetText(m_Validator.ToString(100 * hsv_.saturation)); value_text_entry_->SetText(m_Validator.ToString(100 * hsv_.value)); } QueueDraw(); } Color ColorEditor::GetRGBColor() const { return Color(rgb_); } void ColorEditor::SetRGB(Color const& rgb) { SetRGB(rgb.red, rgb.green, rgb.blue ); } void ColorEditor::SetRGB(double r, double g, double b) { rgb_ = color::RedGreenBlue(Clamp(r, 0.0, 1.0), Clamp(g, 0.0, 1.0), Clamp(b, 0.0, 1.0)); hsv_ = color::HueSaturationValue(rgb_); RecvCheckColorModel(true, m_ColorModel, color_channel_); sigChange.emit(this); } void ColorEditor::SetHSV(double h, double s, double v) { hsv_ = color::HueSaturationValue(Clamp(h, 0.0, 1.0), Clamp(s, 0.0, 1.0), Clamp(v, 0.0, 1.0)); rgb_ = color::RedGreenBlue(hsv_); RecvCheckColorModel(true, m_ColorModel, color_channel_); sigChange.emit(this); } void ColorEditor::SetRed(double red) { SetRGB(red, rgb_.green, rgb_.blue); } void ColorEditor::SetGreen(double green) { SetRGB(rgb_.red, green, rgb_.blue); } void ColorEditor::SetBlue(double blue) { SetRGB(rgb_.red, rgb_.green, blue); } void ColorEditor::SetHue(double hue) { SetHSV(hue, hsv_.saturation, hsv_.value); } void ColorEditor::SetSaturation(double saturation) { SetHSV(hsv_.hue, saturation, hsv_.value); } void ColorEditor::SetValue(double value) { SetHSV(hsv_.hue, hsv_.saturation, value); } void ColorEditor::SetColorModel(color::Model colormodel, color::Channel colorchannel) { if (colormodel == color::HSV) { if ((colorchannel != color::HUE) && (colorchannel != color::SATURATION) && (colorchannel != color::VALUE)) { nuxDebugMsg("[ColorEditor::SetColorModel] The color model(HSV) and the color channel don't match."); return; } } if (colormodel == color::RGB) { if ((colorchannel != color::RED) && (colorchannel != color::GREEN) && (colorchannel != color::BLUE)) { nuxDebugMsg("[ColorEditor::SetColorModel] The color model(RGB) and the color channel don't match."); return; } } m_ColorModel = colormodel; color_channel_ = colorchannel; RecvCheckColorModel(true, m_ColorModel, color_channel_); /*FIXME - disabled because we lost radiogroup if (color_channel_ == color::RED) radiogroup->ActivateButton(redcheck); else if (color_channel_ == color::GREEN) radiogroup->ActivateButton(greencheck); else if (color_channel_ == color::BLUE) radiogroup->ActivateButton(bluecheck); else if (color_channel_ == color::HUE) radiogroup->ActivateButton(huecheck); else if (color_channel_ == color::SATURATION) radiogroup->ActivateButton(saturationcheck); else if (color_channel_ == color::VALUE) radiogroup->ActivateButton(valuecheck); */ } color::Model ColorEditor::GetColorModel() const { return m_ColorModel; } color::Channel ColorEditor::GetColorChannel() const { return color_channel_; } bool ColorEditor::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/ColorPickerDialog.h0000644000015301777760000000251412321344237021216 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef COLORPICKERDIALOG_H #define COLORPICKERDIALOG_H #include "Dialog.h" #include "ColorEditor.h" namespace nux { class HLayout; class VLayout; class ColorPickerDialog : public Dialog { public: ColorPickerDialog(); ~ColorPickerDialog(); virtual void RecvOk(); virtual void RecvCancel(); void StartDialog(Color &color, color::Model ColorModel = color::RGB, bool StartModal = false); private: VLayout *m_Vlayout; ColorEditor *m_ColorEditor; Color &m_Color; }; } #endif // COLORPICKERDIALOG_H nux-4.0.6+14.04.20140409/Nux/Dialog.h0000644000015301777760000000236112321344237017061 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef DIALOG_H #define DIALOG_H #include "FloatingWindow.h" namespace nux { class Button; class Dialog: public FloatingWindow { public: Dialog (const TCHAR *WindowName = TEXT ("") ); virtual ~Dialog(); protected: virtual void RecvOk() = 0; virtual void RecvCancel() = 0; virtual void Start (bool StartModal); Button *m_OkButton; Button *m_CancelButton; HLayout *m_ButtonLayout; }; } #endif // DIALOG_H nux-4.0.6+14.04.20140409/Nux/StaticTextBox.cpp0000644000015301777760000000733212321344237020765 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "Validator.h" #include "StaticTextBox.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(StaticTextBox); StaticTextBox::StaticTextBox(const char *Caption, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_TextAlignment(eAlignTextLeft) , m_bMinimumWidthMatchText(true) , m_bDrawBackground(false) , m_WriteAlpha(true) { m_BackgroundColor = Color(0xFF343434); m_TextColor = Color(1.0f, 1.0f, 1.0f, 1.0f); // First, set the default minimum size. SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); // The width size of the text is computed in SetText and set as the minimum for the widget. // If the text is null or empty, then the default minimum widtth set above remains. SetText(Caption); SetGeometry(Geometry(0, 0, 3 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); // This widget does not use a layout! m_Background = 0; } StaticTextBox::~StaticTextBox() { delete m_Background; } void StaticTextBox::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); { graphics_engine.PushClippingRectangle(base); if (m_bDrawBackground) { GetPainter().PushDrawLayer(graphics_engine, base, m_Background); GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), GetGeometry(), m_Text, m_TextColor, m_WriteAlpha, m_TextAlignment); GetPainter().PopBackground(); } else { //GetPainter().PaintBackground(graphics_engine, base); GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), GetGeometry(), m_Text, m_TextColor, m_WriteAlpha, m_TextAlignment); } graphics_engine.PopClippingRectangle(); } } void StaticTextBox::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void StaticTextBox::SetText(const char *Caption) { std::string s(Caption); SetText(s); } void StaticTextBox::SetText(const std::string &Caption) { m_Text = Caption; if (GetMinWidthMatchText()) AdjustMinWidthToMatchText(); QueueDraw(); } void StaticTextBox::SetMinWidthMatchText(bool b) { m_bMinimumWidthMatchText = b; if (m_bMinimumWidthMatchText) AdjustMinWidthToMatchText(); } bool StaticTextBox::GetMinWidthMatchText() const { return m_bMinimumWidthMatchText; } void StaticTextBox::AdjustMinWidthToMatchText() { if (m_Text.size() == 0) return; SetMinimumWidth(/*4 + */GetFont()->GetStringWidth(m_Text)); } void StaticTextBox::SetFont(ObjectPtr Font) { View::SetFont(Font); if (GetMinWidthMatchText()) AdjustMinWidthToMatchText(); } void StaticTextBox::SetBackground(AbstractPaintLayer *layer) { delete m_Background; m_Background = layer->Clone(); } bool StaticTextBox::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/StaticText.cpp0000644000015301777760000006102112321344237020307 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "Validator.h" #include "cairo/cairo.h" #include "pango/pango.h" #include "pango/pangocairo.h" #include "NuxGraphics/CairoGraphics.h" #include "NuxGraphics/GraphicsDisplay.h" #include "StaticText.h" #if defined(NUX_OS_WINDOWS) #include "D2DTextRenderer.h" #endif namespace nux { // DIP = Device Independent Pixel unit // 1 DIP = 1/96 inch. // 1 inch = 72 points. float ConvertPointSizeToDIP(float points) { return points; //return (points/72.0f)*96.0f; } NUX_IMPLEMENT_OBJECT_TYPE(StaticText); StaticText::StaticText(const std::string& text, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , text_width_(0) , text_height_(0) { padding_x_ = 0; padding_y_ = 0; update_text_rendering_ = true; text_alignment_ = ALIGN_CENTER; #if defined(NUX_STATIC_TEXT_USE_DIRECT_WRITE) layout_left_ = 0; layout_top_ = 0; GetGraphicsDisplay()->GetDirect2DFactory()->GetDesktopDpi(&dpi_scale_x, &dpi_scale_y); dpi_scale_x /= 96.0f; dpi_scale_y /= 96.0f; // 1 DIP = (1/96) inch; 1 inch = 96 DIP // PixelToDIP = (pixels/dpi)*96.0f font_size_ = 12; font_name_ = "Tahoma"; #elif defined(NUX_STATIC_TEXT_USE_CAIRO) cairo_graphics_ = NULL; font_size_ = 10; font_name_ = "Ubuntu"; std::ostringstream os; os << font_name_ << " " << font_size_; pango_font_name_ = std::string(os.str()); dpy_ = 96.0f; #endif size_match_text_ = true; text_color_ = color::White; clip_to_width_ = 0; SetMinimumSize(1, 1); SetText(text); } StaticText::~StaticText() { #if defined(NUX_STATIC_TEXT_USE_CAIRO) if (cairo_graphics_ != 0) delete(cairo_graphics_); #endif if (dw_texture_.IsValid()) dw_texture_.Release(); } void StaticText::ApplyMinWidth() { Size sz = GetTextSizeNoClip(); if ((sz.width <= GetMaximumWidth()) && (sz.width >= GetMinimumWidth())) { SetBaseWidth(sz.width); } else if (sz.width >= GetMaximumWidth()) { View::ApplyMaxWidth(); } else { View::ApplyMinWidth(); } } long StaticText::ComputeContentSize() { int pre_layout_width = GetBaseWidth(); int pre_layout_height = GetBaseHeight(); Size sz = GetTextSizeNoClip(); // The height of the StaticText is the height of the text itself. SetBaseHeight(sz.height); if ((sz.width >= GetMinimumWidth()) && (sz.width <= GetMaximumWidth())) { // The text size is within the bounds of the view. SetBaseWidth(sz.width); } else if (sz.width > GetMaximumWidth()) { // The text is bigger than the available size. ApplyMaxWidth(); } else if (sz.width < GetMinimumWidth()) { // The text size is smaller than the minimum width of the view. View::ApplyMinWidth(); } // Get the width size of this area. int width = GetBaseWidth(); int height = GetBaseHeight(); if (sz.width > width) { // The text is too large to fit. // There will be ellipsis at the end of the text. SetClipping(width); } else { // The text fits inside the view. SetClipping(0); } long result = 0; if (pre_layout_width < width) result |= eLargerWidth; else if (pre_layout_width > width) result |= eSmallerWidth; else result |= eCompliantWidth; if (pre_layout_height < height) result |= eLargerHeight; else if (pre_layout_height > height) result |= eSmallerHeight; else result |= eCompliantHeight; return result; } void StaticText::SetSizeMatchText(bool size_match_text) { size_match_text_ = size_match_text; } bool StaticText::GetSizeMatchText() const { return size_match_text_; } void StaticText::SetClipping(int clipping) { if (clip_to_width_ == clipping) return; clip_to_width_ = clipping; if (clip_to_width_ < 0) clip_to_width_ = 0; ComputeTextSize(); update_text_rendering_ = true; } int StaticText::GetClipping() const { return clip_to_width_; } void StaticText::Draw(GraphicsEngine& graphics_engine, bool /* forceDraw */) { if (update_text_rendering_) { UpdateTextRendering(); } // Draw background texture here. if (!dw_texture_.IsValid()) return; Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); nux::GetPainter().PaintBackground(graphics_engine, base); // Get the current blend states. They will be restored later. unsigned int alpha = 0, src = 0, dest = 0; graphics_engine.GetRenderStates().GetBlend(alpha, src, dest); graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); TexCoordXForm texxform; texxform.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP); texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); // Compute and y coordinate centered on the view int y = base.y + (base.height - dw_texture_->GetHeight()) / 2; int x = base.x; //Special case: In the horizontal direction, if the width of the text is smaller than the // width of the view, then center the text horizontally. if (dw_texture_->GetWidth() < base.width) { if (text_alignment_ == ALIGN_CENTER) { x = base.x + (base.width - dw_texture_->GetWidth()) / 2; } else if (text_alignment_ == ALIGN_LEFT) { x = base.x; } else if (text_alignment_ == ALIGN_RIGHT) { x = base.x + base.width - dw_texture_->GetWidth(); } } graphics_engine.QRP_1Tex(x, y, dw_texture_->GetWidth(), dw_texture_->GetHeight(), dw_texture_, texxform, text_color_); graphics_engine.GetRenderStates().SetBlend(alpha, src, dest); graphics_engine.PopClippingRectangle(); } void StaticText::SetFontSize(int font_size) { if (font_size <= 0) return; #if defined(NUX_STATIC_TEXT_USE_DIRECT_WRITE) font_size_ = font_size; #elif defined(NUX_STATIC_TEXT_USE_CAIRO) font_size_ = font_size; std::ostringstream os; os << font_name_ << " " << font_size_; pango_font_name_ = std::string(os.str()); #endif // reset cache no_clip_size_.width = 0; no_clip_size_.height = 0; // Changing the font can cause the StaticView to resize itself. Size sz = GetTextSizeNoClip(); // Calling SetBaseSize will trigger a layout request of this view and all of its parents. SetBaseSize(sz.width, sz.height); } void StaticText::SetTextPointSize(int font_size) { SetFontSize(font_size); } int StaticText::GetFontSize() const { return font_size_; } int StaticText::GetTextPointSize() const { return GetFontSize(); } void StaticText::SetText(const std::string& text) { if (text_ == text) return; text_ = text; // reset cache no_clip_size_.width = 0; no_clip_size_.height = 0; // Changing the font can cause the StaticView to resize itself. Size sz = GetTextSizeNoClip(); // Calling SetBaseSize will trigger a layout request of this view and all of its parents. SetBaseSize(sz.width, sz.height); update_text_rendering_ = true; text_changed.emit(this); QueueDraw(); } std::string StaticText::GetText() const { return text_; } void StaticText::SetTextColor(const Color& text_color) { text_color_ = text_color; QueueDraw(); } Color StaticText::GetTextColor() const { return text_color_; } void StaticText::SetFontName(const std::string& font_name) { if (font_name_ == font_name) return; font_name_ = font_name; #if defined(NUX_OS_LINUX) std::ostringstream os; os << font_name_ << " " << font_size_; pango_font_name_ = std::string(os.str()); #endif // reset cache no_clip_size_.width = 0; no_clip_size_.height = 0; // Changing the font can cause the StaticView to resize itself. Size sz = GetTextSizeNoClip(); // Calling SetBaseSize will trigger a layout request of this view and all of its parents. SetBaseSize(sz.width, sz.height); QueueDraw(); } std::string StaticText::GetFontName() const { return font_name_; } void StaticText::GetTextLayoutSize(int& width, int& height) const { if (text_ == "") { width = 0; height = 0; return; } width = text_width_; height = text_height_; } Size StaticText::GetTextLayoutSize() const { Size sz; GetTextLayoutSize(sz.width, sz.height); return sz; } void StaticText::SetTextAlignment(TextAlignment alignment) { text_alignment_ = alignment; } StaticText::TextAlignment StaticText::GetTextAlignment() const { return text_alignment_; } ObjectPtr StaticText::GetTextTexture() { if (update_text_rendering_) { // If the text rendering needs to be updated, do it here. UpdateTextRendering(); } return dw_texture_; } Size StaticText::GetTextSizeNoClip() { if (no_clip_size_.width == 0) no_clip_size_ = ComputeTextSize(false, false); return no_clip_size_; } #if defined(NUX_STATIC_TEXT_USE_DIRECT_WRITE) Size StaticText::ComputeTextSize(bool assign, bool with_clipping) { HRESULT hr; IDWriteFactory* pDWriteFactory = GetGraphicsDisplay()->GetDirectWriteFactory(); ID2D1RenderTarget* pRT = NULL; IDWriteTextFormat* pTextFormat = NULL; hr = pDWriteFactory->CreateTextFormat( ANSICHAR_TO_UNICHAR(font_name_.c_str()), // Font family name. NULL, // Font collection(NULL sets it to use the system font collection). DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, ConvertPointSizeToDIP(font_size_), L"en-us", &pTextFormat); // Center align(horizontally) the text. if (SUCCEEDED(hr)) { hr = pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); } if (SUCCEEDED(hr)) { hr = pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); } if (SUCCEEDED(hr)) { hr = pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); } IDWriteTextLayout* pTextLayout_; hr = pDWriteFactory->CreateTextLayout( TCHAR_TO_UNICHAR(text_.c_str()), // The string to be laid out and formatted. text_.length(), // The length of the string. pTextFormat, // The text format to apply to the string(contains font information, etc). 1, // The width of the layout box. 1, // The height of the layout box. &pTextLayout_ // The IDWriteTextLayout interface pointer. ); DWRITE_TEXT_METRICS metrics; pTextLayout_->GetMetrics(&metrics); int text_width = std::ceil(metrics.widthIncludingTrailingWhitespace * dpi_scale_x); int text_height = std::ceil(metrics.height * dpi_scale_y); if (assign) { text_width_ = text_width; text_height_ = text_height; padding_x_ = text_width_ - metrics.widthIncludingTrailingWhitespace * dpi_scale_x; padding_y_ = text_height_ - metrics.height * dpi_scale_y; if (with_clipping && (clip_to_width_ > 0)) { text_width_ = text_width_ <= clip_to_width_ ? text_width_ : clip_to_width_; } text_width = text_width_; text_height = text_height_; } layout_top_ = metrics.top * dpi_scale_x; layout_left_ = metrics.left * dpi_scale_y; if (pTextLayout_) { pTextLayout_->Release(); pTextLayout_ = NULL; } if (pTextFormat) { pTextFormat->Release(); pTextFormat = NULL; } return Size(text_width, text_height); } void StaticText::RasterizeText(Color color) { if ((text_width_ <=0) || (text_height_ <= 0)) { dw_texture_.Release(); return; } HRESULT hr; ID2D1Factory* pD2DFactory = GetGraphicsDisplay()->GetDirect2DFactory(); IDWriteFactory* pDWriteFactory = GetGraphicsDisplay()->GetDirectWriteFactory(); IWICImagingFactory* pWICFactory = GetGraphicsDisplay()->GetWICFactory(); ID2D1RenderTarget* pRT = NULL; IDWriteTextFormat* pTextFormat = NULL; hr = pDWriteFactory->CreateTextFormat( ANSICHAR_TO_UNICHAR(font_name_.c_str()), // Font family name. NULL, // Font collection(NULL sets it to use the system font collection). DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, ConvertPointSizeToDIP(font_size_), L"en-us", &pTextFormat); // Center align(horizontally) the text. if (SUCCEEDED(hr)) { hr = pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); } if (SUCCEEDED(hr)) { hr = pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); } if (SUCCEEDED(hr)) { hr = pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); } IDWriteTextLayout* pTextLayout_ = NULL; hr = pDWriteFactory->CreateTextLayout( TCHAR_TO_UNICHAR(text_.c_str()), // The string to be laid out and formatted. text_.length(), // The length of the string. pTextFormat, // The text format to apply to the string(contains font information, etc). text_width_ / dpi_scale_x, // The width of the layout box. text_height_ / dpi_scale_y, // The height of the layout box. &pTextLayout_ // The IDWriteTextLayout interface pointer. ); IDWriteInlineObject* inlineObject = NULL; if (SUCCEEDED(hr)) { pDWriteFactory->CreateEllipsisTrimmingSign( pTextLayout_, &inlineObject); } DWRITE_TRIMMING trimming = {DWRITE_TRIMMING_GRANULARITY_CHARACTER, 0, 0}; hr = pTextLayout_->SetTrimming(&trimming, inlineObject); IWICBitmap* pWICBitmap = NULL; if (SUCCEEDED(hr)) { hr = pWICFactory->CreateBitmap( text_width_ / dpi_scale_x, text_height_ / dpi_scale_y, GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnLoad, &pWICBitmap); } // Set the render target type to D2D1_RENDER_TARGET_TYPE_DEFAULT to use software rendering. if (SUCCEEDED(hr)) { D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties; renderTargetProperties.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; renderTargetProperties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; renderTargetProperties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; renderTargetProperties.dpiX = 0.0; renderTargetProperties.dpiY = 0.0; renderTargetProperties.usage = D2D1_RENDER_TARGET_USAGE_NONE; renderTargetProperties.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; hr = pD2DFactory->CreateWicBitmapRenderTarget( pWICBitmap, renderTargetProperties, //D2D1::RenderTargetProperties(), &pRT); } ID2D1SolidColorBrush* pBrush; hr = pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(color.red, color.green, color.blue, color.alpha)), &pBrush); // Create the text renderer CustomTextRenderer* pTextRenderer_ = new (std::nothrow) CustomTextRenderer( pD2DFactory, pRT, pBrush, NULL); D2D1_POINT_2F origin = D2D1::Point2F(static_cast(padding_x_ / dpi_scale_x), static_cast(padding_y_ / dpi_scale_y)); if (0) { if (SUCCEEDED(hr)) { pRT->BeginDraw(); pRT->SetTransform(D2D1::IdentityMatrix()); pRT->Clear(D2D1::ColorF(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.0f))); // Call the DrawText method of this class. hr = pTextLayout_->Draw( NULL, pTextRenderer_, // Custom text renderer. origin.x, origin.y ); hr = pRT->EndDraw(); } } else { if (SUCCEEDED(hr)) { pRT->BeginDraw(); pRT->SetTransform(D2D1::IdentityMatrix()); pRT->Clear(D2D1::ColorF(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.0f))); // Call the DrawText method of this class. pRT->DrawTextLayout( origin, pTextLayout_, pBrush); hr = pRT->EndDraw(); } } { unsigned int width, height; pWICBitmap->GetSize(&width, &height); dw_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(width, height, 1, nux::BITFMT_B8G8R8A8, NUX_TRACKER_LOCATION); nux::SURFACE_LOCKED_RECT lock_rect; dw_texture_->LockRect(0, &lock_rect, NULL); pWICBitmap->CopyPixels(NULL, lock_rect.Pitch, 4*width*height, (BYTE*) lock_rect.pBits); dw_texture_->UnlockRect(0); } if (pTextRenderer_) delete pTextRenderer_; if (pBrush) { pBrush->Release(); pBrush = NULL; } if (pRT) { pRT->Release(); pRT = NULL; } if (pWICBitmap) { pWICBitmap->Release(); pWICBitmap = NULL; } if (pTextLayout_) { pTextLayout_->Release(); pTextLayout_ = NULL; } if (pTextFormat) { pTextFormat->Release(); pTextFormat = NULL; } } void StaticText::UpdateTextRendering() { Size sz = ComputeTextSize(); if (sz.width == 0 || sz.height == 0) { // Nothing to render if (dw_texture_.IsValid()) { dw_texture_.Release(); } return; } RasterizeText(color::White); update_text_rendering_ = false; } #elif defined(NUX_STATIC_TEXT_USE_CAIRO) Size StaticText::ComputeTextSize(bool assign, bool with_clipping) { cairo_surface_t* pango_surface = NULL; cairo_t* cairo_ctx = NULL; PangoLayout* pango_layout = NULL; PangoFontDescription* font_desc = NULL; PangoContext* pango_ctx = NULL; PangoRectangle ink_rect = {0, 0, 0, 0}; PangoRectangle logical_rect = {0, 0, 0, 0}; int dpi = 96; // Create Cairo surface. pango_surface = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1); // Create Cairo context. cairo_ctx = cairo_create(pango_surface); // Create layout. pango_layout = pango_cairo_create_layout(cairo_ctx); { pango_layout_set_wrap (pango_layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(pango_layout, PANGO_ELLIPSIZE_END); pango_layout_set_markup (pango_layout, text_.c_str(), -1); } // Create font description: "[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]" font_desc = pango_font_description_from_string(pango_font_name_.c_str()); { pango_font_description_set_weight(font_desc, PANGO_WEIGHT_NORMAL); pango_layout_set_font_description(pango_layout, font_desc); } // Get Pango context pango_ctx = pango_layout_get_context(pango_layout); // is not ref'ed // Set font options CairoFontOptions font_options; { cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_DEFAULT); cairo_font_options_set_subpixel_order(font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_set_font_options(cairo_ctx, font_options); pango_cairo_context_set_font_options(pango_ctx, font_options); } // use some default DPI-value pango_cairo_context_set_resolution(pango_ctx, dpi); pango_layout_context_changed(pango_layout); pango_layout_get_extents(pango_layout, &ink_rect, &logical_rect); int text_width = std::ceil((float)logical_rect.width / PANGO_SCALE); int text_height = std::ceil((float)logical_rect.height / PANGO_SCALE); if (assign) { text_width_ = text_width; text_height_ = text_height; padding_x_ = text_width_ - logical_rect.width / PANGO_SCALE; padding_y_ = text_height_ - logical_rect.height / PANGO_SCALE; if (with_clipping && (clip_to_width_ > 0)) { text_width_ = text_width_ <= clip_to_width_ ? text_width_ : clip_to_width_; } text_width = text_width_; text_height = text_height_; } // clean up pango_font_description_free(font_desc); g_object_unref(pango_layout); cairo_destroy(cairo_ctx); cairo_surface_destroy(pango_surface); return Size(text_width, text_height); } void StaticText::RasterizeText(void* cairo_context, Color /* color */) { cairo_t* cairo_ctx = (cairo_t*) cairo_context; PangoLayout* pango_layout = NULL; PangoFontDescription* font_desc = NULL; PangoContext* pango_ctx = NULL; int dpi = 96; // Create layout. pango_layout = pango_cairo_create_layout(cairo_ctx); { pango_layout_set_wrap (pango_layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize(pango_layout, PANGO_ELLIPSIZE_END); pango_layout_set_markup (pango_layout, text_.c_str(), -1); // Sets the width to which the lines of the PangoLayout should wrap or ellipsized. The default value is -1: no width set. pango_layout_set_width(pango_layout, (clip_to_width_ ? clip_to_width_ : text_width_) * PANGO_SCALE); } // Create font description: "[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]" font_desc = pango_font_description_from_string(pango_font_name_.c_str()); { pango_font_description_set_weight(font_desc, PANGO_WEIGHT_NORMAL); pango_layout_set_font_description(pango_layout, font_desc); } // Get Pango context pango_ctx = pango_layout_get_context(pango_layout); // is not ref'ed // Set font options CairoFontOptions font_options; { cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_DEFAULT); cairo_font_options_set_subpixel_order (font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_set_font_options(cairo_ctx, font_options); pango_cairo_context_set_font_options(pango_ctx, font_options); } pango_cairo_context_set_resolution(pango_ctx, dpi); cairo_set_source_rgba(cairo_ctx, 1.0, 1.0, 1.0, 1.0); pango_layout_context_changed(pango_layout); cairo_move_to(cairo_ctx, padding_x_, padding_y_); pango_cairo_show_layout(cairo_ctx, pango_layout); // clean up pango_font_description_free(font_desc); g_object_unref(pango_layout); } void StaticText::UpdateTextRendering() { Size sz = ComputeTextSize(); if (sz.width == 0 || sz.height == 0) { // Nothing to render if (dw_texture_.IsValid()) { dw_texture_.Release(); } return; } cairo_graphics_ = new CairoGraphics(CAIRO_FORMAT_ARGB32, sz.width, sz.height); cairo_t* cairo_ctx = cairo_graphics_->GetContext(); cairo_set_operator(cairo_ctx, CAIRO_OPERATOR_CLEAR); cairo_paint(cairo_ctx); cairo_set_operator(cairo_ctx, CAIRO_OPERATOR_OVER); RasterizeText(cairo_ctx, text_color_); NBitmapData* bitmap = cairo_graphics_->GetBitmap(); // NTexture2D is the high level representation of an image that is backed by // an actual opengl texture. BaseTexture* rasterized_text_texture = NULL; rasterized_text_texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); rasterized_text_texture->Update(bitmap); dw_texture_ = rasterized_text_texture->GetDeviceTexture(); rasterized_text_texture->UnReference(); rasterized_text_texture = NULL; delete bitmap; cairo_destroy(cairo_ctx); delete cairo_graphics_; cairo_graphics_ = NULL; update_text_rendering_ = false; } #endif } nux-4.0.6+14.04.20140409/Nux/Nux.h0000644000015301777760000002306212321344237016435 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUX_H #define NUX_H #include "NuxCore/NuxCore.h" #include "NuxCore/Error.h" #include "NuxCore/FilePath.h" #include "NuxCore/Color.h" #include "NuxCore/Rect.h" #include "NuxCore/Point.h" #include "NuxCore/Size.h" #include "NuxCore/ObjectPtr.h" #include "NuxCore/Math/Constants.h" #include "NuxCore/Math/Vector3.h" #include "NuxCore/Math/Vector4.h" #include "NuxCore/Math/Matrix3.h" #include "NuxCore/Math/Matrix4.h" #include "NuxCore/Math/Spline.h" #include #include #include #include #include #include #include #define NUX_USE_GLIB_LOOP_ON_WINDOWS //#define NUX_DISABLE_GLIB_LOOP #if defined(NUX_OS_LINUX) #include "Features.h" #endif #include "Utils.h" #include "WidgetMetrics.h" #include "Area.h" #include "InputArea.h" #include "Theme.h" #include "Painter.h" #include "View.h" #include "BasicView.h" #include "AbstractThread.h" #include "WindowThread.h" #include "WindowCompositor.h" #if !defined(NUX_MINIMAL) # include "Timeline.h" #endif #include "SystemThread.h" namespace nux { class WindowThread; class SystemThread; class WindowCompositor; class TimerHandler; void NuxInitialize(const char *CommandLine); //! Create a Nux window. /*! Create a Nux window. The window @param window_title The window title. @param width The window width. @param height The window height. @param parent The window height parent. Should be NULL. @param user_init_func Initialization function to be called before starting the window loop. @param data Parameter to the initialization function. */ WindowThread *CreateGUIThread(const char *window_title, int width, int height, WindowThread *parent = NULL, ThreadUserInitFunc user_init_func = NULL, void *data = NULL); //! Create the only Nux window for the current system thread. /*! There can be only one NuxWindow per system thread. This function creates the only Nux window allowed in the current thread. \n The first time this function is called in the current system thread, it returns a valid pointer to a NuxWindow object. The next time it is called, the system detects that a NuxWindow has already been created in the thread and it returns NULL. \n When CreateNuxWindow successfully returns, the NuxWindow internals (GraphicsDisplay, Compositor, Painter, TimerManager) have been initialized. Calling nux::GetThreadNuxWindow() returns a pointer to the NuxWindow that has been successfully created in the current thread. \n To start the main loop of a NuxWindow created with CreateNuxWindow, call NuxWindow::Run(); \n The modal parameter specifies if the window is blocking while it is active. This is valid only if the parent thread is a WindowThread. @param window_title The window title. @param width The window width. @param height The window height. @param window_border_style The window border style. @param parent The window parent. @param modal Modality of the window. @param user_init_func Initialization function to be called before starting the window loop. @param data Parameter to the initialization function. @return A valid pointer to a NuxWindow if the window has been successfully created. NULL otherwise. */ WindowThread *CreateNuxWindow(const char *window_title, int width, int height, WindowStyle window_border_style = WINDOWSTYLE_NORMAL, AbstractThread *parent = NULL, bool modal = false, ThreadUserInitFunc user_init_func = NULL, void *data = NULL); //! Create a Nux window to be run in a new thread. /*! Create a Nux window that will run in a new thread. Unlike CreateNuxWindow, CreateNuxWindowNewThread should always successfully return a valid NuxWindow pointer. However, the internal objects of the NuxWindow (GraphicsDisplay, Compositor, Painter, TimerManager) have not been initialized yet. So, calling NuxWindow::GetWindowCompositor(), NuxWindow::GetGraphicsDisplay() will fail. \n To start the main loop of a NuxWindow created with CreateNuxWindow, call NuxWindow::Run(); \n The modal parameter specifies if the window is blocking its parent window while it is active. This is valid only if the parent thread is a WindowThread. @param window_title The window title. @param width The window width. @param height The window height. @param window_border_style The window border style. @param parent The window parent. @param modal Modality of the window. @param user_init_func Initialization function to be called before starting the window loop. @param data Parameter to the initialization function. @return A valid pointer to a NuxWindow if the window has been successfully created. NULL otherwise. */ WindowThread *CreateNuxWindowNewThread(const char *window_title, int width, int height, WindowStyle window_border_style = WINDOWSTYLE_NORMAL, AbstractThread *parent = NULL, bool modal = false, ThreadUserInitFunc user_init_func = NULL, void *data = NULL); #if defined(NUX_OS_WINDOWS) //! Create a main graphics thread. This thread has a window and no parent window. WindowThread *CreateFromForeignWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext, ThreadUserInitFunc user_init_func, void *data); #elif defined(NO_X11) #elif defined(NUX_OS_LINUX) //! Create a main graphics thread. This thread has a window and no parent window. #ifdef NUX_OPENGLES_20 WindowThread *CreateFromForeignWindow (Window X11Window, EGLContext OpenGLContext, ThreadUserInitFunc user_init_func, void *data); #else WindowThread *CreateFromForeignWindow (Window X11Window, GLXContext OpenGLContext, ThreadUserInitFunc user_init_func, void *data); #endif #endif // Create a window thread that is a child of the Parent. This thread has a window. /*! @param window_style The window style. @param window_title The window title. @param width The window width. @param height The window height. @param parent The window parent. @param user_init_func Initialization function to be called before starting the window loop. @param data Parameter to the initialization function. */ WindowThread *CreateWindowThread(WindowStyle window_style, const char *window_title, int width, int height, WindowThread *parent, ThreadUserInitFunc user_init_func = NULL, void *data = NULL); // Create a Modal window thread that is a child of the Parent. This thread has a window. /*! @param window_style The window style. @param window_title The window title. @param width The window width. @param height The window height. @param parent The window height parent. Should be NULL. @param user_init_func Initialization function to be called before starting the window loop. @param data Parameter to the initialization function. */ WindowThread *CreateModalWindowThread(WindowStyle window_style, const char *window_title, int width, int height, WindowThread *parent, ThreadUserInitFunc user_init_func = NULL, void *data = NULL); // Create a simple thread SystemThread *CreateSystemThread(AbstractThread *parent = NULL, ThreadUserInitFunc user_init_func = NULL, void *data = NULL); /* ThreadState GetThreadState(unsigned int ThreadID);*/ ObjectPtr GetSysFont(); ObjectPtr GetSysBoldFont(); WindowThread *GetWindowThread(); WindowThread *GetThreadNuxWindow(); WindowCompositor &GetWindowCompositor(); BasePainter &GetPainter(); UXTheme &GetTheme(); TimerHandler &GetTimer(); #define gPainter nux::GetPainter() // deprecated #define gTheme nux::GetTheme() // deprecated inlDeclareThreadLocalStorage(NThread *, 0, ThreadLocal_InalogicAppImpl); } #endif // NUX_H nux-4.0.6+14.04.20140409/Nux/AbstractButton.cpp0000644000015301777760000001024512321344237021154 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * Gordon Allott * */ #include "Nux.h" #include "AbstractButton.h" #include "StaticText.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(AbstractButton); AbstractButton::AbstractButton(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , visual_state_(VISUAL_STATE_NORMAL) { active_ = false; mouse_pressed_ = false; static_text_ = NULL; label_color_ = color::White; same_size_as_content_ = false; label_font_size_ = 0; // use default point size defined in nux::StaticText mouse_click.connect(sigc::mem_fun(this, &AbstractButton::RecvClick)); mouse_down.connect(sigc::mem_fun(this, &AbstractButton::RecvMouseDown)); mouse_double_click.connect(sigc::mem_fun(this, &AbstractButton::RecvMouseDown)); mouse_up.connect(sigc::mem_fun(this, &AbstractButton::RecvMouseUp)); mouse_move.connect(sigc::mem_fun(this, &AbstractButton::RecvMouseMove)); mouse_enter.connect(sigc::mem_fun(this, &AbstractButton::RecvMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &AbstractButton::RecvMouseLeave)); } AbstractButton::~AbstractButton() { } bool AbstractButton::Active() const { return active_; } void AbstractButton::SetActive(bool active) { if (active) Activate(); else Deactivate(); } ButtonVisualState AbstractButton::GetVisualState() { return visual_state_; } void AbstractButton::RecvMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (IsMousePointerInside()) { visual_state_ = VISUAL_STATE_PRELIGHT; } else { visual_state_ = VISUAL_STATE_NORMAL; } mouse_pressed_ = false; visual_state_change.emit(this); QueueDraw(); } void AbstractButton::RecvMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { visual_state_ = VISUAL_STATE_PRESSED; mouse_pressed_ = true; visual_state_change.emit(this); QueueDraw(); } void AbstractButton::RecvMouseMove(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } void AbstractButton::RecvMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (mouse_pressed_) { visual_state_ = VISUAL_STATE_PRESSED; } else { visual_state_ = VISUAL_STATE_PRELIGHT; } visual_state_change.emit(this); QueueDraw(); } void AbstractButton::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { visual_state_ = VISUAL_STATE_NORMAL; visual_state_change.emit(this); QueueDraw(); } void AbstractButton::SetLabelColor(const Color &color) { label_color_ = color; if (static_text_) static_text_->SetTextColor(label_color_); QueueDraw(); } Color AbstractButton::GetLabelColor() { return label_color_; } ButtonVisualState AbstractButton::GetVisualState() const { return visual_state_; } void AbstractButton::SetLabelFontSize(int point) { if (point < 0) return; label_font_size_ = point; if (static_text_) { static_text_->SetTextPointSize(label_font_size_); ComputeContentSize(); QueueDraw(); } } int AbstractButton::GetLabelFontSize() const { return label_font_size_; } } nux-4.0.6+14.04.20140409/Nux/ToggleButton.h0000644000015301777760000000263412321344237020302 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef TOGGLEBUTTON_H #define TOGGLEBUTTON_H #include "Button.h" namespace nux { class HLayout; //! A Button with a persistent activate state. /*! The ToggleButton class has a persistent active state. When it is active, it is visually different from its normal state. */ class ToggleButton: public Button { public: ToggleButton(TextureArea *image, NUX_FILE_LINE_PROTO); ToggleButton(const std::string label, NUX_FILE_LINE_PROTO); ToggleButton(const std::string label, TextureArea *image, NUX_FILE_LINE_PROTO); ToggleButton(NUX_FILE_LINE_PROTO); ~ToggleButton(); }; } #endif // TOGGLEBUTTON_H nux-4.0.6+14.04.20140409/Nux/BaseWindow.h0000644000015301777760000002276412321344237017735 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef BASEWINDOW_H #define BASEWINDOW_H #include #include "ScrollView.h" #include "NuxGraphics/Events.h" #if defined(USE_X11) # include "NuxGraphics/XInputWindow.h" #endif #include "InputArea.h" #include "PaintLayer.h" namespace nux { class BaseWindow; typedef BaseWindow ViewWindow; class HLayout; class PopUpWindow; #ifdef NUX_GESTURES_SUPPORT class GestureEvent; #endif //typedef TopView BaseWindow; /*! A user provided callback to assert the size and position of a floating area. The callback receives a proposed size and position for the floating area. Inside the callback, the size and position of the floating area can be modified. @param int The width of the window. @param int The height of the window. @param Geometry& The tentative size of the window. */ typedef void(*ConfigureNotifyCallback) (int, int, Geometry &, void *); /*! A floating area on top of the main window. A BaseWindow is referenced by the WindowCompositor who calls Reference on the BaseWindow during registration. */ class BaseWindow: public View { NUX_DECLARE_OBJECT_TYPE(BaseWindow, View); public: BaseWindow(const char *WindowName = "", NUX_FILE_LINE_PROTO); virtual ~BaseWindow(); nux::Property premultiply; virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual Layout* GetLayout(); virtual bool SetLayout(Layout *layout); //! Push the view one level up the ViewWindow stack. /*! Push this view one level up the ViewWindow stack. Does it even if the view is hidden. */ void PushHigher(BaseWindow* floating_view); //! Push the view one level down the ViewWindow stack. /*! Push this view one level down the ViewWindow stack. Does it even if the view is hidden. */ void PushLower(BaseWindow* floating_view); //! Push the view to the front of the ViewWindow stack. /*! Push this view to the top of the ViewWindow stack. Does it even if the view is hidden. If a valid ViewWindow has been forced at the top of the stack with a call to WindowCompositor::SetAlwaysOnFrontWindow(), then this view will be positioned one level below that view. \sa SetAlwaysOnFrontWindow(); */ void PushToFront(); //! Push the view to the back of the ViewWindow stack. /*! Push this view to the back of the ViewWindow stack. Does it even if the view is hidden. */ void PushToBack(); //! Set the window size to respect the layout container. /*! Set the window size to be such that the container layout size remains the same after ComputeSizeLayout2 is called on the layout. The window elements(title bar, minimize and close buttons) are positioned accordingly. The size grip is not responding anymore. @param b If b is true, the window size respect the size the layout container. */ virtual void SetWindowSizeMatchLayout(bool b) { _size_match_layout = b; } //! Check if the window size is constrained to the layout container size. /*! Check if the window size is constrained to the layout container size. @return If the return value is true, the window size is constrained by the size the layout container. */ bool IsSizeMatchContent() const { return _size_match_layout; } virtual void ShowWindow(bool b, bool StartModal = false); void StopModal(); bool IsModal() const; bool IsVisible() const; virtual void SetGeometry(const Geometry &geo); /*! Call this function to set a callback function that is called when this object is need to be resized or re-positioned. @param Callback Function to be called to set the this object size and position. @param Data The callback data. */ void SetConfigureNotifyCallback(ConfigureNotifyCallback Callback, void *Data); void SetBackgroundLayer(AbstractPaintLayer *layer); void SetBackgroundColor(const Color &color); void SetOpacity(float opacity); float GetOpacity(); #if defined(NUX_OS_LINUX) void EnableInputWindow(bool b, const char* title = "nux input window", bool take_focus = False, bool override_redirect = False); bool InputWindowEnabled(); void InputWindowEnableStruts(bool enable); bool InputWindowStrutsEnabled(); void InputWindowEnableOverlayStruts(bool enable); bool InputWindowOverlayStrutsEnabled(); void SetInputFocus(); Window GetInputWindowId(); #endif //! Set an InputArea to receive the keyboard focus when the BaseWIndow receives the NUX_WINDOW_ENTER_FOCUS event. /*! \sa _enter_focus_input_area. @param input_area An InputArea pointer object. Must be a child of this BaseWindow. */ void SetEnterFocusInputArea(InputArea *input_area); //! Get the backup texture data of this BaseWindow, void* GetBackupTextureData(int &width, int &height, int &format); //! Emit a signal when the BaseWindow becomes visible. sigc::signal sigVisible; //! Emit a signal when the BaseWindow becomes hidden. sigc::signal sigHidden; std::string GetWindowName() { return _name; } void PresentInEmbeddedModeOnThisFrame(bool force = false); void MarkPresentedInEmbeddedMode(); bool AllowPresentationInEmbeddedMode() const; nux::Geometry const& LastPresentedGeometryInEmbeddedMode() const; void PrepareParentRedirectedView(); #ifdef NUX_GESTURES_SUPPORT virtual Area* GetInputAreaHitByGesture(const nux::GestureEvent &event); #endif protected: void SetAcceptKeyNavFocus(bool accept); bool accept_key_nav_focus_; virtual bool AcceptKeyNavFocus(); //! Callback function to set the window position and size. ConfigureNotifyCallback m_configure_notify_callback; //! Callback data for ConfigureNotifyCallback. void *m_configure_notify_callback_data; //sigc::signal< bool, unsigned int, unsigned int, Geometry & > sigRequestConfigure; Layout *m_layout; friend class ComboBox_Logic_WindowView; virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void ComputeContentPosition(float offsetX, float offsetY); //! Layout the window elements. /*! Layout elements such as button on the title bar, and the resize widget according to the current geometry of the window. Also initiate the computation of the child layout if there is one. */ virtual void LayoutWindowElements(); /*! Floating Area need to be informed when the main window has been resized. @param Width New width of the window. @param Height New height of the window. */ virtual void NotifyConfigurationChange(int Width, int Height); int GetBorder() const; int GetTopBorder() const; void SetBorder(int border); void SetTopBorder(int border); int m_TopBorder; int m_Border; boost::scoped_ptr _paint_layer; bool _entering_visible_state; //!< the window is about to be made visible during event processing bool _entering_hidden_state; //!< the window is about to be made hidden during event processing bool ChildNeedsRedraw(); #if defined(USE_X11) bool m_input_window_enabled; XInputWindow *m_input_window; #endif private: //! Contains the background of the texture. Can be used to blur. It is set by the window compositor. ObjectPtr _background_texture; std::string _name; bool _size_match_layout; bool _is_visible; bool _is_modal; InputArea *_enter_focus_input_area; //!< An input Area to set the keyboad focus on in response to NUX_WINDOW_ENTER_FOCUS. std::list m_InterfaceObject; bool _child_need_redraw; //! * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "GroupBox2.h" namespace nux { int GroupBox2::CAPTION_X_MARGIN = 6; int GroupBox2::X_MARGIN = 4; int GroupBox2::Y_MARGIN = 4; Color GroupBox2::GROUPBOX2_HEADER_BASE_COLOR = Color(0xFF191919); Color GroupBox2::GROUPBOX2_HEADER_TEXT_COLOR = Color(0xFFFFFFFF); int GroupBox2::TOP_HEADER_HEIGHT = 24; GroupBox2::GroupBox2(const char *Caption, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_layout(0) { m_CaptionArea = new BasicView(NUX_TRACKER_LOCATION); SetMinimumSize(DEFAULT_WIDGET_WIDTH + 5, PRACTICAL_WIDGET_HEIGHT + 5); SetBaseSize(DEFAULT_WIDGET_WIDTH + 5, PRACTICAL_WIDGET_HEIGHT + 5); SetCaption(Caption); } GroupBox2::~GroupBox2() { m_CaptionArea->Dispose(); } void GroupBox2::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { graphics_engine.PushClippingRectangle(GetGeometry()); Geometry header = GetGeometry(); header.SetHeight(TOP_HEADER_HEIGHT); Geometry layoutgeomerty = GetGeometry(); layoutgeomerty.OffsetPosition(0, TOP_HEADER_HEIGHT); layoutgeomerty.OffsetSize(0, -TOP_HEADER_HEIGHT); GetPainter().PaintShapeCorner(graphics_engine, header, Color(0xFF000000), eSHAPE_CORNER_ROUND4, eCornerTopLeft | eCornerTopRight, false); GetPainter().PushDrawShapeLayer(graphics_engine, layoutgeomerty, eSHAPE_CORNER_ROUND4, GROUPBOX2_HEADER_BASE_COLOR, eCornerBottomLeft | eCornerBottomRight); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), m_CaptionArea->GetGeometry(), m_CaptionArea->GetBaseString(), GROUPBOX2_HEADER_TEXT_COLOR); if (m_layout != 0) { m_layout->QueueDraw(); } GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } void GroupBox2::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { if (m_layout == 0) return; graphics_engine.PushClippingRectangle(m_layout->GetGeometry()); Geometry layoutgeomerty = GetGeometry(); layoutgeomerty.OffsetPosition(0, TOP_HEADER_HEIGHT); layoutgeomerty.OffsetSize(0, -TOP_HEADER_HEIGHT); if (force_draw) GetPainter().PushDrawShapeLayer(graphics_engine, layoutgeomerty, eSHAPE_CORNER_ROUND4, GROUPBOX2_HEADER_BASE_COLOR, eAllCorners); else GetPainter().PushShapeLayer(graphics_engine, layoutgeomerty, eSHAPE_CORNER_ROUND4, GROUPBOX2_HEADER_BASE_COLOR, eAllCorners); if (m_layout) { graphics_engine.PushClippingRectangle(m_layout->GetGeometry()); m_layout->ProcessDraw(graphics_engine, force_draw); graphics_engine.PopClippingRectangle(); } GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } bool GroupBox2::SetLayout(Layout *layout) { if (View::SetLayout(layout) == false) { return false; } m_layout = layout; return true; } void GroupBox2::PreLayoutManagement() { // Give the managed layout appropriate size and position.. if (GetCompositionLayout()) { Geometry layout_geo = GetGeometry(); layout_geo.OffsetPosition(X_MARGIN, TOP_HEADER_HEIGHT + Y_MARGIN); layout_geo.OffsetSize(-2 * X_MARGIN, -TOP_HEADER_HEIGHT - 2 * Y_MARGIN); GetCompositionLayout()->SetGeometry(layout_geo); } } long GroupBox2::PostLayoutManagement(long /* LayoutResult */) { // A Group box must tightly group its children. // So it must embrace the size that was compute for the composition layout. // Only the size is change is important here of the GroupBox2 is important here. long ret = 0; Geometry old_geo = Area::GetGeometry(); if (GetCompositionLayout()) { Geometry base = GetCompositionLayout()->GetGeometry(); base.OffsetPosition(-X_MARGIN, -TOP_HEADER_HEIGHT - Y_MARGIN); base.OffsetSize(2 * X_MARGIN, TOP_HEADER_HEIGHT + 2 * Y_MARGIN); Area::SetGeometry(base); } Geometry base = GetGeometry(); m_CaptionArea->SetBaseXY(base.x + CAPTION_X_MARGIN, base.y + (TOP_HEADER_HEIGHT - m_CaptionArea->GetBaseHeight()) / 2); if (old_geo.GetWidth() > base.GetWidth()) ret |= eLargerWidth; else if (old_geo.GetWidth() < base.GetWidth()) ret |= eSmallerWidth; else ret |= eCompliantWidth; if (old_geo.GetHeight() > base.GetHeight()) ret |= eLargerHeight; else if (old_geo.GetHeight() < base.GetHeight()) ret |= eSmallerHeight; else ret |= eCompliantHeight; return ret; } void GroupBox2::ComputeContentPosition(float offsetX, float offsetY) { if (GetCompositionLayout()) { GetCompositionLayout()->SetBaseX(GetBaseX() + X_MARGIN); GetCompositionLayout()->SetBaseY(GetBaseY() + TOP_HEADER_HEIGHT + Y_MARGIN); GetCompositionLayout()->ComputeContentPosition(offsetX, offsetY); } Geometry base = GetGeometry(); m_CaptionArea->SetBaseXY(base.x + CAPTION_X_MARGIN, base.y + (TOP_HEADER_HEIGHT - m_CaptionArea->GetBaseHeight()) / 2); } void GroupBox2::SetCaption(const char *Caption) { if ((Caption == 0) || (StringLength(Caption) == 0)) { m_CaptionArea->SetBaseString(""); m_CaptionArea->SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); m_CaptionArea->SetBaseSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); } else { m_CaptionArea->SetBaseString(Caption); m_CaptionArea->SetMinimumSize(4 + GetSysBoldFont()->GetStringWidth(Caption), PRACTICAL_WIDGET_HEIGHT); m_CaptionArea->SetBaseSize(4 + GetSysBoldFont()->GetStringWidth(Caption), PRACTICAL_WIDGET_HEIGHT); Size s = GetMinimumSize(); if (s.width < 2 * CAPTION_X_MARGIN + m_CaptionArea->GetBaseWidth()) { SetMinimumSize(2 * CAPTION_X_MARGIN + m_CaptionArea->GetBaseWidth(), s.height); SetBaseSize(2 * CAPTION_X_MARGIN + m_CaptionArea->GetBaseWidth(), s.height); } } } bool GroupBox2::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/InputMethodIBus.cpp0000644000015301777760000003475312321344257021254 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * Jay Taoko * */ #include "Nux.h" #include "NuxCore/Logger.h" #include "InputMethodIBus.h" namespace nux { namespace { DECLARE_LOGGER(logger, "nux.inputmethod.ibus"); } std::vector IBusIMEContext::hotkeys_; IBusBus* IBusIMEContext::bus_ = NULL; IBusIMEContext::IBusIMEContext(TextEntry* text_entry) : text_entry_(text_entry) , context_(NULL) , cancellable_(g_cancellable_new()) , is_focused_(false) { // init ibus if (!bus_) { ibus_init(); bus_ = ibus_bus_new(); } // connect bus signals g_signal_connect(bus_, "connected", G_CALLBACK(OnConnected_), this); g_signal_connect(bus_, "disconnected", G_CALLBACK(OnDisconnected_), this); if (ibus_bus_is_connected(bus_)) { CreateContext(); } else { LOG_WARN(logger) << "Impossible to connect to connect to ibus"; } } IBusIMEContext::~IBusIMEContext() { DestroyContext(); g_signal_handlers_disconnect_by_data(bus_, this); g_object_unref(cancellable_); } void IBusIMEContext::Focus() { if (is_focused_) return; is_focused_ = true; if (context_) ibus_input_context_focus_in(context_); } void IBusIMEContext::Blur() { if (!is_focused_) return; is_focused_ = false; if (context_) ibus_input_context_focus_out(context_); } void IBusIMEContext::Reset() { if (context_) ibus_input_context_reset(context_); } bool IBusIMEContext::FilterKeyEvent(const KeyEvent& event) { guint keyval = event.key_sym(); // todo(jaytaoko): ui::GdkKeyCodeForWindowsKeyCode(event.key_code(), event.IsShiftDown() ^ event.IsCapsLockDown()); if (context_) { guint modifiers = 0; if (event.flags() & IBUS_IGNORED_MASK) return false; if (event.type() == EVENT_KEY_UP) modifiers |= IBUS_RELEASE_MASK; if (event.IsShiftDown()) modifiers |= IBUS_SHIFT_MASK; if (event.IsControlDown()) modifiers |= IBUS_CONTROL_MASK; if (event.IsAltDown()) modifiers |= IBUS_MOD1_MASK; if (event.IsCapsLockDown()) modifiers |= IBUS_LOCK_MASK; ibus_input_context_process_key_event_async(context_, keyval, event.key_code() - 8, modifiers, -1, cancellable_, reinterpret_cast(ProcessKeyEventDone), new ProcessKeyEventData(this, event)); return true; } return false; } void IBusIMEContext::SetSurrounding(const std::wstring& /* text */, int /* cursor_pos */) { // TODO(penghuang) support surrounding } void IBusIMEContext::CreateContext() { nuxAssert(bus_ != NULL); nuxAssert(ibus_bus_is_connected(bus_)); if (!(context_ = ibus_bus_create_input_context(bus_, "nux"))) { LOG_WARN(logger) << "Cannot create InputContext"; return; } g_cancellable_reset(cancellable_); text_entry_->ime_active_ = false; // connect input context signals g_signal_connect(context_, "commit-text", G_CALLBACK(OnCommitText_), this); g_signal_connect(context_, "update-preedit-text", G_CALLBACK(OnUpdatePreeditText_), this); g_signal_connect(context_, "show-preedit-text", G_CALLBACK(OnShowPreeditText_), this); g_signal_connect(context_, "hide-preedit-text", G_CALLBACK(OnHidePreeditText_), this); g_signal_connect(context_, "enabled", G_CALLBACK(OnEnable_), this); g_signal_connect(context_, "disabled", G_CALLBACK(OnDisable_), this); g_signal_connect(context_, "destroy", G_CALLBACK(OnDestroy_), this); guint32 caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS; ibus_input_context_set_capabilities(context_, caps); if (is_focused_) ibus_input_context_focus_in(context_); UpdateCursorLocation(); if (IBusConfig* bus_conf = ibus_bus_get_config(bus_)) { g_signal_handlers_disconnect_by_func(bus_conf, reinterpret_cast(OnConfigChanged_), this); g_signal_connect(bus_conf, "value-changed", G_CALLBACK(OnConfigChanged_), this); } UpdateHotkeys(); } void IBusIMEContext::DestroyContext() { LOG_DEBUG(logger) << "Destroy context"; if (ibus_bus_is_connected(bus_)) { if (IBusConfig* bus_conf = ibus_bus_get_config(bus_)) g_signal_handlers_disconnect_by_data(bus_conf, this); } if (!context_) return; text_entry_->ResetPreedit(); ibus_proxy_destroy(reinterpret_cast(context_)); nuxAssert(!context_); } bool IBusIMEContext::IsConnected() const { return context_; } void IBusIMEContext::UpdateCursorLocation() { nux::Rect strong, weak; text_entry_->GetCursorRects(&strong, &weak); // Get the position of the TextEntry in the Window. nux::Geometry geo = text_entry_->GetAbsoluteGeometry(); // Get the Geometry of the window on the display. nux::Geometry window_geo = nux::GetGraphicsDisplay()->GetWindowGeometry(); ibus_input_context_set_cursor_location(context_, geo.x + window_geo.x + strong.x, geo.y + window_geo.y, 0, geo.height); } void IBusIMEContext::OnConnected(IBusBus * /* bus */) { LOG_DEBUG(logger) << "Connected"; if (ibus_bus_is_connected(bus_)) { DestroyContext(); CreateContext(); } } void IBusIMEContext::OnDisconnected(IBusBus * /* bus */) { LOG_DEBUG(logger) << "Disconnected"; hotkeys_.clear(); DestroyContext(); } void IBusIMEContext::OnConfigChanged(IBusConfig* /* config */, gchar* section, gchar* name, GVariant* /* value */) { if (g_strcmp0(section, "general/hotkey") == 0) { if (g_strcmp0(name, "trigger") == 0) UpdateHotkeys(); } } void IBusIMEContext::OnCommitText(IBusInputContext * /* context */, IBusText* text) { LOG_DEBUG(logger) << "Text committed " << text->text; text_entry_->DeleteSelection(); if (text->text) { int cursor = text_entry_->cursor_; std::string new_text(text_entry_->GetText()); std::string commit_text (text->text); new_text.insert (cursor, commit_text); text_entry_->SetText(new_text.c_str()); text_entry_->SetCursor(cursor + commit_text.length()); UpdateCursorLocation(); } } void IBusIMEContext::OnUpdatePreeditText(IBusInputContext* /* context */, IBusText* text, guint /* cursor_pos */, gboolean visible) { LOG_DEBUG(logger) << "Preedit Update"; nuxAssert(IBUS_IS_TEXT(text)); if (text_entry_->preedit_.empty()) UpdateCursorLocation(); if (visible) { IBusAttrList* attrs = text->attrs; if (attrs) { PangoAttrList* preedit_attrs = pango_attr_list_new(); int i = 0; while (1) { IBusAttribute* attr = ibus_attr_list_get(attrs, i++); PangoAttribute* pango_attr; if (!attr) break; switch (attr->type) { case IBUS_ATTR_TYPE_UNDERLINE: pango_attr = pango_attr_underline_new ((PangoUnderline)attr->value); break; case IBUS_ATTR_TYPE_FOREGROUND: pango_attr = pango_attr_foreground_new ( ((attr->value & 0xff0000) >> 8) | 0xff, ((attr->value & 0x00ff00)) | 0xff, ((attr->value & 0x0000ff) << 8) | 0xff); break; case IBUS_ATTR_TYPE_BACKGROUND: pango_attr = pango_attr_background_new ( ((attr->value & 0xff0000) >> 8) | 0xff, ((attr->value & 0x00ff00)) | 0xff, ((attr->value & 0x0000ff) << 8) | 0xff); break; default: continue; } pango_attr->start_index = g_utf8_offset_to_pointer (text->text, attr->start_index) - text->text; pango_attr->end_index = g_utf8_offset_to_pointer (text->text, attr->end_index) - text->text; pango_attr_list_insert (preedit_attrs, pango_attr); } if (text_entry_->preedit_attrs_) { pango_attr_list_unref(text_entry_->preedit_attrs_); text_entry_->preedit_attrs_ = NULL; } text_entry_->preedit_attrs_ = preedit_attrs; } if (text->text) { std::string preedit(text->text); text_entry_->preedit_ = preedit; text_entry_->preedit_cursor_ = preedit.length(); text_entry_->QueueRefresh (true, true); } } else { OnHidePreeditText(context_); } } void IBusIMEContext::OnShowPreeditText(IBusInputContext * /* context */) { LOG_DEBUG(logger) << "Show preedit"; } void IBusIMEContext::OnHidePreeditText(IBusInputContext * /* context */) { LOG_DEBUG(logger) << "Hide preedit"; text_entry_->ResetPreedit(); text_entry_->QueueRefresh (true, true); } void IBusIMEContext::OnEnable(IBusInputContext * /* context */) { LOG_DEBUG(logger) << "On enable"; text_entry_->ime_active_ = true; text_entry_->text_changed.emit(text_entry_); UpdateCursorLocation(); } void IBusIMEContext::OnDisable(IBusInputContext * /* context */) { LOG_DEBUG(logger) << "On disable"; text_entry_->ime_active_ = false; text_entry_->ResetPreedit(); text_entry_->QueueRefresh (true, true); } void IBusIMEContext::OnDestroy(IBusInputContext * /* context */) { LOG_DEBUG(logger) << "On Destroy"; if (!context_) return; g_cancellable_cancel(cancellable_); g_signal_handlers_disconnect_by_data(context_, this); g_object_unref(context_); context_ = NULL; } void IBusIMEContext::ProcessKeyEventDone(IBusInputContext *context, GAsyncResult* res, ProcessKeyEventData *data) { LOG_DEBUG(logger) << "Key event processed"; std::unique_ptr key_ev(data); GError *error = NULL; gboolean processed = ibus_input_context_process_key_event_async_finish(context, res, &error); if (error) { if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { LOG_ERROR(logger) << "Process Key Event failed: " << error->message << "."; } g_error_free(error); return; } nuxAssert(key_ev->context->context_ == context); if (!processed) { key_ev->context->text_entry_->ProcessKeyEvent(key_ev->event.type(), key_ev->event.key_sym(), key_ev->event.flags() | IBUS_IGNORED_MASK, key_ev->event.character().c_str(), 0); } } std::vector IBusIMEContext::ParseIBusHotkeys(const gchar** keybindings) { std::vector hotkeys; for (int i = 0; keybindings && keybindings[i]; ++i) { gchar** binding = g_strsplit (keybindings[i], "+", -1); if (binding) { Event ev; ev.type = EVENT_KEY_DOWN; for (int j = 0; binding && binding[j]; ++j) { if (strcmp(binding[j], "Release") == 0) { ev.type = EVENT_KEY_UP; continue; } KeySym key = XStringToKeysym(binding[j]); bool is_modifier = false; if (key) { switch (key) { case XK_Caps_Lock: case XK_Shift_Lock: case XK_Num_Lock: case XK_Scroll_Lock: is_modifier = true; } } else { // Checking if the current key is a generic modifier key key = XStringToKeysym((std::string(binding[j]) + "_L").c_str()); is_modifier = (key != 0); } if (is_modifier) { switch (key) { case XK_Control_L: case XK_Control_R: ev.key_modifiers |= KEY_MODIFIER_CTRL; break; case XK_Shift_L: case XK_Shift_R: case XK_Shift_Lock: ev.key_modifiers |= KEY_MODIFIER_SHIFT; break; case XK_Alt_L: case XK_Alt_R: ev.key_modifiers |= KEY_MODIFIER_ALT; break; case XK_Super_L: case XK_Super_R: ev.key_modifiers |= KEY_MODIFIER_SUPER; case XK_Caps_Lock: ev.key_modifiers |= KEY_MODIFIER_CAPS_LOCK; break; case XK_Num_Lock: ev.key_modifiers |= KEY_MODIFIER_NUMLOCK; break; case XK_Scroll_Lock: ev.key_modifiers |= KEY_MODIFIER_SCROLLLOCK; break; // FIXME add support to Hyper and Meta keys in nux::Event } } if (!is_modifier && key) ev.x11_keysym = key; } if (ev.x11_keysym) { hotkeys.push_back(ev); } g_strfreev(binding); } } return hotkeys; } void IBusIMEContext::UpdateHotkeys() { if (IBusConfig* conf = ibus_bus_get_config(bus_)) { GVariant* val = ibus_config_get_value(conf, "general/hotkey", "triggers"); const gchar** keybindings = g_variant_get_strv(val, NULL); hotkeys_ = ParseIBusHotkeys(keybindings); g_variant_unref(val); } } bool IBusIMEContext::IsHotkeyEvent(EventType type, unsigned long keysym, unsigned long modifiers) const { for (Event const& ev : hotkeys_) { if (ev.x11_keysym == keysym && (ev.type == type || type == EVENT_KEY_DOWN)) { if (ev.type == EVENT_KEY_UP) return (modifiers & ev.key_modifiers); else return (ev.key_modifiers == modifiers); } } return false; } } nux-4.0.6+14.04.20140409/Nux/ColorPreview.cpp0000644000015301777760000001021312321344237020630 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "ColorPreview.h" #include "ColorEditor.h" #include "HLayout.h" #include "TimerProc.h" #include "StaticTextBox.h" #include #include namespace nux { static const int GRAPH_MARGIN = 1; ColorPreview::ColorPreview(Color const& c, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_Color(c) { //setSize(200, 100); m_hlayout = new HLayout(NUX_TRACKER_LOCATION); m_ColorArea = new BasicView(NUX_TRACKER_LOCATION); m_ColorValue = new StaticTextBox("", NUX_TRACKER_LOCATION); m_DialogThreadProxy = new ColorDialogProxy(true); SetMaximumHeight(18); m_ColorArea->SetMaximumHeight(18); m_ColorArea->SetMinimumWidth(32); m_ColorArea->SetMaximumWidth(32); m_ColorValue->SetTextColor(Color(0xFFFFFFFF)); m_ColorValue->SetFont(GetSysBoldFont()); m_ColorValue->SetMinimumWidth(128); std::stringstream s; s << "[ R:" << (int)(m_Color.red * 255) << ", G:" << (int)(m_Color.green * 255) << ", B:" << (int)(m_Color.blue * 255) << " ]"; m_ColorValue->SetText(s.str()); m_ColorArea->mouse_click.connect(sigc::mem_fun(this, &ColorPreview::RecvClick)); m_hlayout->AddView(m_ColorArea, 0); m_hlayout->AddView(m_ColorValue, 1); m_hlayout->SetHorizontalInternalMargin(4); SetCompositionLayout(m_hlayout); m_ChangeDetectionTimer = new TimerFunctor(); m_ChangeDetectionTimer->tick.connect(sigc::mem_fun(this, &ColorPreview::RecvTimer)); m_ChangeTimerHandler = 0; } ColorPreview::~ColorPreview() { delete m_ChangeDetectionTimer; if (m_ChangeTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_ChangeTimerHandler); delete m_DialogThreadProxy; } void ColorPreview::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); GetPainter().PaintBackground(graphics_engine, base); GetPainter().PaintShape(graphics_engine, m_ColorArea->GetGeometry(), m_Color, eSHAPE_CORNER_ROUND4, false); //GetPainter().Paint2DQuadWireFrameColor(graphics_engine, base, Color(COLOR_BACKGROUND_SECONDARY)); m_ColorValue->QueueDraw(); } void ColorPreview::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { m_ColorValue->ProcessDraw(graphics_engine, force_draw); } void ColorPreview::RecvClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { m_DialogThreadProxy->SetColor(m_Color); m_DialogThreadProxy->Start(); m_ChangeTimerHandler = GetTimer().AddOneShotTimer(33, m_ChangeDetectionTimer, this); } void ColorPreview::RecvTimer(void * /* v */) { if (m_DialogThreadProxy->m_bDialogChange && m_DialogThreadProxy->m_bDialogRunning) { m_DialogThreadProxy->m_bDialogChange = false; m_Color = m_DialogThreadProxy->GetColor(); QueueDraw(); } if (m_DialogThreadProxy->IsActive()) { m_ChangeTimerHandler = GetTimer().AddOneShotTimer(33, m_ChangeDetectionTimer, this); } else { if (m_ChangeTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_ChangeTimerHandler); m_ChangeTimerHandler = 0; m_Color = m_DialogThreadProxy->GetColor(); QueueDraw(); } } Color const& ColorPreview::GetRGBColor() const { return m_Color; } void ColorPreview::SetColor(Color const& color) { m_Color = color; } } nux-4.0.6+14.04.20140409/Nux/WindowThread.h0000644000015301777760000006462412321344237020273 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef WINDOWTHREAD_H #define WINDOWTHREAD_H #include "TimerProc.h" #ifdef NUX_GESTURES_SUPPORT #include "GeisAdapter.h" #endif #if defined(NUX_OS_LINUX) && defined(USE_X11) #include "XIMController.h" #endif namespace nux { class BaseWindow; class WindowThread; class Layout; class HLayout; class GraphicsDisplay; class ClientArea; class WindowCompositor; class AbstractThread; class SystemThread; class UXTheme; class TimerHandler; #if !defined(NUX_MINIMAL) class Timeline; #endif class Event; class Area; struct ClientAreaDraw; #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) class ExternalGLibSources; gboolean nux_event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data); gboolean nux_timeout_dispatch(gpointer user_data); #endif //! Event Inspector function prototype. /*! If an event inspector return true, then the event is discarded. */ typedef int(*EventInspector) (Area* area, Event* event, void* data); //! Main class of a Nux window app. /*! Each WindowThread runs in its own loop. There cannot be more than one WindowThread per system thread. */ class WindowThread: public AbstractThread { NUX_DECLARE_OBJECT_TYPE(WindowThread, AbstractThread); public: WindowThread(const char *WindowTitle, int width, int height, AbstractThread *Parent, bool Modal); virtual ~WindowThread(); //! Start the WindowThread in the current Thread. /*! Run the main loop of the window. \n; The function blocks until the the main loop is stopped. @param ptr Reserved. */ virtual int Run(void *ptr = NULL); /*! Start the user interface Window in it own thread. Start return immediately after the thread is created. @param ptr Reserved. */ virtual ThreadState Start(void *ptr = NULL); //! Exit from the WindowThread loop. /*! Exit the WindowThread loop. */ void ExitMainLoop(); //! Set window size. /*! Set window size. @param width Window width. @param height Window height. */ void SetWindowSize(int width, int height); //! Set the background for the window. /*! Set the background for the window. @param background_layer background layer. */ void SetWindowBackgroundPaintLayer(AbstractPaintLayer *background_layer); /*! Get the graphics display (this is the physical window of this thread). @return The graphics display. */ GraphicsDisplay &GetGraphicsDisplay() const; /*! Get the graphics engine (this is the object that renders the graphics primitives). @return The graphics display. */ GraphicsEngine &GetGraphicsEngine() const; /*! Get the UI compositor (this is processes events and renders ui objects). @return The UI compositor. */ WindowCompositor& GetWindowCompositor() const; /*! Get the painter object. @return The painter object. */ BasePainter &GetPainter() const; /*! Get the timer manager. @return The timer manager. */ TimerHandler &GetTimerHandler() const; /*! Get the UI resource manager (load textures and other data for user interface rendering). @param The ui resource manager. */ UXTheme &GetTheme() const; //! Set the layout for this window thread. /*! @param layout The layout of the user interface. */ void SetLayout(Layout *layout); //! Get the layout of this window. /*! @return The layout of this window. */ Layout* GetLayout(); //! Return true if the process is inside a layout cycle. /*! @return True if the process is inside a layout cycle. */ bool IsInsideLayoutCycle() const; //! Deprecated. Replace with IsInsideLayoutCycle. bool IsComputingLayout() const { return IsInsideLayoutCycle(); } //! Schedule a size computation cycle on an area before the rendering is performed. /*! This list contains the area whose size need to be computed. @param area The object that will perform a size computation cycle. \sa ComputeQueuedLayout. @return True if the object was succefully queued. */ bool QueueObjectLayout(Area *area); //! Compute the layout of a specific element /*! Immediate size negotiation for a View or a layout. */ void ComputeElementLayout(Area* bo, bool recurse_to_top_level_layout = false); //! Remove an area from the list of object whose size was scheduled to be computed before the rendering cycle. /*! @param area The object to remove form the list. @return True if the object was in the _queued_layout_list and has been removed. \sa ComputeQueuedLayout, QueueObjectLayout. */ bool RemoveObjectFromLayoutQueue(Area *area); /*! Return \i true while waiting for a modal window to return. @return \i True while waiting for a modal window to return. */ bool IsWaitingforModalWindow() const; /*! Return \i true if this window is modal. @return \i True if this window is modal. */ bool IsModalWindow() const; /*! Return true if this windowThread is embedded inside Compiz. @return True if embedded inside Compiz. */ bool IsEmbeddedWindow() const; #if defined(NUX_OS_WINDOWS) bool ProcessForeignEvent(HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, void *data); #elif defined(USE_X11) bool ProcessForeignEvent(XEvent *event, void *data); #else bool ProcessForeignEvent(); #endif /*! In embedded mode, allow presentation on any windows intersecting this rect. The effect of this is culmulative for the frame, so it can be called multiple times with many different rects until RenderInterfaceFromForeignCmd is called. \sa IsEmbeddedWindow @param rect Region of the display to consider for presenting windows */ void PresentWindowsIntersectingGeometryOnThisFrame(Geometry const& rect); /*! Render the interface. This command is send from the pluging when the window thread is embedded. The clip region matches the surface of one single monitor screen, or a region inside that screen. \sa IsEmbeddedWindow. @param clip Region of the display to render. */ void RenderInterfaceFromForeignCmd(Geometry const& clip); /*! Used to mark the end of the foreign frame. All calls to PresentInEmbeddedModeOnThisFrame are now redirected to this upcoming frame where we will be called next. */ void ForeignFrameEnded(); /*! Used to mark the cutoff point where all calls to PresentInEmbeddedModeOnThisFrame should be effective on the next frame, and not this one, because the parent context has stopped tracking damage events for this frame */ void ForeignFrameCutoff(); #if !defined(NUX_MINIMAL) /*! Add a timeline to our window */ void AddTimeline(Timeline* timeline); void RemoveTimeline(Timeline* timeline); bool ProcessTimelines(gint64 micro_secs); long last_timeline_frame_time_sec_; long last_timeline_frame_time_usec_; #endif void StartMasterClock(); void StopMasterClock(); sigc::signal RedrawRequested; sigc::signal window_configuration; //!< emmitted when the window Geometry changes. //! Set an event inspector function. /*! Inspect all events and returns the action to be taken for the event(process or discard). If \a function as already been added, return its unique id.\n If \a function is null, return 0.\n @param function Event inspector function callback. @param data User defined data. @return Unique id for the event inspector callback. */ int InstallEventInspector(EventInspector function, void* data); //! Remove an event inspector. /*! Remove the event inspector identified by the provided unique id. @param event_inspector_id Unique id for the event inspector. @return True If the event inspector exists and has been removed. */ bool RemoveEventInspector(int event_inspector_id); //! Remove an event inspector. /*! Remove the event inspector identified by the provided function. @param function Event inspector function callback. @return True If the event inspector exists and has been removed. */ bool RemoveEventInspector(EventInspector function); //! Call event inspectors. /*! Call event inspectors to have a look at the event. @return True if the event should be discarded. */ bool CallEventInspectors(Event* event); //! Sets a timer from a different thread. /*! Sets a timer and a callback. When the timer expires, the callback is executed. This function is meant to be called from a different thread. This function very carefully avoid calling any thread specific objects (TLS). @param time_ms Timer delay in milliseconds. @param timeout_signal Pointer to a TimeOutSignal. @param user_data Pointer to user data. @return A timer handle. */ TimerHandle SetAsyncTimerCallback(int time_ms, TimeOutSignal* timeout_signal, void *user_data); /*! Return the Window title. @return The window title. */ std::string GetWindowTitle() const; void ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw); void RequestRedraw(); void ClearRedrawFlag(); bool IsRedrawNeeded() const; // DrawList - this is a maintained list of areas that will // be completely redraw on the next frame void AddToDrawList(View *view); void ClearDrawList(); std::vector const& GetDrawList() const; // PresentationList - this is a maintained list of areas that // will be presented to the reference framebuffer or backbuffer // in embedded mode on the next frame bool AddToPresentationList(nux::BaseWindow*, bool force); std::vector GetPresentationListGeometries() const; Event GetNextEvent(); #ifdef NUX_GESTURES_SUPPORT /*! Simple wrapper for ProcessEvent for connection with GeisAdapter::event_ready */ void ProcessGestureEvent(GestureEvent &event) { ProcessEvent(event); } GeisAdapter *GetGeisAdapter() const {return geis_adapter_.get();} #endif typedef std::function FdWatchCallback; void WatchFdForEvents(int fd, const FdWatchCallback &); void UnwatchFd(int fd); #if defined(NUX_OS_LINUX) && defined(USE_X11) void XICFocus(TextEntry* text_entry); void XICUnFocus(); #endif protected: /*! Constructor-like function for the thread. Will be called by EntryPoint before executing the thread body. For the main window, ThreadCtor is called in nux::CreateMainWindow. ThreadCtor creates and initialize the following elements: - Graphics Window - Timer - Painter - Compositor - Theme engine After ThreadCtor is called, thread_ctor_called_ is set to true; */ virtual bool ThreadCtor(); #if defined(NUX_OS_WINDOWS) /*! Constructor-like function for the thread. Will be called by EntryPoint before executing the thread body. For the main window, ThreadCtor is called in nux::CreateMainWindow. ThreadCtor creates and initialize the following elements: - Graphics Window(from the externally created window) - Timer - Painter - Compositor - Theme engine After ThreadCtor is called, thread_ctor_called_ is set to true; This function is called when Nux is embedded. \sa IsEmbeddedWindow. */ virtual bool ThreadCtor(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext); #elif defined(USE_X11) #ifdef NUX_OPENGLES_20 /*! Constructor-like function for the thread. Will be called by EntryPoint before executing the thread body. For the main window, ThreadCtor is called in nux::CreateMainWindow. ThreadCtor creates and initialize the following elements: - Graphics Window(from the externally created window) - Timer - Painter - Compositor - Theme engine After ThreadCtor is called, thread_ctor_called_ is set to true; This function is called when Nux is embedded. \sa IsEmbeddedWindow. */ virtual bool ThreadCtor(Display *X11Display, Window X11Window, EGLContext OpenGLContext); #else /*! Constructor-like function for the thread. Will be called by EntryPoint before executing the thread body. For the main window, ThreadCtor is called in nux::CreateMainWindow. ThreadCtor creates and initialize the following elements: - Graphics Window(from the externally created window) - Timer - Painter - Compositor - Theme engine After ThreadCtor is called, thread_ctor_called_ is set to true; This function is called when Nux is embedded. \sa IsEmbeddedWindow. */ virtual bool ThreadCtor(Display *X11Display, Window X11Window, GLXContext OpenGLContext); #endif Display *x11display_; bool ownx11display_; #endif /*! Destructor-like function for the thread. Will be called by EntryPoint after executing the thread body. After ThreadDtor is called, thread_dtor_called_ is set to true. ThreadDtor is also called in the destructor of the WindowThread but is protected by thread_dtor_called_ so it is not called twice. In the case of the main window, ThreadDtor is called in the destructor of WindowThread. */ virtual bool ThreadDtor(); //! Causes the Main layout to be recomputed. /*! Causes the main layout to be recomputed. This will happen just before the next draw cycle. */ void QueueLayout(); //! Empty the queue of objects set for layout computation. /*! The queue was filled with calls to QueueObjectLayout. */ void RemoveQueuedLayout(); //! Compute the layout of this window thread. /*! Reconfigure the layout of this window. Start by setting the size of the layout to the size of this window. ReconfigureLayout is executed following an event of type NUX_SIZE_CONFIGURATION or a call to QueueMainLayout. \sa QueueMainLayout. */ void ReconfigureLayout(); /*! Suspend Win32 Mouse and Keyboard inputs for this window thread and its child thread that are also window (not SystemThread). */ void EnableMouseKeyboardInput(); /*! Enable Win32 Mouse and Keyboard inputs for this window thread and its child thread that are also window (not SystemThread). */ void DisableMouseKeyboardInput(); #if (!defined(NUX_OS_LINUX) && !defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) || defined(NUX_DISABLE_GLIB_LOOP) //! Calls ProcessEvent in a loop unsigned int ExecutionLoop(); #endif /*! It does the following: * processes the input events * resizes views * draw the frame This function is called when there is an input event, a gesture event or when a timer has expired. */ unsigned int ProcessEvent(Event &event); virtual ThreadState StartChildThread(AbstractThread *thread, bool Modal); virtual void AddChildThread(AbstractThread *); virtual void RemoveChildThread(AbstractThread *); virtual void ChildHasFinished(AbstractThread *app); virtual void TerminateChildThreads(); virtual ThreadState SuspendChildGraphics(WindowThread *app); bool is_modal_window_; bool wait_for_modal_window_; WindowThread *modal_window_thread_; private: /*! Internally called by ProcessEvent end ExecutionLopp after early return check. */ unsigned int DoProcessEvent(Event &event); void SetupMainLoop(); //! Execute the main loop of this thread. /*! Execute the main loop of this thread. @return And exit code. 0 if there was no error. */ int MainLoop(); //! Custom callback to wake up the main thread and start the execution loop. /*! This function is executed when \i async_wake_up_signal_ expires. It doesn't do anything when called, but the main thread will wake up and start the execution loop. \sa async_wake_up_signal_ @param user_ptr Pointer to user data. */ void AsyncWakeUpCallback(void *user_ptr); TimeOutSignal *async_wake_up_signal_; TimerHandle async_wake_up_timer_handle_; //! Informs the system of the start of a layout cycle. /*! This call merely sets a flag to true or false. This flag is used to decided if some actions should be performed or not. Used by the system only. */ void StartLayoutCycle(); //! Informs the system of the end of a layout cycle. /*! This call merely sets a flag to true or false. This flag is used to decided if some actions should be performed or not. Used by the system only. */ void StopLayoutCycle(); //! Execute the size computation cycle on objects. /* The objects whose size is to be computed are added to a list with a call to QueueObjectLayout. Size computation is performed just before the rendering cycle. \sa QueueObjectLayout */ void ComputeQueuedLayout(); GSource *_MasterClock; WindowThread(const WindowThread &); // Does not make sense for a singleton. This is a self assignment. WindowThread& operator = (const WindowThread &); // Declare operator address-of as private WindowThread* operator & (); bool _inside_main_loop; bool _inside_timer_loop; bool _pending_wake_up_timer; //! This list contains the layout that need to be recomputed following the resizing of one of the sub element. /*! This list contains the layout that need to be recomputed following the resizing of one of the sub element. */ std::list _queued_layout_list; std::vector dirty_areas_; typedef nux::ObjectWeakPtr WeakBaseWindowPtr; std::vector presentation_list_embedded_; /*! This list contains al lthe windows which will be presented on the next frame (eg, after ForeignFrameEnded they are moved into m_presentation_list_embedded and marked for presentation) */ std::vector presentation_list_embedded_next_frame_; /*! Whether or not the current frame is "frozen" because the host WM has stopped tracking damage events. If so we should put all presentation requests on the next frame instead of this one */ bool foreign_frame_frozen_; //! This variable is true while we are computing the layout the starting from the outmost layout(the Main Layout); bool _inside_layout_cycle; //! Set to true to schedule a compute cycle on the main layout. bool queue_main_layout_; #if !defined(NUX_MINIMAL) std::list *_Timelines; #endif bool first_pass_; //!< True when going through the ExecutionLoop for the first time. unsigned int window_initial_width_; //!< Window height at startup. unsigned int window_initial_height_; //!< Window width at startup. std::string window_title_; //!< Window title. bool _draw_requested_to_host_wm; //!< Flags signaling that a draw cycle has been requested to the host window manager. Layout *main_layout_; UXTheme *theme_; BasePainter *painter_; TimerHandler *timer_manager_; //bool created_own_thread_; //!< If true, create a system thread and run the window in it. GraphicsDisplay *graphics_display_; WindowCompositor *window_compositor_; bool m_WidgetInitialized; WindowStyle window_style_; /*! True if the thread constructor has been called. This is a form of per-WindowThread reentry protection. */ bool thread_ctor_called_; /*! True if the thread destructor has been called. This is a form of per-WindowThread reentry protection. */ bool thread_dtor_called_; /*! True when running Ubuntu Unity+Nux has a plugin of Compiz. */ bool embedded_window_; /*! Record if there was a configuration nux_event(NUX_SIZE_CONFIGURATION) that requires a full redraw. Used in the case where event processing and rendering are decoupled(with foreign windows). */ bool window_size_configuration_event_; bool force_rendering_; typedef struct _EventInspectorStorage { _EventInspectorStorage() { _function = 0; _data = 0; _uid = 0; } EventInspector _function; void* _data; int _uid; } EventInspectorStorage; //! Map of events inspectors /*! Events inspectors get to examine events before they are processed. They may also stop an event from being processed if they return true. */ std::map _event_inspectors_map; //!< map of events inspectors typedef struct _ExternalFdData { int fd; FdWatchCallback cb; } ExternalFdData; //! List of external sources. This might make more sense as a map, // but providing a struct provides us much nicer GLib integration std::list _external_fds; static bool FindDataByFd(const WindowThread::ExternalFdData &data, int fd); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) GMainLoop *main_loop_glib_; GMainContext *main_loop_glib_context_; friend gboolean nux_event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data); friend gboolean nux_timeout_dispatch(gpointer user_data); std::list child_window_list_; std::unique_ptr external_glib_sources_; void InitGlibLoop(); void RunGlibLoop(); void StopGLibLoop(); void CleanupGlibLoop(); void AddFdToGLibLoop(int, gpointer, GSourceFunc); void RemoveFdFromGLibLoop(gpointer); bool AddChildWindowGlibLoop(WindowThread* wnd_thread); static gboolean ExternalSourceCallback(gpointer user_data); unsigned int AddGLibTimeout(unsigned int duration); #else // no GLIB loop Event input_event_; GestureEvent gesture_event_; Event *FetchNextEvent(); #endif #ifdef NUX_GESTURES_SUPPORT std::unique_ptr geis_adapter_; #endif #if defined(NUX_OS_LINUX) && defined(USE_X11) std::shared_ptr xim_controller_; #endif /*! Add a timeout and return the timeout index. This function is used internally by Nux. @param timeout_delay Time laps before the timeout is fired. @return An index for the timeout. */ unsigned int AddTimeout(unsigned int timeout_delay); static const int MINIMUM_WINDOW_WIDTH; //!< Minimum width allowed for a window. static const int MINIMUM_WINDOW_HEIGHT; //!< Minimum height allowed for a window. friend class TimerHandler; friend class BasePainter; friend class SystemThread; friend WindowThread *CreateGUIThread(const char *WindowTitle, int width, int height, WindowThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData); friend WindowThread *CreateNuxWindow(const char *WindowTitle, int width, int height, ThreadUserInitFunc UserInitFunc, void *InitData); friend WindowThread *CreateNuxWindow(const char *window_title, int width, int height, WindowStyle window_border_style, AbstractThread *parent, bool modal, ThreadUserInitFunc user_init_func, void *data); friend WindowThread *CreateNuxWindowNewThread(const char *window_title, int width, int height, WindowStyle window_border_style, AbstractThread *parent, bool modal, ThreadUserInitFunc user_init_func, void *data); friend WindowThread *CreateWindowThread(WindowStyle WndStyle, const char *WindowTitle, int width, int height, WindowThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData); friend WindowThread *CreateModalWindowThread(WindowStyle WndStyle, const char *WindowTitle, int width, int height, WindowThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData); #if defined(NUX_OS_WINDOWS) friend WindowThread *CreateFromForeignWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext, ThreadUserInitFunc UserInitFunc, void *InitData); #elif defined(USE_X11) # ifdef NUX_OPENGLES_20 friend WindowThread *CreateFromForeignWindow (Window X11Window, EGLContext OpenGLContext, ThreadUserInitFunc UserInitFunc, void *InitData); # else friend WindowThread *CreateFromForeignWindow (Window X11Window, GLXContext OpenGLContext, ThreadUserInitFunc UserInitFunc, void *InitData); # endif #elif defined(NO_X11) friend WindowThread *CreateFromForeignWindow (EGLDisplay disp, EGLContext OpenGLContext, ThreadUserInitFunc UserInitFunc, void *InitData); #endif friend SystemThread *CreateSystemThread(AbstractThread *Parent, ThreadUserInitFunc UserInitFunc, void *InitData); }; } #endif // WINDOWTHREAD_H nux-4.0.6+14.04.20140409/Nux/AbstractCheckedButton.cpp0000644000015301777760000001430312321344237022422 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HLayout.h" #include "AbstractCheckedButton.h" #include "StaticText.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(AbstractCheckedButton); AbstractCheckedButton::AbstractCheckedButton(const std::string &str, bool state, NUX_FILE_LINE_DECL) : AbstractButton(NUX_FILE_LINE_PARAM) { label_ = str; active_ = state; hlayout_ = 0; static_text_ = new StaticText(label_, NUX_TRACKER_LOCATION); static_text_->SetTextColor(label_color_); hlayout_ = new HLayout(NUX_TRACKER_LOCATION); check_area_ = new BasicView(NUX_TRACKER_LOCATION); check_area_->SetInputEventSensitivity(false); static_text_->SetInputEventSensitivity(false); // Set Geometry check_area_->SetMinMaxSize(14, 14); hlayout_->SetSpaceBetweenChildren(4); hlayout_->SetContentDistribution(MAJOR_POSITION_LEFT); hlayout_->AddView(check_area_, 0, MINOR_POSITION_CENTER, MINOR_SIZE_MATCHCONTENT); hlayout_->AddView(static_text_, 1, MINOR_POSITION_CENTER, MINOR_SIZE_MATCHCONTENT); // // This is convenient to make the layout and the AbstractCheckedButton fit the check area and the caption area. // // Since the check area is bigger than 4x4, it will force the layout and the AbstractCheckedButton to grow. // // This is useful if the AbstractCheckedButton is put in a vertical layout and it has a stretch factor of 0. Then the width of the AbstractCheckedButton // // will be adjusted to fit the minimum width of the check area and the caption area. // { // hlayout_->SetMinimumSize(1, 1); // SetMinimumSize(14, 14); // ApplyMinWidth(); // ApplyMinHeight(); // } hlayout_->SetScaleFactor(0); SetLayout(hlayout_); } AbstractCheckedButton::~AbstractCheckedButton() { } void AbstractCheckedButton::SetLabel(const std::string &checkbox_label) { label_ = checkbox_label; static_text_->SetText(label_); QueueDraw(); } std::string AbstractCheckedButton::GetLabel() const { return label_; } void AbstractCheckedButton::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); GetPainter().PaintBackground(graphics_engine, base); InteractState is; is.is_on = active_; if (visual_state_ == VISUAL_STATE_PRESSED) { is.is_focus = true; } else if (visual_state_ == VISUAL_STATE_PRELIGHT) { is.is_prelight = true; } else { is.is_focus = false; is.is_prelight = false; } GetPainter().PushPaintLayerStack(); { GetPainter().PaintCheckBox(graphics_engine, check_area_->GetGeometry(), is, Color(0xff000000)); static_text_->ProcessDraw(graphics_engine, true); } GetPainter().PopPaintLayerStack(); graphics_engine.PopClippingRectangle(); } long AbstractCheckedButton::ComputeContentSize() { if (view_layout_) { PreLayoutManagement(); int old_width = GetBaseWidth(); int old_height = GetBaseHeight(); // Let the text view be as large as possible. static_text_->SetMaximumWidth(AREA_MAX_WIDTH); // Constrain the vertical expansion of the color selector. view_layout_->SetBaseHeight(1); long ret = view_layout_->ComputeContentSize(); PostLayoutManagement(ret); { // Check if the text view goes out of the AbstractCheckedButton area. Geometry base = GetGeometry(); Geometry text_geo = static_text_->GetGeometry(); // Intersect the AbstractCheckedButton and the text view Geometry intersection = base.Intersect(text_geo); if (intersection != text_geo) { // The text view goes outside of the AbstractCheckedButton area. We have to clip it static_text_->SetMaximumWidth(intersection.width); // Assign a size of 1 to the layout and call ComputeContentSize. // Inside the StaticText::ComputeContentSize there is code that takes care of size negociation. view_layout_->SetBaseWidth(1); ret = view_layout_->ComputeContentSize(); // Assign the layout geometry to the AbstractCheckedButton view. PostLayoutManagement(ret); } } int new_width = GetBaseWidth(); int new_height = GetBaseHeight(); long size_compliance = 0; // The layout has been resized to tightly pack its content if (new_width > old_width) { size_compliance |= eLargerWidth; // need scrollbar } else if (new_width < old_width) { size_compliance |= eSmallerWidth; } else { size_compliance |= eCompliantWidth; } // The layout has been resized to tightly pack its content if (new_height > old_height) { size_compliance |= eLargerHeight; // need scrollbar } else if (new_height < old_height) { size_compliance |= eSmallerHeight; } else { size_compliance |= eCompliantHeight; } return size_compliance; } else { PreLayoutManagement(); int ret = PostLayoutManagement(eCompliantHeight | eCompliantWidth); return ret; } return 0; } void AbstractCheckedButton::SetLabelFontSize(int point) { AbstractButton::SetLabelFontSize(point); if (static_text_ == NULL) return; static_text_->SetTextPointSize(point); ComputeContentSize(); QueueDraw(); } } nux-4.0.6+14.04.20140409/Nux/Coverflow.h0000644000015301777760000000466112321344237017635 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith */ #ifndef COVERFLOWVIEW_H #define COVERFLOWVIEW_H #include "NuxCore/Math/Vector4.h" #include "CoverflowModel.h" #include "ClientArea.h" #if defined(NUX_OS_WINDOWS) #define PKGDATADIR "../../data/" #endif namespace nux { class Coverflow: public nux::ClientArea { NUX_DECLARE_OBJECT_TYPE(Coverflow, ClientArea); public: Coverflow(); ~Coverflow(); Property animation_length; Property camera_motion_drift_angle; Property camera_motion_drift_enabled; Property edge_fade; Property flat_icons; Property folding_angle; Property folding_depth; Property folding_rate; Property fov; Property kinetic_scroll_rate; Property mouse_drag_rate; Property pinching; Property pop_out_selected; Property reflection_fadeout_distance; Property reflection_strength; Property space_between_icons; Property model; Property show_labels; Property show_drop_shadow; Property show_reflection; Property true_perspective; Property y_offset; Property reflection_size; bool AcceptKeyNavFocus(); void SetCameraDistance(float distance); float ViewportWidthAtDepth(float depth); float ViewportHeightAtDepth(float depth); protected: virtual bool InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character); virtual void ClientDraw(nux::GraphicsEngine& graphics_engine, nux::DrawAreaContext &ctx, bool force_draw); private: struct Impl; Impl* pimpl; }; } #endif // COVERFLOWVIEW_H nux-4.0.6+14.04.20140409/Nux/NumericValuator.h0000644000015301777760000000336112321344237021003 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUMERICVALUATOR_H #define NUMERICVALUATOR_H #include "SpinBox_Logic.h" namespace nux { class HLayout; class EditTextBox; class NumericValuator : public SpinBox_Logic { public: NumericValuator(); ~NumericValuator(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void ImplementIncrementBtn(); virtual void ImplementDecrementBtn(); virtual void ImplementValidateEntry(); void SetValue(float value); float GetValue() const; void SetStep(float f); float GetStep(); sigc::signal sigIncrement; sigc::signal sigDecrement; sigc::signal sigValueChanged; protected: void InitializeWidgets(); void InitializeLayout(); private: HLayout *hlayout; DoubleValidator m_DoubleValidator; float m_fValue; float m_Step; }; } #endif // NUMERICVALUATOR_H nux-4.0.6+14.04.20140409/Nux/RGBValuator.cpp0000644000015301777760000013722012321344237020350 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "HLayout.h" #include "VLayout.h" #include "EditTextBox.h" #include "ToggleButton.h" #include "HexRegExpValidator.h" #include "IntegerValidator.h" #include "DoubleValidator.h" #include "RGBValuator.h" #include #include namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(RGBValuator); RGBValuator::RGBValuator(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , rgb_(1, 1, 1) , hsv_(rgb_) , hls_(rgb_) , m_color_model(color::RGB) , m_color_format(color::FLOAT) { InitializeLayout(); SetColorModel(m_color_model); SetColorFormat(m_color_format); SetRGBA(1.0f, 1.0f, 1.0f, 1.0f); InitializeWidgets(); } RGBValuator::RGBValuator(Color const& color, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , rgb_(1, 1, 1) , hsv_(rgb_) , hls_(rgb_) , m_color_model(color::RGB) , m_color_format(color::FLOAT) { InitializeLayout(); SetColorModel(m_color_model); SetColorFormat(m_color_format); SetRGBA(color); InitializeWidgets(); } RGBValuator::RGBValuator(color::Model colorModel, float x, float y, float z, float alpha, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , rgb_(1, 1, 1) , hsv_(rgb_) , hls_(rgb_) , m_color_model(colorModel) , m_color_format(color::FLOAT) { InitializeLayout(); switch(m_color_model) { case color::HSV: { SetColorModel(color::HSV); SetHSV(x, y, z); SetAlpha(alpha); } case color::HLS: { SetColorModel(color::HLS); SetHLS(x, y, z); SetAlpha(alpha); } default: case color::RGB: { SetColorModel(color::RGB); SetRGBA(x, y, z, alpha); } } SetColorFormat(m_color_format); InitializeWidgets(); } void RGBValuator::InitializeLayout() { hlayout = new HLayout("RGBValuatorLayout", NUX_TRACKER_LOCATION); redlayout = new HLayout("RedLayout", NUX_TRACKER_LOCATION); greenlayout = new HLayout("GreenLayout", NUX_TRACKER_LOCATION); bluelayout = new HLayout("BlueLayout", NUX_TRACKER_LOCATION); alphalayout = new HLayout("AlphaLayout", NUX_TRACKER_LOCATION); vlayout = new VLayout("RGBVLayout", NUX_TRACKER_LOCATION); colormodel_layout = new VLayout("ColorModel", NUX_TRACKER_LOCATION); m_ColorModel = new ToggleButton(); m_ColorFormat = new ToggleButton(); red_caption_ = new EditTextBox("", NUX_TRACKER_LOCATION); green_caption_ = new EditTextBox("", NUX_TRACKER_LOCATION); blue_caption_ = new EditTextBox("", NUX_TRACKER_LOCATION); alpha_caption_ = new EditTextBox("", NUX_TRACKER_LOCATION); red_valuator_ = new BasicView(NUX_TRACKER_LOCATION); green_valuator_ = new BasicView(NUX_TRACKER_LOCATION); blue_valuator_ = new BasicView(NUX_TRACKER_LOCATION); alpha_valuator_ = new BasicView(NUX_TRACKER_LOCATION); color_square_ = new BasicView(NUX_TRACKER_LOCATION); m_ComponentLabel0 = new BasicView(NUX_TRACKER_LOCATION); m_ComponentLabel1 = new BasicView(NUX_TRACKER_LOCATION); m_ComponentLabel2 = new BasicView(NUX_TRACKER_LOCATION); m_ComponentAlpha = new BasicView(NUX_TRACKER_LOCATION); } void RGBValuator::InitializeWidgets() { m_HexRegExp.SetMaximum(255); m_HexRegExp.SetMinimum(0); m_IntRegExp.SetMaximum(255); m_IntRegExp.SetMinimum(0); m_DoubleRegExp.SetMaximum(1.0); m_DoubleRegExp.SetMinimum(0); // Set Signals red_valuator_->mouse_down.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDown_Red)); green_valuator_->mouse_down.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDown_Green)); blue_valuator_->mouse_down.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDown_Blue)); alpha_valuator_->mouse_down.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDown_Alpha)); red_valuator_->mouse_drag.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDrag_Red)); green_valuator_->mouse_drag.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDrag_Green)); blue_valuator_->mouse_drag.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDrag_Blue)); alpha_valuator_->mouse_drag.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseDrag_Alpha)); m_ColorModel->click.connect(sigc::mem_fun(this, &RGBValuator::OnChangeColorModel)); m_ColorFormat->click.connect(sigc::mem_fun(this, &RGBValuator::OnChangeColorFormat)); m_ColorModel->SetFont(GetSysBoldFont()); m_ColorFormat->SetFont(GetSysBoldFont()); red_valuator_->mouse_up.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseUp_Red)); green_valuator_->mouse_up.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseUp_Green)); blue_valuator_->mouse_up.connect(sigc::mem_fun(this, &RGBValuator::OnReceiveMouseUp_Blue)); red_caption_->sigValidateKeyboardEntry.connect(sigc::bind(sigc::mem_fun(this, &RGBValuator::OnComponentInput), 0)); green_caption_->sigValidateKeyboardEntry.connect(sigc::bind(sigc::mem_fun(this, &RGBValuator::OnComponentInput), 1)); blue_caption_->sigValidateKeyboardEntry.connect(sigc::bind(sigc::mem_fun(this, &RGBValuator::OnComponentInput), 2)); alpha_caption_->sigValidateKeyboardEntry.connect(sigc::bind(sigc::mem_fun(this, &RGBValuator::OnComponentInput), 3)); // Set Geometry red_caption_->SetGeometry(Geometry(0, 0, 42, DEFAULT_WIDGET_HEIGHT)); red_caption_->SetMaximumHeight(15); green_caption_->SetGeometry(Geometry(0, 0, 42, DEFAULT_WIDGET_HEIGHT)); green_caption_->SetMaximumHeight(15); blue_caption_->SetGeometry(Geometry(0, 0, 42, DEFAULT_WIDGET_HEIGHT)); blue_caption_->SetMaximumHeight(15); alpha_caption_->SetGeometry(Geometry(0, 0, 42, DEFAULT_WIDGET_HEIGHT)); alpha_caption_->SetMaximumHeight(15); m_ComponentLabel0->SetMinimumSize(10, DEFAULT_WIDGET_HEIGHT); m_ComponentLabel0->SetMaximumHeight(15); //m_ComponentLabel0->SetGeometry(Geometry(0, 0, 15, DEFAULT_WIDGET_HEIGHT)); m_ComponentLabel1->SetMinimumSize(10, DEFAULT_WIDGET_HEIGHT); m_ComponentLabel1->SetMaximumHeight(15); //m_ComponentLabel1->SetGeometry(Geometry(0, 0, 15, DEFAULT_WIDGET_HEIGHT)); m_ComponentLabel2->SetMinimumSize(10, DEFAULT_WIDGET_HEIGHT); m_ComponentLabel2->SetMaximumHeight(15); //m_ComponentLabel2->SetGeometry(Geometry(0, 0, 15, DEFAULT_WIDGET_HEIGHT)); m_ComponentAlpha->SetMinimumSize(10, DEFAULT_WIDGET_HEIGHT); m_ComponentAlpha->SetMaximumHeight(15); //m_ComponentAlpha->SetGeometry(Geometry(0, 0, 15, DEFAULT_WIDGET_HEIGHT)); red_valuator_->SetMinimumSize(3 * DEFAULT_WIDGET_WIDTH, 15); red_valuator_->SetMaximumHeight(15); red_valuator_->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); green_valuator_->SetMinimumSize(3 * DEFAULT_WIDGET_WIDTH, 15); green_valuator_->SetMaximumHeight(15); green_valuator_->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); blue_valuator_->SetMinimumSize(3 * DEFAULT_WIDGET_WIDTH, 15); blue_valuator_->SetMaximumHeight(15); blue_valuator_->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); alpha_valuator_->SetMinimumSize(3 * DEFAULT_WIDGET_WIDTH, 15); alpha_valuator_->SetMaximumHeight(15); alpha_valuator_->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); color_square_->SetMinimumSize(32, 32); color_square_->SetGeometry(Geometry(0, 0, 32, 32)); m_ColorModel->SetMinimumSize(20, 16); m_ColorModel->SetLayoutPadding(0, 0, 0, 0); m_ColorFormat->SetMinimumSize(20, 16); m_ColorFormat->SetLayoutPadding(0, 0, 0, 0); redlayout->AddView(m_ComponentLabel0, 0, MINOR_POSITION_CENTER, MINOR_SIZE_MATCHCONTENT); redlayout->AddView(red_caption_, 0); redlayout->AddView(red_valuator_, 1); redlayout->SetSpaceBetweenChildren(4); greenlayout->AddView(m_ComponentLabel1, 0, MINOR_POSITION_CENTER, MINOR_SIZE_MATCHCONTENT); greenlayout->AddView(green_caption_, 0); greenlayout->AddView(green_valuator_, 1); greenlayout->SetSpaceBetweenChildren(4); bluelayout->AddView(m_ComponentLabel2, 0, MINOR_POSITION_CENTER, MINOR_SIZE_MATCHCONTENT); bluelayout->AddView(blue_caption_, 0); bluelayout->AddView(blue_valuator_, 1); bluelayout->SetSpaceBetweenChildren(4); alphalayout->AddView(m_ComponentAlpha, 0, MINOR_POSITION_CENTER, MINOR_SIZE_MATCHCONTENT); alphalayout->AddView(alpha_caption_, 0); alphalayout->AddView(alpha_valuator_, 1); alphalayout->SetSpaceBetweenChildren(4); // Set layout colormodel_layout->AddView(color_square_, 0, eCenter, eFix); colormodel_layout->AddView(m_ColorModel, 0, eCenter, eFull); colormodel_layout->AddView(m_ColorFormat, 0, eCenter, eFull); colormodel_layout->SetSpaceBetweenChildren(2); hlayout->AddView(colormodel_layout, 0, MINOR_POSITION_START, MINOR_SIZE_MATCHCONTENT); vlayout->AddLayout(redlayout, 0); vlayout->AddLayout(greenlayout, 0); vlayout->AddLayout(bluelayout, 0); vlayout->AddLayout(alphalayout, 0); vlayout->SetSpaceBetweenChildren(2); vlayout->SetTopAndBottomPadding(4); vlayout->SetLeftAndRightPadding(4); vlayout->SetContentDistribution(MAJOR_POSITION_CENTER); hlayout->AddLayout(vlayout, 1, MINOR_POSITION_CENTER, MINOR_SIZE_FULL); hlayout->SetSpaceBetweenChildren(2); hlayout->SetLeftAndRightPadding(6, 6); hlayout->SetTopAndBottomPadding(0); SetCompositionLayout(hlayout); NTextureData image; MakeCheckBoardImage(image.GetSurface(0), 64, 64, Color(0xff000000), Color(0xff323232), 4, 4); BaseTexture* CheckboardPattern = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); CheckboardPattern->Update(&image); TexCoordXForm texxform; texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); texxform.SetWrap(TEXWRAP_REPEAT, TEXWRAP_REPEAT); m_CheckboardLayer = new TextureLayer(CheckboardPattern->GetDeviceTexture(), texxform, color::White); CheckboardPattern->UnReference(); } RGBValuator::~RGBValuator() { NUX_SAFE_DELETE(m_CheckboardLayer); } void RGBValuator::DrawRedMarker(GraphicsEngine &graphics_engine) { int marker_position_x; int marker_position_y; float percent = 0.0f; if (m_color_model == color::RGB) percent = rgb_.red; if (m_color_model == color::HSV) percent = hsv_.hue; if (m_color_model == color::HLS) percent = hls_.hue; graphics_engine.PushClippingRectangle(red_valuator_->GetGeometry()); marker_position_x = red_valuator_->GetBaseX() + percent * red_valuator_->GetBaseWidth(); marker_position_y = red_valuator_->GetBaseY() + red_valuator_->GetBaseHeight(); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y, marker_position_x, marker_position_y - 5, marker_position_x + 5, marker_position_y, Color(0xFF000000)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 4, marker_position_y, marker_position_x, marker_position_y - 4, marker_position_x + 4, marker_position_y, Color(0.7f, 0.7f, 0.7f, 1.0f)); graphics_engine.PopClippingRectangle(); } void RGBValuator::DrawGreenMarker(GraphicsEngine &graphics_engine) { int marker_position_x; int marker_position_y; float percent = 0.0f; if (m_color_model == color::RGB) percent = rgb_.green; if (m_color_model == color::HSV) percent = hsv_.saturation; if (m_color_model == color::HLS) percent = hls_.lightness; graphics_engine.PushClippingRectangle(green_valuator_->GetGeometry()); marker_position_x = green_valuator_->GetBaseX() + percent * green_valuator_->GetBaseWidth(); marker_position_y = green_valuator_->GetBaseY() + green_valuator_->GetBaseHeight(); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y, marker_position_x, marker_position_y - 5, marker_position_x + 5, marker_position_y, Color(0.0f, 0.0f, 0.0f, 1.0f)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 4, marker_position_y, marker_position_x, marker_position_y - 4, marker_position_x + 4, marker_position_y, Color(0.7f, 0.7f, 0.7f, 1.0f)); graphics_engine.PopClippingRectangle(); } void RGBValuator::DrawBlueMarker(GraphicsEngine &graphics_engine) { int marker_position_x; int marker_position_y; float percent = 0.0f; if (m_color_model == color::RGB) percent = rgb_.blue; if (m_color_model == color::HSV) percent = hsv_.value; if (m_color_model == color::HLS) percent = hls_.saturation; graphics_engine.PushClippingRectangle(blue_valuator_->GetGeometry()); marker_position_x = blue_valuator_->GetBaseX() + percent * blue_valuator_->GetBaseWidth(); marker_position_y = blue_valuator_->GetBaseY() + blue_valuator_->GetBaseHeight(); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y, marker_position_x, marker_position_y - 5, marker_position_x + 5, marker_position_y, Color(0.0f, 0.0f, 0.0f, 1.0f)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 4, marker_position_y, marker_position_x, marker_position_y - 4, marker_position_x + 4, marker_position_y, Color(0.7f, 0.7f, 0.7f, 1.0f)); graphics_engine.PopClippingRectangle(); } void RGBValuator::DrawAlphaMarker(GraphicsEngine &graphics_engine) { int marker_position_x; int marker_position_y; graphics_engine.PushClippingRectangle(alpha_valuator_->GetGeometry()); marker_position_x = alpha_valuator_->GetBaseX() + alpha_ * alpha_valuator_->GetBaseWidth(); marker_position_y = alpha_valuator_->GetBaseY() + alpha_valuator_->GetBaseHeight(); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y, marker_position_x, marker_position_y - 5, marker_position_x + 5, marker_position_y, Color(0.0f, 0.0f, 0.0f, 1.0f)); GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 4, marker_position_y, marker_position_x, marker_position_y - 4, marker_position_x + 4, marker_position_y, Color(0.7f, 0.7f, 0.7f, 1.0f)); graphics_engine.PopClippingRectangle(); } void RGBValuator::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); GetPainter().PushDrawShapeLayer(graphics_engine, vlayout->GetGeometry(), eSHAPE_CORNER_ROUND4, Color(0xFF000000), eAllCorners, true); if (m_color_model == color::RGB) { DrawRGB(graphics_engine); } else if (m_color_model == color::HSV) { DrawHSV(graphics_engine); } else if (m_color_model == color::HLS) { DrawHLS(graphics_engine); } GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), m_ComponentLabel0->GetGeometry(), m_ComponentLabel0->GetBaseString(), Color(0xFFFFFFFF)); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), m_ComponentLabel1->GetGeometry(), m_ComponentLabel1->GetBaseString(), Color(0xFFFFFFFF)); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), m_ComponentLabel2->GetGeometry(), m_ComponentLabel2->GetBaseString(), Color(0xFFFFFFFF)); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), m_ComponentAlpha->GetGeometry(), m_ComponentAlpha->GetBaseString(), Color(0xFFFFFFFF)); DrawRedMarker(graphics_engine); DrawGreenMarker(graphics_engine); DrawBlueMarker(graphics_engine); DrawAlphaMarker(graphics_engine); GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } void RGBValuator::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); red_caption_->ProcessDraw(graphics_engine, force_draw); green_caption_->ProcessDraw(graphics_engine, force_draw); blue_caption_->ProcessDraw(graphics_engine, force_draw); alpha_caption_->ProcessDraw(graphics_engine, force_draw); m_ColorModel->ProcessDraw(graphics_engine, force_draw); // the button has round corner. That is why we need to push the background. m_ColorFormat->ProcessDraw(graphics_engine, force_draw); // the button has round corner. That is why we need to push the background. graphics_engine.PopClippingRectangle(); } void RGBValuator::DrawRGB(GraphicsEngine &graphics_engine) { // Red Geometry P = red_valuator_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(0.0f, rgb_.green, rgb_.blue), Color(0.0f, rgb_.green, rgb_.blue), Color(1.0f, rgb_.green, rgb_.blue), Color(1.0f, rgb_.green, rgb_.blue)); // Green P = green_valuator_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(rgb_.red, 0.0f, rgb_.blue), Color(rgb_.red, 0.0f, rgb_.blue), Color(rgb_.red, 1.0f, rgb_.blue), Color(rgb_.red, 1.0f, rgb_.blue)); // Blue P = blue_valuator_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(rgb_.red, rgb_.green, 0.0f), Color(rgb_.red, rgb_.green, 0.0f), Color(rgb_.red, rgb_.green, 1.0f), Color(rgb_.red, rgb_.green, 1.0f)); // Alpha P = alpha_valuator_->GetGeometry(); m_CheckboardLayer->SetGeometry(P); m_CheckboardLayer->Renderlayer(graphics_engine); graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(0.0f, 0.0f, 0.0f, 0.0f), Color(0.0f, 0.0f, 0.0f, 0.0f), Color(rgb_.red, rgb_.green, rgb_.blue, 1.0f), Color(rgb_.red, rgb_.green, rgb_.blue, 1.0f)); graphics_engine.GetRenderStates().SetBlend(false); P = color_square_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(rgb_.red, rgb_.green, rgb_.blue), Color(rgb_.red, rgb_.green, rgb_.blue), Color(rgb_.red, rgb_.green, rgb_.blue), Color(rgb_.red, rgb_.green, rgb_.blue)); m_ColorModel->ProcessDraw(graphics_engine, true); m_ColorFormat->ProcessDraw(graphics_engine, true); } void RGBValuator::DrawHSV(GraphicsEngine &graphics_engine) { // Red Geometry P = red_valuator_->GetGeometry(); float s = 0; //XSI: 1.0f - hsv_.saturation; float v = 1; //XSI: hsv_.value; float fw = P.GetWidth() / 6; Geometry p = Geometry(P.x, P.y, fw, P.GetHeight()); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(1.0f * v, s * v, s * v), Color(1.0f * v, s * v, s * v), Color(1.0f * v, 1.0f * v, s * v), Color(1.0f * v, 1.0f * v, s * v)); p.SetX(P.x + fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(1.0f * v, 1.0f * v, s * v), Color(1.0f * v, 1.0f * v, s * v), Color(s * v, 1.0f * v, s * v), Color(s * v, 1.0f * v, s * v)); p.SetX(P.x + 2 * fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(s * v, 1.0f * v, s * v), Color(s * v, 1.0f * v, s * v), Color(s * v, 1.0f * v, 1.0f * v), Color(s * v, 1.0f * v, 1.0f * v)); p.SetX(P.x + 3 * fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(s * v, 1.0f * v, 1.0f * v), Color(s * v, 1.0f * v, 1.0f * v), Color(s * v, s * v, 1.0f * v), Color(s * v, s * v, 1.0f * v)); p.SetX(P.x + 4 * fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(s * v, s * v, 1.0f * v), Color(s * v, s * v, 1.0f * v), Color(1.0f * v, s * v, 1.0f * v), Color(1.0f * v, s * v, 1.0f * v)); p.SetX(P.x + 5 * fw); p.SetWidth(P.GetWidth() - 5 * fw); // correct rounding errors GetPainter().Paint2DQuadColor(graphics_engine, p, Color(1.0f * v, s * v, 1.0f * v), Color(1.0f * v, s * v, 1.0f * v), Color(1.0f * v, s * v, s * v), Color(1.0f * v, s * v, s * v)); s = 1.0f - hsv_.saturation; v = hsv_.value; float hue = hsv_.hue; if (hue == 1.0f) hue = 0.0f; color::RedGreenBlue rgb(color::HueSaturationValue(hue, 1, 1)); Color value_gray(v, v, v); Color value_color(Color(rgb) * v); // Green P = green_valuator_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, value_gray, value_gray, value_color, value_color); rgb = color::RedGreenBlue(color::HueSaturationValue(hue, hsv_.saturation, 1)); // Blue P = blue_valuator_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, color::Black, color::Black, Color(rgb), Color(rgb)); rgb = color::RedGreenBlue(color::HueSaturationValue(hue, hsv_.saturation, hsv_.value)); // Alpha P = alpha_valuator_->GetGeometry(); m_CheckboardLayer->SetGeometry(P); m_CheckboardLayer->Renderlayer(graphics_engine); graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(0.0f, 0.0f, 0.0f, 0.0f), Color(0.0f, 0.0f, 0.0f, 0.0f), Color(rgb), Color(rgb)); graphics_engine.GetRenderStates().SetBlend(false); P = color_square_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(rgb)); m_ColorModel->ProcessDraw(graphics_engine, true); m_ColorFormat->ProcessDraw(graphics_engine, true); } void RGBValuator::DrawHLS(GraphicsEngine &graphics_engine) { // Red Geometry P = red_valuator_->GetGeometry(); float s = 0; //XSI: 1.0f - hls_.saturation; float l = 1; //XSI: hls_.lightness; float fw = P.GetWidth() / 6; Geometry p = Geometry(P.x, P.y, fw, P.GetHeight()); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(1.0f * l, s * l, s * l), Color(1.0f * l, s * l, s * l), Color(1.0f * l, 1.0f * l, s * l), Color(1.0f * l, 1.0f * l, s * l)); p.SetX(P.x + fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(1.0f * l, 1.0f * l, s * l), Color(1.0f * l, 1.0f * l, s * l), Color(s * l, 1.0f * l, s * l), Color(s * l, 1.0f * l, s * l)); p.SetX(P.x + 2 * fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(s * l, 1.0f * l, s * l), Color(s * l, 1.0f * l, s * l), Color(s * l, 1.0f * l, 1.0f * l), Color(s * l, 1.0f * l, 1.0f * l)); p.SetX(P.x + 3 * fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(s * l, 1.0f * l, 1.0f * l), Color(s * l, 1.0f * l, 1.0f * l), Color(s * l, s * l, 1.0f * l), Color(s * l, s * l, 1.0f * l)); p.SetX(P.x + 4 * fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(s * l, s * l, 1.0f * l), Color(s * l, s * l, 1.0f * l), Color(1.0f * l, s * l, 1.0f * l), Color(1.0f * l, s * l, 1.0f * l)); p.SetX(P.x + 5 * fw); p.SetWidth(P.GetWidth() - 5 * fw); // correct rounding errors GetPainter().Paint2DQuadColor(graphics_engine, p, Color(1.0f * l, s * l, 1.0f * l), Color(1.0f * l, s * l, 1.0f * l), Color(1.0f * l, s * l, s * l), Color(1.0f * l, s * l, s * l)); s = 1.0f - hls_.saturation; l = hls_.lightness; float Hue; if (hls_.hue == 1.0f) Hue = 0.0f; else Hue = hls_.hue; // TODO: Tim Penhey 2011-05-13 // refactor this code to use the same methods as the RGB(A)Property classes. color::RedGreenBlue rgb(color::HueSaturationValue(Hue, 1, 1)); // Need to use HSVtoRGB to compute the color float r = rgb.red; float g = rgb.green; float b = rgb.blue; // Green P = green_valuator_->GetGeometry(); fw = P.GetWidth() / 2; p = Geometry(P.x, P.y, fw, P.GetHeight()); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(0.0f, 0.0f, 0.0f), Color(0.0f, 0.0f, 0.0f), Color(r* (1 - s) + 0.5f * s, g* (1 - s) + 0.5f * s, b* (1 - s) + 0.5f * s), Color(r* (1 - s) + 0.5f * s, g* (1 - s) + 0.5f * s, b* (1 - s) + 0.5f * s)); p.SetX(P.x + fw); GetPainter().Paint2DQuadColor(graphics_engine, p, Color(r* (1 - s) + 0.5f * s, g* (1 - s) + 0.5f * s, b* (1 - s) + 0.5f * s), Color(r* (1 - s) + 0.5f * s, g* (1 - s) + 0.5f * s, b* (1 - s) + 0.5f * s), Color(1.0f, 1.0f, 1.0f), Color(1.0f, 1.0f, 1.0f)); //HLStoRGB(r, g, b, Hue, hsv_.saturation, 1.0f); // Blue float cr, cg, cb; if (l > 0.5) { float factor = (l - 0.5f) / 0.5f; cr = (1 - factor) * r * (1 - s) + 0.5 * s + factor * 1.0f; cg = (1 - factor) * g * (1 - s) + 0.5 * s + factor * 1.0f; cb = (1 - factor) * b * (1 - s) + 0.5 * s + factor * 1.0f; } else { float factor = l / 0.5f; cr = (factor) * r * (1 - s) + 0.5 * s; cg = (factor) * g * (1 - s) + 0.5 * s; cb = (factor) * b * (1 - s) + 0.5 * s; } P = blue_valuator_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(l, l, l), Color(l, l, l), Color(cr, cg, cb), Color(cr, cg, cb)); // TODO: Tim Penhey 2011-05-13 // Can we just use the rgb_ member variable? Check later. rgb = color::RedGreenBlue(hls_); // Alpha P = alpha_valuator_->GetGeometry(); m_CheckboardLayer->SetGeometry(P); m_CheckboardLayer->Renderlayer(graphics_engine); graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(0.0f, 0.0f, 0.0f, 0.0f), Color(0.0f, 0.0f, 0.0f, 0.0f), Color(rgb), Color(rgb)); graphics_engine.GetRenderStates().SetBlend(false); P = color_square_->GetGeometry(); GetPainter().Paint2DQuadColor(graphics_engine, P, Color(rgb)); m_ColorModel->ProcessDraw(graphics_engine, true); m_ColorFormat->ProcessDraw(graphics_engine, true); } void RGBValuator::SetRGBA(Color const& color) { SetRGBA(color.red, color.green, color.blue, color.alpha); } void RGBValuator::SetRGBA(float r, float g, float b, float a) { SetRGB(r, g, b); SetAlpha(a); } void RGBValuator::SetRGB(Color const& color) { SetRGB(color.red, color.green, color.blue); } std::string as_hex(float f) { std::ostringstream s; s << std::hex << (int)f; return s.str(); } std::string as_dec(float f) { std::ostringstream s; s << (int)f; return s.str(); } std::string as_float(float f) { std::ostringstream s; s << std::setprecision(3) << f; return s.str(); } void RGBValuator::SetRGB(float r, float g, float b) { rgb_.red = Clamp(r, 0.0f, 1.0f); rgb_.green = Clamp(g, 0.0f, 1.0f); rgb_.blue = Clamp(b, 0.0f, 1.0f); bool RedEditSelected = red_caption_->IsTextSelected(); bool GreenEditSelected = green_caption_->IsTextSelected(); bool BlueEditSelected = blue_caption_->IsTextSelected(); if (m_color_format == color::HEX) { red_caption_->SetText(as_hex(rgb_.red * 255)); green_caption_->SetText(as_hex(rgb_.green * 255)); blue_caption_->SetText(as_hex(rgb_.blue * 255)); } else if (m_color_format == color::INT) { red_caption_->SetText(as_dec(rgb_.red * 255)); green_caption_->SetText(as_dec(rgb_.green * 255)); blue_caption_->SetText(as_dec(rgb_.blue * 255)); } else { red_caption_->SetText(as_float(rgb_.red)); green_caption_->SetText(as_float(rgb_.green)); blue_caption_->SetText(as_float(rgb_.blue)); } // Restore text selection if necessary. // This solves a problem when an EditTextBox of the widget gets the focus and has its text selected // but another who is losing the focus will cause it to lose the text selection by calling SetRGB. if (RedEditSelected) red_caption_->m_KeyboardHandler.SelectAllText(); if (GreenEditSelected) green_caption_->m_KeyboardHandler.SelectAllText(); if (BlueEditSelected) blue_caption_->m_KeyboardHandler.SelectAllText(); sigColorChanged.emit(rgb_.red, rgb_.green, rgb_.blue, alpha_); } void RGBValuator::SetHSV(float h, float s, float v) { hsv_.hue = Clamp(h, 0.0f, 1.0f); hsv_.saturation = Clamp(s, 0.0f, 1.0f); hsv_.value = Clamp(v, 0.0f, 1.0f); bool RedEditSelected = red_caption_->IsTextSelected(); bool GreenEditSelected = green_caption_->IsTextSelected(); bool BlueEditSelected = blue_caption_->IsTextSelected(); if (m_color_format == color::HEX) { red_caption_->SetText(as_hex(hsv_.hue * 255)); green_caption_->SetText(as_hex(hsv_.saturation * 255)); blue_caption_->SetText(as_hex(hsv_.value * 255)); } else if (m_color_format == color::INT) { red_caption_->SetText(as_dec(hsv_.hue * 255)); green_caption_->SetText(as_dec(hsv_.saturation * 255)); blue_caption_->SetText(as_dec(hsv_.value * 255)); } else { red_caption_->SetText(as_float(hsv_.hue)); green_caption_->SetText(as_float(hsv_.saturation)); blue_caption_->SetText(as_float(hsv_.value)); } if (hsv_.hue >= 1.0f) { hsv_.hue = 1.0f; // XSI: hsv_.hue = 0.0f; } if (RedEditSelected) red_caption_->m_KeyboardHandler.SelectAllText(); if (GreenEditSelected) green_caption_->m_KeyboardHandler.SelectAllText(); if (BlueEditSelected) blue_caption_->m_KeyboardHandler.SelectAllText(); rgb_ = color::RedGreenBlue(hsv_); sigColorChanged.emit(rgb_.red, rgb_.green, rgb_.blue, alpha_); } void RGBValuator::SetHLS(float h, float l, float s) { hls_.hue = Clamp(h, 0.0f, 1.0f); hls_.lightness = Clamp(l, 0.0f, 1.0f); hls_.saturation = Clamp(s, 0.0f, 1.0f); bool RedEditSelected = red_caption_->IsTextSelected(); bool GreenEditSelected = green_caption_->IsTextSelected(); bool BlueEditSelected = blue_caption_->IsTextSelected(); if (m_color_format == color::HEX) { red_caption_->SetText(as_hex(hls_.hue * 255)); green_caption_->SetText(as_hex(hls_.lightness * 255)); blue_caption_->SetText(as_hex(hls_.saturation * 255)); } else if (m_color_format == color::INT) { red_caption_->SetText(as_dec(hls_.hue * 255)); green_caption_->SetText(as_dec(hls_.lightness * 255)); blue_caption_->SetText(as_dec(hls_.saturation * 255)); } else { red_caption_->SetText(as_float(hls_.hue)); green_caption_->SetText(as_float(hls_.lightness)); blue_caption_->SetText(as_float(hls_.saturation)); } if (hls_.hue >= 1.0f) { hls_.hue = 1.0f; // XSI: hls_.hue = 0.0f; } if (RedEditSelected) red_caption_->m_KeyboardHandler.SelectAllText(); if (GreenEditSelected) green_caption_->m_KeyboardHandler.SelectAllText(); if (BlueEditSelected) blue_caption_->m_KeyboardHandler.SelectAllText(); rgb_ = color::RedGreenBlue(hls_); sigColorChanged.emit(rgb_.red, rgb_.green, rgb_.blue, alpha_); } void RGBValuator::SetAlpha(float alpha) { alpha_ = Clamp(alpha, 0.0f, 1.0f); if (m_color_format == color::HEX) { alpha_caption_->SetText(as_hex(alpha_ * 255)); } else if (m_color_format == color::INT) { alpha_caption_->SetText(as_dec(alpha_ * 255)); } else { alpha_caption_->SetText(as_float(alpha_)); } sigColorChanged.emit(rgb_.red, rgb_.green, rgb_.blue, alpha_); } void RGBValuator::OnReceiveMouseDown_Red(int x, int /* y */, unsigned long /* button_flags */, unsigned long key_flags) { if (m_color_model == color::RGB) { if (x < 0) rgb_.red = 0.0f; else if (x > red_valuator_->GetBaseWidth()) rgb_.red = 1.0f; else rgb_.red = (float) x / (float) red_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetRGB(rgb_.red, rgb_.red, rgb_.red); } else { SetRGB(rgb_.red, rgb_.green, rgb_.blue); } } else if (m_color_model == color::HSV) { if (x < 0) hsv_.hue = 0.0f; else if (x > red_valuator_->GetBaseWidth()) hsv_.hue = 1.0f; else hsv_.hue = (float) x / (float) red_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetHSV(hsv_.hue, hsv_.hue, hsv_.hue); } else { SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } } else if (m_color_model == color::HLS) { if (x < 0) hls_.hue = 0.0f; else if (x > red_valuator_->GetBaseWidth()) hls_.hue = 1.0f; else hls_.hue = (float) x / (float) red_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetHLS(hls_.hue, hls_.hue, hls_.hue); } else { SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } } QueueDraw(); } void RGBValuator::OnReceiveMouseDown_Green(int x, int /* y */, unsigned long /* button_flags */, unsigned long key_flags) { if (m_color_model == color::RGB) { if (x < 0) rgb_.green = 0.0f; else if (x > green_valuator_->GetBaseWidth()) rgb_.green = 1.0f; else rgb_.green = (float) x / (float) green_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetRGB(rgb_.green, rgb_.green, rgb_.green); } else { SetRGB(rgb_.red, rgb_.green, rgb_.blue); } } else if (m_color_model == color::HSV) { if (x < 0) hsv_.saturation = 0.0f; else if (x > green_valuator_->GetBaseWidth()) hsv_.saturation = 1.0f; else hsv_.saturation = (float) x / (float) green_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetHSV(hsv_.saturation, hsv_.saturation, hsv_.saturation); } else { SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } } else if (m_color_model == color::HLS) { if (x < 0) hls_.lightness = 0.0f; else if (x > green_valuator_->GetBaseWidth()) hls_.lightness = 1.0f; else hls_.lightness = (float) x / (float) green_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetHLS(hls_.lightness, hls_.lightness, hls_.lightness); } else { SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } } QueueDraw(); } void RGBValuator::OnReceiveMouseDown_Blue(int x, int /* y */, unsigned long /* button_flags */, unsigned long key_flags) { if (m_color_model == color::RGB) { if (x < 0) rgb_.blue = 0.0f; else if (x > blue_valuator_->GetBaseWidth()) rgb_.blue = 1.0f; else rgb_.blue = (float) x / (float) blue_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetRGB(rgb_.blue, rgb_.blue, rgb_.blue); } else { SetRGB(rgb_.red, rgb_.green, rgb_.blue); } } else if (m_color_model == color::HSV) { if (x < 0) hsv_.value = 0.0f; else if (x > blue_valuator_->GetBaseWidth()) hsv_.value = 1.0f; else hsv_.value = (float) x / (float) blue_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetHSV(hsv_.value, hsv_.value, hsv_.value); } else { SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } } else if (m_color_model == color::HLS) { if (x < 0) hls_.saturation = 0.0f; else if (x > blue_valuator_->GetBaseWidth()) hls_.saturation = 1.0f; else hls_.saturation = (float) x / (float) blue_valuator_->GetBaseWidth(); if (key_flags & NUX_STATE_CTRL) { SetHLS(hls_.saturation, hls_.saturation, hls_.saturation); } else { SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } } QueueDraw(); } void RGBValuator::OnReceiveMouseDown_Alpha(int x, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (x < 0) alpha_ = 0.0f; else if (x > alpha_valuator_->GetBaseWidth()) alpha_ = 1.0f; else alpha_ = (float) x / (float) alpha_valuator_->GetBaseWidth(); SetAlpha(alpha_); QueueDraw(); } void RGBValuator::OnReceiveMouseDrag_Red(int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { OnReceiveMouseDown_Red(x, y, button_flags, key_flags); } void RGBValuator::OnReceiveMouseDrag_Green(int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { OnReceiveMouseDown_Green(x, y, button_flags, key_flags); } void RGBValuator::OnReceiveMouseDrag_Blue(int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { OnReceiveMouseDown_Blue(x, y, button_flags, key_flags); } void RGBValuator::OnReceiveMouseDrag_Alpha(int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { OnReceiveMouseDown_Alpha(x, y, button_flags, key_flags); } void RGBValuator::OnReceiveMouseUp_Red (int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_color_model == color::HSV) { if (hsv_.hue >= 1.0f) { hsv_.hue = 1.0f; // XSI: hsv_.hue = 0.0f; } if (hsv_.saturation <= 0.0f) { // XSI: hsv_.hue = 0.0f; } if (hsv_.value <= 0.0f) { // XSI: hsv_.hue = 0.0f; // XSI: hsv_.saturation = 0.0f; } SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } if (m_color_model == color::HLS) { if (hls_.hue >= 1.0f) { hls_.hue = 1.0f; // XSI: hls_.hue = 0.0f; } if (hls_.saturation <= 0.0f) { // XSI: hls_.hue = 0.0f; } if (hls_.lightness <= 0.0f || hls_.lightness >= 1.0f) { // XSI: hls_.hue = 0.0f; // XSI: hls_.saturation = 0.0f; } SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } QueueDraw(); } void RGBValuator::OnReceiveMouseUp_Green (int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_color_model == color::HSV) { if (hsv_.hue >= 1.0f) { hsv_.hue = 1.0f; // XSI: hsv_.hue = 0.0f; } if (hsv_.saturation <= 0.0f) { // XSI: hsv_.hue = 0.0f; } if (hsv_.value <= 0.0f) { // XSI: hsv_.hue = 0.0f; // XSI: hsv_.saturation = 0.0f; } SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } if (m_color_model == color::HLS) { if (hls_.hue >= 1.0f) { hls_.hue = 1.0f; // XSI: hls_.hue = 0.0f; } if (hls_.saturation <= 0.0f) { // XSI: hls_.hue = 0.0f; } if (hls_.lightness <= 0.0f || hls_.lightness >= 1.0f) { // XSI: hls_.hue = 0.0f; // XSI: hls_.saturation = 0.0f; } SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } QueueDraw(); } void RGBValuator::OnReceiveMouseUp_Blue(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_color_model == color::HSV) { if (hsv_.hue >= 1.0f) { hsv_.hue = 1.0f; // XSI: hsv_.hue = 0.0f; } if (hsv_.saturation <= 0.0f) { // XSI: hsv_.hue = 0.0f; } if (hsv_.value <= 0.0f) { // XSI: hsv_.hue = 0.0f; // XSI: hsv_.saturation = 0.0f; } SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } if (m_color_model == color::HLS) { if (hls_.hue >= 1.0f) { hls_.hue = 1.0f; // XSI: hls_.hue = 0.0f; } if (hls_.saturation <= 0.0f) { // XSI: hls_.hue = 0.0f; } if (hls_.lightness <= 0.0f || hls_.lightness >= 1.0f) { // XSI: hls_.hue = 0.0f; // XSI: hls_.saturation = 0.0f; } SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } QueueDraw(); } void RGBValuator::RecvMouseDownColorModel(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void RGBValuator::OnChangeColorModel(AbstractButton* /* button */) { if (m_color_model == color::RGB) { SetColorModel(color::HLS); hls_ = color::HueLightnessSaturation(rgb_); SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } else if (m_color_model == color::HLS) { SetColorModel(color::HSV); rgb_ = color::RedGreenBlue(hls_); hsv_ = color::HueSaturationValue(rgb_); SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); if (hsv_.hue == -1.0f) { hsv_.hue = 0; } } else if (m_color_model == color::HSV) { SetColorModel(color::RGB); rgb_ = color::RedGreenBlue(hsv_); SetRGB(rgb_.red, rgb_.green, rgb_.blue); } QueueDraw(); } void RGBValuator::OnChangeColorFormat(AbstractButton* /* button */) { if (m_color_format == color::FLOAT) { SetColorFormat(color::INT); } else if (m_color_format == color::INT) { SetColorFormat(color::HEX); } else if (m_color_format == color::HEX) { SetColorFormat(color::FLOAT); } } void RGBValuator::OnComponentInput(EditTextBox* /* textbox */, const std::string &s, int componentIndex) { float f = 0; if ((m_color_format == color::HEX) && (m_HexRegExp.Validate(s.c_str()) == Validator::Acceptable)) { f = (float) m_HexRegExp.ToInteger(s.c_str()) / 255.0f; } else if ((m_color_format == color::INT) && (m_IntRegExp.Validate(s.c_str()) == Validator::Acceptable)) { f = (float) m_IntRegExp.ToInteger(s.c_str()) / 255.0f; } else { f = (float) m_DoubleRegExp.ToDouble(s.c_str()); } f = Clamp(f, 0.0f, 1.0f); if (componentIndex == 0) { f = Clamp(f, 0.0f, 1.0f); if (m_color_model == color::RGB) { rgb_.red = f; SetRGB(rgb_.red, rgb_.green, rgb_.blue); } else if (m_color_model == color::HSV) { hsv_.hue = f; OnReceiveMouseUp_Red(0, 0, 0, 0); SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } else if (m_color_model == color::HLS) { hls_.hue = f; OnReceiveMouseUp_Red(0, 0, 0, 0); SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } } if (componentIndex == 1) { f = Clamp(f, 0.0f, 1.0f); if (m_color_model == color::RGB) { rgb_.green = f; SetRGB(rgb_.red, rgb_.green, rgb_.blue); } else if (m_color_model == color::HSV) { hsv_.saturation = f; OnReceiveMouseUp_Green(0, 0, 0, 0); SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } else if (m_color_model == color::HLS) { hls_.lightness = f; OnReceiveMouseUp_Green(0, 0, 0, 0); SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } } if (componentIndex == 2) { f = Clamp(f, 0.0f, 1.0f); if (m_color_model == color::RGB) { rgb_.blue = f; SetRGB(rgb_.red, rgb_.green, rgb_.blue); } else if (m_color_model == color::HSV) { hsv_.value = f; OnReceiveMouseUp_Blue(0, 0, 0, 0); SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); } else if (m_color_model == color::HLS) { hls_.saturation = f; OnReceiveMouseUp_Blue(0, 0, 0, 0); SetHLS(hls_.hue, hls_.lightness, hls_.saturation); } } if (componentIndex == 3) { float f = 0; f = CharToDouble(s.c_str()); f = Clamp(f, 0.0f, 1.0f); //if(m_color_model == color::RGB) { alpha_ = f; SetAlpha(alpha_); } } QueueDraw(); } void RGBValuator::SetColorModel(color::Model cm) { if (cm == color::RGB) { m_color_model = color::RGB; m_ColorModel->SetLabel("RGB"); m_ComponentLabel0->SetBaseString("R"); m_ComponentLabel1->SetBaseString("G"); m_ComponentLabel2->SetBaseString("B"); m_ComponentAlpha->SetBaseString("A"); } if (cm == color::HSV) { m_color_model = color::HSV; m_ColorModel->SetLabel("HSV"); m_ComponentLabel0->SetBaseString("H"); m_ComponentLabel1->SetBaseString("S"); m_ComponentLabel2->SetBaseString("V"); m_ComponentAlpha->SetBaseString("A"); } if (cm == color::HLS) { m_color_model = color::HLS; m_ColorModel->SetLabel("HLS"); m_ComponentLabel0->SetBaseString("H"); m_ComponentLabel1->SetBaseString("L"); m_ComponentLabel2->SetBaseString("S"); m_ComponentAlpha->SetBaseString("A"); } if (cm == color::YUV) { m_color_model = color::YUV; m_ColorModel->SetLabel("YUV"); m_ComponentLabel0->SetBaseString("Y"); m_ComponentLabel1->SetBaseString("U"); m_ComponentLabel2->SetBaseString("V"); m_ComponentAlpha->SetBaseString("A"); } } void RGBValuator::SetColorFormat(color::Format cf) { if (cf == color::FLOAT) { m_color_format = color::FLOAT; m_ColorFormat->SetLabel("float"); red_caption_->SetKeyEntryType(BaseKeyboardHandler::eAlphaNumeric); green_caption_->SetKeyEntryType(BaseKeyboardHandler::eAlphaNumeric); blue_caption_->SetKeyEntryType(BaseKeyboardHandler::eAlphaNumeric); red_caption_->SetPrefix(""); green_caption_->SetPrefix(""); blue_caption_->SetPrefix(""); alpha_caption_->SetPrefix(""); } if (cf == color::INT) { m_color_format = color::INT; m_ColorFormat->SetLabel("int"); red_caption_->SetKeyEntryType(BaseKeyboardHandler::eIntegerNumber); green_caption_->SetKeyEntryType(BaseKeyboardHandler::eIntegerNumber); blue_caption_->SetKeyEntryType(BaseKeyboardHandler::eIntegerNumber); red_caption_->SetPrefix(""); green_caption_->SetPrefix(""); blue_caption_->SetPrefix(""); alpha_caption_->SetPrefix(""); } if (cf == color::HEX) { m_color_format = color::HEX; m_ColorFormat->SetLabel("hex"); red_caption_->SetKeyEntryType(BaseKeyboardHandler::eHexadecimalNumber); green_caption_->SetKeyEntryType(BaseKeyboardHandler::eHexadecimalNumber); blue_caption_->SetKeyEntryType(BaseKeyboardHandler::eHexadecimalNumber); red_caption_->SetPrefix("0x"); green_caption_->SetPrefix("0x"); blue_caption_->SetPrefix("0x"); alpha_caption_->SetPrefix("0x"); } if (m_color_model == color::RGB) { SetRGBA(rgb_.red, rgb_.green, rgb_.blue, alpha_); } else if (m_color_model == color::HLS) { SetHLS(hls_.hue, hls_.lightness, hls_.saturation); SetAlpha(alpha_); } else if (m_color_model == color::HSV) { SetHSV(hsv_.hue, hsv_.saturation, hsv_.value); SetAlpha(alpha_); } } void RGBValuator::PreLayoutManagement() { View::PreLayoutManagement(); if (view_layout_) { // Constrain the vertical expansion of the color selector. view_layout_->SetBaseHeight(1); } } Color RGBValuator::GetColor() const { return Color(rgb_, alpha_); } void RGBValuator::EmitColorChangedSignal() { sigColorChanged.emit(rgb_.red, rgb_.green, rgb_.blue, alpha_); } bool RGBValuator::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/FloatingWindow.h0000644000015301777760000001027712321344237020622 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef FLOATINGWINDOW_H #define FLOATINGWINDOW_H #include "NuxGraphics/Events.h" #include "ScrollView.h" #include "BaseWindow.h" #include "BasicView.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "Validator.h" #include "StaticTextBox.h" namespace nux { class HLayout; class PopUpWindow; class FloatingWindow: public BaseWindow { NUX_DECLARE_OBJECT_TYPE(FloatingWindow, BaseWindow); public: FloatingWindow(const char *WindowName = "", NUX_FILE_LINE_PROTO); ~FloatingWindow(); void SetVisibleSizeGrip(bool b) { if (b && (m_bSizeMatchLayout)) m_bIsVisibleSizeGrip = false; else m_bIsVisibleSizeGrip = b; } bool IsVisibleSizeGrip() { return m_bIsVisibleSizeGrip; } void EnableTitleBar(bool b); bool HasTitleBar() const; void OnSizeGrigMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnSizeGrigMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void RecvCloseButtonClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTitleBarMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvTitleBarMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void SetWindowTitle(const char *title); std::string GetWindowTitle(); //! Return true if this object can break the layout. /* Return true if this object can break the layout, meaning, the layout can be done on the composition layout only without recomputing the whole window layout. Inherited from View */ virtual bool CanBreakLayout() { if (IsSizeMatchContent()) return false; return true; } protected: virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void ComputeContentPosition(float offsetX, float offsetY); //! Layout the window elements. /*! Layout elements such as button on the title bar, and the resize widget according to the current geometry of the window. Also initiate the computation of the child layout if there is one. */ virtual void LayoutWindowElements(); int m_SizeGripDragPositionX; int m_SizeGripDragPositionY; private: int _resize_handle_width; int _resize_handle_height; int _title_bar_height; BasicView *_resize_handle; BasicView *_title_bar; Point _title_bar_mouse_down_location; BasicView *_minimize_button; BasicView *_close_button; StaticTextBox *_window_title_bar; bool m_hasTitleBar; bool m_bIsVisible; bool m_bIsVisibleSizeGrip; bool m_bIsModal; //! If true then the FloatingWindow is resized to match the size of the layout. bool m_bSizeMatchLayout; BaseTexture* CloseIcon; BaseTexture* MinimizeIcon; std::list m_InterfaceObject; HLayout *_title_bar_layout; std::string _window_title; friend class PopUpWindow; friend class ComboBox_Logic_WindowView; friend class ComboBoxComplex; friend class WindowCompositor; }; } #endif // FLOATINGWINDOW_H nux-4.0.6+14.04.20140409/Nux/CheckBox.cpp0000644000015301777760000000473012321344237017705 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HLayout.h" #include "CheckBox.h" #include "StaticText.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(CheckBox); CheckBox::CheckBox(const std::string &str, bool state, NUX_FILE_LINE_DECL) : AbstractCheckedButton(str, state, NUX_FILE_LINE_PARAM) { } CheckBox::~CheckBox() { } void CheckBox::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); InteractState is; is.is_on = active_; if (visual_state_ == VISUAL_STATE_PRESSED) { is.is_focus = true; } else if (visual_state_ == VISUAL_STATE_PRELIGHT) { is.is_prelight = true; } else { is.is_focus = false; is.is_prelight = false; } GetPainter().PushPaintLayerStack(); { GetPainter().PaintCheckBox(graphics_engine, check_area_->GetGeometry(), is, Color(0xff000000)); static_text_->ProcessDraw(graphics_engine, true); } GetPainter().PopPaintLayerStack(); graphics_engine.PopClippingRectangle(); } void CheckBox::RecvClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { active_ = !active_; click.emit(this); state_change.emit(this); QueueDraw(); } void CheckBox::Activate() { if (active_ == true) { // already active return; } active_ = true; state_change.emit(this); QueueDraw(); } void CheckBox::Deactivate() { if (active_ == false) return; if (active_ == false) { // already deactivated return; } active_ = false; state_change.emit(this); QueueDraw(); } } nux-4.0.6+14.04.20140409/Nux/KineticScrollView.cpp0000644000015301777760000001066412321344237021622 0ustar pbusernogroup00000000000000/* * Copyright (C) 2012 - Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada */ #include #include #include "KineticScrollView.h" using namespace nux; NUX_IMPLEMENT_OBJECT_TYPE(KineticScrollView); KineticScrollView::KineticScrollView(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM), mouse_pressed_on_child_(false), last_child_mouse_position_x_(0), last_child_mouse_position_y_(0) { mouse_down.connect(sigc::mem_fun(this, &KineticScrollView::OnMouseDown)); mouse_up.connect(sigc::mem_fun(this, &KineticScrollView::OnMouseUp)); mouse_drag.connect(sigc::mem_fun(this, &KineticScrollView::OnMouseDrag)); scroller_.content_position_changed.connect( sigc::mem_fun(this, &KineticScrollView::SetLayoutTranslation)); SetTrackChildMouseEvents(true); SetBoundsBehavior(BoundsBehavior::DragAndOvershootBounds); } KineticScrollView::~KineticScrollView() { } void KineticScrollView::SetBoundsBehavior(BoundsBehavior bounds_behavior) { scroller_.SetBoundsBehavior(bounds_behavior); } void KineticScrollView::SetScrollableDirections(ScrollableDirections scrollable_directions) { scroller_.SetScrollableDirections(scrollable_directions); } bool KineticScrollView::ChildMouseEvent(const Event& event) { bool want_mouse_ownership = false; if (event.type == NUX_MOUSE_PRESSED || event.type == NUX_MOUSE_DOUBLECLICK) { mouse_pressed_on_child_ = true; last_child_mouse_position_x_ = event.x; last_child_mouse_position_y_ = event.y; scroller_.ProcessFingerDown(); } else if (event.type == NUX_MOUSE_MOVE) { int dx = event.x - last_child_mouse_position_x_; int dy = event.y - last_child_mouse_position_y_; scroller_.ProcessFingerDrag(dx, dy); if (scroller_.GetHorizontalAxisState() == KineticScrollerAxisStateFollowingFinger || scroller_.GetVerticalAxisState() == KineticScrollerAxisStateFollowingFinger) { want_mouse_ownership = true; } } else if (event.type == NUX_MOUSE_RELEASED) { mouse_pressed_on_child_ = false; scroller_.ProcessFingerUp(); } return want_mouse_ownership; } void KineticScrollView::Draw(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { if (view_layout_) { view_layout_->QueueDraw(); } } void KineticScrollView::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { if (view_layout_) view_layout_->ProcessDraw(graphics_engine, force_draw); } long KineticScrollView::PostLayoutManagement(long /* LayoutResult */) { if (view_layout_) { scroller_.SetContentSize(view_layout_->GetBaseWidth(), view_layout_->GetBaseHeight()); } scroller_.SetViewportSize(GetBaseWidth(), GetBaseHeight()); /* the return value is meaningless and not used for anything. */ return 0; } void KineticScrollView::PostResizeGeometry() { scroller_.SetViewportSize(GetBaseWidth(), GetBaseHeight()); } void KineticScrollView::OnMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { scroller_.ProcessFingerDown(); } void KineticScrollView::OnMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { scroller_.ProcessFingerUp(); } void KineticScrollView::OnMouseDrag(int /* x */, int /* y */, int dx, int dy, unsigned long /* button_flags */, unsigned long /* key_flags */) { scroller_.ProcessFingerDrag(dx, dy); } void KineticScrollView::SetLayoutTranslation(int x, int y) { if (view_layout_) { view_layout_->Set2DTranslation(x, y, 0); QueueDraw(); } } nux-4.0.6+14.04.20140409/Nux/MouseAreaCtrl.cpp0000644000015301777760000000553612321344237020732 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "MouseAreaCtrl.h" namespace nux { MouseAreaCtrl::MouseAreaCtrl(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { // Set Original State m_vlayout = new VLayout(NUX_TRACKER_LOCATION); m_Area = new BasicView(NUX_TRACKER_LOCATION); // Set Signals m_Area->mouse_down.connect(sigc::mem_fun(this, &MouseAreaCtrl::MouseDown)); m_Area->mouse_up.connect(sigc::mem_fun(this, &MouseAreaCtrl::MouseUp)); m_Area->mouse_drag.connect(sigc::mem_fun(this, &MouseAreaCtrl::MouseDrag)); // Set Geometry m_Area->SetMinimumSize(100, 100); m_Area->SetGeometry(Geometry(0, 0, 200, 400)); m_vlayout->AddView(m_Area, 1); m_vlayout->SetVerticalExternalMargin(6); m_vlayout->SetHorizontalExternalMargin(6); SetCompositionLayout(m_vlayout); } MouseAreaCtrl::~MouseAreaCtrl() { } void MouseAreaCtrl::Draw(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BACKGROUND_SECONDARY), eSHAPE_CORNER_ROUND10); sigDraw.emit(force_draw); } void MouseAreaCtrl::DrawContent(GraphicsEngine & /* graphics_engine */, bool force_draw) { sigDraw.emit(force_draw); } int MouseAreaCtrl::getAreaPosX() { return m_Area->GetBaseX(); } int MouseAreaCtrl::getAreaPosY() { return m_Area->GetBaseY(); } int MouseAreaCtrl::getAreaWidth() { return m_Area->GetBaseWidth(); } int MouseAreaCtrl::getAreaHeight() { return m_Area->GetBaseHeight(); } ///////////////// // EMITERS // ///////////////// void MouseAreaCtrl::MouseDown(int x, int y, unsigned long button_flags, unsigned long /* key_flags */) { sigMouseDown.emit(x, y, button_flags); } void MouseAreaCtrl::MouseUp(int x, int y, unsigned long button_flags, unsigned long /* key_flags */) { sigMouseUp.emit(x, y, button_flags); } void MouseAreaCtrl::MouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long /* key_flags */) { sigMouseDrag.emit(x, y, dx, dy, button_flags); } } nux-4.0.6+14.04.20140409/Nux/AbstractComboBox.cpp0000644000015301777760000001052412321344237021411 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "AbstractComboBox.h" #include "HLayout.h" #include "StaticText.h" namespace nux { Color AbstractComboBox::m_sCOMBO_COLOR = Color(0x009F9F00); Color AbstractComboBox::m_sCOMBO_BUTTON_COLOR = Color(0x00FFFFFF); Color AbstractComboBox::m_sCOMBO_MOUSEOVER_COLOR = Color(0x55FFFFFF); AbstractComboBox::AbstractComboBox(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_MenuIsActive(false) { m_hlayout = new HLayout(NUX_TRACKER_LOCATION); _combo_box_area = new BasicView(NUX_TRACKER_LOCATION); _combo_box_opening_area = new BasicView(NUX_TRACKER_LOCATION); m_hlayout->AddView(_combo_box_area, 1); m_hlayout->AddView(_combo_box_opening_area, 0); m_hlayout->SetHorizontalExternalMargin(0); m_hlayout->SetVerticalExternalMargin(0); SetLayout(m_hlayout); _combo_box_area->mouse_enter.connect(sigc::mem_fun(this, &AbstractComboBox::RecvMouseEnter)); _combo_box_area->mouse_leave.connect(sigc::mem_fun(this, &AbstractComboBox::RecvMouseLeave)); _combo_box_opening_area->mouse_enter.connect(sigc::mem_fun(this, &AbstractComboBox::RecvMouseEnter)); _combo_box_opening_area->mouse_leave.connect(sigc::mem_fun(this, &AbstractComboBox::RecvMouseLeave)); SetTextColor(color::Black); _pango_static_text = new StaticText("", NUX_TRACKER_LOCATION); } AbstractComboBox::~AbstractComboBox() { if (_pango_static_text) _pango_static_text->Dispose(); _pango_static_text = 0; } void AbstractComboBox::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); GetPainter().PaintBackground(graphics_engine, base); GetPainter().PaintShape(graphics_engine, base, m_sCOMBO_COLOR, eSHAPE_CORNER_ROUND4); { //GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), _combo_box_area->GetGeometry(), _combo_box_area->GetBaseString().c_str(), GetTextColor(), eAlignTextLeft); _pango_static_text->SetGeometry(_combo_box_area->GetGeometry()); _pango_static_text->ProcessDraw(graphics_engine, true); } Geometry button_geo = _combo_box_opening_area->GetGeometry(); button_geo.OffsetSize(-5, -2); button_geo.OffsetPosition(+4, +1); if (_combo_box_area->IsMouseInside() || _combo_box_opening_area->IsMouseInside()) GetPainter().PaintShape(graphics_engine, button_geo, m_sCOMBO_MOUSEOVER_COLOR, eSHAPE_CORNER_ROUND4); else GetPainter().PaintShape(graphics_engine, button_geo, m_sCOMBO_BUTTON_COLOR, eSHAPE_CORNER_ROUND4); GeometryPositioning gp(eHACenter, eVACenter); Geometry GeoPo = ComputeGeometryPositioning(button_geo, GetTheme().GetImageGeometry(eCOMBOBOX_OPEN_BUTTON), gp); GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eCOMBOBOX_OPEN_BUTTON); Geometry popup_geometry; popup_geometry.SetX(_combo_box_area->GetBaseX()); popup_geometry.SetY(_combo_box_area->GetBaseY() + _combo_box_area->GetBaseHeight()); popup_geometry.SetWidth(_combo_box_area->GetBaseWidth()); popup_geometry.SetHeight(_combo_box_area->GetBaseHeight()); graphics_engine.PopClippingRectangle(); } void AbstractComboBox::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void AbstractComboBox::RecvMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void AbstractComboBox::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } } nux-4.0.6+14.04.20140409/Nux/TextEntryComposeSeqs.h0000644000015301777760000130463512321344237022024 0ustar pbusernogroup00000000000000/* * Copyright 2010-2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * Jay Taoko * Marco Trevisan * */ #ifndef TEXT_ENTRY_COMPOSE_SEQS_H #define TEXT_ENTRY_COMPOSE_SEQS_H namespace nux { /* This list has been generated using the script ./tools/compose_key_list_generator.py * with this file as input: * http://cgit.freedesktop.org/xorg/lib/libX11/plain/nls/en_US.UTF-8/Compose.pre */ struct ComposeSequence { const static unsigned int MAX_SYMBOLS = 8; KeySym symbols[MAX_SYMBOLS]; const char* result; }; static const size_t COMPOSE_SEQUENCES_SIZE = 4376; static const ComposeSequence COMPOSE_SEQUENCES[] = { {{XK_dead_hook, XK_B, XK_VoidSymbol}, "Ɓ"}, // U0181 | LATIN CAPITAL LETTER B WITH HOOK {{XK_Multi_key, XK_f, XK_l, XK_VoidSymbol}, "fl"}, // Ufb02 | LATIN SMALL LIGATURE FL {{XK_dead_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, // U1F85 | GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾅ"}, {{XK_dead_belowdot, XK_B, XK_VoidSymbol}, "Ḅ"}, // U1E04 | LATIN CAPITAL LETTER B WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_B, XK_VoidSymbol}, "Ḅ"}, {{XK_dead_acute, XK_C, XK_VoidSymbol}, "Ć"}, // U0106 | LATIN CAPITAL LETTER C WITH ACUTE {{XK_Multi_key, XK_acute, XK_C, XK_VoidSymbol}, "Ć"}, {{XK_Multi_key, XK_apostrophe, XK_C, XK_VoidSymbol}, "Ć"}, {{XK_Multi_key, XK_C, XK_apostrophe, XK_VoidSymbol}, "Ć"}, {{XK_dead_caron, XK_minus, XK_VoidSymbol}, "₋"}, // U208B | SUBSCRIPT MINUS {{XK_dead_grave, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἂ"}, // U1F0A | GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἂ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἂ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἂ"}, {{XK_dead_abovedot, XK_y, XK_VoidSymbol}, "ẏ"}, // U1E8F | LATIN SMALL LETTER Y WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_y, XK_VoidSymbol}, "ẏ"}, {{XK_Multi_key, XK_C, XK_equal, XK_VoidSymbol}, "€"}, // EuroSign | EURO SIGN {{XK_Multi_key, XK_equal, XK_C, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_c, XK_equal, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_equal, XK_c, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_E, XK_equal, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_equal, XK_E, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_e, XK_equal, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_equal, XK_e, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_Cyrillic_ES, XK_equal, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_equal, XK_Cyrillic_ES, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_Cyrillic_IE, XK_equal, XK_VoidSymbol}, "€"}, {{XK_Multi_key, XK_equal, XK_Cyrillic_IE, XK_VoidSymbol}, "€"}, {{XK_dead_currency, XK_e, XK_VoidSymbol}, "€"}, {{XK_dead_hook, XK_F, XK_VoidSymbol}, "Ƒ"}, // U0191 | LATIN CAPITAL LETTER F WITH HOOK {{XK_dead_voiced_sound, XK_kana_HE, XK_VoidSymbol}, "ベ"}, // U30D9 | KATAKANA LETTER BE {{XK_Multi_key, XK_slash, XK_Cyrillic_ghe, XK_VoidSymbol}, "ғ"}, // U0493 | CYRILLIC SMALL LETTER GHE WITH STROKE {{XK_Multi_key, XK_KP_Divide, XK_Cyrillic_ghe, XK_VoidSymbol}, "ғ"}, {{XK_Multi_key, XK_parenleft, XK_L, XK_parenright, XK_VoidSymbol}, "Ⓛ"}, // U24C1 | CIRCLED LATIN CAPITAL LETTER L {{XK_dead_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, // U1F95 | GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾕ"}, {{XK_dead_grave, XK_Emacron, XK_VoidSymbol}, "Ḕ"}, // U1E14 | LATIN CAPITAL LETTER E WITH MACRON AND GRAVE {{XK_Multi_key, XK_grave, XK_Emacron, XK_VoidSymbol}, "Ḕ"}, {{XK_dead_grave, XK_dead_macron, XK_E, XK_VoidSymbol}, "Ḕ"}, {{XK_dead_grave, XK_Multi_key, XK_macron, XK_E, XK_VoidSymbol}, "Ḕ"}, {{XK_dead_grave, XK_Multi_key, XK_underscore, XK_E, XK_VoidSymbol}, "Ḕ"}, {{XK_Multi_key, XK_grave, XK_dead_macron, XK_E, XK_VoidSymbol}, "Ḕ"}, {{XK_Multi_key, XK_grave, XK_macron, XK_E, XK_VoidSymbol}, "Ḕ"}, {{XK_Multi_key, XK_grave, XK_underscore, XK_E, XK_VoidSymbol}, "Ḕ"}, {{XK_dead_macron, XK_Egrave, XK_VoidSymbol}, "Ḕ"}, {{XK_dead_macron, XK_dead_grave, XK_E, XK_VoidSymbol}, "Ḕ"}, {{XK_Multi_key, XK_N, XK_o, XK_VoidSymbol}, "№"}, // numerosign | NUMERO SIGN {{XK_Multi_key, XK_N, XK_O, XK_VoidSymbol}, "№"}, {{XK_Multi_key, XK_Cyrillic_EN, XK_Cyrillic_o, XK_VoidSymbol}, "№"}, {{XK_Multi_key, XK_Cyrillic_EN, XK_Cyrillic_O, XK_VoidSymbol}, "№"}, {{XK_dead_acute, XK_nobreakspace, XK_VoidSymbol}, "́"}, // U0301 | COMBINING ACUTE ACCENT {{XK_dead_grave, XK_dead_psili, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἒ"}, // U1F1A | GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἒ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἒ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἒ"}, {{XK_dead_macron, XK_Cyrillic_O, XK_VoidSymbol}, "О̄"}, // CYRILLIC CAPITAL LETTER O WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_O, XK_VoidSymbol}, "О̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_O, XK_VoidSymbol}, "О̄"}, {{XK_dead_horn, XK_o, XK_VoidSymbol}, "ơ"}, // U01A1 | LATIN SMALL LETTER O WITH HORN {{XK_Multi_key, XK_plus, XK_o, XK_VoidSymbol}, "ơ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_0, XK_parenright, XK_VoidSymbol}, "㉚"}, // U325A | CIRCLED NUMBER THIRTY {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_0, XK_parenright, XK_VoidSymbol}, "㉚"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_0, XK_parenright, XK_VoidSymbol}, "㉚"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_0, XK_parenright, XK_VoidSymbol}, "㉚"}, {{XK_dead_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, // U1FA5 | GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾥ"}, {{XK_dead_belowdot, XK_H, XK_VoidSymbol}, "Ḥ"}, // U1E24 | LATIN CAPITAL LETTER H WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_H, XK_VoidSymbol}, "Ḥ"}, {{XK_dead_stroke, XK_H, XK_VoidSymbol}, "Ħ"}, // U0126 | LATIN CAPITAL LETTER H WITH STROKE {{XK_Multi_key, XK_slash, XK_H, XK_VoidSymbol}, "Ħ"}, {{XK_Multi_key, XK_KP_Divide, XK_H, XK_VoidSymbol}, "Ħ"}, {{XK_Multi_key, XK_parenleft, XK_kana_SE, XK_parenright, XK_VoidSymbol}, "㋝"}, // U32DD | CIRCLED KATAKANA SE {{XK_Multi_key, XK_d, XK_equal, XK_VoidSymbol}, "₫"}, // U20ab | DONG SIGN {{XK_Multi_key, XK_equal, XK_d, XK_VoidSymbol}, "₫"}, {{XK_dead_currency, XK_d, XK_VoidSymbol}, "₫"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἢ"}, // U1F2A | GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἢ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἢ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἢ"}, {{XK_dead_acute, XK_Greek_epsilon, XK_VoidSymbol}, "έ"}, // U03AD | GREEK SMALL LETTER EPSILON WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_epsilon, XK_VoidSymbol}, "έ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_epsilon, XK_VoidSymbol}, "έ"}, {{XK_Multi_key, XK_Greek_epsilon, XK_apostrophe, XK_VoidSymbol}, "έ"}, {{XK_dead_macron, XK_Otilde, XK_VoidSymbol}, "Ȭ"}, // U022C | LATIN CAPITAL LETTER O WITH TILDE AND MACRON {{XK_Multi_key, XK_macron, XK_Otilde, XK_VoidSymbol}, "Ȭ"}, {{XK_Multi_key, XK_underscore, XK_Otilde, XK_VoidSymbol}, "Ȭ"}, {{XK_dead_macron, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ȭ"}, {{XK_dead_macron, XK_Multi_key, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ȭ"}, {{XK_Multi_key, XK_macron, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ȭ"}, {{XK_Multi_key, XK_macron, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ȭ"}, {{XK_Multi_key, XK_underscore, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ȭ"}, {{XK_Multi_key, XK_underscore, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ȭ"}, {{XK_dead_tilde, XK_Omacron, XK_VoidSymbol}, "Ȭ"}, {{XK_dead_tilde, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ȭ"}, {{XK_dead_acute, XK_abreve, XK_VoidSymbol}, "ắ"}, // U1EAF | LATIN SMALL LETTER A WITH BREVE AND ACUTE {{XK_Multi_key, XK_acute, XK_abreve, XK_VoidSymbol}, "ắ"}, {{XK_Multi_key, XK_apostrophe, XK_abreve, XK_VoidSymbol}, "ắ"}, {{XK_dead_acute, XK_dead_breve, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_dead_acute, XK_Multi_key, XK_U, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_dead_acute, XK_Multi_key, XK_b, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_Multi_key, XK_acute, XK_dead_breve, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_Multi_key, XK_acute, XK_b, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_breve, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_Multi_key, XK_apostrophe, XK_b, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_dead_breve, XK_aacute, XK_VoidSymbol}, "ắ"}, {{XK_dead_breve, XK_dead_acute, XK_a, XK_VoidSymbol}, "ắ"}, {{XK_dead_stroke, XK_U, XK_VoidSymbol}, "Ʉ"}, // U0244 | LATIN CAPITAL LETTER U BAR {{XK_Multi_key, XK_percent, XK_o, XK_VoidSymbol}, "‰"}, // U2030 | PER MILLE SIGN {{XK_dead_belowmacron, XK_K, XK_VoidSymbol}, "Ḵ"}, // U1E34 | LATIN CAPITAL LETTER K WITH LINE BELOW {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_w, XK_VoidSymbol}, "ʷ"}, // U02B7 | MODIFIER LETTER SMALL W {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_w, XK_VoidSymbol}, "ʷ"}, {{XK_dead_cedilla, XK_K, XK_VoidSymbol}, "Ķ"}, // U0136 | LATIN CAPITAL LETTER K WITH CEDILLA {{XK_Multi_key, XK_comma, XK_K, XK_VoidSymbol}, "Ķ"}, {{XK_Multi_key, XK_K, XK_comma, XK_VoidSymbol}, "Ķ"}, {{XK_Multi_key, XK_cedilla, XK_K, XK_VoidSymbol}, "Ķ"}, {{XK_dead_acute, XK_Cyrillic_u, XK_VoidSymbol}, "у́"}, // CYRILLIC SMALL LETTER U WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_u, XK_VoidSymbol}, "у́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_u, XK_VoidSymbol}, "у́"}, {{XK_Multi_key, XK_greater, XK_greater, XK_VoidSymbol}, "»"}, // guillemotright | RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK {{XK_dead_grave, XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἲ"}, // U1F3A | GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἲ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἲ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἲ"}, {{XK_dead_stroke, XK_c, XK_VoidSymbol}, "ȼ"}, // U023C | LATIN SMALL LETTER C WITH STROKE {{XK_dead_acute, XK_ecircumflex, XK_VoidSymbol}, "ế"}, // U1EBF | LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE {{XK_Multi_key, XK_acute, XK_ecircumflex, XK_VoidSymbol}, "ế"}, {{XK_Multi_key, XK_apostrophe, XK_ecircumflex, XK_VoidSymbol}, "ế"}, {{XK_dead_acute, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ế"}, {{XK_dead_acute, XK_Multi_key, XK_asciicircum, XK_e, XK_VoidSymbol}, "ế"}, {{XK_Multi_key, XK_acute, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ế"}, {{XK_Multi_key, XK_acute, XK_asciicircum, XK_e, XK_VoidSymbol}, "ế"}, {{XK_Multi_key, XK_apostrophe, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ế"}, {{XK_Multi_key, XK_apostrophe, XK_asciicircum, XK_e, XK_VoidSymbol}, "ế"}, {{XK_dead_circumflex, XK_eacute, XK_VoidSymbol}, "ế"}, {{XK_dead_circumflex, XK_dead_acute, XK_e, XK_VoidSymbol}, "ế"}, {{XK_dead_voiced_sound, XK_kana_KO, XK_VoidSymbol}, "ゴ"}, // U30B4 | KATAKANA LETTER GO {{XK_Multi_key, XK_A, XK_T, XK_VoidSymbol}, "@"}, // at | COMMERCIAL AT {{XK_Multi_key, XK_parenleft, XK_N, XK_parenright, XK_VoidSymbol}, "Ⓝ"}, // U24C3 | CIRCLED LATIN CAPITAL LETTER N {{XK_dead_abovedot, XK_N, XK_VoidSymbol}, "Ṅ"}, // U1E44 | LATIN CAPITAL LETTER N WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_N, XK_VoidSymbol}, "Ṅ"}, {{XK_dead_caron, XK_space, XK_VoidSymbol}, "ˇ"}, // caron | CARON {{XK_dead_caron, XK_dead_caron, XK_VoidSymbol}, "ˇ"}, {{XK_Multi_key, XK_space, XK_less, XK_VoidSymbol}, "ˇ"}, {{XK_Multi_key, XK_less, XK_space, XK_VoidSymbol}, "ˇ"}, {{XK_dead_cedilla, XK_n, XK_VoidSymbol}, "ņ"}, // U0146 | LATIN SMALL LETTER N WITH CEDILLA {{XK_Multi_key, XK_comma, XK_n, XK_VoidSymbol}, "ņ"}, {{XK_Multi_key, XK_n, XK_comma, XK_VoidSymbol}, "ņ"}, {{XK_Multi_key, XK_cedilla, XK_n, XK_VoidSymbol}, "ņ"}, {{XK_dead_diaeresis, XK_E, XK_VoidSymbol}, "Ë"}, // Ediaeresis | LATIN CAPITAL LETTER E WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_E, XK_VoidSymbol}, "Ë"}, {{XK_Multi_key, XK_E, XK_quotedbl, XK_VoidSymbol}, "Ë"}, {{XK_Multi_key, XK_E, XK_diaeresis, XK_VoidSymbol}, "Ë"}, {{XK_Multi_key, XK_diaeresis, XK_E, XK_VoidSymbol}, "Ë"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὂ"}, // U1F4A | GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὂ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὂ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὂ"}, {{XK_dead_acute, XK_Greek_upsilon, XK_VoidSymbol}, "ύ"}, // U03CD | GREEK SMALL LETTER UPSILON WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_upsilon, XK_VoidSymbol}, "ύ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_upsilon, XK_VoidSymbol}, "ύ"}, {{XK_Multi_key, XK_Greek_upsilon, XK_apostrophe, XK_VoidSymbol}, "ύ"}, {{XK_dead_grave, XK_nobreakspace, XK_VoidSymbol}, "̀"}, // U0300 | COMBINING GRAVE ACCENT {{XK_dead_hook, XK_o, XK_VoidSymbol}, "ỏ"}, // U1ECF | LATIN SMALL LETTER O WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_o, XK_VoidSymbol}, "ỏ"}, {{XK_dead_caron, XK_O, XK_VoidSymbol}, "Ǒ"}, // U01D1 | LATIN CAPITAL LETTER O WITH CARON {{XK_Multi_key, XK_c, XK_O, XK_VoidSymbol}, "Ǒ"}, {{XK_dead_diaeresis, XK_Cyrillic_a, XK_VoidSymbol}, "ӓ"}, // U04D3 | CYRILLIC SMALL LETTER A WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_a, XK_VoidSymbol}, "ӓ"}, {{XK_dead_acute, XK_P, XK_VoidSymbol}, "Ṕ"}, // U1E54 | LATIN CAPITAL LETTER P WITH ACUTE {{XK_Multi_key, XK_acute, XK_P, XK_VoidSymbol}, "Ṕ"}, {{XK_Multi_key, XK_apostrophe, XK_P, XK_VoidSymbol}, "Ṕ"}, {{XK_Multi_key, XK_parenleft, XK_kana_KU, XK_parenright, XK_VoidSymbol}, "㋗"}, // U32D7 | CIRCLED KATAKANA KU {{XK_dead_cedilla, XK_R, XK_VoidSymbol}, "Ŗ"}, // U0156 | LATIN CAPITAL LETTER R WITH CEDILLA {{XK_Multi_key, XK_comma, XK_R, XK_VoidSymbol}, "Ŗ"}, {{XK_Multi_key, XK_R, XK_comma, XK_VoidSymbol}, "Ŗ"}, {{XK_Multi_key, XK_cedilla, XK_R, XK_VoidSymbol}, "Ŗ"}, {{XK_dead_circumflex, XK_U, XK_VoidSymbol}, "Û"}, // Ucircumflex | LATIN CAPITAL LETTER U WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_U, XK_VoidSymbol}, "Û"}, {{XK_Multi_key, XK_U, XK_asciicircum, XK_VoidSymbol}, "Û"}, {{XK_Multi_key, XK_greater, XK_U, XK_VoidSymbol}, "Û"}, {{XK_Multi_key, XK_U, XK_greater, XK_VoidSymbol}, "Û"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_2, XK_parenright, XK_VoidSymbol}, "㉜"}, // U325C | CIRCLED NUMBER THIRTY TWO {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "㉜"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_2, XK_parenright, XK_VoidSymbol}, "㉜"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_2, XK_parenright, XK_VoidSymbol}, "㉜"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "㉜"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_2, XK_parenright, XK_VoidSymbol}, "㉜"}, {{XK_dead_hook, XK_ohorn, XK_VoidSymbol}, "ở"}, // U1EDF | LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_ohorn, XK_VoidSymbol}, "ở"}, {{XK_dead_hook, XK_dead_horn, XK_o, XK_VoidSymbol}, "ở"}, {{XK_dead_hook, XK_Multi_key, XK_plus, XK_o, XK_VoidSymbol}, "ở"}, {{XK_Multi_key, XK_question, XK_dead_horn, XK_o, XK_VoidSymbol}, "ở"}, {{XK_Multi_key, XK_question, XK_plus, XK_o, XK_VoidSymbol}, "ở"}, {{XK_dead_horn, XK_ohook, XK_VoidSymbol}, "ở"}, {{XK_dead_horn, XK_dead_hook, XK_o, XK_VoidSymbol}, "ở"}, {{XK_dead_macron, XK_dead_abovedot, XK_a, XK_VoidSymbol}, "ǡ"}, // U01E1 | LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON {{XK_dead_macron, XK_Multi_key, XK_period, XK_a, XK_VoidSymbol}, "ǡ"}, {{XK_Multi_key, XK_macron, XK_dead_abovedot, XK_a, XK_VoidSymbol}, "ǡ"}, {{XK_Multi_key, XK_macron, XK_period, XK_a, XK_VoidSymbol}, "ǡ"}, {{XK_Multi_key, XK_underscore, XK_dead_abovedot, XK_a, XK_VoidSymbol}, "ǡ"}, {{XK_Multi_key, XK_underscore, XK_period, XK_a, XK_VoidSymbol}, "ǡ"}, {{XK_dead_abovedot, XK_amacron, XK_VoidSymbol}, "ǡ"}, {{XK_dead_abovedot, XK_dead_macron, XK_a, XK_VoidSymbol}, "ǡ"}, {{XK_dead_grave, XK_space, XK_VoidSymbol}, "`"}, // grave | GRAVE ACCENT {{XK_dead_grave, XK_dead_grave, XK_VoidSymbol}, "`"}, {{XK_Multi_key, XK_grave, XK_space, XK_VoidSymbol}, "`"}, {{XK_Multi_key, XK_space, XK_grave, XK_VoidSymbol}, "`"}, {{XK_dead_macron, XK_Cyrillic_i, XK_VoidSymbol}, "ӣ"}, // U04E3 | CYRILLIC SMALL LETTER I WITH MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_i, XK_VoidSymbol}, "ӣ"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_i, XK_VoidSymbol}, "ӣ"}, {{XK_dead_dasia, XK_Greek_rho, XK_VoidSymbol}, "ῥ"}, // U1FE5 | GREEK SMALL LETTER RHO WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_rho, XK_VoidSymbol}, "ῥ"}, {{XK_dead_abovedot, XK_Sacute, XK_VoidSymbol}, "Ṥ"}, // U1E64 | LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE {{XK_Multi_key, XK_period, XK_Sacute, XK_VoidSymbol}, "Ṥ"}, {{XK_dead_abovedot, XK_dead_acute, XK_S, XK_VoidSymbol}, "Ṥ"}, {{XK_dead_abovedot, XK_Multi_key, XK_acute, XK_S, XK_VoidSymbol}, "Ṥ"}, {{XK_dead_abovedot, XK_Multi_key, XK_apostrophe, XK_S, XK_VoidSymbol}, "Ṥ"}, {{XK_Multi_key, XK_period, XK_dead_acute, XK_S, XK_VoidSymbol}, "Ṥ"}, {{XK_Multi_key, XK_period, XK_acute, XK_S, XK_VoidSymbol}, "Ṥ"}, {{XK_Multi_key, XK_period, XK_apostrophe, XK_S, XK_VoidSymbol}, "Ṥ"}, {{XK_dead_acute, XK_Sabovedot, XK_VoidSymbol}, "Ṥ"}, {{XK_dead_acute, XK_dead_abovedot, XK_S, XK_VoidSymbol}, "Ṥ"}, {{XK_Multi_key, XK_parenleft, XK_kana_NE, XK_parenright, XK_VoidSymbol}, "㋧"}, // U32E7 | CIRCLED KATAKANA NE {{XK_dead_stroke, XK_T, XK_VoidSymbol}, "Ŧ"}, // U0166 | LATIN CAPITAL LETTER T WITH STROKE {{XK_Multi_key, XK_slash, XK_T, XK_VoidSymbol}, "Ŧ"}, {{XK_Multi_key, XK_KP_Divide, XK_T, XK_VoidSymbol}, "Ŧ"}, {{XK_Multi_key, XK_T, XK_slash, XK_VoidSymbol}, "Ŧ"}, {{XK_Multi_key, XK_T, XK_minus, XK_VoidSymbol}, "Ŧ"}, {{XK_Multi_key, XK_parenleft, XK_9, XK_parenright, XK_VoidSymbol}, "⑨"}, // U2468 | CIRCLED DIGIT NINE {{XK_Multi_key, XK_parenleft, XK_KP_9, XK_parenright, XK_VoidSymbol}, "⑨"}, {{XK_dead_diaeresis, XK_e, XK_VoidSymbol}, "ë"}, // ediaeresis | LATIN SMALL LETTER E WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_e, XK_VoidSymbol}, "ë"}, {{XK_Multi_key, XK_e, XK_quotedbl, XK_VoidSymbol}, "ë"}, {{XK_Multi_key, XK_diaeresis, XK_e, XK_VoidSymbol}, "ë"}, {{XK_Multi_key, XK_e, XK_diaeresis, XK_VoidSymbol}, "ë"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὢ"}, // U1F6A | GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὢ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὢ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὢ"}, {{XK_dead_tilde, XK_uhorn, XK_VoidSymbol}, "ữ"}, // U1EEF | LATIN SMALL LETTER U WITH HORN AND TILDE {{XK_Multi_key, XK_asciitilde, XK_uhorn, XK_VoidSymbol}, "ữ"}, {{XK_dead_tilde, XK_dead_horn, XK_u, XK_VoidSymbol}, "ữ"}, {{XK_dead_tilde, XK_Multi_key, XK_plus, XK_u, XK_VoidSymbol}, "ữ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_horn, XK_u, XK_VoidSymbol}, "ữ"}, {{XK_Multi_key, XK_asciitilde, XK_plus, XK_u, XK_VoidSymbol}, "ữ"}, {{XK_dead_horn, XK_utilde, XK_VoidSymbol}, "ữ"}, {{XK_dead_horn, XK_dead_tilde, XK_u, XK_VoidSymbol}, "ữ"}, {{XK_dead_voiced_sound, XK_kana_SE, XK_VoidSymbol}, "ゼ"}, // U30BC | KATAKANA LETTER ZE {{XK_dead_circumflex, XK_0, XK_VoidSymbol}, "⁰"}, // U2070 | SUPERSCRIPT ZERO {{XK_Multi_key, XK_asciicircum, XK_0, XK_VoidSymbol}, "⁰"}, {{XK_dead_circumflex, XK_KP_0, XK_VoidSymbol}, "⁰"}, {{XK_Multi_key, XK_asciicircum, XK_KP_0, XK_VoidSymbol}, "⁰"}, {{XK_dead_doubleacute, XK_Cyrillic_u, XK_VoidSymbol}, "ӳ"}, // U04F3 | CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE {{XK_Multi_key, XK_equal, XK_Cyrillic_u, XK_VoidSymbol}, "ӳ"}, {{XK_Multi_key, XK_parenleft, XK_kana_NA, XK_parenright, XK_VoidSymbol}, "㋤"}, // U32E4 | CIRCLED KATAKANA NA {{XK_dead_belowtilde, XK_U, XK_VoidSymbol}, "Ṵ"}, // U1E74 | LATIN CAPITAL LETTER U WITH TILDE BELOW {{XK_Multi_key, XK_parenleft, XK_kana_RI, XK_parenright, XK_VoidSymbol}, "㋷"}, // U32F7 | CIRCLED KATAKANA RI {{XK_dead_circumflex, XK_Y, XK_VoidSymbol}, "Ŷ"}, // U0176 | LATIN CAPITAL LETTER Y WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_Y, XK_VoidSymbol}, "Ŷ"}, {{XK_Multi_key, XK_Y, XK_asciicircum, XK_VoidSymbol}, "Ŷ"}, {{XK_dead_circumflex, XK_u, XK_VoidSymbol}, "û"}, // ucircumflex | LATIN SMALL LETTER U WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_u, XK_VoidSymbol}, "û"}, {{XK_Multi_key, XK_u, XK_asciicircum, XK_VoidSymbol}, "û"}, {{XK_Multi_key, XK_greater, XK_u, XK_VoidSymbol}, "û"}, {{XK_Multi_key, XK_u, XK_greater, XK_VoidSymbol}, "û"}, {{XK_dead_grave, XK_Greek_upsilon, XK_VoidSymbol}, "ὺ"}, // U1F7A | GREEK SMALL LETTER UPSILON WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_upsilon, XK_VoidSymbol}, "ὺ"}, {{XK_dead_hook, XK_r, XK_VoidSymbol}, "ɼ"}, // U027C | LATIN SMALL LETTER R WITH LONG LEG {{XK_dead_currency, XK_U, XK_VoidSymbol}, "圓"}, // U5713 | YUAN / WEN {{XK_dead_macron, XK_a, XK_VoidSymbol}, "ā"}, // U0101 | LATIN SMALL LETTER A WITH MACRON {{XK_Multi_key, XK_macron, XK_a, XK_VoidSymbol}, "ā"}, {{XK_Multi_key, XK_underscore, XK_a, XK_VoidSymbol}, "ā"}, {{XK_Multi_key, XK_a, XK_underscore, XK_VoidSymbol}, "ā"}, {{XK_Multi_key, XK_minus, XK_a, XK_VoidSymbol}, "ā"}, {{XK_Multi_key, XK_a, XK_minus, XK_VoidSymbol}, "ā"}, {{XK_Multi_key, XK_underscore, XK_0, XK_VoidSymbol}, "₀"}, // U2080 | SUBSCRIPT ZERO {{XK_Multi_key, XK_underscore, XK_KP_0, XK_VoidSymbol}, "₀"}, {{XK_dead_caron, XK_0, XK_VoidSymbol}, "₀"}, {{XK_dead_acute, XK_Cyrillic_GHE, XK_VoidSymbol}, "Ѓ"}, // U0403 | CYRILLIC CAPITAL LETTER GJE {{XK_Multi_key, XK_acute, XK_Cyrillic_GHE, XK_VoidSymbol}, "Ѓ"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_GHE, XK_VoidSymbol}, "Ѓ"}, {{XK_dead_abovedot, XK_T, XK_VoidSymbol}, "Ṫ"}, // U1E6A | LATIN CAPITAL LETTER T WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_T, XK_VoidSymbol}, "Ṫ"}, {{XK_Multi_key, XK_T, XK_period, XK_VoidSymbol}, "Ṫ"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἅ"}, // U1F05 | GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἅ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἅ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἅ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἅ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἅ"}, {{XK_dead_diaeresis, XK_W, XK_VoidSymbol}, "Ẅ"}, // U1E84 | LATIN CAPITAL LETTER W WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_W, XK_VoidSymbol}, "Ẅ"}, {{XK_dead_grave, XK_Ecircumflex, XK_VoidSymbol}, "Ề"}, // U1EC0 | LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE {{XK_Multi_key, XK_grave, XK_Ecircumflex, XK_VoidSymbol}, "Ề"}, {{XK_dead_grave, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ề"}, {{XK_dead_grave, XK_Multi_key, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ề"}, {{XK_Multi_key, XK_grave, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ề"}, {{XK_Multi_key, XK_grave, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ề"}, {{XK_dead_circumflex, XK_Egrave, XK_VoidSymbol}, "Ề"}, {{XK_dead_circumflex, XK_dead_grave, XK_E, XK_VoidSymbol}, "Ề"}, {{XK_dead_abovedot, XK_E, XK_VoidSymbol}, "Ė"}, // U0116 | LATIN CAPITAL LETTER E WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_E, XK_VoidSymbol}, "Ė"}, {{XK_Multi_key, XK_E, XK_period, XK_VoidSymbol}, "Ė"}, {{XK_dead_tilde, XK_equal, XK_VoidSymbol}, "≃"}, // similarequal | ASYMPTOTICALLY EQUAL TO {{XK_dead_belowmacron, XK_d, XK_VoidSymbol}, "ḏ"}, // U1E0F | LATIN SMALL LETTER D WITH LINE BELOW {{XK_Multi_key, XK_minus, XK_d, XK_VoidSymbol}, "đ"}, // dstroke | LATIN SMALL LETTER D WITH STROKE {{XK_dead_stroke, XK_d, XK_VoidSymbol}, "đ"}, {{XK_Multi_key, XK_slash, XK_d, XK_VoidSymbol}, "đ"}, {{XK_Multi_key, XK_d, XK_minus, XK_VoidSymbol}, "đ"}, {{XK_Multi_key, XK_KP_Divide, XK_d, XK_VoidSymbol}, "đ"}, {{XK_dead_voiced_sound, XK_kana_WA, XK_VoidSymbol}, "ヷ"}, // U30F7 | KATAKANA LETTER VA {{XK_dead_acute, XK_dead_dasia, XK_Greek_epsilon, XK_VoidSymbol}, "ἕ"}, // U1F15 | GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_epsilon, XK_VoidSymbol}, "ἕ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_epsilon, XK_VoidSymbol}, "ἕ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_epsilon, XK_VoidSymbol}, "ἕ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_epsilon, XK_VoidSymbol}, "ἕ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_epsilon, XK_VoidSymbol}, "ἕ"}, {{XK_dead_belowmacron, XK_Z, XK_VoidSymbol}, "Ẕ"}, // U1E94 | LATIN CAPITAL LETTER Z WITH LINE BELOW {{XK_dead_iota, XK_dead_grave, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, // U1F9A | GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾚ"}, {{XK_dead_abovedot, XK_f, XK_VoidSymbol}, "ḟ"}, // U1E1F | LATIN SMALL LETTER F WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_f, XK_VoidSymbol}, "ḟ"}, {{XK_Multi_key, XK_f, XK_period, XK_VoidSymbol}, "ḟ"}, {{XK_dead_abovedot, XK_g, XK_VoidSymbol}, "ġ"}, // U0121 | LATIN SMALL LETTER G WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_g, XK_VoidSymbol}, "ġ"}, {{XK_Multi_key, XK_g, XK_period, XK_VoidSymbol}, "ġ"}, {{XK_Multi_key, XK_space, XK_space, XK_VoidSymbol}, " "}, // nobreakspace | NO-BREAK SPACE {{XK_dead_acute, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἥ"}, // U1F25 | GREEK SMALL LETTER ETA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἥ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἥ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἥ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἥ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἥ"}, {{XK_dead_acute, XK_Acircumflex, XK_VoidSymbol}, "Ấ"}, // U1EA4 | LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE {{XK_Multi_key, XK_acute, XK_Acircumflex, XK_VoidSymbol}, "Ấ"}, {{XK_Multi_key, XK_apostrophe, XK_Acircumflex, XK_VoidSymbol}, "Ấ"}, {{XK_dead_acute, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ấ"}, {{XK_dead_acute, XK_Multi_key, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ấ"}, {{XK_Multi_key, XK_acute, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ấ"}, {{XK_Multi_key, XK_acute, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ấ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ấ"}, {{XK_Multi_key, XK_apostrophe, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ấ"}, {{XK_dead_circumflex, XK_Aacute, XK_VoidSymbol}, "Ấ"}, {{XK_dead_circumflex, XK_dead_acute, XK_A, XK_VoidSymbol}, "Ấ"}, {{XK_dead_abovedot, XK_a, XK_VoidSymbol}, "ȧ"}, // U0227 | LATIN SMALL LETTER A WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_a, XK_VoidSymbol}, "ȧ"}, {{XK_dead_iota, XK_dead_grave, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, // U1FAA | GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾪ"}, {{XK_dead_acute, XK_idiaeresis, XK_VoidSymbol}, "ḯ"}, // U1E2F | LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE {{XK_Multi_key, XK_acute, XK_idiaeresis, XK_VoidSymbol}, "ḯ"}, {{XK_Multi_key, XK_apostrophe, XK_idiaeresis, XK_VoidSymbol}, "ḯ"}, {{XK_dead_acute, XK_dead_diaeresis, XK_i, XK_VoidSymbol}, "ḯ"}, {{XK_dead_acute, XK_Multi_key, XK_quotedbl, XK_i, XK_VoidSymbol}, "ḯ"}, {{XK_Multi_key, XK_acute, XK_dead_diaeresis, XK_i, XK_VoidSymbol}, "ḯ"}, {{XK_Multi_key, XK_acute, XK_quotedbl, XK_i, XK_VoidSymbol}, "ḯ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_diaeresis, XK_i, XK_VoidSymbol}, "ḯ"}, {{XK_Multi_key, XK_apostrophe, XK_quotedbl, XK_i, XK_VoidSymbol}, "ḯ"}, {{XK_dead_diaeresis, XK_iacute, XK_VoidSymbol}, "ḯ"}, {{XK_dead_diaeresis, XK_dead_acute, XK_i, XK_VoidSymbol}, "ḯ"}, {{XK_dead_abovedot, XK_i, XK_VoidSymbol}, "ı"}, // U0131 | LATIN SMALL LETTER DOTLESS I {{XK_Multi_key, XK_i, XK_period, XK_VoidSymbol}, "ı"}, {{XK_Multi_key, XK_period, XK_i, XK_VoidSymbol}, "ı"}, {{XK_dead_abovering, XK_space, XK_VoidSymbol}, "°"}, // degree | DEGREE SIGN {{XK_dead_abovering, XK_dead_abovering, XK_VoidSymbol}, "°"}, {{XK_Multi_key, XK_o, XK_o, XK_VoidSymbol}, "°"}, {{XK_Multi_key, XK_asterisk, XK_0, XK_VoidSymbol}, "°"}, {{XK_Multi_key, XK_0, XK_asterisk, XK_VoidSymbol}, "°"}, {{XK_dead_acute, XK_Cyrillic_ie, XK_VoidSymbol}, "е́"}, // CYRILLIC SMALL LETTER IE WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_ie, XK_VoidSymbol}, "е́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_ie, XK_VoidSymbol}, "е́"}, {{XK_dead_tilde, XK_less, XK_VoidSymbol}, "≲"}, // U2272 | LESS-THAN OR EQUIVALENT TO {{XK_dead_acute, XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἵ"}, // U1F35 | GREEK SMALL LETTER IOTA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἵ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἵ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἵ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἵ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἵ"}, {{XK_dead_tilde, XK_Abreve, XK_VoidSymbol}, "Ẵ"}, // U1EB4 | LATIN CAPITAL LETTER A WITH BREVE AND TILDE {{XK_Multi_key, XK_asciitilde, XK_Abreve, XK_VoidSymbol}, "Ẵ"}, {{XK_dead_tilde, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ẵ"}, {{XK_dead_tilde, XK_Multi_key, XK_U, XK_A, XK_VoidSymbol}, "Ẵ"}, {{XK_dead_tilde, XK_Multi_key, XK_b, XK_A, XK_VoidSymbol}, "Ẵ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ẵ"}, {{XK_Multi_key, XK_asciitilde, XK_b, XK_A, XK_VoidSymbol}, "Ẵ"}, {{XK_dead_breve, XK_Atilde, XK_VoidSymbol}, "Ẵ"}, {{XK_dead_breve, XK_dead_tilde, XK_A, XK_VoidSymbol}, "Ẵ"}, {{XK_dead_grave, XK_Omacron, XK_VoidSymbol}, "Ṑ"}, // U1E50 | LATIN CAPITAL LETTER O WITH MACRON AND GRAVE {{XK_Multi_key, XK_grave, XK_Omacron, XK_VoidSymbol}, "Ṑ"}, {{XK_dead_grave, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ṑ"}, {{XK_dead_grave, XK_Multi_key, XK_macron, XK_O, XK_VoidSymbol}, "Ṑ"}, {{XK_dead_grave, XK_Multi_key, XK_underscore, XK_O, XK_VoidSymbol}, "Ṑ"}, {{XK_Multi_key, XK_grave, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ṑ"}, {{XK_Multi_key, XK_grave, XK_macron, XK_O, XK_VoidSymbol}, "Ṑ"}, {{XK_Multi_key, XK_grave, XK_underscore, XK_O, XK_VoidSymbol}, "Ṑ"}, {{XK_dead_macron, XK_Ograve, XK_VoidSymbol}, "Ṑ"}, {{XK_dead_macron, XK_dead_grave, XK_O, XK_VoidSymbol}, "Ṑ"}, {{XK_dead_stroke, XK_z, XK_VoidSymbol}, "ƶ"}, // U01B6 | LATIN SMALL LETTER Z WITH STROKE {{XK_Multi_key, XK_slash, XK_z, XK_VoidSymbol}, "ƶ"}, {{XK_Multi_key, XK_KP_Divide, XK_z, XK_VoidSymbol}, "ƶ"}, {{XK_Multi_key, XK_parenleft, XK_C, XK_parenright, XK_VoidSymbol}, "Ⓒ"}, // U24B8 | CIRCLED LATIN CAPITAL LETTER C {{XK_dead_grave, XK_Greek_ALPHA, XK_VoidSymbol}, "Ὰ"}, // U1FBA | GREEK CAPITAL LETTER ALPHA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_ALPHA, XK_VoidSymbol}, "Ὰ"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_7, XK_parenright, XK_VoidSymbol}, "㊼"}, // U32BC | CIRCLED NUMBER FORTY SEVEN {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_7, XK_parenright, XK_VoidSymbol}, "㊼"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_7, XK_parenright, XK_VoidSymbol}, "㊼"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_7, XK_parenright, XK_VoidSymbol}, "㊼"}, {{XK_dead_acute, XK_m, XK_VoidSymbol}, "ḿ"}, // U1E3F | LATIN SMALL LETTER M WITH ACUTE {{XK_Multi_key, XK_acute, XK_m, XK_VoidSymbol}, "ḿ"}, {{XK_Multi_key, XK_apostrophe, XK_m, XK_VoidSymbol}, "ḿ"}, {{XK_dead_stroke, XK_L, XK_VoidSymbol}, "Ł"}, // U0141 | LATIN CAPITAL LETTER L WITH STROKE {{XK_Multi_key, XK_slash, XK_L, XK_VoidSymbol}, "Ł"}, {{XK_Multi_key, XK_L, XK_slash, XK_VoidSymbol}, "Ł"}, {{XK_Multi_key, XK_KP_Divide, XK_L, XK_VoidSymbol}, "Ł"}, {{XK_dead_grave, XK_A, XK_VoidSymbol}, "À"}, // Agrave | LATIN CAPITAL LETTER A WITH GRAVE {{XK_Multi_key, XK_grave, XK_A, XK_VoidSymbol}, "À"}, {{XK_Multi_key, XK_A, XK_grave, XK_VoidSymbol}, "À"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_omicron, XK_VoidSymbol}, "ὅ"}, // U1F45 | GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_omicron, XK_VoidSymbol}, "ὅ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_omicron, XK_VoidSymbol}, "ὅ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_omicron, XK_VoidSymbol}, "ὅ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_omicron, XK_VoidSymbol}, "ὅ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_omicron, XK_VoidSymbol}, "ὅ"}, {{XK_dead_tilde, XK_Ecircumflex, XK_VoidSymbol}, "Ễ"}, // U1EC4 | LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE {{XK_Multi_key, XK_asciitilde, XK_Ecircumflex, XK_VoidSymbol}, "Ễ"}, {{XK_dead_tilde, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ễ"}, {{XK_dead_tilde, XK_Multi_key, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ễ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ễ"}, {{XK_Multi_key, XK_asciitilde, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ễ"}, {{XK_dead_circumflex, XK_Etilde, XK_VoidSymbol}, "Ễ"}, {{XK_dead_circumflex, XK_dead_tilde, XK_E, XK_VoidSymbol}, "Ễ"}, {{XK_dead_voiced_sound, XK_kana_FU, XK_VoidSymbol}, "ブ"}, // U30D6 | KATAKANA LETTER BU {{XK_Multi_key, XK_parenleft, XK_S, XK_parenright, XK_VoidSymbol}, "Ⓢ"}, // U24C8 | CIRCLED LATIN CAPITAL LETTER S {{XK_dead_voiced_sound, XK_kana_HA, XK_VoidSymbol}, "バ"}, // U30D0 | KATAKANA LETTER BA {{XK_dead_grave, XK_Greek_ETA, XK_VoidSymbol}, "Ὴ"}, // U1FCA | GREEK CAPITAL LETTER ETA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_ETA, XK_VoidSymbol}, "Ὴ"}, {{XK_Multi_key, XK_F, XK_r, XK_VoidSymbol}, "₣"}, // U20a3 | FRENCH FRANC SIGN {{XK_dead_currency, XK_F, XK_VoidSymbol}, "₣"}, {{XK_dead_diaeresis, XK_otilde, XK_VoidSymbol}, "ṏ"}, // U1E4F | LATIN SMALL LETTER O WITH TILDE AND DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_otilde, XK_VoidSymbol}, "ṏ"}, {{XK_dead_diaeresis, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ṏ"}, {{XK_dead_diaeresis, XK_Multi_key, XK_asciitilde, XK_o, XK_VoidSymbol}, "ṏ"}, {{XK_Multi_key, XK_quotedbl, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ṏ"}, {{XK_Multi_key, XK_quotedbl, XK_asciitilde, XK_o, XK_VoidSymbol}, "ṏ"}, {{XK_dead_tilde, XK_odiaeresis, XK_VoidSymbol}, "ṏ"}, {{XK_dead_tilde, XK_dead_diaeresis, XK_o, XK_VoidSymbol}, "ṏ"}, {{XK_dead_grave, XK_Cyrillic_u, XK_VoidSymbol}, "у̀"}, // CYRILLIC SMALL LETTER U WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_u, XK_VoidSymbol}, "у̀"}, {{XK_dead_doubleacute, XK_o, XK_VoidSymbol}, "ő"}, // U0151 | LATIN SMALL LETTER O WITH DOUBLE ACUTE {{XK_Multi_key, XK_equal, XK_o, XK_VoidSymbol}, "ő"}, {{XK_Multi_key, XK_D, XK_H, XK_VoidSymbol}, "Ð"}, // ETH | LATIN CAPITAL LETTER ETH {{XK_dead_acute, XK_Cyrillic_ghe, XK_VoidSymbol}, "ѓ"}, // U0453 | CYRILLIC SMALL LETTER GJE {{XK_Multi_key, XK_acute, XK_Cyrillic_ghe, XK_VoidSymbol}, "ѓ"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_ghe, XK_VoidSymbol}, "ѓ"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_9, XK_parenright, XK_VoidSymbol}, "㉙"}, // U3259 | CIRCLED NUMBER TWENTY NINE {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_9, XK_parenright, XK_VoidSymbol}, "㉙"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_9, XK_parenright, XK_VoidSymbol}, "㉙"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_9, XK_parenright, XK_VoidSymbol}, "㉙"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_9, XK_parenright, XK_VoidSymbol}, "㉙"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_9, XK_parenright, XK_VoidSymbol}, "㉙"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὕ"}, // U1F55 | GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὕ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὕ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὕ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὕ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὕ"}, {{XK_dead_hook, XK_Ocircumflex, XK_VoidSymbol}, "Ổ"}, // U1ED4 | LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_Ocircumflex, XK_VoidSymbol}, "Ổ"}, {{XK_dead_hook, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ổ"}, {{XK_dead_hook, XK_Multi_key, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ổ"}, {{XK_Multi_key, XK_question, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ổ"}, {{XK_Multi_key, XK_question, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ổ"}, {{XK_dead_circumflex, XK_Ohook, XK_VoidSymbol}, "Ổ"}, {{XK_dead_circumflex, XK_dead_hook, XK_O, XK_VoidSymbol}, "Ổ"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_7, XK_parenright, XK_VoidSymbol}, "㉗"}, // U3257 | CIRCLED NUMBER TWENTY SEVEN {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_7, XK_parenright, XK_VoidSymbol}, "㉗"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_7, XK_parenright, XK_VoidSymbol}, "㉗"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_7, XK_parenright, XK_VoidSymbol}, "㉗"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_7, XK_parenright, XK_VoidSymbol}, "㉗"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_7, XK_parenright, XK_VoidSymbol}, "㉗"}, {{XK_dead_macron, XK_udiaeresis, XK_VoidSymbol}, "ǖ"}, // U01D6 | LATIN SMALL LETTER U WITH DIAERESIS AND MACRON {{XK_Multi_key, XK_macron, XK_udiaeresis, XK_VoidSymbol}, "ǖ"}, {{XK_Multi_key, XK_underscore, XK_udiaeresis, XK_VoidSymbol}, "ǖ"}, {{XK_dead_macron, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǖ"}, {{XK_dead_macron, XK_Multi_key, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǖ"}, {{XK_Multi_key, XK_macron, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǖ"}, {{XK_Multi_key, XK_macron, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǖ"}, {{XK_Multi_key, XK_underscore, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǖ"}, {{XK_Multi_key, XK_underscore, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǖ"}, {{XK_dead_macron, XK_v, XK_VoidSymbol}, "ǖ"}, {{XK_Multi_key, XK_parenleft, XK_i, XK_parenright, XK_VoidSymbol}, "ⓘ"}, // U24D8 | CIRCLED LATIN SMALL LETTER I {{XK_Multi_key, XK_parenleft, XK_parenleft, XK_VoidSymbol}, "["}, // bracketleft | LEFT SQUARE BRACKET {{XK_dead_grave, XK_Greek_IOTA, XK_VoidSymbol}, "Ὶ"}, // U1FDA | GREEK CAPITAL LETTER IOTA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_IOTA, XK_VoidSymbol}, "Ὶ"}, {{XK_Multi_key, XK_parenleft, XK_kana_SU, XK_parenright, XK_VoidSymbol}, "㋜"}, // U32DC | CIRCLED KATAKANA SU {{XK_dead_belowmacron, XK_r, XK_VoidSymbol}, "ṟ"}, // U1E5F | LATIN SMALL LETTER R WITH LINE BELOW {{XK_dead_caron, XK_s, XK_VoidSymbol}, "š"}, // U0161 | LATIN SMALL LETTER S WITH CARON {{XK_Multi_key, XK_c, XK_s, XK_VoidSymbol}, "š"}, {{XK_Multi_key, XK_less, XK_s, XK_VoidSymbol}, "š"}, {{XK_Multi_key, XK_s, XK_less, XK_VoidSymbol}, "š"}, {{XK_dead_grave, XK_a, XK_VoidSymbol}, "à"}, // agrave | LATIN SMALL LETTER A WITH GRAVE {{XK_Multi_key, XK_grave, XK_a, XK_VoidSymbol}, "à"}, {{XK_Multi_key, XK_a, XK_grave, XK_VoidSymbol}, "à"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_parenright, XK_VoidSymbol}, "④"}, // U2463 | CIRCLED DIGIT FOUR {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_parenright, XK_VoidSymbol}, "④"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὥ"}, // U1F65 | GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὥ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὥ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὥ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὥ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὥ"}, {{XK_dead_belowdot, XK_U, XK_VoidSymbol}, "Ụ"}, // U1EE4 | LATIN CAPITAL LETTER U WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_U, XK_VoidSymbol}, "Ụ"}, {{XK_dead_caron, XK_G, XK_VoidSymbol}, "Ǧ"}, // U01E6 | LATIN CAPITAL LETTER G WITH CARON {{XK_Multi_key, XK_c, XK_G, XK_VoidSymbol}, "Ǧ"}, {{XK_Multi_key, XK_parenleft, XK_y, XK_parenright, XK_VoidSymbol}, "ⓨ"}, // U24E8 | CIRCLED LATIN SMALL LETTER Y {{XK_dead_grave, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὺ"}, // U1FEA | GREEK CAPITAL LETTER UPSILON WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὺ"}, {{XK_Multi_key, XK_bar, XK_asciitilde, XK_VoidSymbol}, "⍭"}, // U236d | | ~ APL FUNCTIONAL SYMBOL STILE TILDE {{XK_Multi_key, XK_asciitilde, XK_bar, XK_VoidSymbol}, "⍭"}, {{XK_Multi_key, XK_parenleft, XK_kana_HE, XK_parenright, XK_VoidSymbol}, "㋬"}, // U32EC | CIRCLED KATAKANA HE {{XK_Multi_key, XK_numbersign, XK_numbersign, XK_VoidSymbol}, "♯"}, // U266f | MUSIC SHARP SIGN {{XK_dead_doubleacute, XK_u, XK_VoidSymbol}, "ű"}, // U0171 | LATIN SMALL LETTER U WITH DOUBLE ACUTE {{XK_Multi_key, XK_equal, XK_u, XK_VoidSymbol}, "ű"}, {{XK_Multi_key, XK_d, XK_h, XK_VoidSymbol}, "ð"}, // eth | LATIN SMALL LETTER ETH {{XK_Multi_key, XK_parenleft, XK_2, XK_0, XK_parenright, XK_VoidSymbol}, "⑳"}, // U2473 | CIRCLED NUMBER TWENTY {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_0, XK_parenright, XK_VoidSymbol}, "⑳"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_0, XK_parenright, XK_VoidSymbol}, "⑳"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_0, XK_parenright, XK_VoidSymbol}, "⑳"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_0, XK_parenright, XK_VoidSymbol}, "⑳"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_0, XK_parenright, XK_VoidSymbol}, "⑳"}, {{XK_dead_belowdot, XK_Y, XK_VoidSymbol}, "Ỵ"}, // U1EF4 | LATIN CAPITAL LETTER Y WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_Y, XK_VoidSymbol}, "Ỵ"}, {{XK_dead_diaeresis, XK_dead_belowdiaeresis, XK_equal, XK_VoidSymbol}, "⩷"}, // U2A77 | EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW {{XK_dead_belowdiaeresis, XK_dead_diaeresis, XK_equal, XK_VoidSymbol}, "⩷"}, {{XK_dead_invertedbreve, XK_Cyrillic_o, XK_VoidSymbol}, "о̑"}, // CYRILLIC SMALL LETTER O WITH COMBINING INVERTED BREVE {{XK_dead_diaeresis, XK_Cyrillic_YERU, XK_VoidSymbol}, "Ӹ"}, // U04F8 | CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_YERU, XK_VoidSymbol}, "Ӹ"}, {{XK_Multi_key, XK_parenleft, XK_minus, XK_VoidSymbol}, "{"}, // braceleft | LEFT CURLY BRACKET {{XK_Multi_key, XK_minus, XK_parenleft, XK_VoidSymbol}, "{"}, {{XK_dead_grave, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὼ"}, // U1FFA | GREEK CAPITAL LETTER OMEGA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὼ"}, {{XK_Multi_key, XK_less, XK_less, XK_VoidSymbol}, "«"}, // guillemotleft | LEFT-POINTING DOUBLE ANGLE QUOTATION MARK {{XK_dead_belowdot, XK_v, XK_VoidSymbol}, "ṿ"}, // U1E7F | LATIN SMALL LETTER V WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_v, XK_VoidSymbol}, "ṿ"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_3, XK_parenright, XK_VoidSymbol}, "⑬"}, // U246C | CIRCLED NUMBER THIRTEEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_3, XK_parenright, XK_VoidSymbol}, "⑬"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_3, XK_parenright, XK_VoidSymbol}, "⑬"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_3, XK_parenright, XK_VoidSymbol}, "⑬"}, {{XK_Multi_key, XK_underscore, XK_1, XK_VoidSymbol}, "₁"}, // U2081 | SUBSCRIPT ONE {{XK_Multi_key, XK_underscore, XK_KP_1, XK_VoidSymbol}, "₁"}, {{XK_dead_caron, XK_1, XK_VoidSymbol}, "₁"}, {{XK_dead_macron, XK_A, XK_VoidSymbol}, "Ā"}, // U0100 | LATIN CAPITAL LETTER A WITH MACRON {{XK_Multi_key, XK_macron, XK_A, XK_VoidSymbol}, "Ā"}, {{XK_Multi_key, XK_underscore, XK_A, XK_VoidSymbol}, "Ā"}, {{XK_Multi_key, XK_A, XK_underscore, XK_VoidSymbol}, "Ā"}, {{XK_Multi_key, XK_minus, XK_A, XK_VoidSymbol}, "Ā"}, {{XK_Multi_key, XK_A, XK_minus, XK_VoidSymbol}, "Ā"}, {{XK_dead_stroke, XK_R, XK_VoidSymbol}, "Ɍ"}, // U024C | LATIN CAPITAL LETTER R WITH STROKE {{XK_dead_diaeresis, XK_w, XK_VoidSymbol}, "ẅ"}, // U1E85 | LATIN SMALL LETTER W WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_w, XK_VoidSymbol}, "ẅ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἄ"}, // U1F04 | GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἄ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἄ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἄ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἄ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἄ"}, {{XK_dead_abovedot, XK_D, XK_VoidSymbol}, "Ḋ"}, // U1E0A | LATIN CAPITAL LETTER D WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_D, XK_VoidSymbol}, "Ḋ"}, {{XK_Multi_key, XK_D, XK_period, XK_VoidSymbol}, "Ḋ"}, {{XK_dead_caron, XK_nobreakspace, XK_VoidSymbol}, "̌"}, // U030C | COMBINING CARON {{XK_dead_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, // U1F8F | GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾏ"}, {{XK_dead_breve, XK_Cyrillic_U, XK_VoidSymbol}, "Ў"}, // U040E | CYRILLIC CAPITAL LETTER SHORT U {{XK_Multi_key, XK_U, XK_Cyrillic_U, XK_VoidSymbol}, "Ў"}, {{XK_Multi_key, XK_b, XK_Cyrillic_U, XK_VoidSymbol}, "Ў"}, {{XK_Multi_key, XK_minus, XK_D, XK_VoidSymbol}, "Đ"}, // Dstroke | LATIN CAPITAL LETTER D WITH STROKE {{XK_dead_stroke, XK_D, XK_VoidSymbol}, "Đ"}, {{XK_Multi_key, XK_slash, XK_D, XK_VoidSymbol}, "Đ"}, {{XK_Multi_key, XK_KP_Divide, XK_D, XK_VoidSymbol}, "Đ"}, {{XK_Multi_key, XK_D, XK_minus, XK_VoidSymbol}, "Đ"}, {{XK_dead_belowmacron, XK_z, XK_VoidSymbol}, "ẕ"}, // U1E95 | LATIN SMALL LETTER Z WITH LINE BELOW {{XK_dead_acute, XK_dead_psili, XK_Greek_epsilon, XK_VoidSymbol}, "ἔ"}, // U1F14 | GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_epsilon, XK_VoidSymbol}, "ἔ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_epsilon, XK_VoidSymbol}, "ἔ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_epsilon, XK_VoidSymbol}, "ἔ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_epsilon, XK_VoidSymbol}, "ἔ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_epsilon, XK_VoidSymbol}, "ἔ"}, {{XK_dead_circumflex, XK_dead_belowdot, XK_O, XK_VoidSymbol}, "Ộ"}, // U1ED8 | LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW {{XK_dead_circumflex, XK_Multi_key, XK_exclam, XK_O, XK_VoidSymbol}, "Ộ"}, {{XK_Multi_key, XK_asciicircum, XK_dead_belowdot, XK_O, XK_VoidSymbol}, "Ộ"}, {{XK_Multi_key, XK_asciicircum, XK_exclam, XK_O, XK_VoidSymbol}, "Ộ"}, {{XK_dead_belowdot, XK_Ocircumflex, XK_VoidSymbol}, "Ộ"}, {{XK_dead_belowdot, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ộ"}, {{XK_dead_belowtilde, XK_E, XK_VoidSymbol}, "Ḛ"}, // U1E1A | LATIN CAPITAL LETTER E WITH TILDE BELOW {{XK_dead_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, // U1F9F | GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾟ"}, {{XK_Multi_key, XK_C, XK_slash, XK_VoidSymbol}, "₡"}, // U20a1 | COLON SIGN {{XK_Multi_key, XK_slash, XK_C, XK_VoidSymbol}, "₡"}, {{XK_dead_currency, XK_C, XK_VoidSymbol}, "₡"}, {{XK_dead_abovedot, XK_G, XK_VoidSymbol}, "Ġ"}, // U0120 | LATIN CAPITAL LETTER G WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_G, XK_VoidSymbol}, "Ġ"}, {{XK_Multi_key, XK_G, XK_period, XK_VoidSymbol}, "Ġ"}, {{XK_dead_acute, XK_acircumflex, XK_VoidSymbol}, "ấ"}, // U1EA5 | LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE {{XK_Multi_key, XK_acute, XK_acircumflex, XK_VoidSymbol}, "ấ"}, {{XK_Multi_key, XK_apostrophe, XK_acircumflex, XK_VoidSymbol}, "ấ"}, {{XK_dead_acute, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ấ"}, {{XK_dead_acute, XK_Multi_key, XK_asciicircum, XK_a, XK_VoidSymbol}, "ấ"}, {{XK_Multi_key, XK_acute, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ấ"}, {{XK_Multi_key, XK_acute, XK_asciicircum, XK_a, XK_VoidSymbol}, "ấ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ấ"}, {{XK_Multi_key, XK_apostrophe, XK_asciicircum, XK_a, XK_VoidSymbol}, "ấ"}, {{XK_dead_circumflex, XK_aacute, XK_VoidSymbol}, "ấ"}, {{XK_dead_circumflex, XK_dead_acute, XK_a, XK_VoidSymbol}, "ấ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἤ"}, // U1F24 | GREEK SMALL LETTER ETA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἤ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἤ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἤ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἤ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἤ"}, {{XK_Multi_key, XK_period, XK_period, XK_VoidSymbol}, "…"}, // ellipsis | HORIZONTAL ELLIPSIS {{XK_Multi_key, XK_5, XK_8, XK_VoidSymbol}, "⅝"}, // U215D | VULGAR FRACTION FIVE EIGHTHS {{XK_Multi_key, XK_parenleft, XK_kana_KE, XK_parenright, XK_VoidSymbol}, "㋘"}, // U32D8 | CIRCLED KATAKANA KE {{XK_dead_belowbreve, XK_H, XK_VoidSymbol}, "Ḫ"}, // U1E2A | LATIN CAPITAL LETTER H WITH BREVE BELOW {{XK_dead_currency, XK_A, XK_VoidSymbol}, "₳"}, // U20B3 | AUSTRAL SIGN {{XK_dead_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, // U1FAF | GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾯ"}, {{XK_Multi_key, XK_parenleft, XK_D, XK_parenright, XK_VoidSymbol}, "Ⓓ"}, // U24B9 | CIRCLED LATIN CAPITAL LETTER D {{XK_Multi_key, XK_plus, XK_minus, XK_VoidSymbol}, "±"}, // plusminus | PLUS-MINUS SIGN {{XK_Multi_key, XK_minus, XK_plus, XK_VoidSymbol}, "±"}, {{XK_dead_abovedot, XK_I, XK_VoidSymbol}, "İ"}, // U0130 | LATIN CAPITAL LETTER I WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_I, XK_VoidSymbol}, "İ"}, {{XK_Multi_key, XK_I, XK_period, XK_VoidSymbol}, "İ"}, {{XK_dead_macron, XK_Y, XK_VoidSymbol}, "Ȳ"}, // U0232 | LATIN CAPITAL LETTER Y WITH MACRON {{XK_Multi_key, XK_macron, XK_Y, XK_VoidSymbol}, "Ȳ"}, {{XK_Multi_key, XK_underscore, XK_Y, XK_VoidSymbol}, "Ȳ"}, {{XK_dead_tilde, XK_abreve, XK_VoidSymbol}, "ẵ"}, // U1EB5 | LATIN SMALL LETTER A WITH BREVE AND TILDE {{XK_Multi_key, XK_asciitilde, XK_abreve, XK_VoidSymbol}, "ẵ"}, {{XK_dead_tilde, XK_dead_breve, XK_a, XK_VoidSymbol}, "ẵ"}, {{XK_dead_tilde, XK_Multi_key, XK_U, XK_a, XK_VoidSymbol}, "ẵ"}, {{XK_dead_tilde, XK_Multi_key, XK_b, XK_a, XK_VoidSymbol}, "ẵ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_breve, XK_a, XK_VoidSymbol}, "ẵ"}, {{XK_Multi_key, XK_asciitilde, XK_b, XK_a, XK_VoidSymbol}, "ẵ"}, {{XK_dead_breve, XK_atilde, XK_VoidSymbol}, "ẵ"}, {{XK_dead_breve, XK_dead_tilde, XK_a, XK_VoidSymbol}, "ẵ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἴ"}, // U1F34 | GREEK SMALL LETTER IOTA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἴ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἴ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἴ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἴ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἴ"}, {{XK_Multi_key, XK_3, XK_5, XK_VoidSymbol}, "⅗"}, // U2157 | VULGAR FRACTION THREE FIFTHS {{XK_dead_stroke, XK_2, XK_VoidSymbol}, "ƻ"}, // U01BB | LATIN LETTER TWO WITH STROKE {{XK_Multi_key, XK_colon, XK_parenright, XK_VoidSymbol}, "☺"}, // U263A | WHITE SMILING FACE {{XK_Multi_key, XK_parenleft, XK_4, XK_8, XK_parenright, XK_VoidSymbol}, "㊽"}, // U32BD | CIRCLED NUMBER FORTY EIGHT {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_8, XK_parenright, XK_VoidSymbol}, "㊽"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_8, XK_parenright, XK_VoidSymbol}, "㊽"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_8, XK_parenright, XK_VoidSymbol}, "㊽"}, {{XK_dead_acute, XK_A, XK_VoidSymbol}, "Á"}, // Aacute | LATIN CAPITAL LETTER A WITH ACUTE {{XK_Multi_key, XK_acute, XK_A, XK_VoidSymbol}, "Á"}, {{XK_Multi_key, XK_apostrophe, XK_A, XK_VoidSymbol}, "Á"}, {{XK_Multi_key, XK_A, XK_apostrophe, XK_VoidSymbol}, "Á"}, {{XK_Multi_key, XK_A, XK_acute, XK_VoidSymbol}, "Á"}, {{XK_dead_abovedot, XK_l, XK_VoidSymbol}, "ŀ"}, // U0140 | LATIN SMALL LETTER L WITH MIDDLE DOT {{XK_dead_tilde, XK_ecircumflex, XK_VoidSymbol}, "ễ"}, // U1EC5 | LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE {{XK_Multi_key, XK_asciitilde, XK_ecircumflex, XK_VoidSymbol}, "ễ"}, {{XK_dead_tilde, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ễ"}, {{XK_dead_tilde, XK_Multi_key, XK_asciicircum, XK_e, XK_VoidSymbol}, "ễ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ễ"}, {{XK_Multi_key, XK_asciitilde, XK_asciicircum, XK_e, XK_VoidSymbol}, "ễ"}, {{XK_dead_circumflex, XK_etilde, XK_VoidSymbol}, "ễ"}, {{XK_dead_circumflex, XK_dead_tilde, XK_e, XK_VoidSymbol}, "ễ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_omicron, XK_VoidSymbol}, "ὄ"}, // U1F44 | GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_omicron, XK_VoidSymbol}, "ὄ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_omicron, XK_VoidSymbol}, "ὄ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_omicron, XK_VoidSymbol}, "ὄ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_omicron, XK_VoidSymbol}, "ὄ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_omicron, XK_VoidSymbol}, "ὄ"}, {{XK_Multi_key, XK_parenleft, XK_T, XK_parenright, XK_VoidSymbol}, "Ⓣ"}, // U24C9 | CIRCLED LATIN CAPITAL LETTER T {{XK_dead_stroke, XK_P, XK_VoidSymbol}, "Ᵽ"}, // U2C63 | LATIN CAPITAL LETTER P WITH STROKE {{XK_dead_belowcircumflex, XK_N, XK_VoidSymbol}, "Ṋ"}, // U1E4A | LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW {{XK_dead_invertedbreve, XK_Cyrillic_ie, XK_VoidSymbol}, "е̑"}, // CYRILLIC SMALL LETTER IE WITH COMBINING INVERTED BREVE {{XK_dead_tilde, XK_N, XK_VoidSymbol}, "Ñ"}, // Ntilde | LATIN CAPITAL LETTER N WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_N, XK_VoidSymbol}, "Ñ"}, {{XK_Multi_key, XK_N, XK_asciitilde, XK_VoidSymbol}, "Ñ"}, {{XK_dead_doubleacute, XK_O, XK_VoidSymbol}, "Ő"}, // U0150 | LATIN CAPITAL LETTER O WITH DOUBLE ACUTE {{XK_Multi_key, XK_equal, XK_O, XK_VoidSymbol}, "Ő"}, {{XK_dead_doublegrave, XK_Cyrillic_ie, XK_VoidSymbol}, "е̏"}, // CYRILLIC SMALL LETTER IE WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_ie, XK_VoidSymbol}, "е̏"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_2, XK_parenright, XK_VoidSymbol}, "㉒"}, // U3252 | CIRCLED NUMBER TWENTY TWO {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_2, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_2, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_2, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_2, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_2, XK_parenright, XK_VoidSymbol}, "㉒"}, {{XK_dead_hook, XK_ocircumflex, XK_VoidSymbol}, "ổ"}, // U1ED5 | LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_ocircumflex, XK_VoidSymbol}, "ổ"}, {{XK_dead_hook, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ổ"}, {{XK_dead_hook, XK_Multi_key, XK_asciicircum, XK_o, XK_VoidSymbol}, "ổ"}, {{XK_Multi_key, XK_question, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ổ"}, {{XK_Multi_key, XK_question, XK_asciicircum, XK_o, XK_VoidSymbol}, "ổ"}, {{XK_dead_circumflex, XK_ohook, XK_VoidSymbol}, "ổ"}, {{XK_dead_circumflex, XK_dead_hook, XK_o, XK_VoidSymbol}, "ổ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὔ"}, // U1F54 | GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὔ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὔ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὔ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὔ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὔ"}, {{XK_dead_acute, XK_Cyrillic_o, XK_VoidSymbol}, "о́"}, // CYRILLIC SMALL LETTER O WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_o, XK_VoidSymbol}, "о́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_o, XK_VoidSymbol}, "о́"}, {{XK_Multi_key, XK_parenleft, XK_j, XK_parenright, XK_VoidSymbol}, "ⓙ"}, // U24D9 | CIRCLED LATIN SMALL LETTER J {{XK_dead_macron, XK_Cyrillic_ie, XK_VoidSymbol}, "е̄"}, // CYRILLIC SMALL LETTER IE WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_ie, XK_VoidSymbol}, "е̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_ie, XK_VoidSymbol}, "е̄"}, {{XK_dead_grave, XK_Udiaeresis, XK_VoidSymbol}, "Ǜ"}, // U01DB | LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE {{XK_Multi_key, XK_grave, XK_Udiaeresis, XK_VoidSymbol}, "Ǜ"}, {{XK_dead_grave, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǜ"}, {{XK_dead_grave, XK_Multi_key, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǜ"}, {{XK_Multi_key, XK_grave, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǜ"}, {{XK_Multi_key, XK_grave, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǜ"}, {{XK_dead_diaeresis, XK_Ugrave, XK_VoidSymbol}, "Ǜ"}, {{XK_dead_grave, XK_V, XK_VoidSymbol}, "Ǜ"}, {{XK_dead_diaeresis, XK_dead_grave, XK_U, XK_VoidSymbol}, "Ǜ"}, {{XK_dead_belowdot, XK_R, XK_VoidSymbol}, "Ṛ"}, // U1E5A | LATIN CAPITAL LETTER R WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_R, XK_VoidSymbol}, "Ṛ"}, {{XK_dead_doubleacute, XK_space, XK_VoidSymbol}, "˝"}, // U2dd | DOUBLE ACUTE ACCENT {{XK_dead_doubleacute, XK_dead_doubleacute, XK_VoidSymbol}, "˝"}, {{XK_dead_circumflex, XK_Cyrillic_o, XK_VoidSymbol}, "о̂"}, // CYRILLIC SMALL LETTER O WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_o, XK_VoidSymbol}, "о̂"}, {{XK_dead_breve, XK_Cyrillic_u, XK_VoidSymbol}, "ў"}, // U045E | CYRILLIC SMALL LETTER SHORT U {{XK_Multi_key, XK_U, XK_Cyrillic_u, XK_VoidSymbol}, "ў"}, {{XK_Multi_key, XK_b, XK_Cyrillic_u, XK_VoidSymbol}, "ў"}, {{XK_dead_acute, XK_a, XK_VoidSymbol}, "á"}, // aacute | LATIN SMALL LETTER A WITH ACUTE {{XK_Multi_key, XK_acute, XK_a, XK_VoidSymbol}, "á"}, {{XK_Multi_key, XK_a, XK_acute, XK_VoidSymbol}, "á"}, {{XK_Multi_key, XK_apostrophe, XK_a, XK_VoidSymbol}, "á"}, {{XK_Multi_key, XK_a, XK_apostrophe, XK_VoidSymbol}, "á"}, {{XK_dead_caron, XK_S, XK_VoidSymbol}, "Š"}, // U0160 | LATIN CAPITAL LETTER S WITH CARON {{XK_Multi_key, XK_c, XK_S, XK_VoidSymbol}, "Š"}, {{XK_Multi_key, XK_less, XK_S, XK_VoidSymbol}, "Š"}, {{XK_Multi_key, XK_S, XK_less, XK_VoidSymbol}, "Š"}, {{XK_dead_belowdot, XK_u, XK_VoidSymbol}, "ụ"}, // U1EE5 | LATIN SMALL LETTER U WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_u, XK_VoidSymbol}, "ụ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὤ"}, // U1F64 | GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὤ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὤ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὤ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὤ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὤ"}, {{XK_Multi_key, XK_parenleft, XK_z, XK_parenright, XK_VoidSymbol}, "ⓩ"}, // U24E9 | CIRCLED LATIN SMALL LETTER Z {{XK_dead_ogonek, XK_o, XK_VoidSymbol}, "ǫ"}, // U01EB | LATIN SMALL LETTER O WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_o, XK_VoidSymbol}, "ǫ"}, {{XK_Multi_key, XK_numbersign, XK_e, XK_VoidSymbol}, "♪"}, // U266a | EIGHTH NOTE {{XK_Multi_key, XK_parenleft, XK_kana_HO, XK_parenright, XK_VoidSymbol}, "㋭"}, // U32ED | CIRCLED KATAKANA HO {{XK_Multi_key, XK_0, XK_asciitilde, XK_VoidSymbol}, "⍬"}, // U236c | 0 ~ APL FUNCTIONAL SYMBOL ZILDE {{XK_Multi_key, XK_asciitilde, XK_0, XK_VoidSymbol}, "⍬"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_5, XK_parenright, XK_VoidSymbol}, "⑮"}, // U246E | CIRCLED NUMBER FIFTEEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_5, XK_parenright, XK_VoidSymbol}, "⑮"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_5, XK_parenright, XK_VoidSymbol}, "⑮"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_5, XK_parenright, XK_VoidSymbol}, "⑮"}, {{XK_dead_tilde, XK_n, XK_VoidSymbol}, "ñ"}, // ntilde | LATIN SMALL LETTER N WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_n, XK_VoidSymbol}, "ñ"}, {{XK_Multi_key, XK_n, XK_asciitilde, XK_VoidSymbol}, "ñ"}, {{XK_dead_doubleacute, XK_U, XK_VoidSymbol}, "Ű"}, // U0170 | LATIN CAPITAL LETTER U WITH DOUBLE ACUTE {{XK_Multi_key, XK_equal, XK_U, XK_VoidSymbol}, "Ű"}, {{XK_dead_semivoiced_sound, XK_kana_HI, XK_VoidSymbol}, "ピ"}, // U30D4 | KATAKANA LETTER PI {{XK_dead_hook, XK_n, XK_VoidSymbol}, "ɲ"}, // U0272 | LATIN SMALL LETTER N WITH LEFT HOOK {{XK_dead_belowdot, XK_y, XK_VoidSymbol}, "ỵ"}, // U1EF5 | LATIN SMALL LETTER Y WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_y, XK_VoidSymbol}, "ỵ"}, {{XK_dead_grave, XK_Greek_eta, XK_VoidSymbol}, "ὴ"}, // U1F74 | GREEK SMALL LETTER ETA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_eta, XK_VoidSymbol}, "ὴ"}, {{XK_dead_circumflex, XK_6, XK_VoidSymbol}, "⁶"}, // U2076 | SUPERSCRIPT SIX {{XK_Multi_key, XK_asciicircum, XK_6, XK_VoidSymbol}, "⁶"}, {{XK_dead_circumflex, XK_KP_6, XK_VoidSymbol}, "⁶"}, {{XK_Multi_key, XK_asciicircum, XK_KP_6, XK_VoidSymbol}, "⁶"}, {{XK_dead_diaeresis, XK_Cyrillic_yeru, XK_VoidSymbol}, "ӹ"}, // U04F9 | CYRILLIC SMALL LETTER YERU WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_yeru, XK_VoidSymbol}, "ӹ"}, {{XK_dead_acute, XK_aring, XK_VoidSymbol}, "ǻ"}, // U01FB | LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE {{XK_Multi_key, XK_acute, XK_aring, XK_VoidSymbol}, "ǻ"}, {{XK_Multi_key, XK_apostrophe, XK_aring, XK_VoidSymbol}, "ǻ"}, {{XK_dead_acute, XK_dead_abovering, XK_a, XK_VoidSymbol}, "ǻ"}, {{XK_dead_acute, XK_Multi_key, XK_o, XK_a, XK_VoidSymbol}, "ǻ"}, {{XK_Multi_key, XK_acute, XK_dead_abovering, XK_a, XK_VoidSymbol}, "ǻ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_abovering, XK_a, XK_VoidSymbol}, "ǻ"}, {{XK_Multi_key, XK_asterisk, XK_apostrophe, XK_a, XK_VoidSymbol}, "ǻ"}, {{XK_dead_abovering, XK_aacute, XK_VoidSymbol}, "ǻ"}, {{XK_dead_abovering, XK_dead_acute, XK_a, XK_VoidSymbol}, "ǻ"}, {{XK_dead_diaeresis, XK_Umacron, XK_VoidSymbol}, "Ṻ"}, // U1E7A | LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Umacron, XK_VoidSymbol}, "Ṻ"}, {{XK_dead_diaeresis, XK_dead_macron, XK_U, XK_VoidSymbol}, "Ṻ"}, {{XK_dead_diaeresis, XK_Multi_key, XK_macron, XK_U, XK_VoidSymbol}, "Ṻ"}, {{XK_dead_diaeresis, XK_Multi_key, XK_underscore, XK_U, XK_VoidSymbol}, "Ṻ"}, {{XK_Multi_key, XK_quotedbl, XK_dead_macron, XK_U, XK_VoidSymbol}, "Ṻ"}, {{XK_Multi_key, XK_quotedbl, XK_macron, XK_U, XK_VoidSymbol}, "Ṻ"}, {{XK_Multi_key, XK_quotedbl, XK_underscore, XK_U, XK_VoidSymbol}, "Ṻ"}, {{XK_dead_abovedot, XK_t, XK_VoidSymbol}, "ṫ"}, // U1E6B | LATIN SMALL LETTER T WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_t, XK_VoidSymbol}, "ṫ"}, {{XK_Multi_key, XK_t, XK_period, XK_VoidSymbol}, "ṫ"}, {{XK_dead_stroke, XK_b, XK_VoidSymbol}, "ƀ"}, // U0180 | LATIN SMALL LETTER B WITH STROKE {{XK_Multi_key, XK_slash, XK_b, XK_VoidSymbol}, "ƀ"}, {{XK_Multi_key, XK_KP_Divide, XK_b, XK_VoidSymbol}, "ƀ"}, {{XK_dead_hook, XK_s, XK_VoidSymbol}, "ʂ"}, // U0282 | LATIN SMALL LETTER S WITH HOOK {{XK_dead_belowdot, XK_b, XK_VoidSymbol}, "ḅ"}, // U1E05 | LATIN SMALL LETTER B WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_b, XK_VoidSymbol}, "ḅ"}, {{XK_dead_iota, XK_dead_acute, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, // U1F84 | GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾄ"}, {{XK_dead_abovedot, XK_nobreakspace, XK_VoidSymbol}, "̇"}, // U0307 | COMBINING DOT ABOVE {{XK_Multi_key, XK_underscore, XK_6, XK_VoidSymbol}, "₆"}, // U2086 | SUBSCRIPT SIX {{XK_Multi_key, XK_underscore, XK_KP_6, XK_VoidSymbol}, "₆"}, {{XK_dead_caron, XK_6, XK_VoidSymbol}, "₆"}, {{XK_dead_invertedbreve, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̑"}, // CYRILLIC CAPITAL LETTER IE WITH COMBINING INVERTED BREVE {{XK_dead_abovedot, XK_c, XK_VoidSymbol}, "ċ"}, // U010B | LATIN SMALL LETTER C WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_c, XK_VoidSymbol}, "ċ"}, {{XK_Multi_key, XK_c, XK_period, XK_VoidSymbol}, "ċ"}, {{XK_dead_abovedot, XK_X, XK_VoidSymbol}, "Ẋ"}, // U1E8A | LATIN CAPITAL LETTER X WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_X, XK_VoidSymbol}, "Ẋ"}, {{XK_dead_acute, XK_Greek_OMICRON, XK_VoidSymbol}, "Ό"}, // U038C | GREEK CAPITAL LETTER OMICRON WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_OMICRON, XK_VoidSymbol}, "Ό"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_OMICRON, XK_VoidSymbol}, "Ό"}, {{XK_Multi_key, XK_Greek_OMICRON, XK_apostrophe, XK_VoidSymbol}, "Ό"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἇ"}, // U1F0F | GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἇ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἇ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἇ"}, {{XK_Multi_key, XK_less, XK_minus, XK_VoidSymbol}, "←"}, // U2190 | LEFTWARDS ARROW {{XK_dead_grave, XK_emacron, XK_VoidSymbol}, "ḕ"}, // U1E15 | LATIN SMALL LETTER E WITH MACRON AND GRAVE {{XK_Multi_key, XK_grave, XK_emacron, XK_VoidSymbol}, "ḕ"}, {{XK_dead_grave, XK_dead_macron, XK_e, XK_VoidSymbol}, "ḕ"}, {{XK_dead_grave, XK_Multi_key, XK_macron, XK_e, XK_VoidSymbol}, "ḕ"}, {{XK_dead_grave, XK_Multi_key, XK_underscore, XK_e, XK_VoidSymbol}, "ḕ"}, {{XK_Multi_key, XK_grave, XK_dead_macron, XK_e, XK_VoidSymbol}, "ḕ"}, {{XK_Multi_key, XK_grave, XK_macron, XK_e, XK_VoidSymbol}, "ḕ"}, {{XK_Multi_key, XK_grave, XK_underscore, XK_e, XK_VoidSymbol}, "ḕ"}, {{XK_dead_macron, XK_egrave, XK_VoidSymbol}, "ḕ"}, {{XK_dead_macron, XK_dead_grave, XK_e, XK_VoidSymbol}, "ḕ"}, {{XK_dead_iota, XK_dead_acute, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, // U1F94 | GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾔ"}, {{XK_dead_currency, XK_THORN, XK_VoidSymbol}, "৲"}, // U09F2 | BENGALI RUPEE MARK {{XK_dead_currency, XK_thorn, XK_VoidSymbol}, "৲"}, {{XK_dead_breve, XK_Cyrillic_I, XK_VoidSymbol}, "Й"}, // U0419 | CYRILLIC CAPITAL LETTER SHORT I {{XK_Multi_key, XK_U, XK_Cyrillic_I, XK_VoidSymbol}, "Й"}, {{XK_Multi_key, XK_b, XK_Cyrillic_I, XK_VoidSymbol}, "Й"}, {{XK_dead_caron, XK_e, XK_VoidSymbol}, "ě"}, // U011B | LATIN SMALL LETTER E WITH CARON {{XK_Multi_key, XK_c, XK_e, XK_VoidSymbol}, "ě"}, {{XK_Multi_key, XK_less, XK_e, XK_VoidSymbol}, "ě"}, {{XK_Multi_key, XK_e, XK_less, XK_VoidSymbol}, "ě"}, {{XK_Multi_key, XK_4, XK_5, XK_VoidSymbol}, "⅘"}, // U2158 | VULGAR FRACTION FOUR FIFTHS {{XK_Multi_key, XK_slash, XK_Cyrillic_KA, XK_VoidSymbol}, "Ҟ"}, // U049E | CYRILLIC CAPITAL LETTER KA WITH STROKE {{XK_Multi_key, XK_KP_Divide, XK_Cyrillic_KA, XK_VoidSymbol}, "Ҟ"}, {{XK_dead_horn, XK_O, XK_VoidSymbol}, "Ơ"}, // U01A0 | LATIN CAPITAL LETTER O WITH HORN {{XK_Multi_key, XK_plus, XK_O, XK_VoidSymbol}, "Ơ"}, {{XK_dead_belowdot, XK_h, XK_VoidSymbol}, "ḥ"}, // U1E25 | LATIN SMALL LETTER H WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_h, XK_VoidSymbol}, "ḥ"}, {{XK_dead_iota, XK_dead_acute, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, // U1FA4 | GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾤ"}, {{XK_dead_cedilla, XK_nobreakspace, XK_VoidSymbol}, "̧"}, // U0327 | COMBINING CEDILLA {{XK_Multi_key, XK_N, XK_equal, XK_VoidSymbol}, "₦"}, // U20a6 | NAIRA SIGN {{XK_Multi_key, XK_equal, XK_N, XK_VoidSymbol}, "₦"}, {{XK_dead_currency, XK_N, XK_VoidSymbol}, "₦"}, {{XK_dead_currency, XK_n, XK_VoidSymbol}, "₦"}, {{XK_dead_macron, XK_i, XK_VoidSymbol}, "ī"}, // U012B | LATIN SMALL LETTER I WITH MACRON {{XK_Multi_key, XK_macron, XK_i, XK_VoidSymbol}, "ī"}, {{XK_Multi_key, XK_underscore, XK_i, XK_VoidSymbol}, "ī"}, {{XK_Multi_key, XK_i, XK_underscore, XK_VoidSymbol}, "ī"}, {{XK_Multi_key, XK_minus, XK_i, XK_VoidSymbol}, "ī"}, {{XK_Multi_key, XK_i, XK_minus, XK_VoidSymbol}, "ī"}, {{XK_dead_tilde, XK_Acircumflex, XK_VoidSymbol}, "Ẫ"}, // U1EAA | LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE {{XK_Multi_key, XK_asciitilde, XK_Acircumflex, XK_VoidSymbol}, "Ẫ"}, {{XK_dead_tilde, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ẫ"}, {{XK_dead_tilde, XK_Multi_key, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ẫ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ẫ"}, {{XK_Multi_key, XK_asciitilde, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ẫ"}, {{XK_dead_circumflex, XK_Atilde, XK_VoidSymbol}, "Ẫ"}, {{XK_dead_circumflex, XK_dead_tilde, XK_A, XK_VoidSymbol}, "Ẫ"}, {{XK_dead_macron, XK_otilde, XK_VoidSymbol}, "ȭ"}, // U022D | LATIN SMALL LETTER O WITH TILDE AND MACRON {{XK_Multi_key, XK_macron, XK_otilde, XK_VoidSymbol}, "ȭ"}, {{XK_Multi_key, XK_underscore, XK_otilde, XK_VoidSymbol}, "ȭ"}, {{XK_dead_macron, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ȭ"}, {{XK_dead_macron, XK_Multi_key, XK_asciitilde, XK_o, XK_VoidSymbol}, "ȭ"}, {{XK_Multi_key, XK_macron, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ȭ"}, {{XK_Multi_key, XK_macron, XK_asciitilde, XK_o, XK_VoidSymbol}, "ȭ"}, {{XK_Multi_key, XK_underscore, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ȭ"}, {{XK_Multi_key, XK_underscore, XK_asciitilde, XK_o, XK_VoidSymbol}, "ȭ"}, {{XK_dead_tilde, XK_omacron, XK_VoidSymbol}, "ȭ"}, {{XK_dead_tilde, XK_dead_macron, XK_o, XK_VoidSymbol}, "ȭ"}, {{XK_dead_acute, XK_Greek_alpha, XK_VoidSymbol}, "ά"}, // U03AC | GREEK SMALL LETTER ALPHA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_alpha, XK_VoidSymbol}, "ά"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_alpha, XK_VoidSymbol}, "ά"}, {{XK_Multi_key, XK_Greek_alpha, XK_apostrophe, XK_VoidSymbol}, "ά"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἧ"}, // U1F2F | GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἧ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἧ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἧ"}, {{XK_dead_horn, XK_u, XK_VoidSymbol}, "ư"}, // U01B0 | LATIN SMALL LETTER U WITH HORN {{XK_Multi_key, XK_plus, XK_u, XK_VoidSymbol}, "ư"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_j, XK_VoidSymbol}, "ʲ"}, // U02B2 | MODIFIER LETTER SMALL J {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_j, XK_VoidSymbol}, "ʲ"}, {{XK_dead_belowmacron, XK_k, XK_VoidSymbol}, "ḵ"}, // U1E35 | LATIN SMALL LETTER K WITH LINE BELOW {{XK_dead_iota, XK_Greek_alphaaccent, XK_VoidSymbol}, "ᾴ"}, // U1FB4 | GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_alphaaccent, XK_VoidSymbol}, "ᾴ"}, {{XK_dead_iota, XK_dead_acute, XK_Greek_alpha, XK_VoidSymbol}, "ᾴ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_Greek_alpha, XK_VoidSymbol}, "ᾴ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_Greek_alpha, XK_VoidSymbol}, "ᾴ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_Greek_alpha, XK_VoidSymbol}, "ᾴ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_Greek_alpha, XK_VoidSymbol}, "ᾴ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_Greek_alpha, XK_VoidSymbol}, "ᾴ"}, {{XK_Multi_key, XK_bracketleft, XK_bracketright, XK_VoidSymbol}, "⌷"}, // U2337 | [ ] APL FUNCTIONAL SYMBOL SQUISH QUAD {{XK_Multi_key, XK_bracketright, XK_bracketleft, XK_VoidSymbol}, "⌷"}, {{XK_Multi_key, XK_p, XK_exclam, XK_VoidSymbol}, "¶"}, // paragraph | PILCROW SIGN {{XK_Multi_key, XK_P, XK_exclam, XK_VoidSymbol}, "¶"}, {{XK_Multi_key, XK_P, XK_P, XK_VoidSymbol}, "¶"}, {{XK_dead_breve, XK_Cyrillic_i, XK_VoidSymbol}, "й"}, // U0439 | CYRILLIC SMALL LETTER SHORT I {{XK_Multi_key, XK_U, XK_Cyrillic_i, XK_VoidSymbol}, "й"}, {{XK_Multi_key, XK_b, XK_Cyrillic_i, XK_VoidSymbol}, "й"}, {{XK_dead_diaeresis, XK_space, XK_VoidSymbol}, "\""}, // quotedbl | REVERSE SOLIDUS {{XK_dead_cedilla, XK_L, XK_VoidSymbol}, "Ļ"}, // U013B | LATIN CAPITAL LETTER L WITH CEDILLA {{XK_Multi_key, XK_comma, XK_L, XK_VoidSymbol}, "Ļ"}, {{XK_Multi_key, XK_L, XK_comma, XK_VoidSymbol}, "Ļ"}, {{XK_Multi_key, XK_cedilla, XK_L, XK_VoidSymbol}, "Ļ"}, {{XK_dead_hook, XK_E, XK_VoidSymbol}, "Ẻ"}, // U1EBA | LATIN CAPITAL LETTER E WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_E, XK_VoidSymbol}, "Ẻ"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἷ"}, // U1F3F | GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἷ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἷ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἷ"}, {{XK_Multi_key, XK_parenleft, XK_I, XK_parenright, XK_VoidSymbol}, "Ⓘ"}, // U24BE | CIRCLED LATIN CAPITAL LETTER I {{XK_dead_hook, XK_W, XK_VoidSymbol}, "Ⱳ"}, // U2C72 | LATIN CAPITAL LETTER W WITH HOOK {{XK_dead_abovedot, XK_n, XK_VoidSymbol}, "ṅ"}, // U1E45 | LATIN SMALL LETTER N WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_n, XK_VoidSymbol}, "ṅ"}, {{XK_dead_iota, XK_Greek_etaaccent, XK_VoidSymbol}, "ῄ"}, // U1FC4 | GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_etaaccent, XK_VoidSymbol}, "ῄ"}, {{XK_dead_iota, XK_dead_acute, XK_Greek_eta, XK_VoidSymbol}, "ῄ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_Greek_eta, XK_VoidSymbol}, "ῄ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_Greek_eta, XK_VoidSymbol}, "ῄ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_Greek_eta, XK_VoidSymbol}, "ῄ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_Greek_eta, XK_VoidSymbol}, "ῄ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_Greek_eta, XK_VoidSymbol}, "ῄ"}, {{XK_Multi_key, XK_A, XK_E, XK_VoidSymbol}, "Æ"}, // AE | LATIN CAPITAL LETTER AE {{XK_Multi_key, XK_3, XK_8, XK_VoidSymbol}, "⅜"}, // U215C | VULGAR FRACTION THREE EIGHTHS {{XK_Multi_key, XK_n, XK_g, XK_VoidSymbol}, "ŋ"}, // U014B | LATIN SMALL LETTER ENG {{XK_dead_belowdot, XK_I, XK_VoidSymbol}, "Ị"}, // U1ECA | LATIN CAPITAL LETTER I WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_I, XK_VoidSymbol}, "Ị"}, {{XK_dead_stroke, XK_r, XK_VoidSymbol}, "ɍ"}, // U024D | LATIN SMALL LETTER R WITH STROKE {{XK_dead_acute, XK_Greek_omicron, XK_VoidSymbol}, "ό"}, // U03CC | GREEK SMALL LETTER OMICRON WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_omicron, XK_VoidSymbol}, "ό"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_omicron, XK_VoidSymbol}, "ό"}, {{XK_Multi_key, XK_Greek_omicron, XK_apostrophe, XK_VoidSymbol}, "ό"}, {{XK_Multi_key, XK_parenleft, XK_Y, XK_parenright, XK_VoidSymbol}, "Ⓨ"}, // U24CE | CIRCLED LATIN CAPITAL LETTER Y {{XK_dead_caron, XK_i, XK_VoidSymbol}, "ǐ"}, // U01D0 | LATIN SMALL LETTER I WITH CARON {{XK_Multi_key, XK_c, XK_i, XK_VoidSymbol}, "ǐ"}, {{XK_Multi_key, XK_parenleft, XK_kana_U, XK_parenright, XK_VoidSymbol}, "㋒"}, // U32D2 | CIRCLED KATAKANA U {{XK_dead_acute, XK_p, XK_VoidSymbol}, "ṕ"}, // U1E55 | LATIN SMALL LETTER P WITH ACUTE {{XK_Multi_key, XK_acute, XK_p, XK_VoidSymbol}, "ṕ"}, {{XK_Multi_key, XK_apostrophe, XK_p, XK_VoidSymbol}, "ṕ"}, {{XK_dead_diaeresis, XK_O, XK_VoidSymbol}, "Ö"}, // Odiaeresis | LATIN CAPITAL LETTER O WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_O, XK_VoidSymbol}, "Ö"}, {{XK_Multi_key, XK_O, XK_quotedbl, XK_VoidSymbol}, "Ö"}, {{XK_Multi_key, XK_diaeresis, XK_O, XK_VoidSymbol}, "Ö"}, {{XK_Multi_key, XK_O, XK_diaeresis, XK_VoidSymbol}, "Ö"}, {{XK_dead_hook, XK_z, XK_VoidSymbol}, "ȥ"}, // U0225 | LATIN SMALL LETTER Z WITH HOOK {{XK_dead_acute, XK_s, XK_VoidSymbol}, "ś"}, // U015B | LATIN SMALL LETTER S WITH ACUTE {{XK_Multi_key, XK_acute, XK_s, XK_VoidSymbol}, "ś"}, {{XK_Multi_key, XK_apostrophe, XK_s, XK_VoidSymbol}, "ś"}, {{XK_Multi_key, XK_s, XK_apostrophe, XK_VoidSymbol}, "ś"}, {{XK_dead_acute, XK_Ohorn, XK_VoidSymbol}, "Ớ"}, // U1EDA | LATIN CAPITAL LETTER O WITH HORN AND ACUTE {{XK_Multi_key, XK_acute, XK_Ohorn, XK_VoidSymbol}, "Ớ"}, {{XK_Multi_key, XK_apostrophe, XK_Ohorn, XK_VoidSymbol}, "Ớ"}, {{XK_dead_acute, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ớ"}, {{XK_dead_acute, XK_Multi_key, XK_plus, XK_O, XK_VoidSymbol}, "Ớ"}, {{XK_Multi_key, XK_acute, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ớ"}, {{XK_Multi_key, XK_acute, XK_plus, XK_O, XK_VoidSymbol}, "Ớ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ớ"}, {{XK_Multi_key, XK_apostrophe, XK_plus, XK_O, XK_VoidSymbol}, "Ớ"}, {{XK_dead_horn, XK_Oacute, XK_VoidSymbol}, "Ớ"}, {{XK_dead_horn, XK_dead_acute, XK_O, XK_VoidSymbol}, "Ớ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_3, XK_parenright, XK_VoidSymbol}, "㉝"}, // U325D | CIRCLED NUMBER THIRTY THREE {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_3, XK_parenright, XK_VoidSymbol}, "㉝"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_3, XK_parenright, XK_VoidSymbol}, "㉝"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_3, XK_parenright, XK_VoidSymbol}, "㉝"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὗ"}, // U1F5F | GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὗ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὗ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὗ"}, {{XK_dead_diaeresis, XK_Cyrillic_ZE, XK_VoidSymbol}, "Ӟ"}, // U04DE | CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_ZE, XK_VoidSymbol}, "Ӟ"}, {{XK_Multi_key, XK_1, XK_8, XK_VoidSymbol}, "⅛"}, // U215B | VULGAR FRACTION ONE EIGHTH {{XK_dead_macron, XK_dead_abovedot, XK_A, XK_VoidSymbol}, "Ǡ"}, // U01E0 | LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON {{XK_dead_macron, XK_Multi_key, XK_period, XK_A, XK_VoidSymbol}, "Ǡ"}, {{XK_Multi_key, XK_macron, XK_dead_abovedot, XK_A, XK_VoidSymbol}, "Ǡ"}, {{XK_Multi_key, XK_macron, XK_period, XK_A, XK_VoidSymbol}, "Ǡ"}, {{XK_Multi_key, XK_underscore, XK_dead_abovedot, XK_A, XK_VoidSymbol}, "Ǡ"}, {{XK_Multi_key, XK_underscore, XK_period, XK_A, XK_VoidSymbol}, "Ǡ"}, {{XK_dead_abovedot, XK_Amacron, XK_VoidSymbol}, "Ǡ"}, {{XK_dead_abovedot, XK_dead_macron, XK_A, XK_VoidSymbol}, "Ǡ"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_s, XK_VoidSymbol}, "ˢ"}, // U02E2 | MODIFIER LETTER SMALL S {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_s, XK_VoidSymbol}, "ˢ"}, {{XK_Multi_key, XK_less, XK_3, XK_VoidSymbol}, "♥"}, // U2665 | BLACK HEART SUIT {{XK_dead_psili, XK_Greek_rho, XK_VoidSymbol}, "ῤ"}, // U1FE4 | GREEK SMALL LETTER RHO WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_rho, XK_VoidSymbol}, "ῤ"}, {{XK_Multi_key, XK_a, XK_e, XK_VoidSymbol}, "æ"}, // ae | LATIN SMALL LETTER AE {{XK_Multi_key, XK_parenleft, XK_1, XK_0, XK_parenright, XK_VoidSymbol}, "⑩"}, // U2469 | CIRCLED NUMBER TEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_0, XK_parenright, XK_VoidSymbol}, "⑩"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_0, XK_parenright, XK_VoidSymbol}, "⑩"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_0, XK_parenright, XK_VoidSymbol}, "⑩"}, {{XK_dead_acute, XK_Cyrillic_IE, XK_VoidSymbol}, "Е́"}, // CYRILLIC CAPITAL LETTER IE WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_IE, XK_VoidSymbol}, "Е́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_IE, XK_VoidSymbol}, "Е́"}, {{XK_dead_macron, XK_u, XK_VoidSymbol}, "ū"}, // U016B | LATIN SMALL LETTER U WITH MACRON {{XK_Multi_key, XK_macron, XK_u, XK_VoidSymbol}, "ū"}, {{XK_Multi_key, XK_underscore, XK_u, XK_VoidSymbol}, "ū"}, {{XK_Multi_key, XK_u, XK_underscore, XK_VoidSymbol}, "ū"}, {{XK_Multi_key, XK_minus, XK_u, XK_VoidSymbol}, "ū"}, {{XK_Multi_key, XK_u, XK_minus, XK_VoidSymbol}, "ū"}, {{XK_Multi_key, XK_exclam, XK_asciicircum, XK_VoidSymbol}, "¦"}, // brokenbar | BROKEN BAR {{XK_Multi_key, XK_parenleft, XK_d, XK_parenright, XK_VoidSymbol}, "ⓓ"}, // U24D3 | CIRCLED LATIN SMALL LETTER D {{XK_dead_tilde, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὧ"}, // U1F6F | GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὧ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὧ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὧ"}, {{XK_dead_macron, XK_Cyrillic_U, XK_VoidSymbol}, "Ӯ"}, // U04EE | CYRILLIC CAPITAL LETTER U WITH MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_U, XK_VoidSymbol}, "Ӯ"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_U, XK_VoidSymbol}, "Ӯ"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_i, XK_VoidSymbol}, "ⁱ"}, // U2071 | SUPERSCRIPT LATIN SMALL LETTER I {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_i, XK_VoidSymbol}, "ⁱ"}, {{XK_dead_caron, XK_j, XK_VoidSymbol}, "ǰ"}, // U01F0 | LATIN SMALL LETTER J WITH CARON {{XK_Multi_key, XK_c, XK_j, XK_VoidSymbol}, "ǰ"}, {{XK_Multi_key, XK_parenleft, XK_kana_MO, XK_parenright, XK_VoidSymbol}, "㋲"}, // U32F2 | CIRCLED KATAKANA MO {{XK_dead_belowtilde, XK_u, XK_VoidSymbol}, "ṵ"}, // U1E75 | LATIN SMALL LETTER U WITH TILDE BELOW {{XK_dead_iota, XK_Greek_omegaaccent, XK_VoidSymbol}, "ῴ"}, // U1FF4 | GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_omegaaccent, XK_VoidSymbol}, "ῴ"}, {{XK_dead_iota, XK_dead_acute, XK_Greek_omega, XK_VoidSymbol}, "ῴ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_Greek_omega, XK_VoidSymbol}, "ῴ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_Greek_omega, XK_VoidSymbol}, "ῴ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_Greek_omega, XK_VoidSymbol}, "ῴ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_Greek_omega, XK_VoidSymbol}, "ῴ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_Greek_omega, XK_VoidSymbol}, "ῴ"}, {{XK_dead_diaeresis, XK_o, XK_VoidSymbol}, "ö"}, // odiaeresis | LATIN SMALL LETTER O WITH DIAERESIS {{XK_Multi_key, XK_o, XK_diaeresis, XK_VoidSymbol}, "ö"}, {{XK_Multi_key, XK_diaeresis, XK_o, XK_VoidSymbol}, "ö"}, {{XK_Multi_key, XK_quotedbl, XK_o, XK_VoidSymbol}, "ö"}, {{XK_Multi_key, XK_o, XK_quotedbl, XK_VoidSymbol}, "ö"}, {{XK_dead_invertedbreve, XK_Cyrillic_A, XK_VoidSymbol}, "А̑"}, // CYRILLIC CAPITAL LETTER A WITH COMBINING INVERTED BREVE {{XK_dead_abovedot, XK_Z, XK_VoidSymbol}, "Ż"}, // U017B | LATIN CAPITAL LETTER Z WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_Z, XK_VoidSymbol}, "Ż"}, {{XK_Multi_key, XK_Z, XK_period, XK_VoidSymbol}, "Ż"}, {{XK_dead_acute, XK_w, XK_VoidSymbol}, "ẃ"}, // U1E83 | LATIN SMALL LETTER W WITH ACUTE {{XK_Multi_key, XK_acute, XK_w, XK_VoidSymbol}, "ẃ"}, {{XK_Multi_key, XK_apostrophe, XK_w, XK_VoidSymbol}, "ẃ"}, {{XK_dead_breve, XK_A, XK_VoidSymbol}, "Ă"}, // U0102 | LATIN CAPITAL LETTER A WITH BREVE {{XK_Multi_key, XK_U, XK_A, XK_VoidSymbol}, "Ă"}, {{XK_Multi_key, XK_b, XK_A, XK_VoidSymbol}, "Ă"}, {{XK_Multi_key, XK_A, XK_parenleft, XK_VoidSymbol}, "Ă"}, {{XK_dead_doublegrave, XK_Cyrillic_u, XK_VoidSymbol}, "у̏"}, // CYRILLIC SMALL LETTER U WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_u, XK_VoidSymbol}, "у̏"}, {{XK_Multi_key, XK_underscore, XK_7, XK_VoidSymbol}, "₇"}, // U2087 | SUBSCRIPT SEVEN {{XK_Multi_key, XK_underscore, XK_KP_7, XK_VoidSymbol}, "₇"}, {{XK_dead_caron, XK_7, XK_VoidSymbol}, "₇"}, {{XK_Multi_key, XK_d, XK_i, XK_VoidSymbol}, "⌀"}, // U2300 | DIAMETER SIGN {{XK_dead_iota, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾉ"}, // U1F89 | GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾉ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾉ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾉ"}, {{XK_dead_acute, XK_Ccedilla, XK_VoidSymbol}, "Ḉ"}, // U1E08 | LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE {{XK_Multi_key, XK_acute, XK_Ccedilla, XK_VoidSymbol}, "Ḉ"}, {{XK_Multi_key, XK_apostrophe, XK_Ccedilla, XK_VoidSymbol}, "Ḉ"}, {{XK_dead_acute, XK_dead_cedilla, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_dead_acute, XK_Multi_key, XK_comma, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_dead_acute, XK_Multi_key, XK_cedilla, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_Multi_key, XK_acute, XK_dead_cedilla, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_Multi_key, XK_acute, XK_comma, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_Multi_key, XK_acute, XK_cedilla, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_cedilla, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_Multi_key, XK_apostrophe, XK_cedilla, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_dead_cedilla, XK_Cacute, XK_VoidSymbol}, "Ḉ"}, {{XK_dead_cedilla, XK_dead_acute, XK_C, XK_VoidSymbol}, "Ḉ"}, {{XK_dead_hook, XK_v, XK_VoidSymbol}, "ʋ"}, // U028B | LATIN SMALL LETTER V WITH HOOK {{XK_Multi_key, XK_2, XK_5, XK_VoidSymbol}, "⅖"}, // U2156 | VULGAR FRACTION TWO FIFTHS {{XK_dead_tilde, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἆ"}, // U1F0E | GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἆ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἆ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἆ"}, {{XK_dead_belowdot, XK_z, XK_VoidSymbol}, "ẓ"}, // U1E93 | LATIN SMALL LETTER Z WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_z, XK_VoidSymbol}, "ẓ"}, {{XK_dead_macron, XK_E, XK_VoidSymbol}, "Ē"}, // U0112 | LATIN CAPITAL LETTER E WITH MACRON {{XK_Multi_key, XK_macron, XK_E, XK_VoidSymbol}, "Ē"}, {{XK_Multi_key, XK_underscore, XK_E, XK_VoidSymbol}, "Ē"}, {{XK_Multi_key, XK_E, XK_underscore, XK_VoidSymbol}, "Ē"}, {{XK_Multi_key, XK_minus, XK_E, XK_VoidSymbol}, "Ē"}, {{XK_Multi_key, XK_E, XK_minus, XK_VoidSymbol}, "Ē"}, {{XK_dead_currency, XK_f, XK_VoidSymbol}, "ƒ"}, // function | LATIN SMALL LETTER F WITH HOOK {{XK_dead_hook, XK_f, XK_VoidSymbol}, "ƒ"}, {{XK_dead_iota, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾙ"}, // U1F99 | GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾙ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾙ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾙ"}, {{XK_Multi_key, XK_question, XK_exclam, XK_VoidSymbol}, "⸘"}, // U2E18 | INVERTED INTERROBANG {{XK_dead_invertedbreve, XK_Cyrillic_u, XK_VoidSymbol}, "у̑"}, // CYRILLIC SMALL LETTER U WITH COMBINING INVERTED BREVE {{XK_dead_belowtilde, XK_i, XK_VoidSymbol}, "ḭ"}, // U1E2D | LATIN SMALL LETTER I WITH TILDE BELOW {{XK_Multi_key, XK_1, XK_7, XK_VoidSymbol}, "⅐"}, // U2150 | VULGAR FRACTION ONE SEVENTH {{XK_Multi_key, XK_less, XK_quotedbl, XK_VoidSymbol}, "“"}, // U201c | LEFT DOUBLE QUOTATION MARK {{XK_Multi_key, XK_quotedbl, XK_less, XK_VoidSymbol}, "“"}, {{XK_Multi_key, XK_slash, XK_Cyrillic_ka, XK_VoidSymbol}, "ҟ"}, // U049F | CYRILLIC SMALL LETTER KA WITH STROKE {{XK_Multi_key, XK_KP_Divide, XK_Cyrillic_ka, XK_VoidSymbol}, "ҟ"}, {{XK_dead_hook, XK_a, XK_VoidSymbol}, "ả"}, // U1EA3 | LATIN SMALL LETTER A WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_a, XK_VoidSymbol}, "ả"}, {{XK_dead_cedilla, XK_G, XK_VoidSymbol}, "Ģ"}, // U0122 | LATIN CAPITAL LETTER G WITH CEDILLA {{XK_Multi_key, XK_comma, XK_G, XK_VoidSymbol}, "Ģ"}, {{XK_Multi_key, XK_G, XK_comma, XK_VoidSymbol}, "Ģ"}, {{XK_Multi_key, XK_cedilla, XK_G, XK_VoidSymbol}, "Ģ"}, {{XK_Multi_key, XK_P, XK_t, XK_VoidSymbol}, "₧"}, // U20a7 | PESETA SIGN {{XK_dead_currency, XK_P, XK_VoidSymbol}, "₧"}, {{XK_dead_belowcomma, XK_nobreakspace, XK_VoidSymbol}, "̦"}, // U0326 | COMBINING COMMA BELOW {{XK_dead_iota, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾩ"}, // U1FA9 | GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾩ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾩ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾩ"}, {{XK_dead_cedilla, XK_H, XK_VoidSymbol}, "Ḩ"}, // U1E28 | LATIN CAPITAL LETTER H WITH CEDILLA {{XK_Multi_key, XK_comma, XK_H, XK_VoidSymbol}, "Ḩ"}, {{XK_Multi_key, XK_H, XK_comma, XK_VoidSymbol}, "Ḩ"}, {{XK_Multi_key, XK_cedilla, XK_H, XK_VoidSymbol}, "Ḩ"}, {{XK_dead_currency, XK_G, XK_VoidSymbol}, "₲"}, // U20B2 | GUARANI SIGN {{XK_dead_currency, XK_g, XK_VoidSymbol}, "₲"}, {{XK_dead_belowcomma, XK_dead_belowcomma, XK_VoidSymbol}, ","}, // comma | COMMA {{XK_dead_belowcomma, XK_space, XK_VoidSymbol}, ","}, {{XK_dead_tilde, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἦ"}, // U1F2E | GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἦ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἦ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἦ"}, {{XK_dead_hook, XK_b, XK_VoidSymbol}, "ɓ"}, // U0253 | LATIN SMALL LETTER B WITH HOOK {{XK_dead_macron, XK_dead_abovedot, XK_O, XK_VoidSymbol}, "Ȱ"}, // U0230 | LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON {{XK_dead_macron, XK_Multi_key, XK_period, XK_O, XK_VoidSymbol}, "Ȱ"}, {{XK_Multi_key, XK_macron, XK_dead_abovedot, XK_O, XK_VoidSymbol}, "Ȱ"}, {{XK_Multi_key, XK_macron, XK_period, XK_O, XK_VoidSymbol}, "Ȱ"}, {{XK_Multi_key, XK_underscore, XK_dead_abovedot, XK_O, XK_VoidSymbol}, "Ȱ"}, {{XK_Multi_key, XK_underscore, XK_period, XK_O, XK_VoidSymbol}, "Ȱ"}, {{XK_dead_abovedot, XK_Omacron, XK_VoidSymbol}, "Ȱ"}, {{XK_dead_abovedot, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ȱ"}, {{XK_dead_hook, XK_abreve, XK_VoidSymbol}, "ẳ"}, // U1EB3 | LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_abreve, XK_VoidSymbol}, "ẳ"}, {{XK_dead_hook, XK_dead_breve, XK_a, XK_VoidSymbol}, "ẳ"}, {{XK_dead_hook, XK_Multi_key, XK_U, XK_a, XK_VoidSymbol}, "ẳ"}, {{XK_dead_hook, XK_Multi_key, XK_b, XK_a, XK_VoidSymbol}, "ẳ"}, {{XK_Multi_key, XK_question, XK_dead_breve, XK_a, XK_VoidSymbol}, "ẳ"}, {{XK_Multi_key, XK_question, XK_b, XK_a, XK_VoidSymbol}, "ẳ"}, {{XK_dead_breve, XK_ahook, XK_VoidSymbol}, "ẳ"}, {{XK_dead_breve, XK_dead_hook, XK_a, XK_VoidSymbol}, "ẳ"}, {{XK_Multi_key, XK_I, XK_J, XK_VoidSymbol}, "IJ"}, // U0132 | LATIN CAPITAL LIGATURE IJ {{XK_Multi_key, XK_I, XK_j, XK_VoidSymbol}, "IJ"}, {{XK_dead_voiced_sound, XK_kana_KI, XK_VoidSymbol}, "ギ"}, // U30AE | KATAKANA LETTER GI {{XK_Multi_key, XK_period, XK_minus, XK_VoidSymbol}, "·"}, // periodcentered | MIDDLE DOT {{XK_Multi_key, XK_period, XK_asciicircum, XK_VoidSymbol}, "·"}, {{XK_Multi_key, XK_asciicircum, XK_period, XK_VoidSymbol}, "·"}, {{XK_dead_macron, XK_Greek_ALPHA, XK_VoidSymbol}, "Ᾱ"}, // U1FB9 | GREEK CAPITAL LETTER ALPHA WITH MACRON {{XK_Multi_key, XK_macron, XK_Greek_ALPHA, XK_VoidSymbol}, "Ᾱ"}, {{XK_Multi_key, XK_underscore, XK_Greek_ALPHA, XK_VoidSymbol}, "Ᾱ"}, {{XK_dead_macron, XK_dead_belowdot, XK_L, XK_VoidSymbol}, "Ḹ"}, // U1E38 | LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON {{XK_dead_macron, XK_Multi_key, XK_exclam, XK_L, XK_VoidSymbol}, "Ḹ"}, {{XK_Multi_key, XK_macron, XK_dead_belowdot, XK_L, XK_VoidSymbol}, "Ḹ"}, {{XK_Multi_key, XK_macron, XK_exclam, XK_L, XK_VoidSymbol}, "Ḹ"}, {{XK_Multi_key, XK_underscore, XK_dead_belowdot, XK_L, XK_VoidSymbol}, "Ḹ"}, {{XK_Multi_key, XK_underscore, XK_exclam, XK_L, XK_VoidSymbol}, "Ḹ"}, {{XK_dead_belowdot, XK_dead_macron, XK_L, XK_VoidSymbol}, "Ḹ"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_6, XK_parenright, XK_VoidSymbol}, "㊻"}, // U32BB | CIRCLED NUMBER FORTY SIX {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_6, XK_parenright, XK_VoidSymbol}, "㊻"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_6, XK_parenright, XK_VoidSymbol}, "㊻"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_6, XK_parenright, XK_VoidSymbol}, "㊻"}, {{XK_Multi_key, XK_7, XK_8, XK_VoidSymbol}, "⅞"}, // U215E | VULGAR FRACTION SEVEN EIGHTHS {{XK_Multi_key, XK_parenleft, XK_J, XK_parenright, XK_VoidSymbol}, "Ⓙ"}, // U24BF | CIRCLED LATIN CAPITAL LETTER J {{XK_dead_tilde, XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἶ"}, // U1F3E | GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἶ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἶ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἶ"}, {{XK_dead_hook, XK_ecircumflex, XK_VoidSymbol}, "ể"}, // U1EC3 | LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_ecircumflex, XK_VoidSymbol}, "ể"}, {{XK_dead_hook, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ể"}, {{XK_dead_hook, XK_Multi_key, XK_asciicircum, XK_e, XK_VoidSymbol}, "ể"}, {{XK_Multi_key, XK_question, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ể"}, {{XK_Multi_key, XK_question, XK_asciicircum, XK_e, XK_VoidSymbol}, "ể"}, {{XK_dead_circumflex, XK_ehook, XK_VoidSymbol}, "ể"}, {{XK_dead_circumflex, XK_dead_hook, XK_e, XK_VoidSymbol}, "ể"}, {{XK_dead_stroke, XK_l, XK_VoidSymbol}, "ł"}, // U0142 | LATIN SMALL LETTER L WITH STROKE {{XK_Multi_key, XK_slash, XK_l, XK_VoidSymbol}, "ł"}, {{XK_Multi_key, XK_l, XK_slash, XK_VoidSymbol}, "ł"}, {{XK_Multi_key, XK_KP_Divide, XK_l, XK_VoidSymbol}, "ł"}, {{XK_dead_cedilla, XK_C, XK_VoidSymbol}, "Ç"}, // Ccedilla | LATIN CAPITAL LETTER C WITH CEDILLA {{XK_Multi_key, XK_comma, XK_C, XK_VoidSymbol}, "Ç"}, {{XK_Multi_key, XK_C, XK_comma, XK_VoidSymbol}, "Ç"}, {{XK_Multi_key, XK_cedilla, XK_C, XK_VoidSymbol}, "Ç"}, {{XK_dead_belowmacron, XK_N, XK_VoidSymbol}, "Ṉ"}, // U1E48 | LATIN CAPITAL LETTER N WITH LINE BELOW {{XK_dead_voiced_sound, XK_kana_SA, XK_VoidSymbol}, "ザ"}, // U30B6 | KATAKANA LETTER ZA {{XK_dead_caron, XK_A, XK_VoidSymbol}, "Ǎ"}, // U01CD | LATIN CAPITAL LETTER A WITH CARON {{XK_Multi_key, XK_c, XK_A, XK_VoidSymbol}, "Ǎ"}, {{XK_Multi_key, XK_parenleft, XK_t, XK_parenright, XK_VoidSymbol}, "ⓣ"}, // U24E3 | CIRCLED LATIN SMALL LETTER T {{XK_Multi_key, XK_parenleft, XK_Z, XK_parenright, XK_VoidSymbol}, "Ⓩ"}, // U24CF | CIRCLED LATIN CAPITAL LETTER Z {{XK_dead_grave, XK_ocircumflex, XK_VoidSymbol}, "ồ"}, // U1ED3 | LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE {{XK_Multi_key, XK_grave, XK_ocircumflex, XK_VoidSymbol}, "ồ"}, {{XK_dead_grave, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ồ"}, {{XK_dead_grave, XK_Multi_key, XK_asciicircum, XK_o, XK_VoidSymbol}, "ồ"}, {{XK_Multi_key, XK_grave, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ồ"}, {{XK_Multi_key, XK_grave, XK_asciicircum, XK_o, XK_VoidSymbol}, "ồ"}, {{XK_dead_circumflex, XK_ograve, XK_VoidSymbol}, "ồ"}, {{XK_dead_circumflex, XK_dead_grave, XK_o, XK_VoidSymbol}, "ồ"}, {{XK_Multi_key, XK_O, XK_E, XK_VoidSymbol}, "Œ"}, // OE | LATIN CAPITAL LIGATURE OE {{XK_Multi_key, XK_x, XK_x, XK_VoidSymbol}, "×"}, // multiply | MULTIPLICATION SIGN {{XK_dead_macron, XK_Greek_IOTA, XK_VoidSymbol}, "Ῑ"}, // U1FD9 | GREEK CAPITAL LETTER IOTA WITH MACRON {{XK_Multi_key, XK_macron, XK_Greek_IOTA, XK_VoidSymbol}, "Ῑ"}, {{XK_Multi_key, XK_underscore, XK_Greek_IOTA, XK_VoidSymbol}, "Ῑ"}, {{XK_dead_abovedot, XK_R, XK_VoidSymbol}, "Ṙ"}, // U1E58 | LATIN CAPITAL LETTER R WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_R, XK_VoidSymbol}, "Ṙ"}, {{XK_dead_ogonek, XK_space, XK_VoidSymbol}, "˛"}, // ogonek | OGONEK {{XK_dead_ogonek, XK_dead_ogonek, XK_VoidSymbol}, "˛"}, {{XK_Multi_key, XK_slash, XK_slash, XK_VoidSymbol}, "\\"}, // backslash | REVERSE SOLIDUS {{XK_Multi_key, XK_slash, XK_less, XK_VoidSymbol}, "\\"}, {{XK_Multi_key, XK_less, XK_slash, XK_VoidSymbol}, "\\"}, {{XK_dead_diaeresis, XK_Cyrillic_ze, XK_VoidSymbol}, "ӟ"}, // U04DF | CYRILLIC SMALL LETTER ZE WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_ze, XK_VoidSymbol}, "ӟ"}, {{XK_dead_voiced_sound, XK_kana_TO, XK_VoidSymbol}, "ド"}, // U30C9 | KATAKANA LETTER DO {{XK_Multi_key, XK_slash, XK_equal, XK_VoidSymbol}, "≠"}, // U2260 | NOT EQUAL TO {{XK_Multi_key, XK_equal, XK_slash, XK_VoidSymbol}, "≠"}, {{XK_dead_stroke, XK_equal, XK_VoidSymbol}, "≠"}, {{XK_dead_belowdot, XK_ohorn, XK_VoidSymbol}, "ợ"}, // U1EE3 | LATIN SMALL LETTER O WITH HORN AND DOT BELOW {{XK_Multi_key, XK_exclam, XK_ohorn, XK_VoidSymbol}, "ợ"}, {{XK_dead_belowdot, XK_dead_horn, XK_o, XK_VoidSymbol}, "ợ"}, {{XK_dead_belowdot, XK_Multi_key, XK_plus, XK_o, XK_VoidSymbol}, "ợ"}, {{XK_Multi_key, XK_exclam, XK_dead_horn, XK_o, XK_VoidSymbol}, "ợ"}, {{XK_Multi_key, XK_exclam, XK_plus, XK_o, XK_VoidSymbol}, "ợ"}, {{XK_dead_horn, XK_obelowdot, XK_VoidSymbol}, "ợ"}, {{XK_dead_horn, XK_dead_belowdot, XK_o, XK_VoidSymbol}, "ợ"}, {{XK_dead_cedilla, XK_T, XK_VoidSymbol}, "Ţ"}, // U0162 | LATIN CAPITAL LETTER T WITH CEDILLA {{XK_Multi_key, XK_comma, XK_T, XK_VoidSymbol}, "Ţ"}, {{XK_Multi_key, XK_T, XK_comma, XK_VoidSymbol}, "Ţ"}, {{XK_Multi_key, XK_cedilla, XK_T, XK_VoidSymbol}, "Ţ"}, {{XK_Multi_key, XK_parenleft, XK_5, XK_parenright, XK_VoidSymbol}, "⑤"}, // U2464 | CIRCLED DIGIT FIVE {{XK_Multi_key, XK_parenleft, XK_KP_5, XK_parenright, XK_VoidSymbol}, "⑤"}, {{XK_dead_cedilla, XK_c, XK_VoidSymbol}, "ç"}, // ccedilla | LATIN SMALL LETTER C WITH CEDILLA {{XK_Multi_key, XK_comma, XK_c, XK_VoidSymbol}, "ç"}, {{XK_Multi_key, XK_c, XK_comma, XK_VoidSymbol}, "ç"}, {{XK_Multi_key, XK_cedilla, XK_c, XK_VoidSymbol}, "ç"}, {{XK_dead_macron, XK_Greek_UPSILON, XK_VoidSymbol}, "Ῡ"}, // U1FE9 | GREEK CAPITAL LETTER UPSILON WITH MACRON {{XK_Multi_key, XK_macron, XK_Greek_UPSILON, XK_VoidSymbol}, "Ῡ"}, {{XK_Multi_key, XK_underscore, XK_Greek_UPSILON, XK_VoidSymbol}, "Ῡ"}, {{XK_dead_abovedot, XK_dead_belowdot, XK_S, XK_VoidSymbol}, "Ṩ"}, // U1E68 | LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE {{XK_dead_abovedot, XK_Multi_key, XK_exclam, XK_S, XK_VoidSymbol}, "Ṩ"}, {{XK_Multi_key, XK_period, XK_dead_belowdot, XK_S, XK_VoidSymbol}, "Ṩ"}, {{XK_Multi_key, XK_period, XK_exclam, XK_S, XK_VoidSymbol}, "Ṩ"}, {{XK_dead_belowdot, XK_Sabovedot, XK_VoidSymbol}, "Ṩ"}, {{XK_dead_belowdot, XK_dead_abovedot, XK_S, XK_VoidSymbol}, "Ṩ"}, {{XK_Multi_key, XK_parenleft, XK_kana_FU, XK_parenright, XK_VoidSymbol}, "㋫"}, // U32EB | CIRCLED KATAKANA HU {{XK_dead_macron, XK_dead_ogonek, XK_o, XK_VoidSymbol}, "ǭ"}, // U01ED | LATIN SMALL LETTER O WITH OGONEK AND MACRON {{XK_dead_macron, XK_Multi_key, XK_semicolon, XK_o, XK_VoidSymbol}, "ǭ"}, {{XK_Multi_key, XK_macron, XK_dead_ogonek, XK_o, XK_VoidSymbol}, "ǭ"}, {{XK_Multi_key, XK_macron, XK_semicolon, XK_o, XK_VoidSymbol}, "ǭ"}, {{XK_Multi_key, XK_underscore, XK_dead_ogonek, XK_o, XK_VoidSymbol}, "ǭ"}, {{XK_Multi_key, XK_underscore, XK_semicolon, XK_o, XK_VoidSymbol}, "ǭ"}, {{XK_dead_ogonek, XK_omacron, XK_VoidSymbol}, "ǭ"}, {{XK_dead_ogonek, XK_dead_macron, XK_o, XK_VoidSymbol}, "ǭ"}, {{XK_dead_macron, XK_Cyrillic_u, XK_VoidSymbol}, "ӯ"}, // U04EF | CYRILLIC SMALL LETTER U WITH MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_u, XK_VoidSymbol}, "ӯ"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_u, XK_VoidSymbol}, "ӯ"}, {{XK_dead_tilde, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὦ"}, // U1F6E | GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὦ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὦ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὦ"}, {{XK_dead_grave, XK_y, XK_VoidSymbol}, "ỳ"}, // U1EF3 | LATIN SMALL LETTER Y WITH GRAVE {{XK_Multi_key, XK_grave, XK_y, XK_VoidSymbol}, "ỳ"}, {{XK_dead_ogonek, XK_U, XK_VoidSymbol}, "Ų"}, // U0172 | LATIN CAPITAL LETTER U WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_U, XK_VoidSymbol}, "Ų"}, {{XK_Multi_key, XK_comma, XK_U, XK_VoidSymbol}, "Ų"}, {{XK_Multi_key, XK_U, XK_comma, XK_VoidSymbol}, "Ų"}, {{XK_Multi_key, XK_slash, XK_minus, XK_VoidSymbol}, "⌿"}, // U233f | / - APL FUNCTIONAL SYMBOL SLASH BAR {{XK_Multi_key, XK_minus, XK_slash, XK_VoidSymbol}, "⌿"}, {{XK_Multi_key, XK_colon, XK_minus, XK_VoidSymbol}, "÷"}, // division | DIVISION SIGN {{XK_Multi_key, XK_minus, XK_colon, XK_VoidSymbol}, "÷"}, {{XK_dead_acute, XK_Utilde, XK_VoidSymbol}, "Ṹ"}, // U1E78 | LATIN CAPITAL LETTER U WITH TILDE AND ACUTE {{XK_Multi_key, XK_acute, XK_Utilde, XK_VoidSymbol}, "Ṹ"}, {{XK_Multi_key, XK_apostrophe, XK_Utilde, XK_VoidSymbol}, "Ṹ"}, {{XK_dead_acute, XK_dead_tilde, XK_U, XK_VoidSymbol}, "Ṹ"}, {{XK_dead_acute, XK_Multi_key, XK_asciitilde, XK_U, XK_VoidSymbol}, "Ṹ"}, {{XK_Multi_key, XK_acute, XK_dead_tilde, XK_U, XK_VoidSymbol}, "Ṹ"}, {{XK_Multi_key, XK_acute, XK_asciitilde, XK_U, XK_VoidSymbol}, "Ṹ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_tilde, XK_U, XK_VoidSymbol}, "Ṹ"}, {{XK_Multi_key, XK_apostrophe, XK_asciitilde, XK_U, XK_VoidSymbol}, "Ṹ"}, {{XK_dead_tilde, XK_Uacute, XK_VoidSymbol}, "Ṹ"}, {{XK_dead_tilde, XK_dead_acute, XK_U, XK_VoidSymbol}, "Ṹ"}, {{XK_Multi_key, XK_parenleft, XK_kana_WA, XK_parenright, XK_VoidSymbol}, "㋻"}, // U32FB | CIRCLED KATAKANA WA {{XK_dead_voiced_sound, XK_kana_SO, XK_VoidSymbol}, "ゾ"}, // U30BE | KATAKANA LETTER ZO {{XK_dead_acute, XK_ae, XK_VoidSymbol}, "ǽ"}, // U01FD | LATIN SMALL LETTER AE WITH ACUTE {{XK_Multi_key, XK_acute, XK_ae, XK_VoidSymbol}, "ǽ"}, {{XK_Multi_key, XK_apostrophe, XK_ae, XK_VoidSymbol}, "ǽ"}, {{XK_Multi_key, XK_slash, XK_asciicircum, XK_VoidSymbol}, "|"}, // bar | VERTICAL LINE {{XK_Multi_key, XK_asciicircum, XK_slash, XK_VoidSymbol}, "|"}, {{XK_Multi_key, XK_V, XK_L, XK_VoidSymbol}, "|"}, {{XK_Multi_key, XK_L, XK_V, XK_VoidSymbol}, "|"}, {{XK_Multi_key, XK_v, XK_l, XK_VoidSymbol}, "|"}, {{XK_Multi_key, XK_l, XK_v, XK_VoidSymbol}, "|"}, {{XK_dead_invertedbreve, XK_Cyrillic_a, XK_VoidSymbol}, "а̑"}, // CYRILLIC SMALL LETTER A WITH COMBINING INVERTED BREVE {{XK_Multi_key, XK_f, XK_i, XK_VoidSymbol}, "fi"}, // Ufb01 | LATIN SMALL LIGATURE FI {{XK_dead_abovedot, XK_b, XK_VoidSymbol}, "ḃ"}, // U1E03 | LATIN SMALL LETTER B WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_b, XK_VoidSymbol}, "ḃ"}, {{XK_Multi_key, XK_b, XK_period, XK_VoidSymbol}, "ḃ"}, {{XK_dead_acute, XK_Greek_ALPHA, XK_VoidSymbol}, "Ά"}, // U0386 | GREEK CAPITAL LETTER ALPHA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_ALPHA, XK_VoidSymbol}, "Ά"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_ALPHA, XK_VoidSymbol}, "Ά"}, {{XK_Multi_key, XK_Greek_ALPHA, XK_apostrophe, XK_VoidSymbol}, "Ά"}, {{XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἁ"}, // U1F09 | GREEK CAPITAL LETTER ALPHA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἁ"}, {{XK_dead_belowdot, XK_W, XK_VoidSymbol}, "Ẉ"}, // U1E88 | LATIN CAPITAL LETTER W WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_W, XK_VoidSymbol}, "Ẉ"}, {{XK_dead_caron, XK_c, XK_VoidSymbol}, "č"}, // U010D | LATIN SMALL LETTER C WITH CARON {{XK_Multi_key, XK_c, XK_c, XK_VoidSymbol}, "č"}, {{XK_Multi_key, XK_less, XK_c, XK_VoidSymbol}, "č"}, {{XK_Multi_key, XK_c, XK_less, XK_VoidSymbol}, "č"}, {{XK_Multi_key, XK_underscore, XK_equal, XK_VoidSymbol}, "₌"}, // U208C | SUBSCRIPT EQUALS SIGN {{XK_Multi_key, XK_underscore, XK_KP_Equal, XK_VoidSymbol}, "₌"}, {{XK_dead_caron, XK_equal, XK_VoidSymbol}, "₌"}, {{XK_dead_belowdot, XK_T, XK_VoidSymbol}, "Ṭ"}, // U1E6C | LATIN CAPITAL LETTER T WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_T, XK_VoidSymbol}, "Ṭ"}, {{XK_Multi_key, XK_1, XK_3, XK_VoidSymbol}, "⅓"}, // U2153 | VULGAR FRACTION ONE THIRD {{XK_dead_belowcircumflex, XK_d, XK_VoidSymbol}, "ḓ"}, // U1E13 | LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW {{XK_Multi_key, XK_minus, XK_greater, XK_VoidSymbol}, "→"}, // U2192 | RIGHTWARDS ARROW {{XK_dead_dasia, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἑ"}, // U1F19 | GREEK CAPITAL LETTER EPSILON WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἑ"}, {{XK_dead_abovering, XK_w, XK_VoidSymbol}, "ẘ"}, // U1E98 | LATIN SMALL LETTER W WITH RING ABOVE {{XK_Multi_key, XK_o, XK_w, XK_VoidSymbol}, "ẘ"}, {{XK_dead_belowcomma, XK_t, XK_VoidSymbol}, "ț"}, // U021B | LATIN SMALL LETTER T WITH COMMA BELOW {{XK_dead_circumflex, XK_g, XK_VoidSymbol}, "ĝ"}, // U011D | LATIN SMALL LETTER G WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_g, XK_VoidSymbol}, "ĝ"}, {{XK_dead_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, // U1F9E | GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾞ"}, {{XK_dead_hook, XK_q, XK_VoidSymbol}, "ʠ"}, // U02A0 | LATIN SMALL LETTER Q WITH HOOK {{XK_dead_abovedot, XK_h, XK_VoidSymbol}, "ḣ"}, // U1E23 | LATIN SMALL LETTER H WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_h, XK_VoidSymbol}, "ḣ"}, {{XK_dead_acute, XK_space, XK_VoidSymbol}, "'"}, // apostrophe | APOSTROPHE {{XK_Multi_key, XK_apostrophe, XK_space, XK_VoidSymbol}, "'"}, {{XK_Multi_key, XK_space, XK_apostrophe, XK_VoidSymbol}, "'"}, {{XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἡ"}, // U1F29 | GREEK CAPITAL LETTER ETA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἡ"}, {{XK_dead_hook, XK_Acircumflex, XK_VoidSymbol}, "Ẩ"}, // U1EA8 | LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_Acircumflex, XK_VoidSymbol}, "Ẩ"}, {{XK_dead_hook, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ẩ"}, {{XK_dead_hook, XK_Multi_key, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ẩ"}, {{XK_Multi_key, XK_question, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ẩ"}, {{XK_Multi_key, XK_question, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ẩ"}, {{XK_dead_circumflex, XK_Ahook, XK_VoidSymbol}, "Ẩ"}, {{XK_dead_circumflex, XK_dead_hook, XK_A, XK_VoidSymbol}, "Ẩ"}, {{XK_dead_macron, XK_odiaeresis, XK_VoidSymbol}, "ȫ"}, // U022B | LATIN SMALL LETTER O WITH DIAERESIS AND MACRON {{XK_Multi_key, XK_macron, XK_odiaeresis, XK_VoidSymbol}, "ȫ"}, {{XK_Multi_key, XK_underscore, XK_odiaeresis, XK_VoidSymbol}, "ȫ"}, {{XK_dead_macron, XK_dead_diaeresis, XK_o, XK_VoidSymbol}, "ȫ"}, {{XK_dead_macron, XK_Multi_key, XK_quotedbl, XK_o, XK_VoidSymbol}, "ȫ"}, {{XK_Multi_key, XK_macron, XK_dead_diaeresis, XK_o, XK_VoidSymbol}, "ȫ"}, {{XK_Multi_key, XK_macron, XK_quotedbl, XK_o, XK_VoidSymbol}, "ȫ"}, {{XK_Multi_key, XK_underscore, XK_dead_diaeresis, XK_o, XK_VoidSymbol}, "ȫ"}, {{XK_Multi_key, XK_underscore, XK_quotedbl, XK_o, XK_VoidSymbol}, "ȫ"}, {{XK_dead_diaeresis, XK_omacron, XK_VoidSymbol}, "ȫ"}, {{XK_dead_diaeresis, XK_dead_macron, XK_o, XK_VoidSymbol}, "ȫ"}, {{XK_dead_breve, XK_i, XK_VoidSymbol}, "ĭ"}, // U012D | LATIN SMALL LETTER I WITH BREVE {{XK_Multi_key, XK_U, XK_i, XK_VoidSymbol}, "ĭ"}, {{XK_Multi_key, XK_b, XK_i, XK_VoidSymbol}, "ĭ"}, {{XK_Multi_key, XK_comma, XK_minus, XK_VoidSymbol}, "¬"}, // notsign | NOT SIGN {{XK_Multi_key, XK_minus, XK_comma, XK_VoidSymbol}, "¬"}, {{XK_dead_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, // U1FAE | GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾮ"}, {{XK_dead_semivoiced_sound, XK_kana_HA, XK_VoidSymbol}, "パ"}, // U30D1 | KATAKANA LETTER PA {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_h, XK_VoidSymbol}, "ʰ"}, // U02B0 | MODIFIER LETTER SMALL H {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_h, XK_VoidSymbol}, "ʰ"}, {{XK_dead_belowdot, XK_k, XK_VoidSymbol}, "ḳ"}, // U1E33 | LATIN SMALL LETTER K WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_k, XK_VoidSymbol}, "ḳ"}, {{XK_dead_hook, XK_V, XK_VoidSymbol}, "Ʋ"}, // U01B2 | LATIN CAPITAL LETTER V WITH HOOK {{XK_dead_doublegrave, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̏"}, // CYRILLIC CAPITAL LETTER IE WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̏"}, {{XK_dead_hook, XK_w, XK_VoidSymbol}, "ⱳ"}, // U2C73 | LATIN SMALL LETTER W WITH HOOK {{XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἱ"}, // U1F39 | GREEK CAPITAL LETTER IOTA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἱ"}, {{XK_dead_belowdot, XK_E, XK_VoidSymbol}, "Ẹ"}, // U1EB8 | LATIN CAPITAL LETTER E WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_E, XK_VoidSymbol}, "Ẹ"}, {{XK_dead_stroke, XK_C, XK_VoidSymbol}, "Ȼ"}, // U023B | LATIN CAPITAL LETTER C WITH STROKE {{XK_Multi_key, XK_8, XK_8, XK_VoidSymbol}, "∞"}, // U221e | 8 8 INFINITY {{XK_dead_caron, XK_L, XK_VoidSymbol}, "Ľ"}, // U013D | LATIN CAPITAL LETTER L WITH CARON {{XK_Multi_key, XK_c, XK_L, XK_VoidSymbol}, "Ľ"}, {{XK_Multi_key, XK_less, XK_L, XK_VoidSymbol}, "Ľ"}, {{XK_Multi_key, XK_L, XK_less, XK_VoidSymbol}, "Ľ"}, {{XK_Multi_key, XK_1, XK_4, XK_VoidSymbol}, "¼"}, // onequarter | VULGAR FRACTION ONE QUARTER {{XK_dead_semivoiced_sound, XK_kana_HO, XK_VoidSymbol}, "ポ"}, // U30DD | KATAKANA LETTER PO {{XK_dead_belowdot, XK_m, XK_VoidSymbol}, "ṃ"}, // U1E43 | LATIN SMALL LETTER M WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_m, XK_VoidSymbol}, "ṃ"}, {{XK_Multi_key, XK_parenleft, XK_O, XK_parenright, XK_VoidSymbol}, "Ⓞ"}, // U24C4 | CIRCLED LATIN CAPITAL LETTER O {{XK_dead_dasia, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὁ"}, // U1F49 | GREEK CAPITAL LETTER OMICRON WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὁ"}, {{XK_dead_hook, XK_I, XK_VoidSymbol}, "Ỉ"}, // U1EC8 | LATIN CAPITAL LETTER I WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_I, XK_VoidSymbol}, "Ỉ"}, {{XK_dead_macron, XK_o, XK_VoidSymbol}, "ō"}, // U014D | LATIN SMALL LETTER O WITH MACRON {{XK_Multi_key, XK_macron, XK_o, XK_VoidSymbol}, "ō"}, {{XK_Multi_key, XK_underscore, XK_o, XK_VoidSymbol}, "ō"}, {{XK_Multi_key, XK_o, XK_underscore, XK_VoidSymbol}, "ō"}, {{XK_Multi_key, XK_minus, XK_o, XK_VoidSymbol}, "ō"}, {{XK_Multi_key, XK_o, XK_minus, XK_VoidSymbol}, "ō"}, {{XK_dead_grave, XK_I, XK_VoidSymbol}, "Ì"}, // Igrave | LATIN CAPITAL LETTER I WITH GRAVE {{XK_Multi_key, XK_grave, XK_I, XK_VoidSymbol}, "Ì"}, {{XK_Multi_key, XK_I, XK_grave, XK_VoidSymbol}, "Ì"}, {{XK_Multi_key, XK_parenleft, XK_kana_A, XK_parenright, XK_VoidSymbol}, "㋐"}, // U32D0 | CIRCLED KATAKANA A {{XK_dead_acute, XK_omacron, XK_VoidSymbol}, "ṓ"}, // U1E53 | LATIN SMALL LETTER O WITH MACRON AND ACUTE {{XK_Multi_key, XK_acute, XK_omacron, XK_VoidSymbol}, "ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_omacron, XK_VoidSymbol}, "ṓ"}, {{XK_dead_acute, XK_dead_macron, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_dead_acute, XK_Multi_key, XK_macron, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_dead_acute, XK_Multi_key, XK_underscore, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_Multi_key, XK_acute, XK_dead_macron, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_Multi_key, XK_acute, XK_macron, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_Multi_key, XK_acute, XK_underscore, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_macron, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_macron, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_underscore, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_dead_macron, XK_oacute, XK_VoidSymbol}, "ṓ"}, {{XK_dead_macron, XK_dead_acute, XK_o, XK_VoidSymbol}, "ṓ"}, {{XK_dead_caron, XK_o, XK_VoidSymbol}, "ǒ"}, // U01D2 | LATIN SMALL LETTER O WITH CARON {{XK_Multi_key, XK_c, XK_o, XK_VoidSymbol}, "ǒ"}, {{XK_Multi_key, XK_1, XK_5, XK_VoidSymbol}, "⅕"}, // U2155 | VULGAR FRACTION ONE FIFTH {{XK_Multi_key, XK_parenleft, XK_e, XK_parenright, XK_VoidSymbol}, "ⓔ"}, // U24D4 | CIRCLED LATIN SMALL LETTER E {{XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὑ"}, // U1F59 | GREEK CAPITAL LETTER UPSILON WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὑ"}, {{XK_Multi_key, XK_m, XK_slash, XK_VoidSymbol}, "₥"}, // U20a5 | MILL SIGN {{XK_Multi_key, XK_slash, XK_m, XK_VoidSymbol}, "₥"}, {{XK_dead_currency, XK_m, XK_VoidSymbol}, "₥"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_1, XK_parenright, XK_VoidSymbol}, "㉛"}, // U325B | CIRCLED NUMBER THIRTY ONE {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_1, XK_parenright, XK_VoidSymbol}, "㉛"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_1, XK_parenright, XK_VoidSymbol}, "㉛"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_1, XK_parenright, XK_VoidSymbol}, "㉛"}, {{XK_dead_circumflex, XK_s, XK_VoidSymbol}, "ŝ"}, // U015D | LATIN SMALL LETTER S WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_s, XK_VoidSymbol}, "ŝ"}, {{XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ü"}, // Udiaeresis | LATIN CAPITAL LETTER U WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ü"}, {{XK_Multi_key, XK_U, XK_quotedbl, XK_VoidSymbol}, "Ü"}, {{XK_Multi_key, XK_diaeresis, XK_U, XK_VoidSymbol}, "Ü"}, {{XK_Multi_key, XK_U, XK_diaeresis, XK_VoidSymbol}, "Ü"}, {{XK_Multi_key, XK_parenleft, XK_kana_CHI, XK_parenright, XK_VoidSymbol}, "㋠"}, // U32E0 | CIRCLED KATAKANA TI {{XK_dead_belowdot, XK_s, XK_VoidSymbol}, "ṣ"}, // U1E63 | LATIN SMALL LETTER S WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_s, XK_VoidSymbol}, "ṣ"}, {{XK_dead_macron, XK_AE, XK_VoidSymbol}, "Ǣ"}, // U01E2 | LATIN CAPITAL LETTER AE WITH MACRON {{XK_Multi_key, XK_macron, XK_AE, XK_VoidSymbol}, "Ǣ"}, {{XK_Multi_key, XK_underscore, XK_AE, XK_VoidSymbol}, "Ǣ"}, {{XK_dead_circumflex, XK_Cyrillic_u, XK_VoidSymbol}, "у̂"}, // CYRILLIC SMALL LETTER U WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_u, XK_VoidSymbol}, "у̂"}, {{XK_dead_diaeresis, XK_Cyrillic_I, XK_VoidSymbol}, "Ӥ"}, // U04E4 | CYRILLIC CAPITAL LETTER I WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_I, XK_VoidSymbol}, "Ӥ"}, {{XK_dead_invertedbreve, XK_Cyrillic_er, XK_VoidSymbol}, "р̑"}, // CYRILLIC SMALL LETTER ER WITH COMBINING INVERTED BREVE {{XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὡ"}, // U1F69 | GREEK CAPITAL LETTER OMEGA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὡ"}, {{XK_dead_acute, XK_Uhorn, XK_VoidSymbol}, "Ứ"}, // U1EE8 | LATIN CAPITAL LETTER U WITH HORN AND ACUTE {{XK_Multi_key, XK_acute, XK_Uhorn, XK_VoidSymbol}, "Ứ"}, {{XK_Multi_key, XK_apostrophe, XK_Uhorn, XK_VoidSymbol}, "Ứ"}, {{XK_dead_acute, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ứ"}, {{XK_dead_acute, XK_Multi_key, XK_plus, XK_U, XK_VoidSymbol}, "Ứ"}, {{XK_Multi_key, XK_acute, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ứ"}, {{XK_Multi_key, XK_acute, XK_plus, XK_U, XK_VoidSymbol}, "Ứ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ứ"}, {{XK_Multi_key, XK_apostrophe, XK_plus, XK_U, XK_VoidSymbol}, "Ứ"}, {{XK_dead_horn, XK_Uacute, XK_VoidSymbol}, "Ứ"}, {{XK_dead_horn, XK_dead_acute, XK_U, XK_VoidSymbol}, "Ứ"}, {{XK_dead_currency, XK_u, XK_VoidSymbol}, "元"}, // U5143 | YUAN / WEN {{XK_dead_belowtilde, XK_plus, XK_VoidSymbol}, "⨦"}, // U2A26 | PLUS SIGN WITH TILDE BELOW {{XK_dead_breve, XK_u, XK_VoidSymbol}, "ŭ"}, // U016D | LATIN SMALL LETTER U WITH BREVE {{XK_Multi_key, XK_U, XK_u, XK_VoidSymbol}, "ŭ"}, {{XK_Multi_key, XK_u, XK_u, XK_VoidSymbol}, "ŭ"}, {{XK_Multi_key, XK_b, XK_u, XK_VoidSymbol}, "ŭ"}, {{XK_dead_grave, XK_i, XK_VoidSymbol}, "ì"}, // igrave | LATIN SMALL LETTER I WITH GRAVE {{XK_Multi_key, XK_grave, XK_i, XK_VoidSymbol}, "ì"}, {{XK_Multi_key, XK_i, XK_grave, XK_VoidSymbol}, "ì"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_6, XK_parenright, XK_VoidSymbol}, "⑯"}, // U246F | CIRCLED NUMBER SIXTEEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_6, XK_parenright, XK_VoidSymbol}, "⑯"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_6, XK_parenright, XK_VoidSymbol}, "⑯"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_6, XK_parenright, XK_VoidSymbol}, "⑯"}, {{XK_dead_belowring, XK_bar, XK_VoidSymbol}, "⫰"}, // U2AF0 | VERTICAL LINE WITH CIRCLE BELOW {{XK_dead_belowdiaeresis, XK_u, XK_VoidSymbol}, "ṳ"}, // U1E73 | LATIN SMALL LETTER U WITH DIAERESIS BELOW {{XK_dead_grave, XK_Ocircumflex, XK_VoidSymbol}, "Ồ"}, // U1ED2 | LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE {{XK_Multi_key, XK_grave, XK_Ocircumflex, XK_VoidSymbol}, "Ồ"}, {{XK_dead_grave, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ồ"}, {{XK_dead_grave, XK_Multi_key, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ồ"}, {{XK_Multi_key, XK_grave, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ồ"}, {{XK_Multi_key, XK_grave, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ồ"}, {{XK_dead_circumflex, XK_Ograve, XK_VoidSymbol}, "Ồ"}, {{XK_dead_circumflex, XK_dead_grave, XK_O, XK_VoidSymbol}, "Ồ"}, {{XK_dead_diaeresis, XK_Cyrillic_CHE, XK_VoidSymbol}, "Ӵ"}, // U04F4 | CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_CHE, XK_VoidSymbol}, "Ӵ"}, {{XK_dead_circumflex, XK_7, XK_VoidSymbol}, "⁷"}, // U2077 | SUPERSCRIPT SEVEN {{XK_Multi_key, XK_asciicircum, XK_7, XK_VoidSymbol}, "⁷"}, {{XK_dead_circumflex, XK_KP_7, XK_VoidSymbol}, "⁷"}, {{XK_Multi_key, XK_asciicircum, XK_KP_7, XK_VoidSymbol}, "⁷"}, {{XK_dead_tilde, XK_Y, XK_VoidSymbol}, "Ỹ"}, // U1EF8 | LATIN CAPITAL LETTER Y WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_Y, XK_VoidSymbol}, "Ỹ"}, {{XK_dead_voiced_sound, XK_kana_HO, XK_VoidSymbol}, "ボ"}, // U30DC | KATAKANA LETTER BO {{XK_dead_caron, XK_Z, XK_VoidSymbol}, "Ž"}, // U017D | LATIN CAPITAL LETTER Z WITH CARON {{XK_Multi_key, XK_c, XK_Z, XK_VoidSymbol}, "Ž"}, {{XK_Multi_key, XK_v, XK_Z, XK_VoidSymbol}, "Ž"}, {{XK_Multi_key, XK_less, XK_Z, XK_VoidSymbol}, "Ž"}, {{XK_Multi_key, XK_Z, XK_less, XK_VoidSymbol}, "Ž"}, {{XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ü"}, // udiaeresis | LATIN SMALL LETTER U WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_u, XK_VoidSymbol}, "ü"}, {{XK_Multi_key, XK_u, XK_quotedbl, XK_VoidSymbol}, "ü"}, {{XK_Multi_key, XK_diaeresis, XK_u, XK_VoidSymbol}, "ü"}, {{XK_Multi_key, XK_u, XK_diaeresis, XK_VoidSymbol}, "ü"}, {{XK_dead_circumflex, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̂"}, // CYRILLIC CAPITAL LETTER IE WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̂"}, {{XK_Multi_key, XK_f, XK_f, XK_VoidSymbol}, "ff"}, // Ufb00 | LATIN SMALL LIGATURE FF {{XK_dead_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, // U1F83 | GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾃ"}, {{XK_dead_hook, XK_C, XK_VoidSymbol}, "Ƈ"}, // U0187 | LATIN CAPITAL LETTER C WITH HOOK {{XK_Multi_key, XK_parenleft, XK_w, XK_parenright, XK_VoidSymbol}, "ⓦ"}, // U24E6 | CIRCLED LATIN SMALL LETTER W {{XK_dead_belowdot, XK_w, XK_VoidSymbol}, "ẉ"}, // U1E89 | LATIN SMALL LETTER W WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_w, XK_VoidSymbol}, "ẉ"}, {{XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἀ"}, // U1F08 | GREEK CAPITAL LETTER ALPHA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἀ"}, {{XK_Multi_key, XK_parenleft, XK_g, XK_parenright, XK_VoidSymbol}, "ⓖ"}, // U24D6 | CIRCLED LATIN SMALL LETTER G {{XK_Multi_key, XK_underscore, XK_parenleft, XK_VoidSymbol}, "₍"}, // U208D | SUBSCRIPT LEFT PARENTHESIS {{XK_dead_caron, XK_parenleft, XK_VoidSymbol}, "₍"}, {{XK_dead_caron, XK_C, XK_VoidSymbol}, "Č"}, // U010C | LATIN CAPITAL LETTER C WITH CARON {{XK_Multi_key, XK_c, XK_C, XK_VoidSymbol}, "Č"}, {{XK_Multi_key, XK_less, XK_C, XK_VoidSymbol}, "Č"}, {{XK_Multi_key, XK_C, XK_less, XK_VoidSymbol}, "Č"}, {{XK_dead_belowmacron, XK_D, XK_VoidSymbol}, "Ḏ"}, // U1E0E | LATIN CAPITAL LETTER D WITH LINE BELOW {{XK_dead_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, // U1F93 | GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾓ"}, {{XK_dead_stroke, XK_I, XK_VoidSymbol}, "Ɨ"}, // U0197 | LATIN CAPITAL LETTER I WITH STROKE {{XK_Multi_key, XK_slash, XK_I, XK_VoidSymbol}, "Ɨ"}, {{XK_Multi_key, XK_KP_Divide, XK_I, XK_VoidSymbol}, "Ɨ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_7, XK_parenright, XK_VoidSymbol}, "㊲"}, // U32B2 | CIRCLED NUMBER THIRTY SEVEN {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_7, XK_parenright, XK_VoidSymbol}, "㊲"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_7, XK_parenright, XK_VoidSymbol}, "㊲"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_7, XK_parenright, XK_VoidSymbol}, "㊲"}, {{XK_dead_abovering, XK_y, XK_VoidSymbol}, "ẙ"}, // U1E99 | LATIN SMALL LETTER Y WITH RING ABOVE {{XK_Multi_key, XK_o, XK_y, XK_VoidSymbol}, "ẙ"}, {{XK_dead_psili, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἐ"}, // U1F18 | GREEK CAPITAL LETTER EPSILON WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἐ"}, {{XK_Multi_key, XK_parenleft, XK_kana_MU, XK_parenright, XK_VoidSymbol}, "㋰"}, // U32F0 | CIRCLED KATAKANA MU {{XK_dead_circumflex, XK_G, XK_VoidSymbol}, "Ĝ"}, // U011C | LATIN CAPITAL LETTER G WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_G, XK_VoidSymbol}, "Ĝ"}, {{XK_dead_abovedot, XK_F, XK_VoidSymbol}, "Ḟ"}, // U1E1E | LATIN CAPITAL LETTER F WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_F, XK_VoidSymbol}, "Ḟ"}, {{XK_Multi_key, XK_F, XK_period, XK_VoidSymbol}, "Ḟ"}, {{XK_dead_circumflex, XK_Cyrillic_I, XK_VoidSymbol}, "И̂"}, // CYRILLIC CAPITAL LETTER I WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_I, XK_VoidSymbol}, "И̂"}, {{XK_dead_circumflex, XK_Cyrillic_A, XK_VoidSymbol}, "А̂"}, // CYRILLIC CAPITAL LETTER A WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_A, XK_VoidSymbol}, "А̂"}, {{XK_dead_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, // U1FA3 | GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾣ"}, {{XK_Multi_key, XK_period, XK_equal, XK_VoidSymbol}, "•"}, // enfilledcircbullet | BULLET {{XK_dead_abovedot, XK_A, XK_VoidSymbol}, "Ȧ"}, // U0226 | LATIN CAPITAL LETTER A WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_A, XK_VoidSymbol}, "Ȧ"}, {{XK_dead_hook, XK_acircumflex, XK_VoidSymbol}, "ẩ"}, // U1EA9 | LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_acircumflex, XK_VoidSymbol}, "ẩ"}, {{XK_dead_hook, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ẩ"}, {{XK_dead_hook, XK_Multi_key, XK_asciicircum, XK_a, XK_VoidSymbol}, "ẩ"}, {{XK_Multi_key, XK_question, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ẩ"}, {{XK_Multi_key, XK_question, XK_asciicircum, XK_a, XK_VoidSymbol}, "ẩ"}, {{XK_dead_circumflex, XK_ahook, XK_VoidSymbol}, "ẩ"}, {{XK_dead_circumflex, XK_dead_hook, XK_a, XK_VoidSymbol}, "ẩ"}, {{XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἠ"}, // U1F28 | GREEK CAPITAL LETTER ETA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἠ"}, {{XK_dead_diaeresis, XK_Greek_UPSILON, XK_VoidSymbol}, "Ϋ"}, // U03AB | GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA {{XK_Multi_key, XK_quotedbl, XK_Greek_UPSILON, XK_VoidSymbol}, "Ϋ"}, {{XK_Multi_key, XK_Greek_UPSILON, XK_quotedbl, XK_VoidSymbol}, "Ϋ"}, {{XK_dead_currency, XK_Y, XK_VoidSymbol}, "円"}, // U5186 | YEN {{XK_Multi_key, XK_minus, XK_minus, XK_space, XK_VoidSymbol}, "­"}, // U00ad | SOFT HYPHEN {{XK_dead_breve, XK_I, XK_VoidSymbol}, "Ĭ"}, // U012C | LATIN CAPITAL LETTER I WITH BREVE {{XK_Multi_key, XK_U, XK_I, XK_VoidSymbol}, "Ĭ"}, {{XK_Multi_key, XK_b, XK_I, XK_VoidSymbol}, "Ĭ"}, {{XK_dead_acute, XK_Idiaeresis, XK_VoidSymbol}, "Ḯ"}, // U1E2E | LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE {{XK_Multi_key, XK_acute, XK_Idiaeresis, XK_VoidSymbol}, "Ḯ"}, {{XK_Multi_key, XK_apostrophe, XK_Idiaeresis, XK_VoidSymbol}, "Ḯ"}, {{XK_dead_acute, XK_dead_diaeresis, XK_I, XK_VoidSymbol}, "Ḯ"}, {{XK_dead_acute, XK_Multi_key, XK_quotedbl, XK_I, XK_VoidSymbol}, "Ḯ"}, {{XK_Multi_key, XK_acute, XK_dead_diaeresis, XK_I, XK_VoidSymbol}, "Ḯ"}, {{XK_Multi_key, XK_acute, XK_quotedbl, XK_I, XK_VoidSymbol}, "Ḯ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_diaeresis, XK_I, XK_VoidSymbol}, "Ḯ"}, {{XK_Multi_key, XK_apostrophe, XK_quotedbl, XK_I, XK_VoidSymbol}, "Ḯ"}, {{XK_dead_diaeresis, XK_Iacute, XK_VoidSymbol}, "Ḯ"}, {{XK_dead_diaeresis, XK_dead_acute, XK_I, XK_VoidSymbol}, "Ḯ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_6, XK_parenright, XK_VoidSymbol}, "㊱"}, // U32B1 | CIRCLED NUMBER THIRTY SIX {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_6, XK_parenright, XK_VoidSymbol}, "㊱"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_6, XK_parenright, XK_VoidSymbol}, "㊱"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_6, XK_parenright, XK_VoidSymbol}, "㊱"}, {{XK_dead_iota, XK_Greek_alpha, XK_VoidSymbol}, "ᾳ"}, // U1FB3 | GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_alpha, XK_VoidSymbol}, "ᾳ"}, {{XK_dead_acute, XK_Cyrillic_A, XK_VoidSymbol}, "А́"}, // CYRILLIC CAPITAL LETTER A WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_A, XK_VoidSymbol}, "А́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_A, XK_VoidSymbol}, "А́"}, {{XK_dead_macron, XK_Cyrillic_A, XK_VoidSymbol}, "А̄"}, // CYRILLIC CAPITAL LETTER A WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_A, XK_VoidSymbol}, "А̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_A, XK_VoidSymbol}, "А̄"}, {{XK_dead_belowdot, XK_e, XK_VoidSymbol}, "ẹ"}, // U1EB9 | LATIN SMALL LETTER E WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_e, XK_VoidSymbol}, "ẹ"}, {{XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἰ"}, // U1F38 | GREEK CAPITAL LETTER IOTA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἰ"}, {{XK_Multi_key, XK_parenleft, XK_o, XK_parenright, XK_VoidSymbol}, "ⓞ"}, // U24DE | CIRCLED LATIN SMALL LETTER O {{XK_Multi_key, XK_1, XK_2, XK_VoidSymbol}, "½"}, // onehalf | VULGAR FRACTION ONE HALF {{XK_dead_cedilla, XK_l, XK_VoidSymbol}, "ļ"}, // U013C | LATIN SMALL LETTER L WITH CEDILLA {{XK_Multi_key, XK_comma, XK_l, XK_VoidSymbol}, "ļ"}, {{XK_Multi_key, XK_l, XK_comma, XK_VoidSymbol}, "ļ"}, {{XK_Multi_key, XK_cedilla, XK_l, XK_VoidSymbol}, "ļ"}, {{XK_dead_acute, XK_M, XK_VoidSymbol}, "Ḿ"}, // U1E3E | LATIN CAPITAL LETTER M WITH ACUTE {{XK_Multi_key, XK_acute, XK_M, XK_VoidSymbol}, "Ḿ"}, {{XK_Multi_key, XK_apostrophe, XK_M, XK_VoidSymbol}, "Ḿ"}, {{XK_Multi_key, XK_backslash, XK_minus, XK_VoidSymbol}, "⍀"}, // U2340 | \ - APL FUNCTIONAL SYMBOL BACKSLASH BAR {{XK_Multi_key, XK_minus, XK_backslash, XK_VoidSymbol}, "⍀"}, {{XK_dead_iota, XK_Greek_eta, XK_VoidSymbol}, "ῃ"}, // U1FC3 | GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_eta, XK_VoidSymbol}, "ῃ"}, {{XK_dead_iota, XK_dead_grave, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, // U1F8A | GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾊ"}, {{XK_Multi_key, XK_parenleft, XK_P, XK_parenright, XK_VoidSymbol}, "Ⓟ"}, // U24C5 | CIRCLED LATIN CAPITAL LETTER P {{XK_dead_currency, XK_K, XK_VoidSymbol}, "₭"}, // U20AD | KIP SIGN {{XK_dead_currency, XK_k, XK_VoidSymbol}, "₭"}, {{XK_dead_hook, XK_i, XK_VoidSymbol}, "ỉ"}, // U1EC9 | LATIN SMALL LETTER I WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_i, XK_VoidSymbol}, "ỉ"}, {{XK_dead_psili, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὀ"}, // U1F48 | GREEK CAPITAL LETTER OMICRON WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὀ"}, {{XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ϋ"}, // U03CB | GREEK SMALL LETTER UPSILON WITH DIALYTIKA {{XK_Multi_key, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ϋ"}, {{XK_Multi_key, XK_Greek_upsilon, XK_quotedbl, XK_VoidSymbol}, "ϋ"}, {{XK_dead_acute, XK_I, XK_VoidSymbol}, "Í"}, // Iacute | LATIN CAPITAL LETTER I WITH ACUTE {{XK_Multi_key, XK_acute, XK_I, XK_VoidSymbol}, "Í"}, {{XK_Multi_key, XK_I, XK_acute, XK_VoidSymbol}, "Í"}, {{XK_Multi_key, XK_apostrophe, XK_I, XK_VoidSymbol}, "Í"}, {{XK_Multi_key, XK_I, XK_apostrophe, XK_VoidSymbol}, "Í"}, {{XK_dead_macron, XK_O, XK_VoidSymbol}, "Ō"}, // U014C | LATIN CAPITAL LETTER O WITH MACRON {{XK_Multi_key, XK_macron, XK_O, XK_VoidSymbol}, "Ō"}, {{XK_Multi_key, XK_underscore, XK_O, XK_VoidSymbol}, "Ō"}, {{XK_Multi_key, XK_O, XK_underscore, XK_VoidSymbol}, "Ō"}, {{XK_Multi_key, XK_minus, XK_O, XK_VoidSymbol}, "Ō"}, {{XK_Multi_key, XK_O, XK_minus, XK_VoidSymbol}, "Ō"}, {{XK_dead_diaeresis, XK_Otilde, XK_VoidSymbol}, "Ṏ"}, // U1E4E | LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Otilde, XK_VoidSymbol}, "Ṏ"}, {{XK_dead_diaeresis, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ṏ"}, {{XK_dead_diaeresis, XK_Multi_key, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ṏ"}, {{XK_Multi_key, XK_quotedbl, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ṏ"}, {{XK_Multi_key, XK_quotedbl, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ṏ"}, {{XK_dead_tilde, XK_Odiaeresis, XK_VoidSymbol}, "Ṏ"}, {{XK_dead_tilde, XK_dead_diaeresis, XK_O, XK_VoidSymbol}, "Ṏ"}, {{XK_Multi_key, XK_parenleft, XK_b, XK_parenright, XK_VoidSymbol}, "ⓑ"}, // U24D1 | CIRCLED LATIN SMALL LETTER B {{XK_Multi_key, XK_parenleft, XK_kana_TE, XK_parenright, XK_VoidSymbol}, "㋢"}, // U32E2 | CIRCLED KATAKANA TE {{XK_Multi_key, XK_parenleft, XK_f, XK_parenright, XK_VoidSymbol}, "ⓕ"}, // U24D5 | CIRCLED LATIN SMALL LETTER F {{XK_dead_acute, XK_Udiaeresis, XK_VoidSymbol}, "Ǘ"}, // U01D7 | LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE {{XK_Multi_key, XK_acute, XK_Udiaeresis, XK_VoidSymbol}, "Ǘ"}, {{XK_Multi_key, XK_apostrophe, XK_Udiaeresis, XK_VoidSymbol}, "Ǘ"}, {{XK_dead_acute, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǘ"}, {{XK_dead_acute, XK_Multi_key, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǘ"}, {{XK_Multi_key, XK_acute, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǘ"}, {{XK_Multi_key, XK_acute, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǘ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǘ"}, {{XK_Multi_key, XK_apostrophe, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǘ"}, {{XK_dead_acute, XK_V, XK_VoidSymbol}, "Ǘ"}, {{XK_dead_diaeresis, XK_Uacute, XK_VoidSymbol}, "Ǘ"}, {{XK_dead_diaeresis, XK_dead_acute, XK_U, XK_VoidSymbol}, "Ǘ"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_6, XK_parenright, XK_VoidSymbol}, "㉖"}, // U3256 | CIRCLED NUMBER TWENTY SIX {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_6, XK_parenright, XK_VoidSymbol}, "㉖"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_6, XK_parenright, XK_VoidSymbol}, "㉖"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_6, XK_parenright, XK_VoidSymbol}, "㉖"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_6, XK_parenright, XK_VoidSymbol}, "㉖"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_6, XK_parenright, XK_VoidSymbol}, "㉖"}, {{XK_dead_circumflex, XK_dead_belowdot, XK_o, XK_VoidSymbol}, "ộ"}, // U1ED9 | LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW {{XK_dead_circumflex, XK_Multi_key, XK_exclam, XK_o, XK_VoidSymbol}, "ộ"}, {{XK_Multi_key, XK_asciicircum, XK_dead_belowdot, XK_o, XK_VoidSymbol}, "ộ"}, {{XK_Multi_key, XK_asciicircum, XK_exclam, XK_o, XK_VoidSymbol}, "ộ"}, {{XK_dead_belowdot, XK_ocircumflex, XK_VoidSymbol}, "ộ"}, {{XK_dead_belowdot, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ộ"}, {{XK_dead_abovedot, XK_sacute, XK_VoidSymbol}, "ṥ"}, // U1E65 | LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE {{XK_Multi_key, XK_period, XK_sacute, XK_VoidSymbol}, "ṥ"}, {{XK_dead_abovedot, XK_dead_acute, XK_s, XK_VoidSymbol}, "ṥ"}, {{XK_dead_abovedot, XK_Multi_key, XK_acute, XK_s, XK_VoidSymbol}, "ṥ"}, {{XK_dead_abovedot, XK_Multi_key, XK_apostrophe, XK_s, XK_VoidSymbol}, "ṥ"}, {{XK_Multi_key, XK_period, XK_dead_acute, XK_s, XK_VoidSymbol}, "ṥ"}, {{XK_Multi_key, XK_period, XK_acute, XK_s, XK_VoidSymbol}, "ṥ"}, {{XK_Multi_key, XK_period, XK_apostrophe, XK_s, XK_VoidSymbol}, "ṥ"}, {{XK_dead_acute, XK_sabovedot, XK_VoidSymbol}, "ṥ"}, {{XK_dead_acute, XK_dead_abovedot, XK_s, XK_VoidSymbol}, "ṥ"}, {{XK_dead_acute, XK_Y, XK_VoidSymbol}, "Ý"}, // Yacute | LATIN CAPITAL LETTER Y WITH ACUTE {{XK_Multi_key, XK_acute, XK_Y, XK_VoidSymbol}, "Ý"}, {{XK_Multi_key, XK_Y, XK_acute, XK_VoidSymbol}, "Ý"}, {{XK_Multi_key, XK_apostrophe, XK_Y, XK_VoidSymbol}, "Ý"}, {{XK_Multi_key, XK_Y, XK_apostrophe, XK_VoidSymbol}, "Ý"}, {{XK_dead_circumflex, XK_S, XK_VoidSymbol}, "Ŝ"}, // U015C | LATIN CAPITAL LETTER S WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_S, XK_VoidSymbol}, "Ŝ"}, {{XK_dead_belowmacron, XK_R, XK_VoidSymbol}, "Ṟ"}, // U1E5E | LATIN CAPITAL LETTER R WITH LINE BELOW {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_l, XK_VoidSymbol}, "ˡ"}, // U02E1 | MODIFIER LETTER SMALL L {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_l, XK_VoidSymbol}, "ˡ"}, {{XK_dead_diaeresis, XK_Cyrillic_i, XK_VoidSymbol}, "ӥ"}, // U04E5 | CYRILLIC SMALL LETTER I WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_i, XK_VoidSymbol}, "ӥ"}, {{XK_dead_caron, XK_g, XK_VoidSymbol}, "ǧ"}, // U01E7 | LATIN SMALL LETTER G WITH CARON {{XK_Multi_key, XK_c, XK_g, XK_VoidSymbol}, "ǧ"}, {{XK_dead_belowdot, XK_equal, XK_VoidSymbol}, "⩦"}, // U2A66 | EQUALS SIGN WITH DOT BELOW {{XK_dead_acute, XK_uhorn, XK_VoidSymbol}, "ứ"}, // U1EE9 | LATIN SMALL LETTER U WITH HORN AND ACUTE {{XK_Multi_key, XK_acute, XK_uhorn, XK_VoidSymbol}, "ứ"}, {{XK_Multi_key, XK_apostrophe, XK_uhorn, XK_VoidSymbol}, "ứ"}, {{XK_dead_acute, XK_dead_horn, XK_u, XK_VoidSymbol}, "ứ"}, {{XK_dead_acute, XK_Multi_key, XK_plus, XK_u, XK_VoidSymbol}, "ứ"}, {{XK_Multi_key, XK_acute, XK_dead_horn, XK_u, XK_VoidSymbol}, "ứ"}, {{XK_Multi_key, XK_acute, XK_plus, XK_u, XK_VoidSymbol}, "ứ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_horn, XK_u, XK_VoidSymbol}, "ứ"}, {{XK_Multi_key, XK_apostrophe, XK_plus, XK_u, XK_VoidSymbol}, "ứ"}, {{XK_dead_horn, XK_uacute, XK_VoidSymbol}, "ứ"}, {{XK_dead_horn, XK_dead_acute, XK_u, XK_VoidSymbol}, "ứ"}, {{XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὠ"}, // U1F68 | GREEK CAPITAL LETTER OMEGA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὠ"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_1, XK_parenright, XK_VoidSymbol}, "⑪"}, // U246A | CIRCLED NUMBER ELEVEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_1, XK_parenright, XK_VoidSymbol}, "⑪"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_1, XK_parenright, XK_VoidSymbol}, "⑪"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_1, XK_parenright, XK_VoidSymbol}, "⑪"}, {{XK_dead_acute, XK_i, XK_VoidSymbol}, "í"}, // iacute | LATIN SMALL LETTER I WITH ACUTE {{XK_Multi_key, XK_acute, XK_i, XK_VoidSymbol}, "í"}, {{XK_Multi_key, XK_i, XK_acute, XK_VoidSymbol}, "í"}, {{XK_Multi_key, XK_apostrophe, XK_i, XK_VoidSymbol}, "í"}, {{XK_Multi_key, XK_i, XK_apostrophe, XK_VoidSymbol}, "í"}, {{XK_dead_breve, XK_U, XK_VoidSymbol}, "Ŭ"}, // U016C | LATIN CAPITAL LETTER U WITH BREVE {{XK_Multi_key, XK_U, XK_U, XK_VoidSymbol}, "Ŭ"}, {{XK_Multi_key, XK_b, XK_U, XK_VoidSymbol}, "Ŭ"}, {{XK_Multi_key, XK_numbersign, XK_f, XK_VoidSymbol}, "♮"}, // U266e | MUSIC NATURAL SIGN {{XK_Multi_key, XK_parenleft, XK_kana_ME, XK_parenright, XK_VoidSymbol}, "㋱"}, // U32F1 | CIRCLED KATAKANA ME {{XK_dead_iota, XK_Greek_omega, XK_VoidSymbol}, "ῳ"}, // U1FF3 | GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_omega, XK_VoidSymbol}, "ῳ"}, {{XK_dead_diaeresis, XK_Cyrillic_che, XK_VoidSymbol}, "ӵ"}, // U04F5 | CYRILLIC SMALL LETTER CHE WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_che, XK_VoidSymbol}, "ӵ"}, {{XK_dead_tilde, XK_y, XK_VoidSymbol}, "ỹ"}, // U1EF9 | LATIN SMALL LETTER Y WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_y, XK_VoidSymbol}, "ỹ"}, {{XK_dead_grave, XK_Greek_omicron, XK_VoidSymbol}, "ὸ"}, // U1F78 | GREEK SMALL LETTER OMICRON WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_omicron, XK_VoidSymbol}, "ὸ"}, {{XK_dead_acute, XK_Cyrillic_I, XK_VoidSymbol}, "И́"}, // CYRILLIC CAPITAL LETTER I WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_I, XK_VoidSymbol}, "И́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_I, XK_VoidSymbol}, "И́"}, {{XK_dead_acute, XK_y, XK_VoidSymbol}, "ý"}, // yacute | LATIN SMALL LETTER Y WITH ACUTE {{XK_Multi_key, XK_acute, XK_y, XK_VoidSymbol}, "ý"}, {{XK_Multi_key, XK_y, XK_acute, XK_VoidSymbol}, "ý"}, {{XK_Multi_key, XK_apostrophe, XK_y, XK_VoidSymbol}, "ý"}, {{XK_Multi_key, XK_y, XK_apostrophe, XK_VoidSymbol}, "ý"}, {{XK_dead_abovedot, XK_z, XK_VoidSymbol}, "ż"}, // U017C | LATIN SMALL LETTER Z WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_z, XK_VoidSymbol}, "ż"}, {{XK_Multi_key, XK_z, XK_period, XK_VoidSymbol}, "ż"}, {{XK_dead_voiced_sound, XK_kana_CHI, XK_VoidSymbol}, "ヂ"}, // U30C2 | KATAKANA LETTER DI {{XK_dead_belowdot, XK_V, XK_VoidSymbol}, "Ṿ"}, // U1E7E | LATIN CAPITAL LETTER V WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_V, XK_VoidSymbol}, "Ṿ"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἃ"}, // U1F03 | GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἃ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἃ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἃ"}, {{XK_dead_grave, XK_Uhorn, XK_VoidSymbol}, "Ừ"}, // U1EEA | LATIN CAPITAL LETTER U WITH HORN AND GRAVE {{XK_Multi_key, XK_grave, XK_Uhorn, XK_VoidSymbol}, "Ừ"}, {{XK_dead_grave, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ừ"}, {{XK_dead_grave, XK_Multi_key, XK_plus, XK_U, XK_VoidSymbol}, "Ừ"}, {{XK_Multi_key, XK_grave, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ừ"}, {{XK_Multi_key, XK_grave, XK_plus, XK_U, XK_VoidSymbol}, "Ừ"}, {{XK_dead_horn, XK_Ugrave, XK_VoidSymbol}, "Ừ"}, {{XK_dead_horn, XK_dead_grave, XK_U, XK_VoidSymbol}, "Ừ"}, {{XK_dead_acute, XK_c, XK_VoidSymbol}, "ć"}, // U0107 | LATIN SMALL LETTER C WITH ACUTE {{XK_Multi_key, XK_acute, XK_c, XK_VoidSymbol}, "ć"}, {{XK_Multi_key, XK_apostrophe, XK_c, XK_VoidSymbol}, "ć"}, {{XK_Multi_key, XK_c, XK_apostrophe, XK_VoidSymbol}, "ć"}, {{XK_dead_acute, XK_ccedilla, XK_VoidSymbol}, "ḉ"}, // U1E09 | LATIN SMALL LETTER C WITH CEDILLA AND ACUTE {{XK_Multi_key, XK_acute, XK_ccedilla, XK_VoidSymbol}, "ḉ"}, {{XK_Multi_key, XK_apostrophe, XK_ccedilla, XK_VoidSymbol}, "ḉ"}, {{XK_dead_acute, XK_dead_cedilla, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_dead_acute, XK_Multi_key, XK_comma, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_dead_acute, XK_Multi_key, XK_cedilla, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_Multi_key, XK_acute, XK_dead_cedilla, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_Multi_key, XK_acute, XK_comma, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_Multi_key, XK_acute, XK_cedilla, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_cedilla, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_Multi_key, XK_apostrophe, XK_cedilla, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_dead_cedilla, XK_cacute, XK_VoidSymbol}, "ḉ"}, {{XK_dead_cedilla, XK_dead_acute, XK_c, XK_VoidSymbol}, "ḉ"}, {{XK_dead_belowdot, XK_t, XK_VoidSymbol}, "ṭ"}, // U1E6D | LATIN SMALL LETTER T WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_t, XK_VoidSymbol}, "ṭ"}, {{XK_dead_doubleacute, XK_nobreakspace, XK_VoidSymbol}, "̋"}, // U030B | COMBINING DOUBLE ACUTE ACCENT {{XK_dead_abovedot, XK_Y, XK_VoidSymbol}, "Ẏ"}, // U1E8E | LATIN CAPITAL LETTER Y WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_Y, XK_VoidSymbol}, "Ẏ"}, {{XK_dead_circumflex, XK_Cyrillic_a, XK_VoidSymbol}, "а̂"}, // CYRILLIC SMALL LETTER A WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_a, XK_VoidSymbol}, "а̂"}, {{XK_dead_acute, XK_Greek_iotadieresis, XK_VoidSymbol}, "ΐ"}, // U0390 | GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS {{XK_Multi_key, XK_acute, XK_Greek_iotadieresis, XK_VoidSymbol}, "ΐ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_iotadieresis, XK_VoidSymbol}, "ΐ"}, {{XK_dead_acute, XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_dead_diaeresis, XK_dead_acute, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_dead_acute, XK_Multi_key, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_Multi_key, XK_acute, XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_Multi_key, XK_acute, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_Multi_key, XK_apostrophe, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_Greek_accentdieresis, XK_Greek_iota, XK_VoidSymbol}, "ΐ"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_epsilon, XK_VoidSymbol}, "ἓ"}, // U1F13 | GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_epsilon, XK_VoidSymbol}, "ἓ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_epsilon, XK_VoidSymbol}, "ἓ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_epsilon, XK_VoidSymbol}, "ἓ"}, {{XK_dead_acute, XK_Cyrillic_a, XK_VoidSymbol}, "а́"}, // CYRILLIC SMALL LETTER A WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_a, XK_VoidSymbol}, "а́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_a, XK_VoidSymbol}, "а́"}, {{XK_dead_grave, XK_Cyrillic_A, XK_VoidSymbol}, "А̀"}, // CYRILLIC CAPITAL LETTER A WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_A, XK_VoidSymbol}, "А̀"}, {{XK_dead_abovedot, XK_e, XK_VoidSymbol}, "ė"}, // U0117 | LATIN SMALL LETTER E WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_e, XK_VoidSymbol}, "ė"}, {{XK_Multi_key, XK_e, XK_period, XK_VoidSymbol}, "ė"}, {{XK_dead_belowcircumflex, XK_e, XK_VoidSymbol}, "ḙ"}, // U1E19 | LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW {{XK_dead_iota, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾘ"}, // U1F98 | GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾘ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾘ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾘ"}, {{XK_dead_horn, XK_dead_horn, XK_VoidSymbol}, "̛"}, // U031B | COMBINING HORN {{XK_dead_horn, XK_nobreakspace, XK_VoidSymbol}, "̛"}, {{XK_dead_horn, XK_space, XK_VoidSymbol}, "̛"}, {{XK_Multi_key, XK_greater, XK_quotedbl, XK_VoidSymbol}, "”"}, // U201d | RIGHT DOUBLE QUOTATION MARK {{XK_Multi_key, XK_quotedbl, XK_greater, XK_VoidSymbol}, "”"}, {{XK_dead_doublegrave, XK_Cyrillic_a, XK_VoidSymbol}, "а̏"}, // CYRILLIC SMALL LETTER A WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_a, XK_VoidSymbol}, "а̏"}, {{XK_Multi_key, XK_S, XK_S, XK_VoidSymbol}, "ẞ"}, // U1e9e | LATIN CAPITAL LETTER SHARP S {{XK_dead_grave, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἣ"}, // U1F23 | GREEK SMALL LETTER ETA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἣ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἣ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἣ"}, {{XK_Multi_key, XK_bar, XK_C, XK_VoidSymbol}, "¢"}, // cent | CENT SIGN {{XK_Multi_key, XK_bar, XK_c, XK_VoidSymbol}, "¢"}, {{XK_Multi_key, XK_C, XK_bar, XK_VoidSymbol}, "¢"}, {{XK_Multi_key, XK_c, XK_bar, XK_VoidSymbol}, "¢"}, {{XK_Multi_key, XK_c, XK_slash, XK_VoidSymbol}, "¢"}, {{XK_Multi_key, XK_slash, XK_c, XK_VoidSymbol}, "¢"}, {{XK_dead_currency, XK_c, XK_VoidSymbol}, "¢"}, {{XK_dead_doublegrave, XK_Cyrillic_U, XK_VoidSymbol}, "У̏"}, // CYRILLIC CAPITAL LETTER U WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_U, XK_VoidSymbol}, "У̏"}, {{XK_dead_stroke, XK_h, XK_VoidSymbol}, "ħ"}, // U0127 | LATIN SMALL LETTER H WITH STROKE {{XK_Multi_key, XK_slash, XK_h, XK_VoidSymbol}, "ħ"}, {{XK_Multi_key, XK_KP_Divide, XK_h, XK_VoidSymbol}, "ħ"}, {{XK_dead_cedilla, XK_h, XK_VoidSymbol}, "ḩ"}, // U1E29 | LATIN SMALL LETTER H WITH CEDILLA {{XK_Multi_key, XK_comma, XK_h, XK_VoidSymbol}, "ḩ"}, {{XK_Multi_key, XK_h, XK_comma, XK_VoidSymbol}, "ḩ"}, {{XK_Multi_key, XK_cedilla, XK_h, XK_VoidSymbol}, "ḩ"}, {{XK_dead_iota, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾨ"}, // U1FA8 | GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾨ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾨ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾨ"}, {{XK_dead_acute, XK_Cyrillic_U, XK_VoidSymbol}, "У́"}, // CYRILLIC CAPITAL LETTER U WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_U, XK_VoidSymbol}, "У́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_U, XK_VoidSymbol}, "У́"}, {{XK_dead_stroke, XK_E, XK_VoidSymbol}, "Ɇ"}, // U0246 | LATIN CAPITAL LETTER E WITH STROKE {{XK_dead_hook, XK_T, XK_VoidSymbol}, "Ƭ"}, // U01AC | LATIN CAPITAL LETTER T WITH HOOK {{XK_dead_acute, XK_Abreve, XK_VoidSymbol}, "Ắ"}, // U1EAE | LATIN CAPITAL LETTER A WITH BREVE AND ACUTE {{XK_Multi_key, XK_acute, XK_Abreve, XK_VoidSymbol}, "Ắ"}, {{XK_Multi_key, XK_apostrophe, XK_Abreve, XK_VoidSymbol}, "Ắ"}, {{XK_dead_acute, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_dead_acute, XK_Multi_key, XK_U, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_dead_acute, XK_Multi_key, XK_b, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_Multi_key, XK_acute, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_Multi_key, XK_acute, XK_b, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_Multi_key, XK_apostrophe, XK_b, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_dead_breve, XK_Aacute, XK_VoidSymbol}, "Ắ"}, {{XK_dead_breve, XK_dead_acute, XK_A, XK_VoidSymbol}, "Ắ"}, {{XK_dead_macron, XK_dead_abovedot, XK_o, XK_VoidSymbol}, "ȱ"}, // U0231 | LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON {{XK_dead_macron, XK_Multi_key, XK_period, XK_o, XK_VoidSymbol}, "ȱ"}, {{XK_Multi_key, XK_macron, XK_dead_abovedot, XK_o, XK_VoidSymbol}, "ȱ"}, {{XK_Multi_key, XK_macron, XK_period, XK_o, XK_VoidSymbol}, "ȱ"}, {{XK_Multi_key, XK_underscore, XK_dead_abovedot, XK_o, XK_VoidSymbol}, "ȱ"}, {{XK_Multi_key, XK_underscore, XK_period, XK_o, XK_VoidSymbol}, "ȱ"}, {{XK_dead_abovedot, XK_omacron, XK_VoidSymbol}, "ȱ"}, {{XK_dead_abovedot, XK_dead_macron, XK_o, XK_VoidSymbol}, "ȱ"}, {{XK_dead_acute, XK_Greek_upsilondieresis, XK_VoidSymbol}, "ΰ"}, // U03B0 | GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS {{XK_Multi_key, XK_acute, XK_Greek_upsilondieresis, XK_VoidSymbol}, "ΰ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_upsilondieresis, XK_VoidSymbol}, "ΰ"}, {{XK_dead_acute, XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_dead_acute, XK_Multi_key, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_Multi_key, XK_acute, XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_Multi_key, XK_acute, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_Multi_key, XK_apostrophe, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_dead_diaeresis, XK_dead_acute, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_Greek_accentdieresis, XK_Greek_upsilon, XK_VoidSymbol}, "ΰ"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἳ"}, // U1F33 | GREEK SMALL LETTER IOTA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἳ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἳ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἳ"}, {{XK_dead_circumflex, XK_2, XK_VoidSymbol}, "²"}, // twosuperior | SUPERSCRIPT TWO {{XK_Multi_key, XK_asciicircum, XK_2, XK_VoidSymbol}, "²"}, {{XK_dead_circumflex, XK_KP_Space, XK_VoidSymbol}, "²"}, {{XK_Multi_key, XK_asciicircum, XK_KP_Space, XK_VoidSymbol}, "²"}, {{XK_dead_circumflex, XK_KP_2, XK_VoidSymbol}, "²"}, {{XK_Multi_key, XK_asciicircum, XK_KP_2, XK_VoidSymbol}, "²"}, {{XK_Multi_key, XK_2, XK_asciicircum, XK_VoidSymbol}, "²"}, {{XK_Multi_key, XK_parenleft, XK_kana_RA, XK_parenright, XK_VoidSymbol}, "㋶"}, // U32F6 | CIRCLED KATAKANA RA {{XK_dead_cedilla, XK_k, XK_VoidSymbol}, "ķ"}, // U0137 | LATIN SMALL LETTER K WITH CEDILLA {{XK_Multi_key, XK_comma, XK_k, XK_VoidSymbol}, "ķ"}, {{XK_Multi_key, XK_k, XK_comma, XK_VoidSymbol}, "ķ"}, {{XK_Multi_key, XK_cedilla, XK_k, XK_VoidSymbol}, "ķ"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_1, XK_parenright, XK_VoidSymbol}, "㊶"}, // U32B6 | CIRCLED NUMBER FORTY ONE {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_1, XK_parenright, XK_VoidSymbol}, "㊶"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_1, XK_parenright, XK_VoidSymbol}, "㊶"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_1, XK_parenright, XK_VoidSymbol}, "㊶"}, {{XK_Multi_key, XK_colon, XK_parenleft, XK_VoidSymbol}, "☹"}, // U2639 | WHITE FROWNING FACE {{XK_dead_breve, XK_Greek_ALPHA, XK_VoidSymbol}, "Ᾰ"}, // U1FB8 | GREEK CAPITAL LETTER ALPHA WITH VRACHY {{XK_Multi_key, XK_U, XK_Greek_ALPHA, XK_VoidSymbol}, "Ᾰ"}, {{XK_Multi_key, XK_b, XK_Greek_ALPHA, XK_VoidSymbol}, "Ᾰ"}, {{XK_dead_invertedbreve, XK_Cyrillic_U, XK_VoidSymbol}, "У̑"}, // CYRILLIC CAPITAL LETTER U WITH COMBINING INVERTED BREVE {{XK_Multi_key, XK_parenleft, XK_E, XK_parenright, XK_VoidSymbol}, "Ⓔ"}, // U24BA | CIRCLED LATIN CAPITAL LETTER E {{XK_Multi_key, XK_exclam, XK_question, XK_VoidSymbol}, "‽"}, // U203D | INTERROBANG {{XK_dead_acute, XK_Ecircumflex, XK_VoidSymbol}, "Ế"}, // U1EBE | LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE {{XK_Multi_key, XK_acute, XK_Ecircumflex, XK_VoidSymbol}, "Ế"}, {{XK_Multi_key, XK_apostrophe, XK_Ecircumflex, XK_VoidSymbol}, "Ế"}, {{XK_dead_acute, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ế"}, {{XK_dead_acute, XK_Multi_key, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ế"}, {{XK_Multi_key, XK_acute, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ế"}, {{XK_Multi_key, XK_acute, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ế"}, {{XK_Multi_key, XK_apostrophe, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ế"}, {{XK_Multi_key, XK_apostrophe, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ế"}, {{XK_dead_circumflex, XK_Eacute, XK_VoidSymbol}, "Ế"}, {{XK_dead_circumflex, XK_dead_acute, XK_E, XK_VoidSymbol}, "Ế"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_omicron, XK_VoidSymbol}, "ὃ"}, // U1F43 | GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_omicron, XK_VoidSymbol}, "ὃ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_omicron, XK_VoidSymbol}, "ὃ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_omicron, XK_VoidSymbol}, "ὃ"}, {{XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Â"}, // Acircumflex | LATIN CAPITAL LETTER A WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_A, XK_VoidSymbol}, "Â"}, {{XK_Multi_key, XK_greater, XK_A, XK_VoidSymbol}, "Â"}, {{XK_Multi_key, XK_A, XK_greater, XK_VoidSymbol}, "Â"}, {{XK_Multi_key, XK_A, XK_asciicircum, XK_VoidSymbol}, "Â"}, {{XK_dead_caron, XK_N, XK_VoidSymbol}, "Ň"}, // U0147 | LATIN CAPITAL LETTER N WITH CARON {{XK_Multi_key, XK_c, XK_N, XK_VoidSymbol}, "Ň"}, {{XK_Multi_key, XK_less, XK_N, XK_VoidSymbol}, "Ň"}, {{XK_Multi_key, XK_N, XK_less, XK_VoidSymbol}, "Ň"}, {{XK_Multi_key, XK_C, XK_E, XK_VoidSymbol}, "₠"}, // U20a0 | EURO-CURRENCY SIGN {{XK_dead_currency, XK_E, XK_VoidSymbol}, "₠"}, {{XK_dead_belowmacron, XK_n, XK_VoidSymbol}, "ṉ"}, // U1E49 | LATIN SMALL LETTER N WITH LINE BELOW {{XK_dead_grave, XK_Greek_EPSILON, XK_VoidSymbol}, "Ὲ"}, // U1FC8 | GREEK CAPITAL LETTER EPSILON WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_EPSILON, XK_VoidSymbol}, "Ὲ"}, {{XK_Multi_key, XK_parenleft, XK_U, XK_parenright, XK_VoidSymbol}, "Ⓤ"}, // U24CA | CIRCLED LATIN CAPITAL LETTER U {{XK_dead_hook, XK_O, XK_VoidSymbol}, "Ỏ"}, // U1ECE | LATIN CAPITAL LETTER O WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_O, XK_VoidSymbol}, "Ỏ"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_1, XK_parenright, XK_VoidSymbol}, "㉑"}, // U3251 | CIRCLED NUMBER TWENTY ONE {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_1, XK_parenright, XK_VoidSymbol}, "㉑"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_1, XK_parenright, XK_VoidSymbol}, "㉑"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_1, XK_parenright, XK_VoidSymbol}, "㉑"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_1, XK_parenright, XK_VoidSymbol}, "㉑"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_1, XK_parenright, XK_VoidSymbol}, "㉑"}, {{XK_dead_circumflex, XK_Cyrillic_ie, XK_VoidSymbol}, "е̂"}, // CYRILLIC SMALL LETTER IE WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_ie, XK_VoidSymbol}, "е̂"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὓ"}, // U1F53 | GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὓ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὓ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὓ"}, {{XK_dead_grave, XK_O, XK_VoidSymbol}, "Ò"}, // Ograve | LATIN CAPITAL LETTER O WITH GRAVE {{XK_Multi_key, XK_grave, XK_O, XK_VoidSymbol}, "Ò"}, {{XK_Multi_key, XK_O, XK_grave, XK_VoidSymbol}, "Ò"}, {{XK_dead_cedilla, XK_r, XK_VoidSymbol}, "ŗ"}, // U0157 | LATIN SMALL LETTER R WITH CEDILLA {{XK_Multi_key, XK_comma, XK_r, XK_VoidSymbol}, "ŗ"}, {{XK_Multi_key, XK_r, XK_comma, XK_VoidSymbol}, "ŗ"}, {{XK_Multi_key, XK_cedilla, XK_r, XK_VoidSymbol}, "ŗ"}, {{XK_Multi_key, XK_parenleft, XK_kana_KI, XK_parenright, XK_VoidSymbol}, "㋖"}, // U32D6 | CIRCLED KATAKANA KI {{XK_dead_abovedot, XK_r, XK_VoidSymbol}, "ṙ"}, // U1E59 | LATIN SMALL LETTER R WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_r, XK_VoidSymbol}, "ṙ"}, {{XK_dead_breve, XK_Greek_IOTA, XK_VoidSymbol}, "Ῐ"}, // U1FD8 | GREEK CAPITAL LETTER IOTA WITH VRACHY {{XK_Multi_key, XK_U, XK_Greek_IOTA, XK_VoidSymbol}, "Ῐ"}, {{XK_Multi_key, XK_b, XK_Greek_IOTA, XK_VoidSymbol}, "Ῐ"}, {{XK_Multi_key, XK_parenleft, XK_k, XK_parenright, XK_VoidSymbol}, "ⓚ"}, // U24DA | CIRCLED LATIN SMALL LETTER K {{XK_Multi_key, XK_parenright, XK_parenright, XK_VoidSymbol}, "]"}, // bracketright | RIGHT SQUARE BRACKET {{XK_dead_grave, XK_udiaeresis, XK_VoidSymbol}, "ǜ"}, // U01DC | LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE {{XK_Multi_key, XK_grave, XK_udiaeresis, XK_VoidSymbol}, "ǜ"}, {{XK_dead_grave, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǜ"}, {{XK_dead_grave, XK_Multi_key, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǜ"}, {{XK_Multi_key, XK_grave, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǜ"}, {{XK_Multi_key, XK_grave, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǜ"}, {{XK_dead_diaeresis, XK_ugrave, XK_VoidSymbol}, "ǜ"}, {{XK_dead_grave, XK_v, XK_VoidSymbol}, "ǜ"}, {{XK_dead_diaeresis, XK_dead_grave, XK_u, XK_VoidSymbol}, "ǜ"}, {{XK_dead_hook, XK_Ohorn, XK_VoidSymbol}, "Ở"}, // U1EDE | LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_Ohorn, XK_VoidSymbol}, "Ở"}, {{XK_dead_hook, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ở"}, {{XK_dead_hook, XK_Multi_key, XK_plus, XK_O, XK_VoidSymbol}, "Ở"}, {{XK_Multi_key, XK_question, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ở"}, {{XK_Multi_key, XK_question, XK_plus, XK_O, XK_VoidSymbol}, "Ở"}, {{XK_dead_horn, XK_Ohook, XK_VoidSymbol}, "Ở"}, {{XK_dead_horn, XK_dead_hook, XK_O, XK_VoidSymbol}, "Ở"}, {{XK_Multi_key, XK_equal, XK_underscore, XK_VoidSymbol}, "≡"}, // U2261 | = _ IDENTICAL TO {{XK_Multi_key, XK_parenleft, XK_kana_I, XK_parenright, XK_VoidSymbol}, "㋑"}, // U32D1 | CIRCLED KATAKANA I {{XK_dead_grave, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὣ"}, // U1F63 | GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὣ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὣ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὣ"}, {{XK_dead_circumflex, XK_a, XK_VoidSymbol}, "â"}, // acircumflex | LATIN SMALL LETTER A WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_a, XK_VoidSymbol}, "â"}, {{XK_Multi_key, XK_a, XK_asciicircum, XK_VoidSymbol}, "â"}, {{XK_Multi_key, XK_greater, XK_a, XK_VoidSymbol}, "â"}, {{XK_Multi_key, XK_a, XK_greater, XK_VoidSymbol}, "â"}, {{XK_Multi_key, XK_parenleft, XK_6, XK_parenright, XK_VoidSymbol}, "⑥"}, // U2465 | CIRCLED DIGIT SIX {{XK_Multi_key, XK_parenleft, XK_KP_6, XK_parenright, XK_VoidSymbol}, "⑥"}, {{XK_dead_stroke, XK_t, XK_VoidSymbol}, "ŧ"}, // U0167 | LATIN SMALL LETTER T WITH STROKE {{XK_Multi_key, XK_slash, XK_t, XK_VoidSymbol}, "ŧ"}, {{XK_Multi_key, XK_KP_Divide, XK_t, XK_VoidSymbol}, "ŧ"}, {{XK_Multi_key, XK_t, XK_slash, XK_VoidSymbol}, "ŧ"}, {{XK_Multi_key, XK_t, XK_minus, XK_VoidSymbol}, "ŧ"}, {{XK_Multi_key, XK_parenleft, XK_kana_NU, XK_parenright, XK_VoidSymbol}, "㋦"}, // U32E6 | CIRCLED KATAKANA NU {{XK_Multi_key, XK_numbersign, XK_q, XK_VoidSymbol}, "♩"}, // U2669 | QUARTER NOTE {{XK_dead_breve, XK_Greek_UPSILON, XK_VoidSymbol}, "Ῠ"}, // U1FE8 | GREEK CAPITAL LETTER UPSILON WITH VRACHY {{XK_Multi_key, XK_U, XK_Greek_UPSILON, XK_VoidSymbol}, "Ῠ"}, {{XK_Multi_key, XK_b, XK_Greek_UPSILON, XK_VoidSymbol}, "Ῠ"}, {{XK_Multi_key, XK_parenleft, XK_0, XK_parenright, XK_VoidSymbol}, "⓪"}, // U24EA | CIRCLED DIGIT ZERO {{XK_Multi_key, XK_parenleft, XK_KP_0, XK_parenright, XK_VoidSymbol}, "⓪"}, {{XK_dead_macron, XK_dead_ogonek, XK_O, XK_VoidSymbol}, "Ǭ"}, // U01EC | LATIN CAPITAL LETTER O WITH OGONEK AND MACRON {{XK_dead_macron, XK_Multi_key, XK_semicolon, XK_O, XK_VoidSymbol}, "Ǭ"}, {{XK_Multi_key, XK_macron, XK_dead_ogonek, XK_O, XK_VoidSymbol}, "Ǭ"}, {{XK_Multi_key, XK_macron, XK_semicolon, XK_O, XK_VoidSymbol}, "Ǭ"}, {{XK_Multi_key, XK_underscore, XK_dead_ogonek, XK_O, XK_VoidSymbol}, "Ǭ"}, {{XK_Multi_key, XK_underscore, XK_semicolon, XK_O, XK_VoidSymbol}, "Ǭ"}, {{XK_dead_ogonek, XK_Omacron, XK_VoidSymbol}, "Ǭ"}, {{XK_dead_ogonek, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ǭ"}, {{XK_dead_voiced_sound, XK_kana_HI, XK_VoidSymbol}, "ビ"}, // U30D3 | KATAKANA LETTER BI {{XK_dead_tilde, XK_Uhorn, XK_VoidSymbol}, "Ữ"}, // U1EEE | LATIN CAPITAL LETTER U WITH HORN AND TILDE {{XK_Multi_key, XK_asciitilde, XK_Uhorn, XK_VoidSymbol}, "Ữ"}, {{XK_dead_tilde, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ữ"}, {{XK_dead_tilde, XK_Multi_key, XK_plus, XK_U, XK_VoidSymbol}, "Ữ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ữ"}, {{XK_Multi_key, XK_asciitilde, XK_plus, XK_U, XK_VoidSymbol}, "Ữ"}, {{XK_dead_horn, XK_Utilde, XK_VoidSymbol}, "Ữ"}, {{XK_dead_horn, XK_dead_tilde, XK_U, XK_VoidSymbol}, "Ữ"}, {{XK_dead_hook, XK_m, XK_VoidSymbol}, "ɱ"}, // U0271 | LATIN SMALL LETTER M WITH HOOK {{XK_dead_currency, XK_M, XK_VoidSymbol}, "ℳ"}, // U2133 | SCRIPT CAPITAL M {{XK_Multi_key, XK_parenleft, XK_v, XK_parenright, XK_VoidSymbol}, "ⓥ"}, // U24E5 | CIRCLED LATIN SMALL LETTER V {{XK_dead_grave, XK_o, XK_VoidSymbol}, "ò"}, // ograve | LATIN SMALL LETTER O WITH GRAVE {{XK_Multi_key, XK_grave, XK_o, XK_VoidSymbol}, "ò"}, {{XK_Multi_key, XK_o, XK_grave, XK_VoidSymbol}, "ò"}, {{XK_dead_circumflex, XK_y, XK_VoidSymbol}, "ŷ"}, // U0177 | LATIN SMALL LETTER Y WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_y, XK_VoidSymbol}, "ŷ"}, {{XK_Multi_key, XK_y, XK_asciicircum, XK_VoidSymbol}, "ŷ"}, {{XK_Multi_key, XK_R, XK_s, XK_VoidSymbol}, "₨"}, // U20a8 | RUPEE SIGN {{XK_dead_currency, XK_R, XK_VoidSymbol}, "₨"}, {{XK_dead_acute, XK_utilde, XK_VoidSymbol}, "ṹ"}, // U1E79 | LATIN SMALL LETTER U WITH TILDE AND ACUTE {{XK_Multi_key, XK_acute, XK_utilde, XK_VoidSymbol}, "ṹ"}, {{XK_Multi_key, XK_apostrophe, XK_utilde, XK_VoidSymbol}, "ṹ"}, {{XK_dead_acute, XK_dead_tilde, XK_u, XK_VoidSymbol}, "ṹ"}, {{XK_dead_acute, XK_Multi_key, XK_asciitilde, XK_u, XK_VoidSymbol}, "ṹ"}, {{XK_Multi_key, XK_acute, XK_dead_tilde, XK_u, XK_VoidSymbol}, "ṹ"}, {{XK_Multi_key, XK_acute, XK_asciitilde, XK_u, XK_VoidSymbol}, "ṹ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_tilde, XK_u, XK_VoidSymbol}, "ṹ"}, {{XK_Multi_key, XK_apostrophe, XK_asciitilde, XK_u, XK_VoidSymbol}, "ṹ"}, {{XK_dead_tilde, XK_uacute, XK_VoidSymbol}, "ṹ"}, {{XK_dead_tilde, XK_dead_acute, XK_u, XK_VoidSymbol}, "ṹ"}, {{XK_dead_grave, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὸ"}, // U1FF8 | GREEK CAPITAL LETTER OMICRON WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὸ"}, {{XK_dead_belowdot, XK_Uhorn, XK_VoidSymbol}, "Ự"}, // U1EF0 | LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW {{XK_Multi_key, XK_exclam, XK_Uhorn, XK_VoidSymbol}, "Ự"}, {{XK_dead_belowdot, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ự"}, {{XK_dead_belowdot, XK_Multi_key, XK_plus, XK_U, XK_VoidSymbol}, "Ự"}, {{XK_Multi_key, XK_exclam, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ự"}, {{XK_Multi_key, XK_exclam, XK_plus, XK_U, XK_VoidSymbol}, "Ự"}, {{XK_dead_horn, XK_Ubelowdot, XK_VoidSymbol}, "Ự"}, {{XK_dead_horn, XK_dead_belowdot, XK_U, XK_VoidSymbol}, "Ự"}, {{XK_Multi_key, XK_parenright, XK_minus, XK_VoidSymbol}, "}"}, // braceright | RIGHT CURLY BRACKET {{XK_Multi_key, XK_minus, XK_parenright, XK_VoidSymbol}, "}"}, {{XK_dead_acute, XK_AE, XK_VoidSymbol}, "Ǽ"}, // U01FC | LATIN CAPITAL LETTER AE WITH ACUTE {{XK_Multi_key, XK_acute, XK_AE, XK_VoidSymbol}, "Ǽ"}, {{XK_Multi_key, XK_apostrophe, XK_AE, XK_VoidSymbol}, "Ǽ"}, {{XK_Multi_key, XK_2, XK_3, XK_VoidSymbol}, "⅔"}, // U2154 | VULGAR FRACTION TWO THIRDS {{XK_dead_grave, XK_Cyrillic_IE, XK_VoidSymbol}, "Ѐ"}, // U0400 | CYRILLIC CAPITAL LETTER IE WITH GRAVE {{XK_Multi_key, XK_grave, XK_Cyrillic_IE, XK_VoidSymbol}, "Ѐ"}, {{XK_Multi_key, XK_underscore, XK_3, XK_VoidSymbol}, "₃"}, // U2083 | SUBSCRIPT THREE {{XK_Multi_key, XK_underscore, XK_KP_3, XK_VoidSymbol}, "₃"}, {{XK_dead_caron, XK_3, XK_VoidSymbol}, "₃"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἂ"}, // U1F02 | GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἂ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἂ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἂ"}, {{XK_dead_acute, XK_dead_diaeresis, XK_space, XK_VoidSymbol}, "΅"}, // U0385 | GREEK DIALYTIKA TONOS {{XK_dead_diaeresis, XK_dead_acute, XK_space, XK_VoidSymbol}, "΅"}, {{XK_Multi_key, XK_diaeresis, XK_dead_acute, XK_VoidSymbol}, "΅"}, {{XK_Multi_key, XK_diaeresis, XK_acute, XK_VoidSymbol}, "΅"}, {{XK_Multi_key, XK_diaeresis, XK_apostrophe, XK_VoidSymbol}, "΅"}, {{XK_Multi_key, XK_apostrophe, XK_quotedbl, XK_space, XK_VoidSymbol}, "΅"}, {{XK_dead_abovedot, XK_w, XK_VoidSymbol}, "ẇ"}, // U1E87 | LATIN SMALL LETTER W WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_w, XK_VoidSymbol}, "ẇ"}, {{XK_Multi_key, XK_0, XK_3, XK_VoidSymbol}, "↉"}, // U2189 | VULGAR FRACTION ZERO THIRDS {{XK_Multi_key, XK_space, XK_period, XK_VoidSymbol}, " "}, // U2008 | PUNCTUATION SPACE {{XK_dead_grave, XK_Cyrillic_U, XK_VoidSymbol}, "У̀"}, // CYRILLIC CAPITAL LETTER U WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_U, XK_VoidSymbol}, "У̀"}, {{XK_dead_abovering, XK_nobreakspace, XK_VoidSymbol}, "̊"}, // U030A | COMBINING RING ABOVE {{XK_dead_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, // U1F8D | GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾍ"}, {{XK_dead_belowdot, XK_D, XK_VoidSymbol}, "Ḍ"}, // U1E0C | LATIN CAPITAL LETTER D WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_D, XK_VoidSymbol}, "Ḍ"}, {{XK_dead_caron, XK_D, XK_VoidSymbol}, "Ď"}, // U010E | LATIN CAPITAL LETTER D WITH CARON {{XK_Multi_key, XK_c, XK_D, XK_VoidSymbol}, "Ď"}, {{XK_Multi_key, XK_less, XK_D, XK_VoidSymbol}, "Ď"}, {{XK_Multi_key, XK_D, XK_less, XK_VoidSymbol}, "Ď"}, {{XK_Multi_key, XK_parenleft, XK_kana_KO, XK_parenright, XK_VoidSymbol}, "㋙"}, // U32D9 | CIRCLED KATAKANA KO {{XK_dead_grave, XK_dead_psili, XK_Greek_epsilon, XK_VoidSymbol}, "ἒ"}, // U1F12 | GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_epsilon, XK_VoidSymbol}, "ἒ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_epsilon, XK_VoidSymbol}, "ἒ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_epsilon, XK_VoidSymbol}, "ἒ"}, {{XK_dead_diaeresis, XK_t, XK_VoidSymbol}, "ẗ"}, // U1E97 | LATIN SMALL LETTER T WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_t, XK_VoidSymbol}, "ẗ"}, {{XK_Multi_key, XK_underscore, XK_apostrophe, XK_VoidSymbol}, "⍘"}, // U2358 | _ ' APL FUNCTIONAL SYMBOL QUOTE UNDERBAR {{XK_dead_hook, XK_k, XK_VoidSymbol}, "ƙ"}, // U0199 | LATIN SMALL LETTER K WITH HOOK {{XK_Multi_key, XK_less, XK_apostrophe, XK_VoidSymbol}, "‘"}, // U2018 | LEFT SINGLE QUOTATION MARK {{XK_Multi_key, XK_apostrophe, XK_less, XK_VoidSymbol}, "‘"}, {{XK_dead_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, // U1F9D | GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾝ"}, {{XK_dead_breve, XK_dead_cedilla, XK_E, XK_VoidSymbol}, "Ḝ"}, // U1E1C | LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE {{XK_dead_breve, XK_Multi_key, XK_comma, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_dead_breve, XK_Multi_key, XK_cedilla, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_Multi_key, XK_U, XK_dead_cedilla, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_Multi_key, XK_U, XK_space, XK_comma, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_Multi_key, XK_U, XK_cedilla, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_Multi_key, XK_b, XK_dead_cedilla, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_Multi_key, XK_b, XK_comma, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_Multi_key, XK_b, XK_cedilla, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_dead_cedilla, XK_dead_breve, XK_E, XK_VoidSymbol}, "Ḝ"}, {{XK_dead_breve, XK_G, XK_VoidSymbol}, "Ğ"}, // U011E | LATIN CAPITAL LETTER G WITH BREVE {{XK_Multi_key, XK_U, XK_G, XK_VoidSymbol}, "Ğ"}, {{XK_Multi_key, XK_G, XK_U, XK_VoidSymbol}, "Ğ"}, {{XK_Multi_key, XK_b, XK_G, XK_VoidSymbol}, "Ğ"}, {{XK_Multi_key, XK_breve, XK_G, XK_VoidSymbol}, "Ğ"}, {{XK_Multi_key, XK_G, XK_breve, XK_VoidSymbol}, "Ğ"}, {{XK_Multi_key, XK_G, XK_parenleft, XK_VoidSymbol}, "Ğ"}, {{XK_dead_hook, XK_d, XK_VoidSymbol}, "ɗ"}, // U0257 | LATIN SMALL LETTER D WITH HOOK {{XK_Multi_key, XK_L, XK_minus, XK_VoidSymbol}, "£"}, // sterling | POUND SIGN {{XK_Multi_key, XK_l, XK_minus, XK_VoidSymbol}, "£"}, {{XK_Multi_key, XK_minus, XK_L, XK_VoidSymbol}, "£"}, {{XK_Multi_key, XK_minus, XK_l, XK_VoidSymbol}, "£"}, {{XK_dead_currency, XK_l, XK_VoidSymbol}, "£"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἢ"}, // U1F22 | GREEK SMALL LETTER ETA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἢ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἢ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἢ"}, {{XK_dead_hook, XK_N, XK_VoidSymbol}, "Ɲ"}, // U019D | LATIN CAPITAL LETTER N WITH LEFT HOOK {{XK_dead_hook, XK_Z, XK_VoidSymbol}, "Ȥ"}, // U0224 | LATIN CAPITAL LETTER Z WITH HOOK {{XK_dead_grave, XK_acircumflex, XK_VoidSymbol}, "ầ"}, // U1EA7 | LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE {{XK_Multi_key, XK_grave, XK_acircumflex, XK_VoidSymbol}, "ầ"}, {{XK_dead_grave, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ầ"}, {{XK_dead_grave, XK_Multi_key, XK_asciicircum, XK_a, XK_VoidSymbol}, "ầ"}, {{XK_Multi_key, XK_grave, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ầ"}, {{XK_Multi_key, XK_grave, XK_asciicircum, XK_a, XK_VoidSymbol}, "ầ"}, {{XK_dead_circumflex, XK_agrave, XK_VoidSymbol}, "ầ"}, {{XK_dead_circumflex, XK_dead_grave, XK_a, XK_VoidSymbol}, "ầ"}, {{XK_dead_voiced_sound, XK_kana_KU, XK_VoidSymbol}, "グ"}, // U30B0 | KATAKANA LETTER GU {{XK_Multi_key, XK_parenleft, XK_n, XK_parenright, XK_VoidSymbol}, "ⓝ"}, // U24DD | CIRCLED LATIN SMALL LETTER N {{XK_dead_breve, XK_nobreakspace, XK_VoidSymbol}, "̆"}, // U0306 | COMBINING BREVE {{XK_dead_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, // U1FAD | GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾭ"}, {{XK_dead_belowtilde, XK_I, XK_VoidSymbol}, "Ḭ"}, // U1E2C | LATIN CAPITAL LETTER I WITH TILDE BELOW {{XK_dead_ogonek, XK_I, XK_VoidSymbol}, "Į"}, // U012E | LATIN CAPITAL LETTER I WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_I, XK_VoidSymbol}, "Į"}, {{XK_Multi_key, XK_comma, XK_I, XK_VoidSymbol}, "Į"}, {{XK_Multi_key, XK_I, XK_comma, XK_VoidSymbol}, "Į"}, {{XK_dead_circumflex, XK_3, XK_VoidSymbol}, "³"}, // threesuperior | SUPERSCRIPT THREE {{XK_Multi_key, XK_asciicircum, XK_3, XK_VoidSymbol}, "³"}, {{XK_dead_circumflex, XK_KP_3, XK_VoidSymbol}, "³"}, {{XK_Multi_key, XK_asciicircum, XK_KP_3, XK_VoidSymbol}, "³"}, {{XK_Multi_key, XK_3, XK_asciicircum, XK_VoidSymbol}, "³"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἲ"}, // U1F32 | GREEK SMALL LETTER IOTA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἲ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἲ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἲ"}, {{XK_dead_breve, XK_dead_belowdot, XK_a, XK_VoidSymbol}, "ặ"}, // U1EB7 | LATIN SMALL LETTER A WITH BREVE AND DOT BELOW {{XK_dead_breve, XK_Multi_key, XK_exclam, XK_a, XK_VoidSymbol}, "ặ"}, {{XK_Multi_key, XK_U, XK_dead_belowdot, XK_a, XK_VoidSymbol}, "ặ"}, {{XK_Multi_key, XK_U, XK_exclam, XK_a, XK_VoidSymbol}, "ặ"}, {{XK_Multi_key, XK_b, XK_dead_belowdot, XK_a, XK_VoidSymbol}, "ặ"}, {{XK_Multi_key, XK_b, XK_exclam, XK_a, XK_VoidSymbol}, "ặ"}, {{XK_dead_belowdot, XK_abreve, XK_VoidSymbol}, "ặ"}, {{XK_dead_belowdot, XK_dead_breve, XK_a, XK_VoidSymbol}, "ặ"}, {{XK_dead_doublegrave, XK_Cyrillic_o, XK_VoidSymbol}, "о̏"}, // CYRILLIC SMALL LETTER O WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_o, XK_VoidSymbol}, "о̏"}, {{XK_dead_grave, XK_Cyrillic_o, XK_VoidSymbol}, "о̀"}, // CYRILLIC SMALL LETTER O WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_o, XK_VoidSymbol}, "о̀"}, {{XK_dead_currency, XK_T, XK_VoidSymbol}, "₮"}, // U20AE | TUGRIK SIGN {{XK_Multi_key, XK_parenleft, XK_F, XK_parenright, XK_VoidSymbol}, "Ⓕ"}, // U24BB | CIRCLED LATIN CAPITAL LETTER F {{XK_dead_macron, XK_Cyrillic_o, XK_VoidSymbol}, "о̄"}, // CYRILLIC SMALL LETTER O WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_o, XK_VoidSymbol}, "о̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_o, XK_VoidSymbol}, "о̄"}, {{XK_dead_belowcircumflex, XK_L, XK_VoidSymbol}, "Ḽ"}, // U1E3C | LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW {{XK_Multi_key, XK_parenleft, XK_5, XK_0, XK_parenright, XK_VoidSymbol}, "㊿"}, // U32BF | CIRCLED NUMBER FIFTY {{XK_Multi_key, XK_parenleft, XK_5, XK_KP_0, XK_parenright, XK_VoidSymbol}, "㊿"}, {{XK_Multi_key, XK_parenleft, XK_KP_5, XK_0, XK_parenright, XK_VoidSymbol}, "㊿"}, {{XK_Multi_key, XK_parenleft, XK_KP_5, XK_KP_0, XK_parenright, XK_VoidSymbol}, "㊿"}, {{XK_dead_caron, XK_l, XK_VoidSymbol}, "ľ"}, // U013E | LATIN SMALL LETTER L WITH CARON {{XK_Multi_key, XK_c, XK_l, XK_VoidSymbol}, "ľ"}, {{XK_Multi_key, XK_less, XK_l, XK_VoidSymbol}, "ľ"}, {{XK_Multi_key, XK_l, XK_less, XK_VoidSymbol}, "ľ"}, {{XK_Multi_key, XK_parenleft, XK_kana_TSU, XK_parenright, XK_VoidSymbol}, "㋡"}, // U32E1 | CIRCLED KATAKANA TU {{XK_dead_tilde, XK_A, XK_VoidSymbol}, "Ã"}, // Atilde | LATIN CAPITAL LETTER A WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_A, XK_VoidSymbol}, "Ã"}, {{XK_Multi_key, XK_A, XK_asciitilde, XK_VoidSymbol}, "Ã"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_omicron, XK_VoidSymbol}, "ὂ"}, // U1F42 | GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_omicron, XK_VoidSymbol}, "ὂ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_omicron, XK_VoidSymbol}, "ὂ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_omicron, XK_VoidSymbol}, "ὂ"}, {{XK_dead_abovedot, XK_j, XK_VoidSymbol}, "ȷ"}, // U0237 | LATIN SMALL LETTER DOTLESS J {{XK_dead_circumflex, XK_dead_belowdot, XK_e, XK_VoidSymbol}, "ệ"}, // U1EC7 | LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW {{XK_dead_circumflex, XK_Multi_key, XK_exclam, XK_e, XK_VoidSymbol}, "ệ"}, {{XK_Multi_key, XK_asciicircum, XK_dead_belowdot, XK_e, XK_VoidSymbol}, "ệ"}, {{XK_Multi_key, XK_asciicircum, XK_exclam, XK_e, XK_VoidSymbol}, "ệ"}, {{XK_dead_belowdot, XK_ecircumflex, XK_VoidSymbol}, "ệ"}, {{XK_dead_belowdot, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ệ"}, {{XK_Multi_key, XK_parenleft, XK_V, XK_parenright, XK_VoidSymbol}, "Ⓥ"}, // U24CB | CIRCLED LATIN CAPITAL LETTER V {{XK_dead_acute, XK_Otilde, XK_VoidSymbol}, "Ṍ"}, // U1E4C | LATIN CAPITAL LETTER O WITH TILDE AND ACUTE {{XK_Multi_key, XK_acute, XK_Otilde, XK_VoidSymbol}, "Ṍ"}, {{XK_Multi_key, XK_apostrophe, XK_Otilde, XK_VoidSymbol}, "Ṍ"}, {{XK_dead_acute, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ṍ"}, {{XK_dead_acute, XK_Multi_key, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ṍ"}, {{XK_Multi_key, XK_acute, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ṍ"}, {{XK_Multi_key, XK_acute, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ṍ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ṍ"}, {{XK_Multi_key, XK_apostrophe, XK_asciitilde, XK_O, XK_VoidSymbol}, "Ṍ"}, {{XK_dead_tilde, XK_Oacute, XK_VoidSymbol}, "Ṍ"}, {{XK_dead_tilde, XK_dead_acute, XK_O, XK_VoidSymbol}, "Ṍ"}, {{XK_dead_breve, XK_O, XK_VoidSymbol}, "Ŏ"}, // U014E | LATIN CAPITAL LETTER O WITH BREVE {{XK_Multi_key, XK_U, XK_O, XK_VoidSymbol}, "Ŏ"}, {{XK_Multi_key, XK_b, XK_O, XK_VoidSymbol}, "Ŏ"}, {{XK_dead_grave, XK_Cyrillic_ie, XK_VoidSymbol}, "ѐ"}, // U0450 | CYRILLIC SMALL LETTER IE WITH GRAVE {{XK_Multi_key, XK_grave, XK_Cyrillic_ie, XK_VoidSymbol}, "ѐ"}, {{XK_dead_acute, XK_O, XK_VoidSymbol}, "Ó"}, // Oacute | LATIN CAPITAL LETTER O WITH ACUTE {{XK_Multi_key, XK_acute, XK_O, XK_VoidSymbol}, "Ó"}, {{XK_Multi_key, XK_O, XK_acute, XK_VoidSymbol}, "Ó"}, {{XK_Multi_key, XK_apostrophe, XK_O, XK_VoidSymbol}, "Ó"}, {{XK_Multi_key, XK_O, XK_apostrophe, XK_VoidSymbol}, "Ó"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὒ"}, // U1F52 | GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὒ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὒ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὒ"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_4, XK_parenright, XK_VoidSymbol}, "㉔"}, // U3254 | CIRCLED NUMBER TWENTY FOUR {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_4, XK_parenright, XK_VoidSymbol}, "㉔"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_4, XK_parenright, XK_VoidSymbol}, "㉔"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_4, XK_parenright, XK_VoidSymbol}, "㉔"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_4, XK_parenright, XK_VoidSymbol}, "㉔"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_4, XK_parenright, XK_VoidSymbol}, "㉔"}, {{XK_dead_tilde, XK_ocircumflex, XK_VoidSymbol}, "ỗ"}, // U1ED7 | LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE {{XK_Multi_key, XK_asciitilde, XK_ocircumflex, XK_VoidSymbol}, "ỗ"}, {{XK_dead_tilde, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ỗ"}, {{XK_dead_tilde, XK_Multi_key, XK_asciicircum, XK_o, XK_VoidSymbol}, "ỗ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ỗ"}, {{XK_Multi_key, XK_asciitilde, XK_asciicircum, XK_o, XK_VoidSymbol}, "ỗ"}, {{XK_dead_circumflex, XK_otilde, XK_VoidSymbol}, "ỗ"}, {{XK_dead_circumflex, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ỗ"}, {{XK_dead_voiced_sound, XK_kana_SHI, XK_VoidSymbol}, "ジ"}, // U30B8 | KATAKANA LETTER ZI {{XK_dead_caron, XK_Udiaeresis, XK_VoidSymbol}, "Ǚ"}, // U01D9 | LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON {{XK_Multi_key, XK_c, XK_Udiaeresis, XK_VoidSymbol}, "Ǚ"}, {{XK_dead_caron, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǚ"}, {{XK_dead_caron, XK_Multi_key, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǚ"}, {{XK_Multi_key, XK_c, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǚ"}, {{XK_Multi_key, XK_c, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǚ"}, {{XK_dead_caron, XK_V, XK_VoidSymbol}, "Ǚ"}, {{XK_dead_diaeresis, XK_dead_caron, XK_U, XK_VoidSymbol}, "Ǚ"}, {{XK_dead_iota, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾼ"}, // U1FBC | GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾼ"}, {{XK_Multi_key, XK_parenleft, XK_l, XK_parenright, XK_VoidSymbol}, "ⓛ"}, // U24DB | CIRCLED LATIN SMALL LETTER L {{XK_Multi_key, XK_parenleft, XK_4, XK_2, XK_parenright, XK_VoidSymbol}, "㊷"}, // U32B7 | CIRCLED NUMBER FORTY TWO {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "㊷"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_2, XK_parenright, XK_VoidSymbol}, "㊷"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_2, XK_parenright, XK_VoidSymbol}, "㊷"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "㊷"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_2, XK_parenright, XK_VoidSymbol}, "㊷"}, {{XK_dead_macron, XK_dead_belowdot, XK_R, XK_VoidSymbol}, "Ṝ"}, // U1E5C | LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON {{XK_dead_macron, XK_Multi_key, XK_exclam, XK_R, XK_VoidSymbol}, "Ṝ"}, {{XK_Multi_key, XK_macron, XK_dead_belowdot, XK_R, XK_VoidSymbol}, "Ṝ"}, {{XK_Multi_key, XK_macron, XK_exclam, XK_R, XK_VoidSymbol}, "Ṝ"}, {{XK_Multi_key, XK_underscore, XK_dead_belowdot, XK_R, XK_VoidSymbol}, "Ṝ"}, {{XK_Multi_key, XK_underscore, XK_exclam, XK_R, XK_VoidSymbol}, "Ṝ"}, {{XK_dead_belowdot, XK_dead_macron, XK_R, XK_VoidSymbol}, "Ṝ"}, {{XK_Multi_key, XK_parenleft, XK_kana_TA, XK_parenright, XK_VoidSymbol}, "㋟"}, // U32DF | CIRCLED KATAKANA TA {{XK_dead_cedilla, XK_S, XK_VoidSymbol}, "Ş"}, // U015E | LATIN CAPITAL LETTER S WITH CEDILLA {{XK_Multi_key, XK_comma, XK_S, XK_VoidSymbol}, "Ş"}, {{XK_Multi_key, XK_S, XK_comma, XK_VoidSymbol}, "Ş"}, {{XK_Multi_key, XK_cedilla, XK_S, XK_VoidSymbol}, "Ş"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_parenright, XK_VoidSymbol}, "①"}, // U2460 | CIRCLED DIGIT ONE {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_parenright, XK_VoidSymbol}, "①"}, {{XK_dead_tilde, XK_a, XK_VoidSymbol}, "ã"}, // atilde | LATIN SMALL LETTER A WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_a, XK_VoidSymbol}, "ã"}, {{XK_Multi_key, XK_a, XK_asciitilde, XK_VoidSymbol}, "ã"}, {{XK_dead_grave, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὢ"}, // U1F62 | GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὢ"}, {{XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὢ"}, {{XK_Multi_key, XK_grave, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὢ"}, {{XK_Multi_key, XK_less, XK_equal, XK_VoidSymbol}, "≤"}, // U2264 | LESS-THAN OR EQUAL TO {{XK_Multi_key, XK_less, XK_underscore, XK_VoidSymbol}, "≤"}, {{XK_Multi_key, XK_underscore, XK_less, XK_VoidSymbol}, "≤"}, {{XK_dead_hook, XK_u, XK_VoidSymbol}, "ủ"}, // U1EE7 | LATIN SMALL LETTER U WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_u, XK_VoidSymbol}, "ủ"}, {{XK_dead_caron, XK_k, XK_VoidSymbol}, "ǩ"}, // U01E9 | LATIN SMALL LETTER K WITH CARON {{XK_Multi_key, XK_c, XK_k, XK_VoidSymbol}, "ǩ"}, {{XK_dead_hook, XK_h, XK_VoidSymbol}, "ɦ"}, // U0266 | LATIN SMALL LETTER H WITH HOOK {{XK_Multi_key, XK_diaeresis, XK_dead_grave, XK_VoidSymbol}, "῭"}, // U1FED | GREEK DIALYTIKA AND VARIA {{XK_Multi_key, XK_diaeresis, XK_grave, XK_VoidSymbol}, "῭"}, {{XK_Multi_key, XK_numbersign, XK_S, XK_VoidSymbol}, "♬"}, // U266c | BEAMED SIXTEENTH NOTES {{XK_Multi_key, XK_parenleft, XK_kana_MI, XK_parenright, XK_VoidSymbol}, "㋯"}, // U32EF | CIRCLED KATAKANA MI {{XK_dead_abovering, XK_U, XK_VoidSymbol}, "Ů"}, // U016E | LATIN CAPITAL LETTER U WITH RING ABOVE {{XK_Multi_key, XK_o, XK_U, XK_VoidSymbol}, "Ů"}, {{XK_Multi_key, XK_asterisk, XK_U, XK_VoidSymbol}, "Ů"}, {{XK_Multi_key, XK_U, XK_asterisk, XK_VoidSymbol}, "Ů"}, {{XK_dead_tilde, XK_nobreakspace, XK_VoidSymbol}, "̃"}, // U0303 | COMBINING TILDE {{XK_Multi_key, XK_parenleft, XK_1, XK_7, XK_parenright, XK_VoidSymbol}, "⑰"}, // U2470 | CIRCLED NUMBER SEVENTEEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_7, XK_parenright, XK_VoidSymbol}, "⑰"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_7, XK_parenright, XK_VoidSymbol}, "⑰"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_7, XK_parenright, XK_VoidSymbol}, "⑰"}, {{XK_dead_acute, XK_o, XK_VoidSymbol}, "ó"}, // oacute | LATIN SMALL LETTER O WITH ACUTE {{XK_Multi_key, XK_acute, XK_o, XK_VoidSymbol}, "ó"}, {{XK_Multi_key, XK_o, XK_acute, XK_VoidSymbol}, "ó"}, {{XK_Multi_key, XK_apostrophe, XK_o, XK_VoidSymbol}, "ó"}, {{XK_Multi_key, XK_o, XK_apostrophe, XK_VoidSymbol}, "ó"}, {{XK_dead_grave, XK_Greek_epsilon, XK_VoidSymbol}, "ὲ"}, // U1F72 | GREEK SMALL LETTER EPSILON WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_epsilon, XK_VoidSymbol}, "ὲ"}, {{XK_dead_hook, XK_schwa, XK_VoidSymbol}, "ɚ"}, // U025A | LATIN SMALL LETTER SCHWA WITH HOOK {{XK_dead_currency, XK_b, XK_VoidSymbol}, "฿"}, // Thai_baht | THAI CURRENCY SYMBOL BAHT {{XK_dead_hook, XK_y, XK_VoidSymbol}, "ỷ"}, // U1EF7 | LATIN SMALL LETTER Y WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_y, XK_VoidSymbol}, "ỷ"}, {{XK_dead_grave, XK_n, XK_VoidSymbol}, "ǹ"}, // U01F9 | LATIN SMALL LETTER N WITH GRAVE {{XK_Multi_key, XK_grave, XK_n, XK_VoidSymbol}, "ǹ"}, {{XK_dead_circumflex, XK_8, XK_VoidSymbol}, "⁸"}, // U2078 | SUPERSCRIPT EIGHT {{XK_Multi_key, XK_asciicircum, XK_8, XK_VoidSymbol}, "⁸"}, {{XK_dead_circumflex, XK_KP_8, XK_VoidSymbol}, "⁸"}, {{XK_Multi_key, XK_asciicircum, XK_KP_8, XK_VoidSymbol}, "⁸"}, {{XK_dead_iota, XK_space, XK_VoidSymbol}, "ͺ"}, // U37a | GREEK YPOGEGRAMMENI {{XK_dead_iota, XK_dead_iota, XK_VoidSymbol}, "ͺ"}, {{XK_dead_tilde, XK_V, XK_VoidSymbol}, "Ṽ"}, // U1E7C | LATIN CAPITAL LETTER V WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_V, XK_VoidSymbol}, "Ṽ"}, {{XK_dead_caron, XK_z, XK_VoidSymbol}, "ž"}, // U017E | LATIN SMALL LETTER Z WITH CARON {{XK_Multi_key, XK_c, XK_z, XK_VoidSymbol}, "ž"}, {{XK_Multi_key, XK_v, XK_z, XK_VoidSymbol}, "ž"}, {{XK_Multi_key, XK_less, XK_z, XK_VoidSymbol}, "ž"}, {{XK_Multi_key, XK_z, XK_less, XK_VoidSymbol}, "ž"}, {{XK_dead_circumflex, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̂"}, // CYRILLIC CAPITAL LETTER ER WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̂"}, {{XK_dead_iota, XK_dead_grave, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, // U1F82 | GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾂ"}, {{XK_dead_hook, XK_t, XK_VoidSymbol}, "ƭ"}, // U01AD | LATIN SMALL LETTER T WITH HOOK {{XK_dead_belowmacron, XK_b, XK_VoidSymbol}, "ḇ"}, // U1E07 | LATIN SMALL LETTER B WITH LINE BELOW {{XK_dead_voiced_sound, XK_kana_TA, XK_VoidSymbol}, "ダ"}, // U30C0 | KATAKANA LETTER DA {{XK_dead_circumflex, XK_c, XK_VoidSymbol}, "ĉ"}, // U0109 | LATIN SMALL LETTER C WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_c, XK_VoidSymbol}, "ĉ"}, {{XK_Multi_key, XK_underscore, XK_8, XK_VoidSymbol}, "₈"}, // U2088 | SUBSCRIPT EIGHT {{XK_Multi_key, XK_underscore, XK_KP_8, XK_VoidSymbol}, "₈"}, {{XK_dead_caron, XK_8, XK_VoidSymbol}, "₈"}, {{XK_dead_acute, XK_Greek_IOTA, XK_VoidSymbol}, "Ί"}, // U038A | GREEK CAPITAL LETTER IOTA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_IOTA, XK_VoidSymbol}, "Ί"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_IOTA, XK_VoidSymbol}, "Ί"}, {{XK_Multi_key, XK_Greek_IOTA, XK_apostrophe, XK_VoidSymbol}, "Ί"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἅ"}, // U1F0D | GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἅ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἅ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἅ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἅ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἅ"}, {{XK_dead_diaeresis, XK_X, XK_VoidSymbol}, "Ẍ"}, // U1E8C | LATIN CAPITAL LETTER X WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_X, XK_VoidSymbol}, "Ẍ"}, {{XK_dead_circumflex, XK_parenright, XK_VoidSymbol}, "⁾"}, // U207E | SUPERSCRIPT RIGHT PARENTHESIS {{XK_Multi_key, XK_asciicircum, XK_parenright, XK_VoidSymbol}, "⁾"}, {{XK_Multi_key, XK_minus, XK_minus, XK_period, XK_VoidSymbol}, "–"}, // U2013 | EN DASH {{XK_dead_iota, XK_dead_grave, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, // U1F92 | GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾒ"}, {{XK_dead_acute, XK_emacron, XK_VoidSymbol}, "ḗ"}, // U1E17 | LATIN SMALL LETTER E WITH MACRON AND ACUTE {{XK_Multi_key, XK_acute, XK_emacron, XK_VoidSymbol}, "ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_emacron, XK_VoidSymbol}, "ḗ"}, {{XK_dead_acute, XK_dead_macron, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_dead_acute, XK_Multi_key, XK_macron, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_dead_acute, XK_Multi_key, XK_underscore, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_Multi_key, XK_acute, XK_dead_macron, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_Multi_key, XK_acute, XK_macron, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_Multi_key, XK_acute, XK_underscore, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_macron, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_macron, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_underscore, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_dead_macron, XK_eacute, XK_VoidSymbol}, "ḗ"}, {{XK_dead_macron, XK_dead_acute, XK_e, XK_VoidSymbol}, "ḗ"}, {{XK_dead_belowcircumflex, XK_E, XK_VoidSymbol}, "Ḙ"}, // U1E18 | LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW {{XK_dead_ogonek, XK_e, XK_VoidSymbol}, "ę"}, // U0119 | LATIN SMALL LETTER E WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_e, XK_VoidSymbol}, "ę"}, {{XK_Multi_key, XK_comma, XK_e, XK_VoidSymbol}, "ę"}, {{XK_Multi_key, XK_e, XK_comma, XK_VoidSymbol}, "ę"}, {{XK_dead_belowmacron, XK_T, XK_VoidSymbol}, "Ṯ"}, // U1E6E | LATIN CAPITAL LETTER T WITH LINE BELOW {{XK_dead_acute, XK_dead_dasia, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἕ"}, // U1F1D | GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἕ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἕ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἕ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἕ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἕ"}, {{XK_dead_caron, XK_h, XK_VoidSymbol}, "ȟ"}, // U021F | LATIN SMALL LETTER H WITH CARON {{XK_Multi_key, XK_c, XK_h, XK_VoidSymbol}, "ȟ"}, {{XK_dead_currency, XK_O, XK_VoidSymbol}, "૱"}, // U0AF1 | GUJARATI RUPEE SIGN {{XK_Multi_key, XK_plus, XK_plus, XK_VoidSymbol}, "#"}, // numbersign | NUMBER SIGN {{XK_dead_iota, XK_dead_grave, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, // U1FA2 | GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾢ"}, {{XK_dead_stroke, XK_e, XK_VoidSymbol}, "ɇ"}, // U0247 | LATIN SMALL LETTER E WITH STROKE {{XK_dead_diaeresis, XK_h, XK_VoidSymbol}, "ḧ"}, // U1E27 | LATIN SMALL LETTER H WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_h, XK_VoidSymbol}, "ḧ"}, {{XK_dead_grave, XK_Greek_alpha, XK_VoidSymbol}, "ὰ"}, // U1F70 | GREEK SMALL LETTER ALPHA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_alpha, XK_VoidSymbol}, "ὰ"}, {{XK_dead_tilde, XK_i, XK_VoidSymbol}, "ĩ"}, // U0129 | LATIN SMALL LETTER I WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_i, XK_VoidSymbol}, "ĩ"}, {{XK_Multi_key, XK_i, XK_asciitilde, XK_VoidSymbol}, "ĩ"}, {{XK_dead_diaeresis, XK_dead_diaeresis, XK_VoidSymbol}, "¨"}, // diaeresis | DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_quotedbl, XK_VoidSymbol}, "¨"}, {{XK_dead_diaeresis, XK_Greek_IOTA, XK_VoidSymbol}, "Ϊ"}, // U03AA | GREEK CAPITAL LETTER IOTA WITH DIALYTIKA {{XK_Multi_key, XK_quotedbl, XK_Greek_IOTA, XK_VoidSymbol}, "Ϊ"}, {{XK_Multi_key, XK_Greek_IOTA, XK_quotedbl, XK_VoidSymbol}, "Ϊ"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἥ"}, // U1F2D | GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἥ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἥ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἥ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἥ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἥ"}, {{XK_dead_circumflex, XK_dead_belowdot, XK_A, XK_VoidSymbol}, "Ậ"}, // U1EAC | LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW {{XK_dead_circumflex, XK_Multi_key, XK_exclam, XK_A, XK_VoidSymbol}, "Ậ"}, {{XK_Multi_key, XK_asciicircum, XK_dead_belowdot, XK_A, XK_VoidSymbol}, "Ậ"}, {{XK_Multi_key, XK_asciicircum, XK_exclam, XK_A, XK_VoidSymbol}, "Ậ"}, {{XK_dead_belowdot, XK_Acircumflex, XK_VoidSymbol}, "Ậ"}, {{XK_dead_belowdot, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ậ"}, {{XK_dead_abovedot, XK_o, XK_VoidSymbol}, "ȯ"}, // U022F | LATIN SMALL LETTER O WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_o, XK_VoidSymbol}, "ȯ"}, {{XK_dead_iota, XK_dead_grave, XK_Greek_alpha, XK_VoidSymbol}, "ᾲ"}, // U1FB2 | GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_grave, XK_Greek_alpha, XK_VoidSymbol}, "ᾲ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_Greek_alpha, XK_VoidSymbol}, "ᾲ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_Greek_alpha, XK_VoidSymbol}, "ᾲ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_9, XK_parenright, XK_VoidSymbol}, "㊴"}, // U32B4 | CIRCLED NUMBER THIRTY NINE {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_9, XK_parenright, XK_VoidSymbol}, "㊴"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_9, XK_parenright, XK_VoidSymbol}, "㊴"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_9, XK_parenright, XK_VoidSymbol}, "㊴"}, {{XK_dead_belowdot, XK_l, XK_VoidSymbol}, "ḷ"}, // U1E37 | LATIN SMALL LETTER L WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_l, XK_VoidSymbol}, "ḷ"}, {{XK_dead_acute, XK_L, XK_VoidSymbol}, "Ĺ"}, // U0139 | LATIN CAPITAL LETTER L WITH ACUTE {{XK_Multi_key, XK_acute, XK_L, XK_VoidSymbol}, "Ĺ"}, {{XK_Multi_key, XK_apostrophe, XK_L, XK_VoidSymbol}, "Ĺ"}, {{XK_Multi_key, XK_L, XK_apostrophe, XK_VoidSymbol}, "Ĺ"}, {{XK_dead_cedilla, XK_space, XK_VoidSymbol}, "¸"}, // cedilla | CEDILLA {{XK_dead_cedilla, XK_dead_cedilla, XK_VoidSymbol}, "¸"}, {{XK_Multi_key, XK_comma, XK_space, XK_VoidSymbol}, "¸"}, {{XK_Multi_key, XK_space, XK_comma, XK_VoidSymbol}, "¸"}, {{XK_Multi_key, XK_comma, XK_comma, XK_VoidSymbol}, "¸"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἵ"}, // U1F3D | GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἵ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἵ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἵ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἵ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἵ"}, {{XK_dead_tilde, XK_E, XK_VoidSymbol}, "Ẽ"}, // U1EBC | LATIN CAPITAL LETTER E WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_E, XK_VoidSymbol}, "Ẽ"}, {{XK_Multi_key, XK_parenleft, XK_K, XK_parenright, XK_VoidSymbol}, "Ⓚ"}, // U24C0 | CIRCLED LATIN CAPITAL LETTER K {{XK_dead_iota, XK_dead_grave, XK_Greek_eta, XK_VoidSymbol}, "ῂ"}, // U1FC2 | GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_grave, XK_Greek_eta, XK_VoidSymbol}, "ῂ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_Greek_eta, XK_VoidSymbol}, "ῂ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_Greek_eta, XK_VoidSymbol}, "ῂ"}, {{XK_Multi_key, XK_less, XK_greater, XK_VoidSymbol}, "⋄"}, // U22c4 | < > DIAMOND OPERATOR {{XK_Multi_key, XK_greater, XK_less, XK_VoidSymbol}, "⋄"}, {{XK_dead_belowdot, XK_n, XK_VoidSymbol}, "ṇ"}, // U1E47 | LATIN SMALL LETTER N WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_n, XK_VoidSymbol}, "ṇ"}, {{XK_dead_grave, XK_E, XK_VoidSymbol}, "È"}, // Egrave | LATIN CAPITAL LETTER E WITH GRAVE {{XK_Multi_key, XK_grave, XK_E, XK_VoidSymbol}, "È"}, {{XK_Multi_key, XK_E, XK_grave, XK_VoidSymbol}, "È"}, {{XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ϊ"}, // U03CA | GREEK SMALL LETTER IOTA WITH DIALYTIKA {{XK_Multi_key, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ϊ"}, {{XK_Multi_key, XK_Greek_iota, XK_quotedbl, XK_VoidSymbol}, "ϊ"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὅ"}, // U1F4D | GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὅ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὅ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὅ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὅ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὅ"}, {{XK_dead_belowdot, XK_O, XK_VoidSymbol}, "Ọ"}, // U1ECC | LATIN CAPITAL LETTER O WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_O, XK_VoidSymbol}, "Ọ"}, {{XK_dead_stroke, XK_y, XK_VoidSymbol}, "ɏ"}, // U024F | LATIN SMALL LETTER Y WITH STROKE {{XK_dead_caron, XK_a, XK_VoidSymbol}, "ǎ"}, // U01CE | LATIN SMALL LETTER A WITH CARON {{XK_Multi_key, XK_c, XK_a, XK_VoidSymbol}, "ǎ"}, {{XK_dead_breve, XK_Cyrillic_A, XK_VoidSymbol}, "Ӑ"}, // U04D0 | CYRILLIC CAPITAL LETTER A WITH BREVE {{XK_Multi_key, XK_U, XK_Cyrillic_A, XK_VoidSymbol}, "Ӑ"}, {{XK_Multi_key, XK_b, XK_Cyrillic_A, XK_VoidSymbol}, "Ӑ"}, {{XK_dead_grave, XK_Greek_iotadieresis, XK_VoidSymbol}, "ῒ"}, // U1FD2 | GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA {{XK_Multi_key, XK_grave, XK_Greek_iotadieresis, XK_VoidSymbol}, "ῒ"}, {{XK_dead_grave, XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ῒ"}, {{XK_dead_grave, XK_Multi_key, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ῒ"}, {{XK_Multi_key, XK_grave, XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ῒ"}, {{XK_Multi_key, XK_grave, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ῒ"}, {{XK_Multi_key, XK_parenleft, XK_kana_O, XK_parenright, XK_VoidSymbol}, "㋔"}, // U32D4 | CIRCLED KATAKANA O {{XK_dead_abovedot, XK_p, XK_VoidSymbol}, "ṗ"}, // U1E57 | LATIN SMALL LETTER P WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_p, XK_VoidSymbol}, "ṗ"}, {{XK_Multi_key, XK_p, XK_period, XK_VoidSymbol}, "ṗ"}, {{XK_dead_caron, XK_r, XK_VoidSymbol}, "ř"}, // U0159 | LATIN SMALL LETTER R WITH CARON {{XK_Multi_key, XK_c, XK_r, XK_VoidSymbol}, "ř"}, {{XK_Multi_key, XK_less, XK_r, XK_VoidSymbol}, "ř"}, {{XK_Multi_key, XK_r, XK_less, XK_VoidSymbol}, "ř"}, {{XK_dead_stroke, XK_O, XK_VoidSymbol}, "Ø"}, // Oslash | LATIN CAPITAL LETTER O WITH STROKE {{XK_Multi_key, XK_slash, XK_O, XK_VoidSymbol}, "Ø"}, {{XK_Multi_key, XK_O, XK_slash, XK_VoidSymbol}, "Ø"}, {{XK_Multi_key, XK_KP_Divide, XK_O, XK_VoidSymbol}, "Ø"}, {{XK_dead_acute, XK_Cyrillic_ER, XK_VoidSymbol}, "Р́"}, // CYRILLIC CAPITAL LETTER ER WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_ER, XK_VoidSymbol}, "Р́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_ER, XK_VoidSymbol}, "Р́"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὕ"}, // U1F5D | GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὕ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὕ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὕ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὕ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὕ"}, {{XK_dead_grave, XK_Ohorn, XK_VoidSymbol}, "Ờ"}, // U1EDC | LATIN CAPITAL LETTER O WITH HORN AND GRAVE {{XK_Multi_key, XK_grave, XK_Ohorn, XK_VoidSymbol}, "Ờ"}, {{XK_dead_grave, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ờ"}, {{XK_dead_grave, XK_Multi_key, XK_plus, XK_O, XK_VoidSymbol}, "Ờ"}, {{XK_Multi_key, XK_grave, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ờ"}, {{XK_Multi_key, XK_grave, XK_plus, XK_O, XK_VoidSymbol}, "Ờ"}, {{XK_dead_horn, XK_Ograve, XK_VoidSymbol}, "Ờ"}, {{XK_dead_horn, XK_dead_grave, XK_O, XK_VoidSymbol}, "Ờ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_5, XK_parenright, XK_VoidSymbol}, "㉟"}, // U325F | CIRCLED NUMBER THIRTY FIVE {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_5, XK_parenright, XK_VoidSymbol}, "㉟"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_5, XK_parenright, XK_VoidSymbol}, "㉟"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_5, XK_parenright, XK_VoidSymbol}, "㉟"}, {{XK_dead_macron, XK_Adiaeresis, XK_VoidSymbol}, "Ǟ"}, // U01DE | LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON {{XK_Multi_key, XK_macron, XK_Adiaeresis, XK_VoidSymbol}, "Ǟ"}, {{XK_Multi_key, XK_underscore, XK_Adiaeresis, XK_VoidSymbol}, "Ǟ"}, {{XK_dead_macron, XK_dead_diaeresis, XK_A, XK_VoidSymbol}, "Ǟ"}, {{XK_dead_macron, XK_Multi_key, XK_quotedbl, XK_A, XK_VoidSymbol}, "Ǟ"}, {{XK_Multi_key, XK_macron, XK_dead_diaeresis, XK_A, XK_VoidSymbol}, "Ǟ"}, {{XK_Multi_key, XK_macron, XK_quotedbl, XK_A, XK_VoidSymbol}, "Ǟ"}, {{XK_Multi_key, XK_underscore, XK_dead_diaeresis, XK_A, XK_VoidSymbol}, "Ǟ"}, {{XK_Multi_key, XK_underscore, XK_quotedbl, XK_A, XK_VoidSymbol}, "Ǟ"}, {{XK_dead_diaeresis, XK_Amacron, XK_VoidSymbol}, "Ǟ"}, {{XK_dead_diaeresis, XK_dead_macron, XK_A, XK_VoidSymbol}, "Ǟ"}, {{XK_Multi_key, XK_1, XK_9, XK_VoidSymbol}, "⅑"}, // U2151 | VULGAR FRACTION ONE NINTH {{XK_dead_grave, XK_Greek_upsilondieresis, XK_VoidSymbol}, "ῢ"}, // U1FE2 | GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA {{XK_Multi_key, XK_grave, XK_Greek_upsilondieresis, XK_VoidSymbol}, "ῢ"}, {{XK_dead_grave, XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ῢ"}, {{XK_dead_grave, XK_Multi_key, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ῢ"}, {{XK_Multi_key, XK_grave, XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ῢ"}, {{XK_Multi_key, XK_grave, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ῢ"}, {{XK_Multi_key, XK_s, XK_o, XK_VoidSymbol}, "§"}, // section | SECTION SIGN {{XK_Multi_key, XK_o, XK_s, XK_VoidSymbol}, "§"}, {{XK_Multi_key, XK_S, XK_O, XK_VoidSymbol}, "§"}, {{XK_Multi_key, XK_O, XK_S, XK_VoidSymbol}, "§"}, {{XK_Multi_key, XK_s, XK_exclam, XK_VoidSymbol}, "§"}, {{XK_Multi_key, XK_S, XK_exclam, XK_VoidSymbol}, "§"}, {{XK_Multi_key, XK_Cyrillic_pe, XK_Cyrillic_a, XK_VoidSymbol}, "§"}, {{XK_dead_abovedot, XK_scaron, XK_VoidSymbol}, "ṧ"}, // U1E67 | LATIN SMALL LETTER S WITH CARON AND DOT ABOVE {{XK_Multi_key, XK_period, XK_scaron, XK_VoidSymbol}, "ṧ"}, {{XK_dead_abovedot, XK_dead_caron, XK_s, XK_VoidSymbol}, "ṧ"}, {{XK_dead_abovedot, XK_Multi_key, XK_c, XK_s, XK_VoidSymbol}, "ṧ"}, {{XK_Multi_key, XK_period, XK_dead_caron, XK_s, XK_VoidSymbol}, "ṧ"}, {{XK_dead_caron, XK_sabovedot, XK_VoidSymbol}, "ṧ"}, {{XK_dead_caron, XK_dead_abovedot, XK_s, XK_VoidSymbol}, "ṧ"}, {{XK_Multi_key, XK_parenleft, XK_a, XK_parenright, XK_VoidSymbol}, "ⓐ"}, // U24D0 | CIRCLED LATIN SMALL LETTER A {{XK_dead_tilde, XK_u, XK_VoidSymbol}, "ũ"}, // U0169 | LATIN SMALL LETTER U WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_u, XK_VoidSymbol}, "ũ"}, {{XK_Multi_key, XK_u, XK_asciitilde, XK_VoidSymbol}, "ũ"}, {{XK_dead_grave, XK_e, XK_VoidSymbol}, "è"}, // egrave | LATIN SMALL LETTER E WITH GRAVE {{XK_Multi_key, XK_grave, XK_e, XK_VoidSymbol}, "è"}, {{XK_Multi_key, XK_e, XK_grave, XK_VoidSymbol}, "è"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_2, XK_parenright, XK_VoidSymbol}, "⑫"}, // U246B | CIRCLED NUMBER TWELVE {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "⑫"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_2, XK_parenright, XK_VoidSymbol}, "⑫"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_2, XK_parenright, XK_VoidSymbol}, "⑫"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "⑫"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_2, XK_parenright, XK_VoidSymbol}, "⑫"}, {{XK_dead_acute, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὥ"}, // U1F6D | GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὥ"}, {{XK_Multi_key, XK_acute, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὥ"}, {{XK_Multi_key, XK_acute, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὥ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὥ"}, {{XK_Multi_key, XK_apostrophe, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὥ"}, {{XK_dead_hook, XK_Uhorn, XK_VoidSymbol}, "Ử"}, // U1EEC | LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_Uhorn, XK_VoidSymbol}, "Ử"}, {{XK_dead_hook, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ử"}, {{XK_dead_hook, XK_Multi_key, XK_plus, XK_U, XK_VoidSymbol}, "Ử"}, {{XK_Multi_key, XK_question, XK_dead_horn, XK_U, XK_VoidSymbol}, "Ử"}, {{XK_Multi_key, XK_question, XK_plus, XK_U, XK_VoidSymbol}, "Ử"}, {{XK_dead_horn, XK_Uhook, XK_VoidSymbol}, "Ử"}, {{XK_dead_horn, XK_dead_hook, XK_U, XK_VoidSymbol}, "Ử"}, {{XK_dead_stroke, XK_greater, XK_VoidSymbol}, "≯"}, // U226F | NOT GREATER-THAN {{XK_dead_diaeresis, XK_Cyrillic_U, XK_VoidSymbol}, "Ӱ"}, // U04F0 | CYRILLIC CAPITAL LETTER U WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_U, XK_VoidSymbol}, "Ӱ"}, {{XK_dead_iota, XK_dead_grave, XK_Greek_omega, XK_VoidSymbol}, "ῲ"}, // U1FF2 | GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_grave, XK_Greek_omega, XK_VoidSymbol}, "ῲ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_Greek_omega, XK_VoidSymbol}, "ῲ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_Greek_omega, XK_VoidSymbol}, "ῲ"}, {{XK_Multi_key, XK_parenleft, XK_kana_YU, XK_parenright, XK_VoidSymbol}, "㋴"}, // U32F4 | CIRCLED KATAKANA YU {{XK_dead_belowcircumflex, XK_u, XK_VoidSymbol}, "ṷ"}, // U1E77 | LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW {{XK_dead_hook, XK_M, XK_VoidSymbol}, "Ɱ"}, // U2C6E | LATIN CAPITAL LETTER M WITH HOOK {{XK_dead_acute, XK_Z, XK_VoidSymbol}, "Ź"}, // U0179 | LATIN CAPITAL LETTER Z WITH ACUTE {{XK_Multi_key, XK_acute, XK_Z, XK_VoidSymbol}, "Ź"}, {{XK_Multi_key, XK_apostrophe, XK_Z, XK_VoidSymbol}, "Ź"}, {{XK_Multi_key, XK_Z, XK_apostrophe, XK_VoidSymbol}, "Ź"}, {{XK_dead_stroke, XK_o, XK_VoidSymbol}, "ø"}, // oslash | LATIN SMALL LETTER O WITH STROKE {{XK_Multi_key, XK_slash, XK_o, XK_VoidSymbol}, "ø"}, {{XK_Multi_key, XK_o, XK_slash, XK_VoidSymbol}, "ø"}, {{XK_Multi_key, XK_KP_Divide, XK_o, XK_VoidSymbol}, "ø"}, {{XK_dead_acute, XK_Ooblique, XK_VoidSymbol}, "Ǿ"}, // U01FE | LATIN CAPITAL LETTER O WITH STROKE AND ACUTE {{XK_Multi_key, XK_acute, XK_Ooblique, XK_VoidSymbol}, "Ǿ"}, {{XK_Multi_key, XK_apostrophe, XK_Ooblique, XK_VoidSymbol}, "Ǿ"}, {{XK_dead_acute, XK_dead_stroke, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_dead_acute, XK_Multi_key, XK_slash, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_Multi_key, XK_acute, XK_slash, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_Multi_key, XK_apostrophe, XK_slash, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_dead_acute, XK_Multi_key, XK_KP_Divide, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_Multi_key, XK_acute, XK_KP_Divide, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_Multi_key, XK_apostrophe, XK_KP_Divide, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_dead_stroke, XK_dead_acute, XK_O, XK_VoidSymbol}, "Ǿ"}, {{XK_dead_stroke, XK_Oacute, XK_VoidSymbol}, "Ǿ"}, {{XK_dead_abovedot, XK_B, XK_VoidSymbol}, "Ḃ"}, // U1E02 | LATIN CAPITAL LETTER B WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_B, XK_VoidSymbol}, "Ḃ"}, {{XK_Multi_key, XK_B, XK_period, XK_VoidSymbol}, "Ḃ"}, {{XK_Multi_key, XK_F, XK_l, XK_VoidSymbol}, "ffl"}, // Ufb04 | LATIN SMALL LIGATURE FFL {{XK_dead_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, // U1F87 | GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾇ"}, {{XK_Multi_key, XK_underscore, XK_9, XK_VoidSymbol}, "₉"}, // U2089 | SUBSCRIPT NINE {{XK_Multi_key, XK_underscore, XK_KP_9, XK_VoidSymbol}, "₉"}, {{XK_dead_caron, XK_9, XK_VoidSymbol}, "₉"}, {{XK_dead_circumflex, XK_C, XK_VoidSymbol}, "Ĉ"}, // U0108 | LATIN CAPITAL LETTER C WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_C, XK_VoidSymbol}, "Ĉ"}, {{XK_dead_diaeresis, XK_x, XK_VoidSymbol}, "ẍ"}, // U1E8D | LATIN SMALL LETTER X WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_x, XK_VoidSymbol}, "ẍ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἄ"}, // U1F0C | GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἄ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἄ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἄ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἄ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἄ"}, {{XK_dead_acute, XK_Greek_OMEGA, XK_VoidSymbol}, "Ώ"}, // U038F | GREEK CAPITAL LETTER OMEGA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_OMEGA, XK_VoidSymbol}, "Ώ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_OMEGA, XK_VoidSymbol}, "Ώ"}, {{XK_Multi_key, XK_Greek_OMEGA, XK_apostrophe, XK_VoidSymbol}, "Ώ"}, {{XK_Multi_key, XK_1, XK_6, XK_VoidSymbol}, "⅙"}, // U2159 | VULGAR FRACTION ONE SIXTH {{XK_dead_hook, XK_G, XK_VoidSymbol}, "Ɠ"}, // U0193 | LATIN CAPITAL LETTER G WITH HOOK {{XK_dead_belowcircumflex, XK_D, XK_VoidSymbol}, "Ḓ"}, // U1E12 | LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW {{XK_dead_currency, XK_D, XK_VoidSymbol}, "₯"}, // U20AF | DRACHMA SIGN {{XK_dead_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, // U1F97 | GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾗ"}, {{XK_dead_ogonek, XK_E, XK_VoidSymbol}, "Ę"}, // U0118 | LATIN CAPITAL LETTER E WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_E, XK_VoidSymbol}, "Ę"}, {{XK_Multi_key, XK_comma, XK_E, XK_VoidSymbol}, "Ę"}, {{XK_Multi_key, XK_E, XK_comma, XK_VoidSymbol}, "Ę"}, {{XK_dead_belowcomma, XK_T, XK_VoidSymbol}, "Ț"}, // U021A | LATIN CAPITAL LETTER T WITH COMMA BELOW {{XK_dead_acute, XK_dead_psili, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἔ"}, // U1F1C | GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἔ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἔ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἔ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἔ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἔ"}, {{XK_Multi_key, XK_comma, XK_quotedbl, XK_VoidSymbol}, "„"}, // U201e | DOUBLE LOW-9 QUOTATION MARK {{XK_Multi_key, XK_quotedbl, XK_comma, XK_VoidSymbol}, "„"}, {{XK_dead_abovedot, XK_H, XK_VoidSymbol}, "Ḣ"}, // U1E22 | LATIN CAPITAL LETTER H WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_H, XK_VoidSymbol}, "Ḣ"}, {{XK_dead_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, // U1FA7 | GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾧ"}, {{XK_Multi_key, XK_W, XK_equal, XK_VoidSymbol}, "₩"}, // U20a9 | WON SIGN {{XK_Multi_key, XK_equal, XK_W, XK_VoidSymbol}, "₩"}, {{XK_dead_currency, XK_W, XK_VoidSymbol}, "₩"}, {{XK_dead_currency, XK_w, XK_VoidSymbol}, "₩"}, {{XK_dead_tilde, XK_I, XK_VoidSymbol}, "Ĩ"}, // U0128 | LATIN CAPITAL LETTER I WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_I, XK_VoidSymbol}, "Ĩ"}, {{XK_Multi_key, XK_I, XK_asciitilde, XK_VoidSymbol}, "Ĩ"}, {{XK_dead_macron, XK_Odiaeresis, XK_VoidSymbol}, "Ȫ"}, // U022A | LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON {{XK_Multi_key, XK_macron, XK_Odiaeresis, XK_VoidSymbol}, "Ȫ"}, {{XK_Multi_key, XK_underscore, XK_Odiaeresis, XK_VoidSymbol}, "Ȫ"}, {{XK_dead_macron, XK_dead_diaeresis, XK_O, XK_VoidSymbol}, "Ȫ"}, {{XK_dead_macron, XK_Multi_key, XK_quotedbl, XK_O, XK_VoidSymbol}, "Ȫ"}, {{XK_Multi_key, XK_macron, XK_dead_diaeresis, XK_O, XK_VoidSymbol}, "Ȫ"}, {{XK_Multi_key, XK_macron, XK_quotedbl, XK_O, XK_VoidSymbol}, "Ȫ"}, {{XK_Multi_key, XK_underscore, XK_dead_diaeresis, XK_O, XK_VoidSymbol}, "Ȫ"}, {{XK_Multi_key, XK_underscore, XK_quotedbl, XK_O, XK_VoidSymbol}, "Ȫ"}, {{XK_dead_diaeresis, XK_Omacron, XK_VoidSymbol}, "Ȫ"}, {{XK_dead_diaeresis, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ȫ"}, {{XK_dead_circumflex, XK_dead_belowdot, XK_a, XK_VoidSymbol}, "ậ"}, // U1EAD | LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW {{XK_dead_circumflex, XK_Multi_key, XK_exclam, XK_a, XK_VoidSymbol}, "ậ"}, {{XK_Multi_key, XK_asciicircum, XK_dead_belowdot, XK_a, XK_VoidSymbol}, "ậ"}, {{XK_Multi_key, XK_asciicircum, XK_exclam, XK_a, XK_VoidSymbol}, "ậ"}, {{XK_dead_belowdot, XK_acircumflex, XK_VoidSymbol}, "ậ"}, {{XK_dead_belowdot, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ậ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἤ"}, // U1F2C | GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἤ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἤ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἤ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "Ἤ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "Ἤ"}, {{XK_dead_acute, XK_Greek_iota, XK_VoidSymbol}, "ί"}, // U03AF | GREEK SMALL LETTER IOTA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_iota, XK_VoidSymbol}, "ί"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_iota, XK_VoidSymbol}, "ί"}, {{XK_dead_belowdot, XK_K, XK_VoidSymbol}, "Ḳ"}, // U1E32 | LATIN CAPITAL LETTER K WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_K, XK_VoidSymbol}, "Ḳ"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_0, XK_parenright, XK_VoidSymbol}, "㊵"}, // U32B5 | CIRCLED NUMBER FORTY {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_0, XK_parenright, XK_VoidSymbol}, "㊵"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_0, XK_parenright, XK_VoidSymbol}, "㊵"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_0, XK_parenright, XK_VoidSymbol}, "㊵"}, {{XK_Multi_key, XK_underscore, XK_2, XK_VoidSymbol}, "₂"}, // U2082 | SUBSCRIPT TWO {{XK_Multi_key, XK_underscore, XK_KP_Space, XK_VoidSymbol}, "₂"}, {{XK_Multi_key, XK_underscore, XK_KP_2, XK_VoidSymbol}, "₂"}, {{XK_dead_caron, XK_2, XK_VoidSymbol}, "₂"}, {{XK_dead_iota, XK_dead_tilde, XK_Greek_alpha, XK_VoidSymbol}, "ᾷ"}, // U1FB7 | GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_Greek_alpha, XK_VoidSymbol}, "ᾷ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_Greek_alpha, XK_VoidSymbol}, "ᾷ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_Greek_alpha, XK_VoidSymbol}, "ᾷ"}, {{XK_dead_iota, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾈ"}, // U1F88 | GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾈ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾈ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾈ"}, {{XK_dead_circumflex, XK_1, XK_VoidSymbol}, "¹"}, // onesuperior | SUPERSCRIPT ONE {{XK_Multi_key, XK_asciicircum, XK_1, XK_VoidSymbol}, "¹"}, {{XK_dead_circumflex, XK_KP_1, XK_VoidSymbol}, "¹"}, {{XK_Multi_key, XK_asciicircum, XK_KP_1, XK_VoidSymbol}, "¹"}, {{XK_Multi_key, XK_1, XK_asciicircum, XK_VoidSymbol}, "¹"}, {{XK_Multi_key, XK_k, XK_k, XK_VoidSymbol}, "ĸ"}, // U0138 | LATIN SMALL LETTER KRA {{XK_dead_stroke, XK_A, XK_VoidSymbol}, "Ⱥ"}, // U023A | LATIN CAPITAL LETTER A WITH STROKE {{XK_dead_tilde, XK_e, XK_VoidSymbol}, "ẽ"}, // U1EBD | LATIN SMALL LETTER E WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_e, XK_VoidSymbol}, "ẽ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἴ"}, // U1F3C | GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἴ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἴ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἴ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_IOTA, XK_VoidSymbol}, "Ἴ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_IOTA, XK_VoidSymbol}, "Ἴ"}, {{XK_dead_breve, XK_Cyrillic_ZHE, XK_VoidSymbol}, "Ӂ"}, // U04C1 | CYRILLIC CAPITAL LETTER ZHE WITH BREVE {{XK_Multi_key, XK_U, XK_Cyrillic_ZHE, XK_VoidSymbol}, "Ӂ"}, {{XK_Multi_key, XK_b, XK_Cyrillic_ZHE, XK_VoidSymbol}, "Ӂ"}, {{XK_dead_belowdot, XK_M, XK_VoidSymbol}, "Ṃ"}, // U1E42 | LATIN CAPITAL LETTER M WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_M, XK_VoidSymbol}, "Ṃ"}, {{XK_dead_diaeresis, XK_acute, XK_VoidSymbol}, "̈́"}, // U0344 | COMBINING GREEK DIALYTIKA TONOS {{XK_dead_diaeresis, XK_apostrophe, XK_VoidSymbol}, "̈́"}, {{XK_Multi_key, XK_quotedbl, XK_dead_acute, XK_VoidSymbol}, "̈́"}, {{XK_Multi_key, XK_quotedbl, XK_acute, XK_VoidSymbol}, "̈́"}, {{XK_Multi_key, XK_quotedbl, XK_apostrophe, XK_VoidSymbol}, "̈́"}, {{XK_dead_iota, XK_dead_tilde, XK_Greek_eta, XK_VoidSymbol}, "ῇ"}, // U1FC7 | GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_Greek_eta, XK_VoidSymbol}, "ῇ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_Greek_eta, XK_VoidSymbol}, "ῇ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_Greek_eta, XK_VoidSymbol}, "ῇ"}, {{XK_Multi_key, XK_parenleft, XK_q, XK_parenright, XK_VoidSymbol}, "ⓠ"}, // U24E0 | CIRCLED LATIN SMALL LETTER Q {{XK_dead_acute, XK_E, XK_VoidSymbol}, "É"}, // Eacute | LATIN CAPITAL LETTER E WITH ACUTE {{XK_Multi_key, XK_acute, XK_E, XK_VoidSymbol}, "É"}, {{XK_Multi_key, XK_apostrophe, XK_E, XK_VoidSymbol}, "É"}, {{XK_Multi_key, XK_E, XK_apostrophe, XK_VoidSymbol}, "É"}, {{XK_Multi_key, XK_E, XK_acute, XK_VoidSymbol}, "É"}, {{XK_dead_caron, XK_n, XK_VoidSymbol}, "ň"}, // U0148 | LATIN SMALL LETTER N WITH CARON {{XK_Multi_key, XK_c, XK_n, XK_VoidSymbol}, "ň"}, {{XK_Multi_key, XK_less, XK_n, XK_VoidSymbol}, "ň"}, {{XK_Multi_key, XK_n, XK_less, XK_VoidSymbol}, "ň"}, {{XK_dead_macron, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̄"}, // CYRILLIC CAPITAL LETTER IE WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_IE, XK_VoidSymbol}, "Е̄"}, {{XK_dead_belowdot, XK_o, XK_VoidSymbol}, "ọ"}, // U1ECD | LATIN SMALL LETTER O WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_o, XK_VoidSymbol}, "ọ"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὄ"}, // U1F4C | GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὄ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὄ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὄ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὄ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὄ"}, {{XK_dead_breve, XK_Cyrillic_a, XK_VoidSymbol}, "ӑ"}, // U04D1 | CYRILLIC SMALL LETTER A WITH BREVE {{XK_Multi_key, XK_U, XK_Cyrillic_a, XK_VoidSymbol}, "ӑ"}, {{XK_Multi_key, XK_b, XK_Cyrillic_a, XK_VoidSymbol}, "ӑ"}, {{XK_dead_caron, XK_U, XK_VoidSymbol}, "Ǔ"}, // U01D3 | LATIN CAPITAL LETTER U WITH CARON {{XK_Multi_key, XK_c, XK_U, XK_VoidSymbol}, "Ǔ"}, {{XK_dead_acute, XK_Omacron, XK_VoidSymbol}, "Ṓ"}, // U1E52 | LATIN CAPITAL LETTER O WITH MACRON AND ACUTE {{XK_Multi_key, XK_acute, XK_Omacron, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_Omacron, XK_VoidSymbol}, "Ṓ"}, {{XK_dead_acute, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_dead_acute, XK_Multi_key, XK_macron, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_dead_acute, XK_Multi_key, XK_underscore, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_acute, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_acute, XK_macron, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_acute, XK_underscore, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_macron, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_macron, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_apostrophe, XK_underscore, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_dead_macron, XK_Oacute, XK_VoidSymbol}, "Ṓ"}, {{XK_dead_macron, XK_dead_acute, XK_O, XK_VoidSymbol}, "Ṓ"}, {{XK_Multi_key, XK_parenleft, XK_kana_KA, XK_parenright, XK_VoidSymbol}, "㋕"}, // U32D5 | CIRCLED KATAKANA KA {{XK_dead_tilde, XK_Greek_iotadieresis, XK_VoidSymbol}, "ῗ"}, // U1FD7 | GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI {{XK_Multi_key, XK_asciitilde, XK_Greek_iotadieresis, XK_VoidSymbol}, "ῗ"}, {{XK_dead_tilde, XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ῗ"}, {{XK_dead_tilde, XK_Multi_key, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ῗ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_diaeresis, XK_Greek_iota, XK_VoidSymbol}, "ῗ"}, {{XK_Multi_key, XK_asciitilde, XK_quotedbl, XK_Greek_iota, XK_VoidSymbol}, "ῗ"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_3, XK_parenright, XK_VoidSymbol}, "㊸"}, // U32B8 | CIRCLED NUMBER FORTY THREE {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_3, XK_parenright, XK_VoidSymbol}, "㊸"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_3, XK_parenright, XK_VoidSymbol}, "㊸"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_3, XK_parenright, XK_VoidSymbol}, "㊸"}, {{XK_dead_grave, XK_U, XK_VoidSymbol}, "Ù"}, // Ugrave | LATIN CAPITAL LETTER U WITH GRAVE {{XK_Multi_key, XK_grave, XK_U, XK_VoidSymbol}, "Ù"}, {{XK_Multi_key, XK_U, XK_grave, XK_VoidSymbol}, "Ù"}, {{XK_dead_caron, XK_R, XK_VoidSymbol}, "Ř"}, // U0158 | LATIN CAPITAL LETTER R WITH CARON {{XK_Multi_key, XK_c, XK_R, XK_VoidSymbol}, "Ř"}, {{XK_Multi_key, XK_less, XK_R, XK_VoidSymbol}, "Ř"}, {{XK_Multi_key, XK_R, XK_less, XK_VoidSymbol}, "Ř"}, {{XK_dead_invertedbreve, XK_Cyrillic_I, XK_VoidSymbol}, "И̑"}, // CYRILLIC CAPITAL LETTER I WITH COMBINING INVERTED BREVE {{XK_Multi_key, XK_parenleft, XK_3, XK_parenright, XK_VoidSymbol}, "③"}, // U2462 | CIRCLED DIGIT THREE {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_parenright, XK_VoidSymbol}, "③"}, {{XK_dead_grave, XK_ohorn, XK_VoidSymbol}, "ờ"}, // U1EDD | LATIN SMALL LETTER O WITH HORN AND GRAVE {{XK_Multi_key, XK_grave, XK_ohorn, XK_VoidSymbol}, "ờ"}, {{XK_dead_grave, XK_dead_horn, XK_o, XK_VoidSymbol}, "ờ"}, {{XK_dead_grave, XK_Multi_key, XK_plus, XK_o, XK_VoidSymbol}, "ờ"}, {{XK_Multi_key, XK_grave, XK_dead_horn, XK_o, XK_VoidSymbol}, "ờ"}, {{XK_Multi_key, XK_grave, XK_plus, XK_o, XK_VoidSymbol}, "ờ"}, {{XK_dead_horn, XK_ograve, XK_VoidSymbol}, "ờ"}, {{XK_dead_horn, XK_dead_grave, XK_o, XK_VoidSymbol}, "ờ"}, {{XK_dead_circumflex, XK_space, XK_VoidSymbol}, "^"}, // asciicircum | CIRCUMFLEX ACCENT {{XK_dead_circumflex, XK_dead_circumflex, XK_VoidSymbol}, "^"}, {{XK_Multi_key, XK_asciicircum, XK_space, XK_VoidSymbol}, "^"}, {{XK_Multi_key, XK_space, XK_asciicircum, XK_VoidSymbol}, "^"}, {{XK_Multi_key, XK_greater, XK_space, XK_VoidSymbol}, "^"}, {{XK_Multi_key, XK_space, XK_greater, XK_VoidSymbol}, "^"}, {{XK_Multi_key, XK_parenleft, XK_r, XK_parenright, XK_VoidSymbol}, "ⓡ"}, // U24E1 | CIRCLED LATIN SMALL LETTER R {{XK_dead_macron, XK_ae, XK_VoidSymbol}, "ǣ"}, // U01E3 | LATIN SMALL LETTER AE WITH MACRON {{XK_Multi_key, XK_macron, XK_ae, XK_VoidSymbol}, "ǣ"}, {{XK_Multi_key, XK_underscore, XK_ae, XK_VoidSymbol}, "ǣ"}, {{XK_dead_belowdot, XK_S, XK_VoidSymbol}, "Ṣ"}, // U1E62 | LATIN CAPITAL LETTER S WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_S, XK_VoidSymbol}, "Ṣ"}, {{XK_Multi_key, XK_parenleft, XK_kana_NI, XK_parenright, XK_VoidSymbol}, "㋥"}, // U32E5 | CIRCLED KATAKANA NI {{XK_dead_tilde, XK_Greek_upsilondieresis, XK_VoidSymbol}, "ῧ"}, // U1FE7 | GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI {{XK_Multi_key, XK_asciitilde, XK_Greek_upsilondieresis, XK_VoidSymbol}, "ῧ"}, {{XK_dead_tilde, XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ῧ"}, {{XK_dead_tilde, XK_Multi_key, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ῧ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_diaeresis, XK_Greek_upsilon, XK_VoidSymbol}, "ῧ"}, {{XK_Multi_key, XK_asciitilde, XK_quotedbl, XK_Greek_upsilon, XK_VoidSymbol}, "ῧ"}, {{XK_Multi_key, XK_parenleft, XK_7, XK_parenright, XK_VoidSymbol}, "⑦"}, // U2466 | CIRCLED DIGIT SEVEN {{XK_Multi_key, XK_parenleft, XK_KP_7, XK_parenright, XK_VoidSymbol}, "⑦"}, {{XK_dead_acute, XK_e, XK_VoidSymbol}, "é"}, // eacute | LATIN SMALL LETTER E WITH ACUTE {{XK_Multi_key, XK_acute, XK_e, XK_VoidSymbol}, "é"}, {{XK_Multi_key, XK_e, XK_acute, XK_VoidSymbol}, "é"}, {{XK_Multi_key, XK_apostrophe, XK_e, XK_VoidSymbol}, "é"}, {{XK_Multi_key, XK_e, XK_apostrophe, XK_VoidSymbol}, "é"}, {{XK_dead_tilde, XK_U, XK_VoidSymbol}, "Ũ"}, // U0168 | LATIN CAPITAL LETTER U WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_U, XK_VoidSymbol}, "Ũ"}, {{XK_Multi_key, XK_U, XK_asciitilde, XK_VoidSymbol}, "Ũ"}, {{XK_dead_hook, XK_uhorn, XK_VoidSymbol}, "ử"}, // U1EED | LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_uhorn, XK_VoidSymbol}, "ử"}, {{XK_dead_hook, XK_dead_horn, XK_u, XK_VoidSymbol}, "ử"}, {{XK_dead_hook, XK_Multi_key, XK_plus, XK_u, XK_VoidSymbol}, "ử"}, {{XK_Multi_key, XK_question, XK_dead_horn, XK_u, XK_VoidSymbol}, "ử"}, {{XK_Multi_key, XK_question, XK_plus, XK_u, XK_VoidSymbol}, "ử"}, {{XK_dead_horn, XK_uhook, XK_VoidSymbol}, "ử"}, {{XK_dead_horn, XK_dead_hook, XK_u, XK_VoidSymbol}, "ử"}, {{XK_dead_acute, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὤ"}, // U1F6C | GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA {{XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὤ"}, {{XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὤ"}, {{XK_Multi_key, XK_acute, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὤ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὤ"}, {{XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὤ"}, {{XK_dead_diaeresis, XK_Cyrillic_u, XK_VoidSymbol}, "ӱ"}, // U04F1 | CYRILLIC SMALL LETTER U WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_u, XK_VoidSymbol}, "ӱ"}, {{XK_dead_currency, XK_t, XK_VoidSymbol}, "৳"}, // U09F3 | BENGALI RUPEE SIGN {{XK_dead_belowdiaeresis, XK_U, XK_VoidSymbol}, "Ṳ"}, // U1E72 | LATIN CAPITAL LETTER U WITH DIAERESIS BELOW {{XK_Multi_key, XK_parenleft, XK_kana_YO, XK_parenright, XK_VoidSymbol}, "㋵"}, // U32F5 | CIRCLED KATAKANA YO {{XK_dead_iota, XK_dead_tilde, XK_Greek_omega, XK_VoidSymbol}, "ῷ"}, // U1FF7 | GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_Greek_omega, XK_VoidSymbol}, "ῷ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_Greek_omega, XK_VoidSymbol}, "ῷ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_Greek_omega, XK_VoidSymbol}, "ῷ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_8, XK_parenright, XK_VoidSymbol}, "㊳"}, // U32B3 | CIRCLED NUMBER THIRTY EIGHT {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_8, XK_parenright, XK_VoidSymbol}, "㊳"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_8, XK_parenright, XK_VoidSymbol}, "㊳"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_8, XK_parenright, XK_VoidSymbol}, "㊳"}, {{XK_dead_grave, XK_u, XK_VoidSymbol}, "ù"}, // ugrave | LATIN SMALL LETTER U WITH GRAVE {{XK_Multi_key, XK_grave, XK_u, XK_VoidSymbol}, "ù"}, {{XK_Multi_key, XK_u, XK_grave, XK_VoidSymbol}, "ù"}, {{XK_dead_diaeresis, XK_Y, XK_VoidSymbol}, "Ÿ"}, // U0178 | LATIN CAPITAL LETTER Y WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Y, XK_VoidSymbol}, "Ÿ"}, {{XK_Multi_key, XK_Y, XK_quotedbl, XK_VoidSymbol}, "Ÿ"}, {{XK_Multi_key, XK_diaeresis, XK_Y, XK_VoidSymbol}, "Ÿ"}, {{XK_Multi_key, XK_Y, XK_diaeresis, XK_VoidSymbol}, "Ÿ"}, {{XK_dead_grave, XK_Greek_omega, XK_VoidSymbol}, "ὼ"}, // U1F7C | GREEK SMALL LETTER OMEGA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_omega, XK_VoidSymbol}, "ὼ"}, {{XK_dead_tilde, XK_space, XK_VoidSymbol}, "~"}, // asciitilde | TILDE {{XK_dead_tilde, XK_dead_tilde, XK_VoidSymbol}, "~"}, {{XK_Multi_key, XK_asciitilde, XK_space, XK_VoidSymbol}, "~"}, {{XK_Multi_key, XK_space, XK_asciitilde, XK_VoidSymbol}, "~"}, {{XK_Multi_key, XK_minus, XK_space, XK_VoidSymbol}, "~"}, {{XK_Multi_key, XK_space, XK_minus, XK_VoidSymbol}, "~"}, {{XK_dead_diaeresis, XK_Cyrillic_IE, XK_VoidSymbol}, "Ё"}, // U0401 | CYRILLIC CAPITAL LETTER IO {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_IE, XK_VoidSymbol}, "Ё"}, {{XK_dead_breve, XK_a, XK_VoidSymbol}, "ă"}, // U0103 | LATIN SMALL LETTER A WITH BREVE {{XK_Multi_key, XK_U, XK_a, XK_VoidSymbol}, "ă"}, {{XK_Multi_key, XK_b, XK_a, XK_VoidSymbol}, "ă"}, {{XK_Multi_key, XK_a, XK_parenleft, XK_VoidSymbol}, "ă"}, {{XK_dead_acute, XK_W, XK_VoidSymbol}, "Ẃ"}, // U1E82 | LATIN CAPITAL LETTER W WITH ACUTE {{XK_Multi_key, XK_acute, XK_W, XK_VoidSymbol}, "Ẃ"}, {{XK_Multi_key, XK_apostrophe, XK_W, XK_VoidSymbol}, "Ẃ"}, {{XK_Multi_key, XK_braceleft, XK_braceright, XK_VoidSymbol}, "∅"}, // U2205 | EMPTY SET {{XK_dead_macron, XK_Cyrillic_a, XK_VoidSymbol}, "а̄"}, // CYRILLIC SMALL LETTER A WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_a, XK_VoidSymbol}, "а̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_a, XK_VoidSymbol}, "а̄"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἇ"}, // U1F07 | GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἇ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἇ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἇ"}, {{XK_dead_hook, XK_c, XK_VoidSymbol}, "ƈ"}, // U0188 | LATIN SMALL LETTER C WITH HOOK {{XK_dead_belowdot, XK_d, XK_VoidSymbol}, "ḍ"}, // U1E0D | LATIN SMALL LETTER D WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_d, XK_VoidSymbol}, "ḍ"}, {{XK_dead_iota, XK_dead_acute, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, // U1F8C | GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾌ"}, {{XK_Multi_key, XK_underscore, XK_parenright, XK_VoidSymbol}, "₎"}, // U208E | SUBSCRIPT RIGHT PARENTHESIS {{XK_dead_caron, XK_parenright, XK_VoidSymbol}, "₎"}, {{XK_dead_macron, XK_e, XK_VoidSymbol}, "ē"}, // U0113 | LATIN SMALL LETTER E WITH MACRON {{XK_Multi_key, XK_macron, XK_e, XK_VoidSymbol}, "ē"}, {{XK_Multi_key, XK_underscore, XK_e, XK_VoidSymbol}, "ē"}, {{XK_Multi_key, XK_e, XK_underscore, XK_VoidSymbol}, "ē"}, {{XK_Multi_key, XK_minus, XK_e, XK_VoidSymbol}, "ē"}, {{XK_Multi_key, XK_e, XK_minus, XK_VoidSymbol}, "ē"}, {{XK_dead_belowdot, XK_Z, XK_VoidSymbol}, "Ẓ"}, // U1E92 | LATIN CAPITAL LETTER Z WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_Z, XK_VoidSymbol}, "Ẓ"}, {{XK_dead_belowmacron, XK_t, XK_VoidSymbol}, "ṯ"}, // U1E6F | LATIN SMALL LETTER T WITH LINE BELOW {{XK_dead_currency, XK_B, XK_VoidSymbol}, "₱"}, // U20B1 | PESO SIGN {{XK_Multi_key, XK_greater, XK_apostrophe, XK_VoidSymbol}, "’"}, // U2019 | RIGHT SINGLE QUOTATION MARK {{XK_Multi_key, XK_apostrophe, XK_greater, XK_VoidSymbol}, "’"}, {{XK_dead_hook, XK_K, XK_VoidSymbol}, "Ƙ"}, // U0198 | LATIN CAPITAL LETTER K WITH HOOK {{XK_dead_breve, XK_dead_cedilla, XK_e, XK_VoidSymbol}, "ḝ"}, // U1E1D | LATIN SMALL LETTER E WITH CEDILLA AND BREVE {{XK_dead_breve, XK_Multi_key, XK_comma, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_dead_breve, XK_Multi_key, XK_cedilla, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_Multi_key, XK_U, XK_dead_cedilla, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_Multi_key, XK_U, XK_space, XK_comma, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_Multi_key, XK_U, XK_cedilla, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_Multi_key, XK_b, XK_dead_cedilla, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_Multi_key, XK_b, XK_comma, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_Multi_key, XK_b, XK_cedilla, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_dead_cedilla, XK_dead_breve, XK_e, XK_VoidSymbol}, "ḝ"}, {{XK_dead_iota, XK_dead_acute, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, // U1F9C | GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_psili, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenright, XK_Greek_ETA, XK_VoidSymbol}, "ᾜ"}, {{XK_dead_cedilla, XK_g, XK_VoidSymbol}, "ģ"}, // U0123 | LATIN SMALL LETTER G WITH CEDILLA {{XK_Multi_key, XK_comma, XK_g, XK_VoidSymbol}, "ģ"}, {{XK_Multi_key, XK_g, XK_comma, XK_VoidSymbol}, "ģ"}, {{XK_Multi_key, XK_cedilla, XK_g, XK_VoidSymbol}, "ģ"}, {{XK_dead_hook, XK_A, XK_VoidSymbol}, "Ả"}, // U1EA2 | LATIN CAPITAL LETTER A WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_A, XK_VoidSymbol}, "Ả"}, {{XK_dead_belowdot, XK_plus, XK_VoidSymbol}, "⨥"}, // U2A25 | PLUS SIGN WITH DOT BELOW {{XK_dead_voiced_sound, XK_kana_TE, XK_VoidSymbol}, "デ"}, // U30C7 | KATAKANA LETTER DE {{XK_dead_tilde, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἧ"}, // U1F27 | GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἧ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἧ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἧ"}, {{XK_dead_circumflex, XK_Cyrillic_i, XK_VoidSymbol}, "и̂"}, // CYRILLIC SMALL LETTER I WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_i, XK_VoidSymbol}, "и̂"}, {{XK_dead_acute, XK_Cyrillic_i, XK_VoidSymbol}, "и́"}, // CYRILLIC SMALL LETTER I WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_i, XK_VoidSymbol}, "и́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_i, XK_VoidSymbol}, "и́"}, {{XK_Multi_key, XK_C, XK_C, XK_C, XK_P, XK_VoidSymbol}, "☭"}, // U262D | HAMMER AND SICKLE {{XK_dead_iota, XK_dead_acute, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, // U1FAC | GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_acute, XK_Multi_key, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_dead_iota, XK_Multi_key, XK_acute, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_dead_iota, XK_Multi_key, XK_apostrophe, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_acute, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_Multi_key, XK_Greek_iota, XK_acute, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_dead_psili, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_Multi_key, XK_Greek_iota, XK_apostrophe, XK_parenright, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾬ"}, {{XK_Multi_key, XK_o, XK_r, XK_VoidSymbol}, "®"}, // registered | REGISTERED SIGN {{XK_Multi_key, XK_o, XK_R, XK_VoidSymbol}, "®"}, {{XK_Multi_key, XK_O, XK_r, XK_VoidSymbol}, "®"}, {{XK_Multi_key, XK_O, XK_R, XK_VoidSymbol}, "®"}, {{XK_Multi_key, XK_R, XK_O, XK_VoidSymbol}, "®"}, {{XK_Multi_key, XK_i, XK_j, XK_VoidSymbol}, "ij"}, // U0133 | LATIN SMALL LIGATURE IJ {{XK_dead_hook, XK_Abreve, XK_VoidSymbol}, "Ẳ"}, // U1EB2 | LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_Abreve, XK_VoidSymbol}, "Ẳ"}, {{XK_dead_hook, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ẳ"}, {{XK_dead_hook, XK_Multi_key, XK_U, XK_A, XK_VoidSymbol}, "Ẳ"}, {{XK_dead_hook, XK_Multi_key, XK_b, XK_A, XK_VoidSymbol}, "Ẳ"}, {{XK_Multi_key, XK_question, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ẳ"}, {{XK_Multi_key, XK_question, XK_b, XK_A, XK_VoidSymbol}, "Ẳ"}, {{XK_dead_breve, XK_Ahook, XK_VoidSymbol}, "Ẳ"}, {{XK_dead_breve, XK_dead_hook, XK_A, XK_VoidSymbol}, "Ẳ"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἷ"}, // U1F37 | GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἷ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἷ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἷ"}, {{XK_Multi_key, XK_O, XK_A, XK_VoidSymbol}, "Ⓐ"}, // U24B6 | CIRCLED LATIN CAPITAL LETTER A {{XK_Multi_key, XK_parenleft, XK_A, XK_parenright, XK_VoidSymbol}, "Ⓐ"}, {{XK_Multi_key, XK_period, XK_less, XK_VoidSymbol}, "‹"}, // U2039 | SINGLE LEFT-POINTING ANGLE QUOTATION MARK {{XK_Multi_key, XK_parenleft, XK_4, XK_5, XK_parenright, XK_VoidSymbol}, "㊺"}, // U32BA | CIRCLED NUMBER FORTY FIVE {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_5, XK_parenright, XK_VoidSymbol}, "㊺"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_5, XK_parenright, XK_VoidSymbol}, "㊺"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_5, XK_parenright, XK_VoidSymbol}, "㊺"}, {{XK_dead_belowcircumflex, XK_l, XK_VoidSymbol}, "ḽ"}, // U1E3D | LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW {{XK_dead_diaeresis, XK_y, XK_VoidSymbol}, "ÿ"}, // ydiaeresis | LATIN SMALL LETTER Y WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_y, XK_VoidSymbol}, "ÿ"}, {{XK_Multi_key, XK_y, XK_quotedbl, XK_VoidSymbol}, "ÿ"}, {{XK_Multi_key, XK_diaeresis, XK_y, XK_VoidSymbol}, "ÿ"}, {{XK_Multi_key, XK_y, XK_diaeresis, XK_VoidSymbol}, "ÿ"}, {{XK_dead_grave, XK_Cyrillic_a, XK_VoidSymbol}, "а̀"}, // CYRILLIC SMALL LETTER A WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_a, XK_VoidSymbol}, "а̀"}, {{XK_Multi_key, XK_3, XK_4, XK_VoidSymbol}, "¾"}, // threequarters | VULGAR FRACTION THREE QUARTERS {{XK_dead_acute, XK_N, XK_VoidSymbol}, "Ń"}, // U0143 | LATIN CAPITAL LETTER N WITH ACUTE {{XK_Multi_key, XK_acute, XK_N, XK_VoidSymbol}, "Ń"}, {{XK_Multi_key, XK_apostrophe, XK_N, XK_VoidSymbol}, "Ń"}, {{XK_Multi_key, XK_N, XK_apostrophe, XK_VoidSymbol}, "Ń"}, {{XK_dead_hook, XK_Ecircumflex, XK_VoidSymbol}, "Ể"}, // U1EC2 | LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE {{XK_Multi_key, XK_question, XK_Ecircumflex, XK_VoidSymbol}, "Ể"}, {{XK_dead_hook, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ể"}, {{XK_dead_hook, XK_Multi_key, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ể"}, {{XK_Multi_key, XK_question, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ể"}, {{XK_Multi_key, XK_question, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ể"}, {{XK_dead_circumflex, XK_Ehook, XK_VoidSymbol}, "Ể"}, {{XK_dead_circumflex, XK_dead_hook, XK_E, XK_VoidSymbol}, "Ể"}, {{XK_Multi_key, XK_parenleft, XK_Q, XK_parenright, XK_VoidSymbol}, "Ⓠ"}, // U24C6 | CIRCLED LATIN CAPITAL LETTER Q {{XK_dead_invertedbreve, XK_Cyrillic_O, XK_VoidSymbol}, "О̑"}, // CYRILLIC CAPITAL LETTER O WITH COMBINING INVERTED BREVE {{XK_dead_acute, XK_otilde, XK_VoidSymbol}, "ṍ"}, // U1E4D | LATIN SMALL LETTER O WITH TILDE AND ACUTE {{XK_Multi_key, XK_acute, XK_otilde, XK_VoidSymbol}, "ṍ"}, {{XK_Multi_key, XK_apostrophe, XK_otilde, XK_VoidSymbol}, "ṍ"}, {{XK_dead_acute, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ṍ"}, {{XK_dead_acute, XK_Multi_key, XK_asciitilde, XK_o, XK_VoidSymbol}, "ṍ"}, {{XK_Multi_key, XK_acute, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ṍ"}, {{XK_Multi_key, XK_acute, XK_asciitilde, XK_o, XK_VoidSymbol}, "ṍ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ṍ"}, {{XK_Multi_key, XK_apostrophe, XK_asciitilde, XK_o, XK_VoidSymbol}, "ṍ"}, {{XK_dead_tilde, XK_oacute, XK_VoidSymbol}, "ṍ"}, {{XK_dead_tilde, XK_dead_acute, XK_o, XK_VoidSymbol}, "ṍ"}, {{XK_dead_iota, XK_Greek_ETA, XK_VoidSymbol}, "ῌ"}, // U1FCC | GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_ETA, XK_VoidSymbol}, "ῌ"}, {{XK_dead_circumflex, XK_I, XK_VoidSymbol}, "Î"}, // Icircumflex | LATIN CAPITAL LETTER I WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_I, XK_VoidSymbol}, "Î"}, {{XK_Multi_key, XK_I, XK_asciicircum, XK_VoidSymbol}, "Î"}, {{XK_Multi_key, XK_greater, XK_I, XK_VoidSymbol}, "Î"}, {{XK_Multi_key, XK_I, XK_greater, XK_VoidSymbol}, "Î"}, {{XK_dead_diaeresis, XK_Cyrillic_ie, XK_VoidSymbol}, "ё"}, // U0451 | CYRILLIC SMALL LETTER IO {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_ie, XK_VoidSymbol}, "ё"}, {{XK_Multi_key, XK_o, XK_e, XK_VoidSymbol}, "œ"}, // oe | LATIN SMALL LIGATURE OE {{XK_Multi_key, XK_C, XK_r, XK_VoidSymbol}, "₢"}, // U20a2 | CRUZEIRO SIGN {{XK_dead_currency, XK_r, XK_VoidSymbol}, "₢"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_5, XK_parenright, XK_VoidSymbol}, "㉕"}, // U3255 | CIRCLED NUMBER TWENTY FIVE {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_5, XK_parenright, XK_VoidSymbol}, "㉕"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_5, XK_parenright, XK_VoidSymbol}, "㉕"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_5, XK_parenright, XK_VoidSymbol}, "㉕"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_5, XK_parenright, XK_VoidSymbol}, "㉕"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_5, XK_parenright, XK_VoidSymbol}, "㉕"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὗ"}, // U1F57 | GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὗ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὗ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὗ"}, {{XK_dead_breve, XK_Cyrillic_IE, XK_VoidSymbol}, "Ӗ"}, // U04D6 | CYRILLIC CAPITAL LETTER IE WITH BREVE {{XK_Multi_key, XK_U, XK_Cyrillic_IE, XK_VoidSymbol}, "Ӗ"}, {{XK_Multi_key, XK_b, XK_Cyrillic_IE, XK_VoidSymbol}, "Ӗ"}, {{XK_dead_grave, XK_Cyrillic_O, XK_VoidSymbol}, "О̀"}, // CYRILLIC CAPITAL LETTER O WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_O, XK_VoidSymbol}, "О̀"}, {{XK_dead_acute, XK_udiaeresis, XK_VoidSymbol}, "ǘ"}, // U01D8 | LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE {{XK_Multi_key, XK_acute, XK_udiaeresis, XK_VoidSymbol}, "ǘ"}, {{XK_Multi_key, XK_apostrophe, XK_udiaeresis, XK_VoidSymbol}, "ǘ"}, {{XK_dead_acute, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǘ"}, {{XK_dead_acute, XK_Multi_key, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǘ"}, {{XK_Multi_key, XK_acute, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǘ"}, {{XK_Multi_key, XK_acute, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǘ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǘ"}, {{XK_Multi_key, XK_apostrophe, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǘ"}, {{XK_dead_acute, XK_v, XK_VoidSymbol}, "ǘ"}, {{XK_dead_diaeresis, XK_uacute, XK_VoidSymbol}, "ǘ"}, {{XK_dead_diaeresis, XK_dead_acute, XK_u, XK_VoidSymbol}, "ǘ"}, {{XK_dead_circumflex, XK_Cyrillic_O, XK_VoidSymbol}, "О̂"}, // CYRILLIC CAPITAL LETTER O WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_O, XK_VoidSymbol}, "О̂"}, {{XK_Multi_key, XK_parenleft, XK_kana_SA, XK_parenright, XK_VoidSymbol}, "㋚"}, // U32DA | CIRCLED KATAKANA SA {{XK_dead_macron, XK_dead_belowdot, XK_r, XK_VoidSymbol}, "ṝ"}, // U1E5D | LATIN SMALL LETTER R WITH DOT BELOW AND MACRON {{XK_dead_macron, XK_Multi_key, XK_exclam, XK_r, XK_VoidSymbol}, "ṝ"}, {{XK_Multi_key, XK_macron, XK_dead_belowdot, XK_r, XK_VoidSymbol}, "ṝ"}, {{XK_Multi_key, XK_macron, XK_exclam, XK_r, XK_VoidSymbol}, "ṝ"}, {{XK_Multi_key, XK_underscore, XK_dead_belowdot, XK_r, XK_VoidSymbol}, "ṝ"}, {{XK_Multi_key, XK_underscore, XK_exclam, XK_r, XK_VoidSymbol}, "ṝ"}, {{XK_dead_belowdot, XK_dead_macron, XK_r, XK_VoidSymbol}, "ṝ"}, {{XK_dead_circumflex, XK_minus, XK_VoidSymbol}, "⁻"}, // U207B | SUPERSCRIPT MINUS {{XK_Multi_key, XK_T, XK_H, XK_VoidSymbol}, "Þ"}, // THORN | LATIN CAPITAL LETTER THORN {{XK_Multi_key, XK_parenleft, XK_2, XK_parenright, XK_VoidSymbol}, "②"}, // U2461 | CIRCLED DIGIT TWO {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_parenright, XK_VoidSymbol}, "②"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_parenright, XK_VoidSymbol}, "②"}, {{XK_dead_voiced_sound, XK_kana_KA, XK_VoidSymbol}, "ガ"}, // U30AC | KATAKANA LETTER GA {{XK_dead_cedilla, XK_t, XK_VoidSymbol}, "ţ"}, // U0163 | LATIN SMALL LETTER T WITH CEDILLA {{XK_Multi_key, XK_comma, XK_t, XK_VoidSymbol}, "ţ"}, {{XK_Multi_key, XK_t, XK_comma, XK_VoidSymbol}, "ţ"}, {{XK_Multi_key, XK_cedilla, XK_t, XK_VoidSymbol}, "ţ"}, {{XK_dead_belowdot, XK_Ohorn, XK_VoidSymbol}, "Ợ"}, // U1EE2 | LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW {{XK_Multi_key, XK_exclam, XK_Ohorn, XK_VoidSymbol}, "Ợ"}, {{XK_dead_belowdot, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ợ"}, {{XK_dead_belowdot, XK_Multi_key, XK_plus, XK_O, XK_VoidSymbol}, "Ợ"}, {{XK_Multi_key, XK_exclam, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ợ"}, {{XK_Multi_key, XK_exclam, XK_plus, XK_O, XK_VoidSymbol}, "Ợ"}, {{XK_dead_horn, XK_Obelowdot, XK_VoidSymbol}, "Ợ"}, {{XK_dead_horn, XK_dead_belowdot, XK_O, XK_VoidSymbol}, "Ợ"}, {{XK_Multi_key, XK_greater, XK_equal, XK_VoidSymbol}, "≥"}, // U2265 | GREATER-THAN OR EQUAL TO {{XK_Multi_key, XK_greater, XK_underscore, XK_VoidSymbol}, "≥"}, {{XK_Multi_key, XK_underscore, XK_greater, XK_VoidSymbol}, "≥"}, {{XK_dead_tilde, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὧ"}, // U1F67 | GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὧ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὧ"}, {{XK_Multi_key, XK_asciitilde, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὧ"}, {{XK_dead_diaeresis, XK_Cyrillic_O, XK_VoidSymbol}, "Ӧ"}, // U04E6 | CYRILLIC CAPITAL LETTER O WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_O, XK_VoidSymbol}, "Ӧ"}, {{XK_dead_caron, XK_K, XK_VoidSymbol}, "Ǩ"}, // U01E8 | LATIN CAPITAL LETTER K WITH CARON {{XK_Multi_key, XK_c, XK_K, XK_VoidSymbol}, "Ǩ"}, {{XK_Multi_key, XK_parenleft, XK_kana_HI, XK_parenright, XK_VoidSymbol}, "㋪"}, // U32EA | CIRCLED KATAKANA HI {{XK_Multi_key, XK_numbersign, XK_b, XK_VoidSymbol}, "♭"}, // U266d | MUSIC FLAT SIGN {{XK_dead_dasia, XK_Greek_RHO, XK_VoidSymbol}, "Ῥ"}, // U1FEC | GREEK CAPITAL LETTER RHO WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_RHO, XK_VoidSymbol}, "Ῥ"}, {{XK_dead_circumflex, XK_i, XK_VoidSymbol}, "î"}, // icircumflex | LATIN SMALL LETTER I WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_i, XK_VoidSymbol}, "î"}, {{XK_Multi_key, XK_i, XK_asciicircum, XK_VoidSymbol}, "î"}, {{XK_Multi_key, XK_greater, XK_i, XK_VoidSymbol}, "î"}, {{XK_Multi_key, XK_i, XK_greater, XK_VoidSymbol}, "î"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_8, XK_parenright, XK_VoidSymbol}, "⑱"}, // U2471 | CIRCLED NUMBER EIGHTEEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_8, XK_parenright, XK_VoidSymbol}, "⑱"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_8, XK_parenright, XK_VoidSymbol}, "⑱"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_8, XK_parenright, XK_VoidSymbol}, "⑱"}, {{XK_dead_ogonek, XK_u, XK_VoidSymbol}, "ų"}, // U0173 | LATIN SMALL LETTER U WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_u, XK_VoidSymbol}, "ų"}, {{XK_Multi_key, XK_comma, XK_u, XK_VoidSymbol}, "ų"}, {{XK_Multi_key, XK_u, XK_comma, XK_VoidSymbol}, "ų"}, {{XK_dead_grave, XK_Y, XK_VoidSymbol}, "Ỳ"}, // U1EF2 | LATIN CAPITAL LETTER Y WITH GRAVE {{XK_Multi_key, XK_grave, XK_Y, XK_VoidSymbol}, "Ỳ"}, {{XK_dead_circumflex, XK_Cyrillic_U, XK_VoidSymbol}, "У̂"}, // CYRILLIC CAPITAL LETTER U WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_U, XK_VoidSymbol}, "У̂"}, {{XK_dead_circumflex, XK_9, XK_VoidSymbol}, "⁹"}, // U2079 | SUPERSCRIPT NINE {{XK_Multi_key, XK_asciicircum, XK_9, XK_VoidSymbol}, "⁹"}, {{XK_dead_circumflex, XK_KP_9, XK_VoidSymbol}, "⁹"}, {{XK_Multi_key, XK_asciicircum, XK_KP_9, XK_VoidSymbol}, "⁹"}, {{XK_dead_grave, XK_N, XK_VoidSymbol}, "Ǹ"}, // U01F8 | LATIN CAPITAL LETTER N WITH GRAVE {{XK_Multi_key, XK_grave, XK_N, XK_VoidSymbol}, "Ǹ"}, {{XK_Multi_key, XK_parenleft, XK_kana_RO, XK_parenright, XK_VoidSymbol}, "㋺"}, // U32FA | CIRCLED KATAKANA RO {{XK_dead_tilde, XK_v, XK_VoidSymbol}, "ṽ"}, // U1E7D | LATIN SMALL LETTER V WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_v, XK_VoidSymbol}, "ṽ"}, {{XK_dead_iota, XK_Greek_OMEGA, XK_VoidSymbol}, "ῼ"}, // U1FFC | GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI {{XK_Multi_key, XK_Greek_iota, XK_Greek_OMEGA, XK_VoidSymbol}, "ῼ"}, {{XK_Multi_key, XK_t, XK_h, XK_VoidSymbol}, "þ"}, // thorn | LATIN SMALL LETTER THORN {{XK_dead_iota, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾁ"}, // U1F81 | GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾁ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ᾁ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ᾁ"}, {{XK_dead_belowring, XK_A, XK_VoidSymbol}, "Ḁ"}, // U1E00 | LATIN CAPITAL LETTER A WITH RING BELOW {{XK_dead_currency, XK_s, XK_VoidSymbol}, "₪"}, // NewSheqelSign | NEW SHEQEL SIGN {{XK_Multi_key, XK_parenleft, XK_h, XK_parenright, XK_VoidSymbol}, "ⓗ"}, // U24D7 | CIRCLED LATIN SMALL LETTER H {{XK_dead_tilde, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἆ"}, // U1F06 | GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἆ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἆ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἆ"}, {{XK_dead_acute, XK_Greek_ETA, XK_VoidSymbol}, "Ή"}, // U0389 | GREEK CAPITAL LETTER ETA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_ETA, XK_VoidSymbol}, "Ή"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_ETA, XK_VoidSymbol}, "Ή"}, {{XK_Multi_key, XK_Greek_ETA, XK_apostrophe, XK_VoidSymbol}, "Ή"}, {{XK_dead_currency, XK_p, XK_VoidSymbol}, "₰"}, // U20B0 | GERMAN PENNY SIGN {{XK_dead_abovedot, XK_x, XK_VoidSymbol}, "ẋ"}, // U1E8B | LATIN SMALL LETTER X WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_x, XK_VoidSymbol}, "ẋ"}, {{XK_dead_abovedot, XK_C, XK_VoidSymbol}, "Ċ"}, // U010A | LATIN CAPITAL LETTER C WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_C, XK_VoidSymbol}, "Ċ"}, {{XK_Multi_key, XK_C, XK_period, XK_VoidSymbol}, "Ċ"}, {{XK_dead_acute, XK_Cyrillic_KA, XK_VoidSymbol}, "Ќ"}, // U040C | CYRILLIC CAPITAL LETTER KJE {{XK_Multi_key, XK_acute, XK_Cyrillic_KA, XK_VoidSymbol}, "Ќ"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_KA, XK_VoidSymbol}, "Ќ"}, {{XK_dead_circumflex, XK_Cyrillic_er, XK_VoidSymbol}, "р̂"}, // CYRILLIC SMALL LETTER ER WITH COMBINING CIRCUMFLEX ACCENT {{XK_Multi_key, XK_asciicircum, XK_Cyrillic_er, XK_VoidSymbol}, "р̂"}, {{XK_dead_iota, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾑ"}, // U1F91 | GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾑ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ᾑ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ᾑ"}, {{XK_dead_cedilla, XK_D, XK_VoidSymbol}, "Ḑ"}, // U1E10 | LATIN CAPITAL LETTER D WITH CEDILLA {{XK_Multi_key, XK_comma, XK_D, XK_VoidSymbol}, "Ḑ"}, {{XK_Multi_key, XK_D, XK_comma, XK_VoidSymbol}, "Ḑ"}, {{XK_Multi_key, XK_cedilla, XK_D, XK_VoidSymbol}, "Ḑ"}, {{XK_Multi_key, XK_minus, XK_minus, XK_minus, XK_VoidSymbol}, "—"}, // U2014 | EM DASH {{XK_dead_cedilla, XK_ColonSign, XK_VoidSymbol}, "₵"}, // U20B5 | CEDI SIGN {{XK_dead_cedilla, XK_cent, XK_VoidSymbol}, "₵"}, {{XK_dead_currency, XK_Ccedilla, XK_VoidSymbol}, "₵"}, {{XK_dead_currency, XK_ccedilla, XK_VoidSymbol}, "₵"}, {{XK_dead_cedilla, XK_dead_currency, XK_C, XK_VoidSymbol}, "₵"}, {{XK_dead_currency, XK_dead_cedilla, XK_C, XK_VoidSymbol}, "₵"}, {{XK_dead_cedilla, XK_dead_currency, XK_c, XK_VoidSymbol}, "₵"}, {{XK_dead_currency, XK_dead_cedilla, XK_c, XK_VoidSymbol}, "₵"}, {{XK_dead_belowcomma, XK_S, XK_VoidSymbol}, "Ș"}, // U0218 | LATIN CAPITAL LETTER S WITH COMMA BELOW {{XK_dead_abovedot, XK_Multi_key, XK_f, XK_s, XK_VoidSymbol}, "ẛ"}, // U1e9b | LATIN SMALL LETTER LONG S WITH DOT ABOVE {{XK_Multi_key, XK_dead_abovedot, XK_f, XK_s, XK_VoidSymbol}, "ẛ"}, {{XK_dead_caron, XK_E, XK_VoidSymbol}, "Ě"}, // U011A | LATIN CAPITAL LETTER E WITH CARON {{XK_Multi_key, XK_c, XK_E, XK_VoidSymbol}, "Ě"}, {{XK_Multi_key, XK_less, XK_E, XK_VoidSymbol}, "Ě"}, {{XK_Multi_key, XK_E, XK_less, XK_VoidSymbol}, "Ě"}, {{XK_Multi_key, XK_parenleft, XK_kana_SHI, XK_parenright, XK_VoidSymbol}, "㋛"}, // U32DB | CIRCLED KATAKANA SI {{XK_dead_macron, XK_nobreakspace, XK_VoidSymbol}, "̄"}, // U0304 | COMBINING MACRON {{XK_dead_iota, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾡ"}, // U1FA1 | GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾡ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ᾡ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ᾡ"}, {{XK_dead_macron, XK_G, XK_VoidSymbol}, "Ḡ"}, // U1E20 | LATIN CAPITAL LETTER G WITH MACRON {{XK_Multi_key, XK_macron, XK_G, XK_VoidSymbol}, "Ḡ"}, {{XK_Multi_key, XK_underscore, XK_G, XK_VoidSymbol}, "Ḡ"}, {{XK_Multi_key, XK_5, XK_6, XK_VoidSymbol}, "⅚"}, // U215A | VULGAR FRACTION FIVE SIXTHS {{XK_dead_hook, XK_p, XK_VoidSymbol}, "ƥ"}, // U01A5 | LATIN SMALL LETTER P WITH HOOK {{XK_dead_currency, XK_S, XK_VoidSymbol}, "$"}, // dollar | DOLLAR SIGN {{XK_Multi_key, XK_parenleft, XK_kana_SO, XK_parenright, XK_VoidSymbol}, "㋞"}, // U32DE | CIRCLED KATAKANA SO {{XK_dead_tilde, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἦ"}, // U1F26 | GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἦ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἦ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἦ"}, {{XK_dead_cedilla, XK_E, XK_VoidSymbol}, "Ȩ"}, // U0228 | LATIN CAPITAL LETTER E WITH CEDILLA {{XK_Multi_key, XK_cedilla, XK_E, XK_VoidSymbol}, "Ȩ"}, {{XK_dead_tilde, XK_acircumflex, XK_VoidSymbol}, "ẫ"}, // U1EAB | LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE {{XK_Multi_key, XK_asciitilde, XK_acircumflex, XK_VoidSymbol}, "ẫ"}, {{XK_dead_tilde, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ẫ"}, {{XK_dead_tilde, XK_Multi_key, XK_asciicircum, XK_a, XK_VoidSymbol}, "ẫ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_circumflex, XK_a, XK_VoidSymbol}, "ẫ"}, {{XK_Multi_key, XK_asciitilde, XK_asciicircum, XK_a, XK_VoidSymbol}, "ẫ"}, {{XK_dead_circumflex, XK_atilde, XK_VoidSymbol}, "ẫ"}, {{XK_dead_circumflex, XK_dead_tilde, XK_a, XK_VoidSymbol}, "ẫ"}, {{XK_dead_macron, XK_I, XK_VoidSymbol}, "Ī"}, // U012A | LATIN CAPITAL LETTER I WITH MACRON {{XK_Multi_key, XK_macron, XK_I, XK_VoidSymbol}, "Ī"}, {{XK_Multi_key, XK_underscore, XK_I, XK_VoidSymbol}, "Ī"}, {{XK_Multi_key, XK_I, XK_underscore, XK_VoidSymbol}, "Ī"}, {{XK_Multi_key, XK_minus, XK_I, XK_VoidSymbol}, "Ī"}, {{XK_Multi_key, XK_I, XK_minus, XK_VoidSymbol}, "Ī"}, {{XK_dead_macron, XK_space, XK_VoidSymbol}, "¯"}, // macron | MACRON {{XK_dead_macron, XK_dead_macron, XK_VoidSymbol}, "¯"}, {{XK_Multi_key, XK_minus, XK_asciicircum, XK_VoidSymbol}, "¯"}, {{XK_Multi_key, XK_asciicircum, XK_minus, XK_VoidSymbol}, "¯"}, {{XK_Multi_key, XK_underscore, XK_underscore, XK_VoidSymbol}, "¯"}, {{XK_Multi_key, XK_underscore, XK_asciicircum, XK_VoidSymbol}, "¯"}, {{XK_dead_macron, XK_Greek_alpha, XK_VoidSymbol}, "ᾱ"}, // U1FB1 | GREEK SMALL LETTER ALPHA WITH MACRON {{XK_Multi_key, XK_macron, XK_Greek_alpha, XK_VoidSymbol}, "ᾱ"}, {{XK_Multi_key, XK_underscore, XK_Greek_alpha, XK_VoidSymbol}, "ᾱ"}, {{XK_dead_acute, XK_K, XK_VoidSymbol}, "Ḱ"}, // U1E30 | LATIN CAPITAL LETTER K WITH ACUTE {{XK_Multi_key, XK_acute, XK_K, XK_VoidSymbol}, "Ḱ"}, {{XK_Multi_key, XK_apostrophe, XK_K, XK_VoidSymbol}, "Ḱ"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_r, XK_VoidSymbol}, "ʳ"}, // U02B3 | MODIFIER LETTER SMALL R {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_r, XK_VoidSymbol}, "ʳ"}, {{XK_dead_voiced_sound, XK_kana_KE, XK_VoidSymbol}, "ゲ"}, // U30B2 | KATAKANA LETTER GE {{XK_dead_stroke, XK_Z, XK_VoidSymbol}, "Ƶ"}, // U01B5 | LATIN CAPITAL LETTER Z WITH STROKE {{XK_Multi_key, XK_slash, XK_Z, XK_VoidSymbol}, "Ƶ"}, {{XK_Multi_key, XK_KP_Divide, XK_Z, XK_VoidSymbol}, "Ƶ"}, {{XK_Multi_key, XK_parenleft, XK_p, XK_parenright, XK_VoidSymbol}, "ⓟ"}, // U24DF | CIRCLED LATIN SMALL LETTER P {{XK_Multi_key, XK_parenleft, XK_B, XK_parenright, XK_VoidSymbol}, "Ⓑ"}, // U24B7 | CIRCLED LATIN CAPITAL LETTER B {{XK_dead_tilde, XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἶ"}, // U1F36 | GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἶ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἶ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἶ"}, {{XK_dead_hook, XK_e, XK_VoidSymbol}, "ẻ"}, // U1EBB | LATIN SMALL LETTER E WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_e, XK_VoidSymbol}, "ẻ"}, {{XK_dead_acute, XK_l, XK_VoidSymbol}, "ĺ"}, // U013A | LATIN SMALL LETTER L WITH ACUTE {{XK_Multi_key, XK_acute, XK_l, XK_VoidSymbol}, "ĺ"}, {{XK_Multi_key, XK_apostrophe, XK_l, XK_VoidSymbol}, "ĺ"}, {{XK_Multi_key, XK_l, XK_apostrophe, XK_VoidSymbol}, "ĺ"}, {{XK_dead_voiced_sound, XK_kana_TSU, XK_VoidSymbol}, "ヅ"}, // U30C5 | KATAKANA LETTER DU {{XK_Multi_key, XK_question, XK_question, XK_VoidSymbol}, "¿"}, // questiondown | INVERTED QUESTION MARK {{XK_Multi_key, XK_diaeresis, XK_dead_tilde, XK_VoidSymbol}, "῁"}, // U1FC1 | GREEK DIALYTIKA AND PERISPOMENI {{XK_Multi_key, XK_diaeresis, XK_asciitilde, XK_VoidSymbol}, "῁"}, {{XK_dead_abovedot, XK_M, XK_VoidSymbol}, "Ṁ"}, // U1E40 | LATIN CAPITAL LETTER M WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_M, XK_VoidSymbol}, "Ṁ"}, {{XK_Multi_key, XK_M, XK_period, XK_VoidSymbol}, "Ṁ"}, {{XK_Multi_key, XK_parenleft, XK_R, XK_parenright, XK_VoidSymbol}, "Ⓡ"}, // U24C7 | CIRCLED LATIN CAPITAL LETTER R {{XK_dead_hook, XK_g, XK_VoidSymbol}, "ɠ"}, // U0260 | LATIN SMALL LETTER G WITH HOOK {{XK_dead_stroke, XK_J, XK_VoidSymbol}, "Ɉ"}, // U0248 | LATIN CAPITAL LETTER J WITH STROKE {{XK_dead_belowdot, XK_i, XK_VoidSymbol}, "ị"}, // U1ECB | LATIN SMALL LETTER I WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_i, XK_VoidSymbol}, "ị"}, {{XK_Multi_key, XK_N, XK_G, XK_VoidSymbol}, "Ŋ"}, // U014A | LATIN CAPITAL LETTER ENG {{XK_Multi_key, XK_parenleft, XK_kana_TO, XK_parenright, XK_VoidSymbol}, "㋣"}, // U32E3 | CIRCLED KATAKANA TO {{XK_dead_diaeresis, XK_I, XK_VoidSymbol}, "Ï"}, // Idiaeresis | LATIN CAPITAL LETTER I WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_I, XK_VoidSymbol}, "Ï"}, {{XK_Multi_key, XK_I, XK_quotedbl, XK_VoidSymbol}, "Ï"}, {{XK_Multi_key, XK_diaeresis, XK_I, XK_VoidSymbol}, "Ï"}, {{XK_Multi_key, XK_I, XK_diaeresis, XK_VoidSymbol}, "Ï"}, {{XK_dead_macron, XK_Greek_iota, XK_VoidSymbol}, "ῑ"}, // U1FD1 | GREEK SMALL LETTER IOTA WITH MACRON {{XK_Multi_key, XK_macron, XK_Greek_iota, XK_VoidSymbol}, "ῑ"}, {{XK_Multi_key, XK_underscore, XK_Greek_iota, XK_VoidSymbol}, "ῑ"}, {{XK_dead_macron, XK_dead_belowdot, XK_l, XK_VoidSymbol}, "ḹ"}, // U1E39 | LATIN SMALL LETTER L WITH DOT BELOW AND MACRON {{XK_dead_macron, XK_Multi_key, XK_exclam, XK_l, XK_VoidSymbol}, "ḹ"}, {{XK_Multi_key, XK_macron, XK_dead_belowdot, XK_l, XK_VoidSymbol}, "ḹ"}, {{XK_Multi_key, XK_macron, XK_exclam, XK_l, XK_VoidSymbol}, "ḹ"}, {{XK_Multi_key, XK_underscore, XK_dead_belowdot, XK_l, XK_VoidSymbol}, "ḹ"}, {{XK_Multi_key, XK_underscore, XK_exclam, XK_l, XK_VoidSymbol}, "ḹ"}, {{XK_dead_belowdot, XK_dead_macron, XK_l, XK_VoidSymbol}, "ḹ"}, {{XK_Multi_key, XK_parenleft, XK_kana_E, XK_parenright, XK_VoidSymbol}, "㋓"}, // U32D3 | CIRCLED KATAKANA E {{XK_dead_macron, XK_Udiaeresis, XK_VoidSymbol}, "Ǖ"}, // U01D5 | LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON {{XK_Multi_key, XK_macron, XK_Udiaeresis, XK_VoidSymbol}, "Ǖ"}, {{XK_Multi_key, XK_underscore, XK_Udiaeresis, XK_VoidSymbol}, "Ǖ"}, {{XK_dead_macron, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǖ"}, {{XK_dead_macron, XK_Multi_key, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǖ"}, {{XK_Multi_key, XK_macron, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǖ"}, {{XK_Multi_key, XK_macron, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǖ"}, {{XK_Multi_key, XK_underscore, XK_dead_diaeresis, XK_U, XK_VoidSymbol}, "Ǖ"}, {{XK_Multi_key, XK_underscore, XK_quotedbl, XK_U, XK_VoidSymbol}, "Ǖ"}, {{XK_dead_macron, XK_V, XK_VoidSymbol}, "Ǖ"}, {{XK_dead_breve, XK_Cyrillic_ie, XK_VoidSymbol}, "ӗ"}, // U04D7 | CYRILLIC SMALL LETTER IE WITH BREVE {{XK_Multi_key, XK_U, XK_Cyrillic_ie, XK_VoidSymbol}, "ӗ"}, {{XK_Multi_key, XK_b, XK_Cyrillic_ie, XK_VoidSymbol}, "ӗ"}, {{XK_dead_tilde, XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὖ"}, // U1F56 | GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὖ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὖ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὖ"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_8, XK_parenright, XK_VoidSymbol}, "㉘"}, // U3258 | CIRCLED NUMBER TWENTY EIGHT {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_8, XK_parenright, XK_VoidSymbol}, "㉘"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_8, XK_parenright, XK_VoidSymbol}, "㉘"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_8, XK_parenright, XK_VoidSymbol}, "㉘"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_8, XK_parenright, XK_VoidSymbol}, "㉘"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_8, XK_parenright, XK_VoidSymbol}, "㉘"}, {{XK_dead_acute, XK_ohorn, XK_VoidSymbol}, "ớ"}, // U1EDB | LATIN SMALL LETTER O WITH HORN AND ACUTE {{XK_Multi_key, XK_acute, XK_ohorn, XK_VoidSymbol}, "ớ"}, {{XK_Multi_key, XK_apostrophe, XK_ohorn, XK_VoidSymbol}, "ớ"}, {{XK_dead_acute, XK_dead_horn, XK_o, XK_VoidSymbol}, "ớ"}, {{XK_dead_acute, XK_Multi_key, XK_plus, XK_o, XK_VoidSymbol}, "ớ"}, {{XK_Multi_key, XK_acute, XK_dead_horn, XK_o, XK_VoidSymbol}, "ớ"}, {{XK_Multi_key, XK_acute, XK_plus, XK_o, XK_VoidSymbol}, "ớ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_horn, XK_o, XK_VoidSymbol}, "ớ"}, {{XK_Multi_key, XK_apostrophe, XK_plus, XK_o, XK_VoidSymbol}, "ớ"}, {{XK_dead_horn, XK_oacute, XK_VoidSymbol}, "ớ"}, {{XK_dead_horn, XK_dead_acute, XK_o, XK_VoidSymbol}, "ớ"}, {{XK_dead_acute, XK_S, XK_VoidSymbol}, "Ś"}, // U015A | LATIN CAPITAL LETTER S WITH ACUTE {{XK_Multi_key, XK_acute, XK_S, XK_VoidSymbol}, "Ś"}, {{XK_Multi_key, XK_apostrophe, XK_S, XK_VoidSymbol}, "Ś"}, {{XK_Multi_key, XK_S, XK_apostrophe, XK_VoidSymbol}, "Ś"}, {{XK_dead_acute, XK_Cyrillic_ka, XK_VoidSymbol}, "ќ"}, // U045C | CYRILLIC SMALL LETTER KJE {{XK_Multi_key, XK_acute, XK_Cyrillic_ka, XK_VoidSymbol}, "ќ"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_ka, XK_VoidSymbol}, "ќ"}, {{XK_Multi_key, XK_s, XK_s, XK_VoidSymbol}, "ß"}, // ssharp | LATIN SMALL LETTER SHARP S {{XK_dead_macron, XK_Greek_upsilon, XK_VoidSymbol}, "ῡ"}, // U1FE1 | GREEK SMALL LETTER UPSILON WITH MACRON {{XK_Multi_key, XK_macron, XK_Greek_upsilon, XK_VoidSymbol}, "ῡ"}, {{XK_Multi_key, XK_underscore, XK_Greek_upsilon, XK_VoidSymbol}, "ῡ"}, {{XK_dead_abovedot, XK_S, XK_VoidSymbol}, "Ṡ"}, // U1E60 | LATIN CAPITAL LETTER S WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_S, XK_VoidSymbol}, "Ṡ"}, {{XK_Multi_key, XK_S, XK_period, XK_VoidSymbol}, "Ṡ"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_x, XK_VoidSymbol}, "ˣ"}, // U02E3 | MODIFIER LETTER SMALL X {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_x, XK_VoidSymbol}, "ˣ"}, {{XK_dead_voiced_sound, XK_kana_SU, XK_VoidSymbol}, "ズ"}, // U30BA | KATAKANA LETTER ZU {{XK_dead_stroke, XK_g, XK_VoidSymbol}, "ǥ"}, // U01E5 | LATIN SMALL LETTER G WITH STROKE {{XK_Multi_key, XK_slash, XK_g, XK_VoidSymbol}, "ǥ"}, {{XK_Multi_key, XK_KP_Divide, XK_g, XK_VoidSymbol}, "ǥ"}, {{XK_Multi_key, XK_parenleft, XK_x, XK_parenright, XK_VoidSymbol}, "ⓧ"}, // U24E7 | CIRCLED LATIN SMALL LETTER X {{XK_dead_diaeresis, XK_Cyrillic_o, XK_VoidSymbol}, "ӧ"}, // U04E7 | CYRILLIC SMALL LETTER O WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_o, XK_VoidSymbol}, "ӧ"}, {{XK_dead_tilde, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὦ"}, // U1F66 | GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI {{XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὦ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὦ"}, {{XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὦ"}, {{XK_dead_stroke, XK_i, XK_VoidSymbol}, "ɨ"}, // U0268 | LATIN SMALL LETTER I WITH STROKE {{XK_Multi_key, XK_slash, XK_i, XK_VoidSymbol}, "ɨ"}, {{XK_Multi_key, XK_KP_Divide, XK_i, XK_VoidSymbol}, "ɨ"}, {{XK_dead_grave, XK_uhorn, XK_VoidSymbol}, "ừ"}, // U1EEB | LATIN SMALL LETTER U WITH HORN AND GRAVE {{XK_Multi_key, XK_grave, XK_uhorn, XK_VoidSymbol}, "ừ"}, {{XK_dead_grave, XK_dead_horn, XK_u, XK_VoidSymbol}, "ừ"}, {{XK_dead_grave, XK_Multi_key, XK_plus, XK_u, XK_VoidSymbol}, "ừ"}, {{XK_Multi_key, XK_grave, XK_dead_horn, XK_u, XK_VoidSymbol}, "ừ"}, {{XK_Multi_key, XK_grave, XK_plus, XK_u, XK_VoidSymbol}, "ừ"}, {{XK_dead_horn, XK_ugrave, XK_VoidSymbol}, "ừ"}, {{XK_dead_horn, XK_dead_grave, XK_u, XK_VoidSymbol}, "ừ"}, {{XK_dead_macron, XK_U, XK_VoidSymbol}, "Ū"}, // U016A | LATIN CAPITAL LETTER U WITH MACRON {{XK_Multi_key, XK_macron, XK_U, XK_VoidSymbol}, "Ū"}, {{XK_Multi_key, XK_underscore, XK_U, XK_VoidSymbol}, "Ū"}, {{XK_Multi_key, XK_U, XK_underscore, XK_VoidSymbol}, "Ū"}, {{XK_Multi_key, XK_minus, XK_U, XK_VoidSymbol}, "Ū"}, {{XK_Multi_key, XK_U, XK_minus, XK_VoidSymbol}, "Ū"}, {{XK_Multi_key, XK_backslash, XK_o, XK_slash, XK_VoidSymbol}, "🙌"}, // PERSON RAISING BOTH HANDS IN CELEBRATION {{XK_dead_circumflex, XK_Multi_key, XK_S, XK_M, XK_VoidSymbol}, "℠"}, // U2120 | SERVICE MARK {{XK_Multi_key, XK_S, XK_M, XK_VoidSymbol}, "℠"}, {{XK_dead_circumflex, XK_Multi_key, XK_s, XK_M, XK_VoidSymbol}, "℠"}, {{XK_Multi_key, XK_s, XK_M, XK_VoidSymbol}, "℠"}, {{XK_dead_circumflex, XK_Multi_key, XK_S, XK_m, XK_VoidSymbol}, "℠"}, {{XK_Multi_key, XK_S, XK_m, XK_VoidSymbol}, "℠"}, {{XK_dead_circumflex, XK_Multi_key, XK_s, XK_m, XK_VoidSymbol}, "℠"}, {{XK_Multi_key, XK_s, XK_m, XK_VoidSymbol}, "℠"}, {{XK_dead_diaeresis, XK_i, XK_VoidSymbol}, "ï"}, // idiaeresis | LATIN SMALL LETTER I WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_i, XK_VoidSymbol}, "ï"}, {{XK_Multi_key, XK_i, XK_quotedbl, XK_VoidSymbol}, "ï"}, {{XK_Multi_key, XK_diaeresis, XK_i, XK_VoidSymbol}, "ï"}, {{XK_Multi_key, XK_i, XK_diaeresis, XK_VoidSymbol}, "ï"}, {{XK_Multi_key, XK_semicolon, XK_underscore, XK_VoidSymbol}, "⍮"}, // U236e | ; _ APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR {{XK_dead_belowcircumflex, XK_T, XK_VoidSymbol}, "Ṱ"}, // U1E70 | LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW {{XK_Multi_key, XK_parenleft, XK_kana_YA, XK_parenright, XK_VoidSymbol}, "㋳"}, // U32F3 | CIRCLED KATAKANA YA {{XK_Multi_key, XK_parenleft, XK_u, XK_parenright, XK_VoidSymbol}, "ⓤ"}, // U24E4 | CIRCLED LATIN SMALL LETTER U {{XK_dead_acute, XK_g, XK_VoidSymbol}, "ǵ"}, // U01F5 | LATIN SMALL LETTER G WITH ACUTE {{XK_Multi_key, XK_acute, XK_g, XK_VoidSymbol}, "ǵ"}, {{XK_Multi_key, XK_apostrophe, XK_g, XK_VoidSymbol}, "ǵ"}, {{XK_dead_circumflex, XK_4, XK_VoidSymbol}, "⁴"}, // U2074 | SUPERSCRIPT FOUR {{XK_Multi_key, XK_asciicircum, XK_4, XK_VoidSymbol}, "⁴"}, {{XK_dead_circumflex, XK_KP_4, XK_VoidSymbol}, "⁴"}, {{XK_Multi_key, XK_asciicircum, XK_KP_4, XK_VoidSymbol}, "⁴"}, {{XK_dead_grave, XK_Greek_iota, XK_VoidSymbol}, "ὶ"}, // U1F76 | GREEK SMALL LETTER IOTA WITH VARIA {{XK_Multi_key, XK_grave, XK_Greek_iota, XK_VoidSymbol}, "ὶ"}, {{XK_dead_currency, XK_o, XK_VoidSymbol}, "௹"}, // U0BF9 | TAMIL RUPEE SIGN {{XK_dead_acute, XK_z, XK_VoidSymbol}, "ź"}, // U017A | LATIN SMALL LETTER Z WITH ACUTE {{XK_Multi_key, XK_acute, XK_z, XK_VoidSymbol}, "ź"}, {{XK_Multi_key, XK_apostrophe, XK_z, XK_VoidSymbol}, "ź"}, {{XK_Multi_key, XK_z, XK_apostrophe, XK_VoidSymbol}, "ź"}, {{XK_Multi_key, XK_u, XK_b, XK_u, XK_n, XK_t, XK_u, XK_VoidSymbol}, ""}, // UBUNTU CIRCLE {{XK_Multi_key, XK_U, XK_B, XK_U, XK_N, XK_T, XK_U, XK_VoidSymbol}, ""}, {{XK_dead_dasia, XK_Greek_alpha, XK_VoidSymbol}, "ἁ"}, // U1F01 | GREEK SMALL LETTER ALPHA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_alpha, XK_VoidSymbol}, "ἁ"}, {{XK_dead_grave, XK_W, XK_VoidSymbol}, "Ẁ"}, // U1E80 | LATIN CAPITAL LETTER W WITH GRAVE {{XK_Multi_key, XK_grave, XK_W, XK_VoidSymbol}, "Ẁ"}, {{XK_dead_ogonek, XK_a, XK_VoidSymbol}, "ą"}, // U0105 | LATIN SMALL LETTER A WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_a, XK_VoidSymbol}, "ą"}, {{XK_Multi_key, XK_comma, XK_a, XK_VoidSymbol}, "ą"}, {{XK_Multi_key, XK_a, XK_comma, XK_VoidSymbol}, "ą"}, {{XK_Multi_key, XK_underscore, XK_4, XK_VoidSymbol}, "₄"}, // U2084 | SUBSCRIPT FOUR {{XK_Multi_key, XK_underscore, XK_KP_4, XK_VoidSymbol}, "₄"}, {{XK_dead_caron, XK_4, XK_VoidSymbol}, "₄"}, {{XK_dead_diaeresis, XK_Ukrainian_I, XK_VoidSymbol}, "Ї"}, // U0407 | CYRILLIC CAPITAL LETTER YI {{XK_Multi_key, XK_quotedbl, XK_Ukrainian_I, XK_VoidSymbol}, "Ї"}, {{XK_dead_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, // U1F86 | GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾆ"}, {{XK_dead_hook, XK_dead_hook, XK_VoidSymbol}, "̉"}, // U0309 | COMBINING HOOK ABOVE {{XK_dead_hook, XK_nobreakspace, XK_VoidSymbol}, "̉"}, {{XK_dead_hook, XK_space, XK_VoidSymbol}, "̉"}, {{XK_dead_doublegrave, XK_Cyrillic_i, XK_VoidSymbol}, "и̏"}, // CYRILLIC SMALL LETTER I WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_i, XK_VoidSymbol}, "и̏"}, {{XK_dead_abovedot, XK_d, XK_VoidSymbol}, "ḋ"}, // U1E0B | LATIN SMALL LETTER D WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_d, XK_VoidSymbol}, "ḋ"}, {{XK_Multi_key, XK_d, XK_period, XK_VoidSymbol}, "ḋ"}, {{XK_dead_hook, XK_D, XK_VoidSymbol}, "Ɗ"}, // U018A | LATIN CAPITAL LETTER D WITH HOOK {{XK_dead_acute, XK_Greek_UPSILON, XK_VoidSymbol}, "Ύ"}, // U038E | GREEK CAPITAL LETTER UPSILON WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_UPSILON, XK_VoidSymbol}, "Ύ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_UPSILON, XK_VoidSymbol}, "Ύ"}, {{XK_Multi_key, XK_Greek_UPSILON, XK_apostrophe, XK_VoidSymbol}, "Ύ"}, {{XK_dead_dasia, XK_Greek_epsilon, XK_VoidSymbol}, "ἑ"}, // U1F11 | GREEK SMALL LETTER EPSILON WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_epsilon, XK_VoidSymbol}, "ἑ"}, {{XK_dead_circumflex, XK_Z, XK_VoidSymbol}, "Ẑ"}, // U1E90 | LATIN CAPITAL LETTER Z WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_Z, XK_VoidSymbol}, "Ẑ"}, {{XK_Multi_key, XK_1, XK_1, XK_0, XK_VoidSymbol}, "⅒"}, // U2152 | VULGAR FRACTION ONE TENTH {{XK_Multi_key, XK_parenleft, XK_M, XK_parenright, XK_VoidSymbol}, "Ⓜ"}, // U24C2 | CIRCLED LATIN CAPITAL LETTER M {{XK_dead_breve, XK_e, XK_VoidSymbol}, "ĕ"}, // U0115 | LATIN SMALL LETTER E WITH BREVE {{XK_Multi_key, XK_U, XK_e, XK_VoidSymbol}, "ĕ"}, {{XK_Multi_key, XK_b, XK_e, XK_VoidSymbol}, "ĕ"}, {{XK_dead_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, // U1F96 | GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾖ"}, {{XK_dead_belowtilde, XK_e, XK_VoidSymbol}, "ḛ"}, // U1E1B | LATIN SMALL LETTER E WITH TILDE BELOW {{XK_dead_dasia, XK_Greek_eta, XK_VoidSymbol}, "ἡ"}, // U1F21 | GREEK SMALL LETTER ETA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_eta, XK_VoidSymbol}, "ἡ"}, {{XK_dead_belowdot, XK_A, XK_VoidSymbol}, "Ạ"}, // U1EA0 | LATIN CAPITAL LETTER A WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_A, XK_VoidSymbol}, "Ạ"}, {{XK_Multi_key, XK_v, XK_slash, XK_VoidSymbol}, "√"}, // U221a | v / SQUARE ROOT {{XK_Multi_key, XK_slash, XK_v, XK_VoidSymbol}, "√"}, {{XK_dead_circumflex, XK_h, XK_VoidSymbol}, "ĥ"}, // U0125 | LATIN SMALL LETTER H WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_h, XK_VoidSymbol}, "ĥ"}, {{XK_Multi_key, XK_L, XK_equal, XK_VoidSymbol}, "₤"}, // U20a4 | LIRA SIGN {{XK_Multi_key, XK_equal, XK_L, XK_VoidSymbol}, "₤"}, {{XK_dead_currency, XK_L, XK_VoidSymbol}, "₤"}, {{XK_Multi_key, XK_parenleft, XK_m, XK_parenright, XK_VoidSymbol}, "ⓜ"}, // U24DC | CIRCLED LATIN SMALL LETTER M {{XK_dead_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, // U1FA6 | GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾦ"}, {{XK_dead_belowbreve, XK_h, XK_VoidSymbol}, "ḫ"}, // U1E2B | LATIN SMALL LETTER H WITH BREVE BELOW {{XK_dead_semivoiced_sound, XK_kana_FU, XK_VoidSymbol}, "プ"}, // U30D7 | KATAKANA LETTER PU {{XK_dead_stroke, XK_dead_stroke, XK_VoidSymbol}, "/"}, // slash | SOLIDUS {{XK_dead_stroke, XK_space, XK_VoidSymbol}, "/"}, {{XK_dead_acute, XK_Greek_eta, XK_VoidSymbol}, "ή"}, // U03AE | GREEK SMALL LETTER ETA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_eta, XK_VoidSymbol}, "ή"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_eta, XK_VoidSymbol}, "ή"}, {{XK_Multi_key, XK_Greek_eta, XK_apostrophe, XK_VoidSymbol}, "ή"}, {{XK_dead_dasia, XK_Greek_iota, XK_VoidSymbol}, "ἱ"}, // U1F31 | GREEK SMALL LETTER IOTA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_iota, XK_VoidSymbol}, "ἱ"}, {{XK_dead_grave, XK_Abreve, XK_VoidSymbol}, "Ằ"}, // U1EB0 | LATIN CAPITAL LETTER A WITH BREVE AND GRAVE {{XK_Multi_key, XK_grave, XK_Abreve, XK_VoidSymbol}, "Ằ"}, {{XK_dead_grave, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ằ"}, {{XK_dead_grave, XK_Multi_key, XK_U, XK_A, XK_VoidSymbol}, "Ằ"}, {{XK_dead_grave, XK_Multi_key, XK_b, XK_A, XK_VoidSymbol}, "Ằ"}, {{XK_Multi_key, XK_grave, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ằ"}, {{XK_Multi_key, XK_grave, XK_b, XK_A, XK_VoidSymbol}, "Ằ"}, {{XK_dead_breve, XK_Agrave, XK_VoidSymbol}, "Ằ"}, {{XK_dead_breve, XK_dead_grave, XK_A, XK_VoidSymbol}, "Ằ"}, {{XK_dead_macron, XK_y, XK_VoidSymbol}, "ȳ"}, // U0233 | LATIN SMALL LETTER Y WITH MACRON {{XK_Multi_key, XK_macron, XK_y, XK_VoidSymbol}, "ȳ"}, {{XK_Multi_key, XK_underscore, XK_y, XK_VoidSymbol}, "ȳ"}, {{XK_dead_circumflex, XK_j, XK_VoidSymbol}, "ĵ"}, // U0135 | LATIN SMALL LETTER J WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_j, XK_VoidSymbol}, "ĵ"}, {{XK_dead_acute, XK_dead_acute, XK_VoidSymbol}, "´"}, // acute | ACUTE ACCENT {{XK_Multi_key, XK_apostrophe, XK_apostrophe, XK_VoidSymbol}, "´"}, {{XK_dead_tilde, XK_Greek_alpha, XK_VoidSymbol}, "ᾶ"}, // U1FB6 | GREEK SMALL LETTER ALPHA WITH PERISPOMENI {{XK_Multi_key, XK_asciitilde, XK_Greek_alpha, XK_VoidSymbol}, "ᾶ"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_y, XK_VoidSymbol}, "ʸ"}, // U02B8 | MODIFIER LETTER SMALL Y {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_y, XK_VoidSymbol}, "ʸ"}, {{XK_dead_belowmacron, XK_l, XK_VoidSymbol}, "ḻ"}, // U1E3B | LATIN SMALL LETTER L WITH LINE BELOW {{XK_dead_invertedbreve, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̑"}, // CYRILLIC CAPITAL LETTER ER WITH COMBINING INVERTED BREVE {{XK_Multi_key, XK_parenleft, XK_G, XK_parenright, XK_VoidSymbol}, "Ⓖ"}, // U24BC | CIRCLED LATIN CAPITAL LETTER G {{XK_dead_dasia, XK_Greek_omicron, XK_VoidSymbol}, "ὁ"}, // U1F41 | GREEK SMALL LETTER OMICRON WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_omicron, XK_VoidSymbol}, "ὁ"}, {{XK_Multi_key, XK_exclam, XK_exclam, XK_VoidSymbol}, "¡"}, // exclamdown | INVERTED EXCLAMATION MARK {{XK_dead_stroke, XK_B, XK_VoidSymbol}, "Ƀ"}, // U0243 | LATIN CAPITAL LETTER B WITH STROKE {{XK_dead_cedilla, XK_N, XK_VoidSymbol}, "Ņ"}, // U0145 | LATIN CAPITAL LETTER N WITH CEDILLA {{XK_Multi_key, XK_comma, XK_N, XK_VoidSymbol}, "Ņ"}, {{XK_Multi_key, XK_N, XK_comma, XK_VoidSymbol}, "Ņ"}, {{XK_Multi_key, XK_cedilla, XK_N, XK_VoidSymbol}, "Ņ"}, {{XK_dead_diaeresis, XK_A, XK_VoidSymbol}, "Ä"}, // Adiaeresis | LATIN CAPITAL LETTER A WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_A, XK_VoidSymbol}, "Ä"}, {{XK_Multi_key, XK_A, XK_quotedbl, XK_VoidSymbol}, "Ä"}, {{XK_Multi_key, XK_A, XK_diaeresis, XK_VoidSymbol}, "Ä"}, {{XK_Multi_key, XK_diaeresis, XK_A, XK_VoidSymbol}, "Ä"}, {{XK_dead_tilde, XK_Greek_eta, XK_VoidSymbol}, "ῆ"}, // U1FC6 | GREEK SMALL LETTER ETA WITH PERISPOMENI {{XK_Multi_key, XK_asciitilde, XK_Greek_eta, XK_VoidSymbol}, "ῆ"}, {{XK_dead_belowcircumflex, XK_n, XK_VoidSymbol}, "ṋ"}, // U1E4B | LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW {{XK_dead_abovedot, XK_dead_stroke, XK_j, XK_VoidSymbol}, "ɟ"}, // U025F | LATIN SMALL LETTER DOTLESS J WITH STROKE {{XK_dead_stroke, XK_dead_abovedot, XK_j, XK_VoidSymbol}, "ɟ"}, {{XK_Multi_key, XK_parenleft, XK_W, XK_parenright, XK_VoidSymbol}, "Ⓦ"}, // U24CC | CIRCLED LATIN CAPITAL LETTER W {{XK_dead_currency, XK_H, XK_VoidSymbol}, "₴"}, // U20B4 | HRYVNIA SIGN {{XK_dead_currency, XK_h, XK_VoidSymbol}, "₴"}, {{XK_dead_acute, XK_Greek_omega, XK_VoidSymbol}, "ώ"}, // U03CE | GREEK SMALL LETTER OMEGA WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_omega, XK_VoidSymbol}, "ώ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_omega, XK_VoidSymbol}, "ώ"}, {{XK_Multi_key, XK_Greek_omega, XK_apostrophe, XK_VoidSymbol}, "ώ"}, {{XK_dead_dasia, XK_Greek_upsilon, XK_VoidSymbol}, "ὑ"}, // U1F51 | GREEK SMALL LETTER UPSILON WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_upsilon, XK_VoidSymbol}, "ὑ"}, {{XK_dead_acute, XK_Ocircumflex, XK_VoidSymbol}, "Ố"}, // U1ED0 | LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE {{XK_Multi_key, XK_acute, XK_Ocircumflex, XK_VoidSymbol}, "Ố"}, {{XK_Multi_key, XK_apostrophe, XK_Ocircumflex, XK_VoidSymbol}, "Ố"}, {{XK_dead_acute, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ố"}, {{XK_dead_acute, XK_Multi_key, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ố"}, {{XK_Multi_key, XK_acute, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ố"}, {{XK_Multi_key, XK_acute, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ố"}, {{XK_Multi_key, XK_apostrophe, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ố"}, {{XK_Multi_key, XK_apostrophe, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ố"}, {{XK_dead_circumflex, XK_Oacute, XK_VoidSymbol}, "Ố"}, {{XK_dead_circumflex, XK_dead_acute, XK_O, XK_VoidSymbol}, "Ố"}, {{XK_Multi_key, XK_parenleft, XK_2, XK_3, XK_parenright, XK_VoidSymbol}, "㉓"}, // U3253 | CIRCLED NUMBER TWENTY THREE {{XK_Multi_key, XK_parenleft, XK_2, XK_KP_3, XK_parenright, XK_VoidSymbol}, "㉓"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_3, XK_parenright, XK_VoidSymbol}, "㉓"}, {{XK_Multi_key, XK_parenleft, XK_KP_Space, XK_KP_3, XK_parenright, XK_VoidSymbol}, "㉓"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_3, XK_parenright, XK_VoidSymbol}, "㉓"}, {{XK_Multi_key, XK_parenleft, XK_KP_2, XK_KP_3, XK_parenright, XK_VoidSymbol}, "㉓"}, {{XK_dead_acute, XK_r, XK_VoidSymbol}, "ŕ"}, // U0155 | LATIN SMALL LETTER R WITH ACUTE {{XK_Multi_key, XK_acute, XK_r, XK_VoidSymbol}, "ŕ"}, {{XK_Multi_key, XK_apostrophe, XK_r, XK_VoidSymbol}, "ŕ"}, {{XK_Multi_key, XK_r, XK_apostrophe, XK_VoidSymbol}, "ŕ"}, {{XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ô"}, // Ocircumflex | LATIN CAPITAL LETTER O WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ô"}, {{XK_Multi_key, XK_O, XK_asciicircum, XK_VoidSymbol}, "Ô"}, {{XK_Multi_key, XK_greater, XK_O, XK_VoidSymbol}, "Ô"}, {{XK_Multi_key, XK_O, XK_greater, XK_VoidSymbol}, "Ô"}, {{XK_dead_diaeresis, XK_Ukrainian_i, XK_VoidSymbol}, "ї"}, // U0457 | CYRILLIC SMALL LETTER YI {{XK_Multi_key, XK_quotedbl, XK_Ukrainian_i, XK_VoidSymbol}, "ї"}, {{XK_dead_tilde, XK_Greek_iota, XK_VoidSymbol}, "ῖ"}, // U1FD6 | GREEK SMALL LETTER IOTA WITH PERISPOMENI {{XK_Multi_key, XK_asciitilde, XK_Greek_iota, XK_VoidSymbol}, "ῖ"}, {{XK_dead_breve, XK_space, XK_VoidSymbol}, "˘"}, // breve | BREVE {{XK_dead_breve, XK_dead_breve, XK_VoidSymbol}, "˘"}, {{XK_Multi_key, XK_space, XK_parenleft, XK_VoidSymbol}, "˘"}, {{XK_Multi_key, XK_parenleft, XK_space, XK_VoidSymbol}, "˘"}, {{XK_dead_belowdot, XK_r, XK_VoidSymbol}, "ṛ"}, // U1E5B | LATIN SMALL LETTER R WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_r, XK_VoidSymbol}, "ṛ"}, {{XK_dead_caron, XK_udiaeresis, XK_VoidSymbol}, "ǚ"}, // U01DA | LATIN SMALL LETTER U WITH DIAERESIS AND CARON {{XK_Multi_key, XK_c, XK_udiaeresis, XK_VoidSymbol}, "ǚ"}, {{XK_dead_caron, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǚ"}, {{XK_dead_caron, XK_Multi_key, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǚ"}, {{XK_Multi_key, XK_c, XK_dead_diaeresis, XK_u, XK_VoidSymbol}, "ǚ"}, {{XK_Multi_key, XK_c, XK_quotedbl, XK_u, XK_VoidSymbol}, "ǚ"}, {{XK_dead_caron, XK_v, XK_VoidSymbol}, "ǚ"}, {{XK_dead_diaeresis, XK_dead_caron, XK_u, XK_VoidSymbol}, "ǚ"}, {{XK_dead_diaeresis, XK_Cyrillic_ZHE, XK_VoidSymbol}, "Ӝ"}, // U04DC | CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_ZHE, XK_VoidSymbol}, "Ӝ"}, {{XK_dead_acute, XK_Cyrillic_er, XK_VoidSymbol}, "р́"}, // CYRILLIC SMALL LETTER ER WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_er, XK_VoidSymbol}, "р́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_er, XK_VoidSymbol}, "р́"}, {{XK_dead_dasia, XK_Greek_omega, XK_VoidSymbol}, "ὡ"}, // U1F61 | GREEK SMALL LETTER OMEGA WITH DASIA {{XK_Multi_key, XK_parenleft, XK_Greek_omega, XK_VoidSymbol}, "ὡ"}, {{XK_dead_tilde, XK_Ohorn, XK_VoidSymbol}, "Ỡ"}, // U1EE0 | LATIN CAPITAL LETTER O WITH HORN AND TILDE {{XK_Multi_key, XK_asciitilde, XK_Ohorn, XK_VoidSymbol}, "Ỡ"}, {{XK_dead_tilde, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ỡ"}, {{XK_dead_tilde, XK_Multi_key, XK_plus, XK_O, XK_VoidSymbol}, "Ỡ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_horn, XK_O, XK_VoidSymbol}, "Ỡ"}, {{XK_Multi_key, XK_asciitilde, XK_plus, XK_O, XK_VoidSymbol}, "Ỡ"}, {{XK_dead_horn, XK_Otilde, XK_VoidSymbol}, "Ỡ"}, {{XK_dead_horn, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ỡ"}, {{XK_dead_caron, XK_t, XK_VoidSymbol}, "ť"}, // U0165 | LATIN SMALL LETTER T WITH CARON {{XK_Multi_key, XK_c, XK_t, XK_VoidSymbol}, "ť"}, {{XK_Multi_key, XK_less, XK_t, XK_VoidSymbol}, "ť"}, {{XK_Multi_key, XK_t, XK_less, XK_VoidSymbol}, "ť"}, {{XK_dead_diaeresis, XK_a, XK_VoidSymbol}, "ä"}, // adiaeresis | LATIN SMALL LETTER A WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_a, XK_VoidSymbol}, "ä"}, {{XK_Multi_key, XK_a, XK_quotedbl, XK_VoidSymbol}, "ä"}, {{XK_Multi_key, XK_diaeresis, XK_a, XK_VoidSymbol}, "ä"}, {{XK_Multi_key, XK_a, XK_diaeresis, XK_VoidSymbol}, "ä"}, {{XK_Multi_key, XK_parenleft, XK_8, XK_parenright, XK_VoidSymbol}, "⑧"}, // U2467 | CIRCLED DIGIT EIGHT {{XK_Multi_key, XK_parenleft, XK_KP_8, XK_parenright, XK_VoidSymbol}, "⑧"}, {{XK_dead_tilde, XK_Greek_upsilon, XK_VoidSymbol}, "ῦ"}, // U1FE6 | GREEK SMALL LETTER UPSILON WITH PERISPOMENI {{XK_Multi_key, XK_asciitilde, XK_Greek_upsilon, XK_VoidSymbol}, "ῦ"}, {{XK_Multi_key, XK_diaeresis, XK_greater, XK_VoidSymbol}, "⍩"}, // U2369 | ¨ > APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS {{XK_Multi_key, XK_greater, XK_diaeresis, XK_VoidSymbol}, "⍩"}, {{XK_Multi_key, XK_parenleft, XK_kana_NO, XK_parenright, XK_VoidSymbol}, "㋨"}, // U32E8 | CIRCLED KATAKANA NO {{XK_Multi_key, XK_numbersign, XK_E, XK_VoidSymbol}, "♫"}, // U266b | BEAMED EIGHTH NOTES {{XK_dead_ogonek, XK_O, XK_VoidSymbol}, "Ǫ"}, // U01EA | LATIN CAPITAL LETTER O WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_O, XK_VoidSymbol}, "Ǫ"}, {{XK_dead_diaeresis, XK_Cyrillic_E, XK_VoidSymbol}, "Ӭ"}, // U04EC | CYRILLIC CAPITAL LETTER E WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_E, XK_VoidSymbol}, "Ӭ"}, {{XK_dead_circumflex, XK_equal, XK_VoidSymbol}, "⁼"}, // U207C | SUPERSCRIPT EQUALS SIGN {{XK_Multi_key, XK_asciicircum, XK_equal, XK_VoidSymbol}, "⁼"}, {{XK_dead_circumflex, XK_KP_Equal, XK_VoidSymbol}, "⁼"}, {{XK_Multi_key, XK_asciicircum, XK_KP_Equal, XK_VoidSymbol}, "⁼"}, {{XK_Multi_key, XK_o, XK_c, XK_VoidSymbol}, "©"}, // copyright | COPYRIGHT SIGN {{XK_Multi_key, XK_o, XK_C, XK_VoidSymbol}, "©"}, {{XK_Multi_key, XK_O, XK_c, XK_VoidSymbol}, "©"}, {{XK_Multi_key, XK_O, XK_C, XK_VoidSymbol}, "©"}, {{XK_Multi_key, XK_C, XK_o, XK_VoidSymbol}, "©"}, {{XK_Multi_key, XK_C, XK_O, XK_VoidSymbol}, "©"}, {{XK_dead_tilde, XK_greater, XK_VoidSymbol}, "≳"}, // U2273 | GREATER-THAN OR EQUIVALENT TO {{XK_Multi_key, XK_parenleft, XK_c, XK_parenright, XK_VoidSymbol}, "ⓒ"}, // U24D2 | CIRCLED LATIN SMALL LETTER C {{XK_dead_circumflex, XK_w, XK_VoidSymbol}, "ŵ"}, // U0175 | LATIN SMALL LETTER W WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_w, XK_VoidSymbol}, "ŵ"}, {{XK_Multi_key, XK_w, XK_asciicircum, XK_VoidSymbol}, "ŵ"}, {{XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ô"}, // ocircumflex | LATIN SMALL LETTER O WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_o, XK_VoidSymbol}, "ô"}, {{XK_Multi_key, XK_o, XK_asciicircum, XK_VoidSymbol}, "ô"}, {{XK_Multi_key, XK_greater, XK_o, XK_VoidSymbol}, "ô"}, {{XK_Multi_key, XK_o, XK_greater, XK_VoidSymbol}, "ô"}, {{XK_dead_tilde, XK_Greek_omega, XK_VoidSymbol}, "ῶ"}, // U1FF6 | GREEK SMALL LETTER OMEGA WITH PERISPOMENI {{XK_Multi_key, XK_asciitilde, XK_Greek_omega, XK_VoidSymbol}, "ῶ"}, {{XK_Multi_key, XK_parenleft, XK_kana_RU, XK_parenright, XK_VoidSymbol}, "㋸"}, // U32F8 | CIRCLED KATAKANA RU {{XK_dead_diaeresis, XK_umacron, XK_VoidSymbol}, "ṻ"}, // U1E7B | LATIN SMALL LETTER U WITH MACRON AND DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_umacron, XK_VoidSymbol}, "ṻ"}, {{XK_dead_diaeresis, XK_dead_macron, XK_u, XK_VoidSymbol}, "ṻ"}, {{XK_dead_diaeresis, XK_Multi_key, XK_macron, XK_u, XK_VoidSymbol}, "ṻ"}, {{XK_dead_diaeresis, XK_Multi_key, XK_underscore, XK_u, XK_VoidSymbol}, "ṻ"}, {{XK_Multi_key, XK_quotedbl, XK_dead_macron, XK_u, XK_VoidSymbol}, "ṻ"}, {{XK_Multi_key, XK_quotedbl, XK_macron, XK_u, XK_VoidSymbol}, "ṻ"}, {{XK_Multi_key, XK_quotedbl, XK_underscore, XK_u, XK_VoidSymbol}, "ṻ"}, {{XK_dead_acute, XK_Aring, XK_VoidSymbol}, "Ǻ"}, // U01FA | LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE {{XK_Multi_key, XK_acute, XK_Aring, XK_VoidSymbol}, "Ǻ"}, {{XK_Multi_key, XK_apostrophe, XK_Aring, XK_VoidSymbol}, "Ǻ"}, {{XK_dead_acute, XK_dead_abovering, XK_A, XK_VoidSymbol}, "Ǻ"}, {{XK_dead_acute, XK_Multi_key, XK_o, XK_A, XK_VoidSymbol}, "Ǻ"}, {{XK_Multi_key, XK_acute, XK_dead_abovering, XK_A, XK_VoidSymbol}, "Ǻ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_abovering, XK_A, XK_VoidSymbol}, "Ǻ"}, {{XK_Multi_key, XK_asterisk, XK_apostrophe, XK_A, XK_VoidSymbol}, "Ǻ"}, {{XK_dead_abovering, XK_Aacute, XK_VoidSymbol}, "Ǻ"}, {{XK_dead_abovering, XK_dead_acute, XK_A, XK_VoidSymbol}, "Ǻ"}, {{XK_dead_stroke, XK_p, XK_VoidSymbol}, "ᵽ"}, // U1D7D | LATIN SMALL LETTER P WITH STROKE {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_n, XK_VoidSymbol}, "ⁿ"}, // U207F | SUPERSCRIPT LATIN SMALL LETTER N {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_n, XK_VoidSymbol}, "ⁿ"}, {{XK_dead_grave, XK_w, XK_VoidSymbol}, "ẁ"}, // U1E81 | LATIN SMALL LETTER W WITH GRAVE {{XK_Multi_key, XK_grave, XK_w, XK_VoidSymbol}, "ẁ"}, {{XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ἀ"}, // U1F00 | GREEK SMALL LETTER ALPHA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ἀ"}, {{XK_dead_belowdot, XK_minus, XK_VoidSymbol}, "⨪"}, // U2A2A | MINUS SIGN WITH DOT BELOW {{XK_Multi_key, XK_underscore, XK_5, XK_VoidSymbol}, "₅"}, // U2085 | SUBSCRIPT FIVE {{XK_Multi_key, XK_underscore, XK_KP_5, XK_VoidSymbol}, "₅"}, {{XK_dead_caron, XK_5, XK_VoidSymbol}, "₅"}, {{XK_dead_ogonek, XK_A, XK_VoidSymbol}, "Ą"}, // U0104 | LATIN CAPITAL LETTER A WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_A, XK_VoidSymbol}, "Ą"}, {{XK_Multi_key, XK_comma, XK_A, XK_VoidSymbol}, "Ą"}, {{XK_Multi_key, XK_A, XK_comma, XK_VoidSymbol}, "Ą"}, {{XK_dead_belowmacron, XK_B, XK_VoidSymbol}, "Ḇ"}, // U1E06 | LATIN CAPITAL LETTER B WITH LINE BELOW {{XK_dead_stroke, XK_u, XK_VoidSymbol}, "ʉ"}, // U0289 | LATIN SMALL LETTER U BAR {{XK_dead_diaeresis, XK_nobreakspace, XK_VoidSymbol}, "̈"}, // U0308 | COMBINING DIAERESIS {{XK_dead_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, // U1F8B | GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾋ"}, {{XK_dead_circumflex, XK_z, XK_VoidSymbol}, "ẑ"}, // U1E91 | LATIN SMALL LETTER Z WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_z, XK_VoidSymbol}, "ẑ"}, {{XK_dead_psili, XK_Greek_epsilon, XK_VoidSymbol}, "ἐ"}, // U1F10 | GREEK SMALL LETTER EPSILON WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_epsilon, XK_VoidSymbol}, "ἐ"}, {{XK_dead_breve, XK_E, XK_VoidSymbol}, "Ĕ"}, // U0114 | LATIN CAPITAL LETTER E WITH BREVE {{XK_Multi_key, XK_U, XK_E, XK_VoidSymbol}, "Ĕ"}, {{XK_Multi_key, XK_b, XK_E, XK_VoidSymbol}, "Ĕ"}, {{XK_dead_acute, XK_Emacron, XK_VoidSymbol}, "Ḗ"}, // U1E16 | LATIN CAPITAL LETTER E WITH MACRON AND ACUTE {{XK_Multi_key, XK_acute, XK_Emacron, XK_VoidSymbol}, "Ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_Emacron, XK_VoidSymbol}, "Ḗ"}, {{XK_dead_acute, XK_dead_macron, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_dead_acute, XK_Multi_key, XK_macron, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_dead_acute, XK_Multi_key, XK_underscore, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_Multi_key, XK_acute, XK_dead_macron, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_Multi_key, XK_acute, XK_macron, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_Multi_key, XK_acute, XK_underscore, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_dead_macron, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_macron, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_Multi_key, XK_apostrophe, XK_underscore, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_dead_macron, XK_Eacute, XK_VoidSymbol}, "Ḗ"}, {{XK_dead_macron, XK_dead_acute, XK_E, XK_VoidSymbol}, "Ḗ"}, {{XK_dead_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, // U1F9B | GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "ᾛ"}, {{XK_Multi_key, XK_comma, XK_apostrophe, XK_VoidSymbol}, "‚"}, // U201a | SINGLE LOW-9 QUOTATION MARK {{XK_Multi_key, XK_apostrophe, XK_comma, XK_VoidSymbol}, "‚"}, {{XK_dead_caron, XK_H, XK_VoidSymbol}, "Ȟ"}, // U021E | LATIN CAPITAL LETTER H WITH CARON {{XK_Multi_key, XK_c, XK_H, XK_VoidSymbol}, "Ȟ"}, {{XK_dead_belowdot, XK_a, XK_VoidSymbol}, "ạ"}, // U1EA1 | LATIN SMALL LETTER A WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_a, XK_VoidSymbol}, "ạ"}, {{XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ἠ"}, // U1F20 | GREEK SMALL LETTER ETA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ἠ"}, {{XK_dead_semivoiced_sound, XK_kana_HE, XK_VoidSymbol}, "ペ"}, // U30DA | KATAKANA LETTER PE {{XK_Multi_key, XK_Y, XK_equal, XK_VoidSymbol}, "¥"}, // yen | YEN SIGN {{XK_Multi_key, XK_y, XK_equal, XK_VoidSymbol}, "¥"}, {{XK_Multi_key, XK_equal, XK_Y, XK_VoidSymbol}, "¥"}, {{XK_Multi_key, XK_equal, XK_y, XK_VoidSymbol}, "¥"}, {{XK_Multi_key, XK_Y, XK_minus, XK_VoidSymbol}, "¥"}, {{XK_Multi_key, XK_minus, XK_Y, XK_VoidSymbol}, "¥"}, {{XK_Multi_key, XK_y, XK_minus, XK_VoidSymbol}, "¥"}, {{XK_Multi_key, XK_minus, XK_y, XK_VoidSymbol}, "¥"}, {{XK_dead_currency, XK_y, XK_VoidSymbol}, "¥"}, {{XK_dead_circumflex, XK_H, XK_VoidSymbol}, "Ĥ"}, // U0124 | LATIN CAPITAL LETTER H WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_H, XK_VoidSymbol}, "Ĥ"}, {{XK_dead_diaeresis, XK_H, XK_VoidSymbol}, "Ḧ"}, // U1E26 | LATIN CAPITAL LETTER H WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_H, XK_VoidSymbol}, "Ḧ"}, {{XK_dead_ogonek, XK_nobreakspace, XK_VoidSymbol}, "̨"}, // U0328 | COMBINING OGONEK {{XK_dead_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, // U1FAB | GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, {{XK_dead_iota, XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_grave, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, {{XK_Multi_key, XK_Greek_iota, XK_grave, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "ᾫ"}, {{XK_dead_horn, XK_U, XK_VoidSymbol}, "Ư"}, // U01AF | LATIN CAPITAL LETTER U WITH HORN {{XK_Multi_key, XK_plus, XK_U, XK_VoidSymbol}, "Ư"}, {{XK_dead_abovedot, XK_O, XK_VoidSymbol}, "Ȯ"}, // U022E | LATIN CAPITAL LETTER O WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_O, XK_VoidSymbol}, "Ȯ"}, {{XK_dead_grave, XK_abreve, XK_VoidSymbol}, "ằ"}, // U1EB1 | LATIN SMALL LETTER A WITH BREVE AND GRAVE {{XK_Multi_key, XK_grave, XK_abreve, XK_VoidSymbol}, "ằ"}, {{XK_dead_grave, XK_dead_breve, XK_a, XK_VoidSymbol}, "ằ"}, {{XK_dead_grave, XK_Multi_key, XK_U, XK_a, XK_VoidSymbol}, "ằ"}, {{XK_dead_grave, XK_Multi_key, XK_b, XK_a, XK_VoidSymbol}, "ằ"}, {{XK_Multi_key, XK_grave, XK_dead_breve, XK_a, XK_VoidSymbol}, "ằ"}, {{XK_Multi_key, XK_grave, XK_b, XK_a, XK_VoidSymbol}, "ằ"}, {{XK_dead_breve, XK_agrave, XK_VoidSymbol}, "ằ"}, {{XK_dead_breve, XK_dead_grave, XK_a, XK_VoidSymbol}, "ằ"}, {{XK_dead_psili, XK_Greek_iota, XK_VoidSymbol}, "ἰ"}, // U1F30 | GREEK SMALL LETTER IOTA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_iota, XK_VoidSymbol}, "ἰ"}, {{XK_Multi_key, XK_m, XK_u, XK_VoidSymbol}, "µ"}, // mu | MICRO SIGN {{XK_Multi_key, XK_slash, XK_u, XK_VoidSymbol}, "µ"}, {{XK_Multi_key, XK_u, XK_slash, XK_VoidSymbol}, "µ"}, {{XK_dead_circumflex, XK_J, XK_VoidSymbol}, "Ĵ"}, // U0134 | LATIN CAPITAL LETTER J WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_J, XK_VoidSymbol}, "Ĵ"}, {{XK_dead_belowdot, XK_L, XK_VoidSymbol}, "Ḷ"}, // U1E36 | LATIN CAPITAL LETTER L WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_L, XK_VoidSymbol}, "Ḷ"}, {{XK_Multi_key, XK_parenleft, XK_4, XK_4, XK_parenright, XK_VoidSymbol}, "㊹"}, // U32B9 | CIRCLED NUMBER FORTY FOUR {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_4, XK_parenright, XK_VoidSymbol}, "㊹"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_4, XK_parenright, XK_VoidSymbol}, "㊹"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_4, XK_parenright, XK_VoidSymbol}, "㊹"}, {{XK_dead_stroke, XK_nobreakspace, XK_VoidSymbol}, "̸"}, // U0338 | COMBINING LONG SOLIDUS OVERLAY {{XK_Multi_key, XK_period, XK_greater, XK_VoidSymbol}, "›"}, // U203a | SINGLE RIGHT-POINTING ANGLE QUOTATION MARK {{XK_Multi_key, XK_parenleft, XK_H, XK_parenright, XK_VoidSymbol}, "Ⓗ"}, // U24BD | CIRCLED LATIN CAPITAL LETTER H {{XK_dead_currency, XK_a, XK_VoidSymbol}, "؋"}, // U060B | AFGHANI SIGN {{XK_dead_voiced_sound, XK_kana_WO, XK_VoidSymbol}, "ヺ"}, // U30FA | KATAKANA LETTER VO {{XK_dead_grave, XK_ecircumflex, XK_VoidSymbol}, "ề"}, // U1EC1 | LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE {{XK_Multi_key, XK_grave, XK_ecircumflex, XK_VoidSymbol}, "ề"}, {{XK_dead_grave, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ề"}, {{XK_dead_grave, XK_Multi_key, XK_asciicircum, XK_e, XK_VoidSymbol}, "ề"}, {{XK_Multi_key, XK_grave, XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ề"}, {{XK_Multi_key, XK_grave, XK_asciicircum, XK_e, XK_VoidSymbol}, "ề"}, {{XK_dead_circumflex, XK_egrave, XK_VoidSymbol}, "ề"}, {{XK_dead_circumflex, XK_dead_grave, XK_e, XK_VoidSymbol}, "ề"}, {{XK_dead_psili, XK_Greek_omicron, XK_VoidSymbol}, "ὀ"}, // U1F40 | GREEK SMALL LETTER OMICRON WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_omicron, XK_VoidSymbol}, "ὀ"}, {{XK_dead_abovering, XK_A, XK_VoidSymbol}, "Å"}, // Aring | LATIN CAPITAL LETTER A WITH RING ABOVE {{XK_Multi_key, XK_o, XK_A, XK_VoidSymbol}, "Å"}, {{XK_Multi_key, XK_asterisk, XK_A, XK_VoidSymbol}, "Å"}, {{XK_Multi_key, XK_A, XK_asterisk, XK_VoidSymbol}, "Å"}, {{XK_Multi_key, XK_A, XK_A, XK_VoidSymbol}, "Å"}, {{XK_dead_acute, XK_n, XK_VoidSymbol}, "ń"}, // U0144 | LATIN SMALL LETTER N WITH ACUTE {{XK_Multi_key, XK_acute, XK_n, XK_VoidSymbol}, "ń"}, {{XK_Multi_key, XK_apostrophe, XK_n, XK_VoidSymbol}, "ń"}, {{XK_Multi_key, XK_n, XK_apostrophe, XK_VoidSymbol}, "ń"}, {{XK_dead_belowdot, XK_N, XK_VoidSymbol}, "Ṇ"}, // U1E46 | LATIN CAPITAL LETTER N WITH DOT BELOW {{XK_Multi_key, XK_exclam, XK_N, XK_VoidSymbol}, "Ṇ"}, {{XK_Multi_key, XK_parenleft, XK_X, XK_parenright, XK_VoidSymbol}, "Ⓧ"}, // U24CD | CIRCLED LATIN CAPITAL LETTER X {{XK_dead_caron, XK_I, XK_VoidSymbol}, "Ǐ"}, // U01CF | LATIN CAPITAL LETTER I WITH CARON {{XK_Multi_key, XK_c, XK_I, XK_VoidSymbol}, "Ǐ"}, {{XK_dead_stroke, XK_Y, XK_VoidSymbol}, "Ɏ"}, // U024E | LATIN CAPITAL LETTER Y WITH STROKE {{XK_dead_acute, XK_ocircumflex, XK_VoidSymbol}, "ố"}, // U1ED1 | LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE {{XK_Multi_key, XK_acute, XK_ocircumflex, XK_VoidSymbol}, "ố"}, {{XK_Multi_key, XK_apostrophe, XK_ocircumflex, XK_VoidSymbol}, "ố"}, {{XK_dead_acute, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ố"}, {{XK_dead_acute, XK_Multi_key, XK_asciicircum, XK_o, XK_VoidSymbol}, "ố"}, {{XK_Multi_key, XK_acute, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ố"}, {{XK_Multi_key, XK_acute, XK_asciicircum, XK_o, XK_VoidSymbol}, "ố"}, {{XK_Multi_key, XK_apostrophe, XK_dead_circumflex, XK_o, XK_VoidSymbol}, "ố"}, {{XK_Multi_key, XK_apostrophe, XK_asciicircum, XK_o, XK_VoidSymbol}, "ố"}, {{XK_dead_circumflex, XK_oacute, XK_VoidSymbol}, "ố"}, {{XK_dead_circumflex, XK_dead_acute, XK_o, XK_VoidSymbol}, "ố"}, {{XK_dead_psili, XK_Greek_upsilon, XK_VoidSymbol}, "ὐ"}, // U1F50 | GREEK SMALL LETTER UPSILON WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_upsilon, XK_VoidSymbol}, "ὐ"}, {{XK_Multi_key, XK_parenleft, XK_s, XK_parenright, XK_VoidSymbol}, "ⓢ"}, // U24E2 | CIRCLED LATIN SMALL LETTER S {{XK_dead_tilde, XK_O, XK_VoidSymbol}, "Õ"}, // Otilde | LATIN CAPITAL LETTER O WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_O, XK_VoidSymbol}, "Õ"}, {{XK_Multi_key, XK_O, XK_asciitilde, XK_VoidSymbol}, "Õ"}, {{XK_dead_acute, XK_R, XK_VoidSymbol}, "Ŕ"}, // U0154 | LATIN CAPITAL LETTER R WITH ACUTE {{XK_Multi_key, XK_acute, XK_R, XK_VoidSymbol}, "Ŕ"}, {{XK_Multi_key, XK_apostrophe, XK_R, XK_VoidSymbol}, "Ŕ"}, {{XK_Multi_key, XK_R, XK_apostrophe, XK_VoidSymbol}, "Ŕ"}, {{XK_dead_abovedot, XK_P, XK_VoidSymbol}, "Ṗ"}, // U1E56 | LATIN CAPITAL LETTER P WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_P, XK_VoidSymbol}, "Ṗ"}, {{XK_Multi_key, XK_P, XK_period, XK_VoidSymbol}, "Ṗ"}, {{XK_dead_abovedot, XK_space, XK_VoidSymbol}, "˙"}, // abovedot | DOT ABOVE {{XK_dead_abovedot, XK_dead_abovedot, XK_VoidSymbol}, "˙"}, {{XK_dead_stroke, XK_a, XK_VoidSymbol}, "ⱥ"}, // U2C65 | LATIN SMALL LETTER A WITH STROKE {{XK_dead_currency, XK_I, XK_VoidSymbol}, "៛"}, // U17DB | KHMER CURRENCY SYMBOL RIEL {{XK_dead_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, // U1F8E | GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI {{XK_dead_iota, XK_dead_tilde, XK_Multi_key, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, {{XK_dead_iota, XK_Multi_key, XK_asciitilde, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_tilde, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_dead_psili, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, {{XK_Multi_key, XK_Greek_iota, XK_asciitilde, XK_parenright, XK_Greek_ALPHA, XK_VoidSymbol}, "ᾎ"}, {{XK_dead_diaeresis, XK_Cyrillic_zhe, XK_VoidSymbol}, "ӝ"}, // U04DD | CYRILLIC SMALL LETTER ZHE WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_zhe, XK_VoidSymbol}, "ӝ"}, {{XK_dead_invertedbreve, XK_Cyrillic_i, XK_VoidSymbol}, "и̑"}, // CYRILLIC SMALL LETTER I WITH COMBINING INVERTED BREVE {{XK_dead_macron, XK_adiaeresis, XK_VoidSymbol}, "ǟ"}, // U01DF | LATIN SMALL LETTER A WITH DIAERESIS AND MACRON {{XK_Multi_key, XK_macron, XK_adiaeresis, XK_VoidSymbol}, "ǟ"}, {{XK_Multi_key, XK_underscore, XK_adiaeresis, XK_VoidSymbol}, "ǟ"}, {{XK_dead_macron, XK_dead_diaeresis, XK_a, XK_VoidSymbol}, "ǟ"}, {{XK_dead_macron, XK_Multi_key, XK_quotedbl, XK_a, XK_VoidSymbol}, "ǟ"}, {{XK_Multi_key, XK_macron, XK_dead_diaeresis, XK_a, XK_VoidSymbol}, "ǟ"}, {{XK_Multi_key, XK_macron, XK_quotedbl, XK_a, XK_VoidSymbol}, "ǟ"}, {{XK_Multi_key, XK_underscore, XK_dead_diaeresis, XK_a, XK_VoidSymbol}, "ǟ"}, {{XK_Multi_key, XK_underscore, XK_quotedbl, XK_a, XK_VoidSymbol}, "ǟ"}, {{XK_dead_diaeresis, XK_amacron, XK_VoidSymbol}, "ǟ"}, {{XK_dead_diaeresis, XK_dead_macron, XK_a, XK_VoidSymbol}, "ǟ"}, {{XK_Multi_key, XK_parenleft, XK_3, XK_4, XK_parenright, XK_VoidSymbol}, "㉞"}, // U325E | CIRCLED NUMBER THIRTY FOUR {{XK_Multi_key, XK_parenleft, XK_3, XK_KP_4, XK_parenright, XK_VoidSymbol}, "㉞"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_4, XK_parenright, XK_VoidSymbol}, "㉞"}, {{XK_Multi_key, XK_parenleft, XK_KP_3, XK_KP_4, XK_parenright, XK_VoidSymbol}, "㉞"}, {{XK_dead_tilde, XK_ohorn, XK_VoidSymbol}, "ỡ"}, // U1EE1 | LATIN SMALL LETTER O WITH HORN AND TILDE {{XK_Multi_key, XK_asciitilde, XK_ohorn, XK_VoidSymbol}, "ỡ"}, {{XK_dead_tilde, XK_dead_horn, XK_o, XK_VoidSymbol}, "ỡ"}, {{XK_dead_tilde, XK_Multi_key, XK_plus, XK_o, XK_VoidSymbol}, "ỡ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_horn, XK_o, XK_VoidSymbol}, "ỡ"}, {{XK_Multi_key, XK_asciitilde, XK_plus, XK_o, XK_VoidSymbol}, "ỡ"}, {{XK_dead_horn, XK_otilde, XK_VoidSymbol}, "ỡ"}, {{XK_dead_horn, XK_dead_tilde, XK_o, XK_VoidSymbol}, "ỡ"}, {{XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ὠ"}, // U1F60 | GREEK SMALL LETTER OMEGA WITH PSILI {{XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ὠ"}, {{XK_dead_grave, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̀"}, // CYRILLIC CAPITAL LETTER ER WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̀"}, {{XK_dead_belowmacron, XK_L, XK_VoidSymbol}, "Ḻ"}, // U1E3A | LATIN CAPITAL LETTER L WITH LINE BELOW {{XK_dead_abovering, XK_a, XK_VoidSymbol}, "å"}, // aring | LATIN SMALL LETTER A WITH RING ABOVE {{XK_Multi_key, XK_o, XK_a, XK_VoidSymbol}, "å"}, {{XK_Multi_key, XK_asterisk, XK_a, XK_VoidSymbol}, "å"}, {{XK_Multi_key, XK_a, XK_asterisk, XK_VoidSymbol}, "å"}, {{XK_Multi_key, XK_a, XK_a, XK_VoidSymbol}, "å"}, {{XK_dead_caron, XK_T, XK_VoidSymbol}, "Ť"}, // U0164 | LATIN CAPITAL LETTER T WITH CARON {{XK_Multi_key, XK_c, XK_T, XK_VoidSymbol}, "Ť"}, {{XK_Multi_key, XK_less, XK_T, XK_VoidSymbol}, "Ť"}, {{XK_Multi_key, XK_T, XK_less, XK_VoidSymbol}, "Ť"}, {{XK_dead_macron, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̄"}, // CYRILLIC CAPITAL LETTER ER WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̄"}, {{XK_dead_abovedot, XK_Scaron, XK_VoidSymbol}, "Ṧ"}, // U1E66 | LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE {{XK_Multi_key, XK_period, XK_Scaron, XK_VoidSymbol}, "Ṧ"}, {{XK_dead_abovedot, XK_dead_caron, XK_S, XK_VoidSymbol}, "Ṧ"}, {{XK_dead_abovedot, XK_Multi_key, XK_c, XK_S, XK_VoidSymbol}, "Ṧ"}, {{XK_Multi_key, XK_period, XK_dead_caron, XK_S, XK_VoidSymbol}, "Ṧ"}, {{XK_dead_caron, XK_Sabovedot, XK_VoidSymbol}, "Ṧ"}, {{XK_dead_caron, XK_dead_abovedot, XK_S, XK_VoidSymbol}, "Ṧ"}, {{XK_Multi_key, XK_parenleft, XK_kana_HA, XK_parenright, XK_VoidSymbol}, "㋩"}, // U32E9 | CIRCLED KATAKANA HA {{XK_Multi_key, XK_asciitilde, XK_diaeresis, XK_VoidSymbol}, "⍨"}, // U2368 | ~ ¨ APL FUNCTIONAL SYMBOL TILDE DIAERESIS {{XK_dead_circumflex, XK_Multi_key, XK_T, XK_M, XK_VoidSymbol}, "™"}, // U2122 | TRADE MARK SIGN {{XK_Multi_key, XK_T, XK_M, XK_VoidSymbol}, "™"}, {{XK_dead_circumflex, XK_Multi_key, XK_t, XK_M, XK_VoidSymbol}, "™"}, {{XK_Multi_key, XK_t, XK_M, XK_VoidSymbol}, "™"}, {{XK_dead_circumflex, XK_Multi_key, XK_T, XK_m, XK_VoidSymbol}, "™"}, {{XK_Multi_key, XK_T, XK_m, XK_VoidSymbol}, "™"}, {{XK_dead_circumflex, XK_Multi_key, XK_t, XK_m, XK_VoidSymbol}, "™"}, {{XK_Multi_key, XK_t, XK_m, XK_VoidSymbol}, "™"}, {{XK_dead_diaeresis, XK_Cyrillic_e, XK_VoidSymbol}, "ӭ"}, // U04ED | CYRILLIC SMALL LETTER E WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_e, XK_VoidSymbol}, "ӭ"}, {{XK_dead_doublegrave, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̏"}, // CYRILLIC CAPITAL LETTER ER WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_ER, XK_VoidSymbol}, "Р̏"}, {{XK_dead_stroke, XK_less, XK_VoidSymbol}, "≮"}, // U226E | NOT LESS-THAN {{XK_dead_belowdot, XK_uhorn, XK_VoidSymbol}, "ự"}, // U1EF1 | LATIN SMALL LETTER U WITH HORN AND DOT BELOW {{XK_Multi_key, XK_exclam, XK_uhorn, XK_VoidSymbol}, "ự"}, {{XK_dead_belowdot, XK_dead_horn, XK_u, XK_VoidSymbol}, "ự"}, {{XK_dead_belowdot, XK_Multi_key, XK_plus, XK_u, XK_VoidSymbol}, "ự"}, {{XK_Multi_key, XK_exclam, XK_dead_horn, XK_u, XK_VoidSymbol}, "ự"}, {{XK_Multi_key, XK_exclam, XK_plus, XK_u, XK_VoidSymbol}, "ự"}, {{XK_dead_horn, XK_ubelowdot, XK_VoidSymbol}, "ự"}, {{XK_dead_horn, XK_dead_belowdot, XK_u, XK_VoidSymbol}, "ự"}, {{XK_dead_abovedot, XK_dead_belowdot, XK_s, XK_VoidSymbol}, "ṩ"}, // U1E69 | LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE {{XK_dead_abovedot, XK_Multi_key, XK_exclam, XK_s, XK_VoidSymbol}, "ṩ"}, {{XK_Multi_key, XK_period, XK_dead_belowdot, XK_s, XK_VoidSymbol}, "ṩ"}, {{XK_Multi_key, XK_period, XK_exclam, XK_s, XK_VoidSymbol}, "ṩ"}, {{XK_dead_belowdot, XK_sabovedot, XK_VoidSymbol}, "ṩ"}, {{XK_dead_belowdot, XK_dead_abovedot, XK_s, XK_VoidSymbol}, "ṩ"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_9, XK_parenright, XK_VoidSymbol}, "⑲"}, // U2472 | CIRCLED NUMBER NINETEEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_9, XK_parenright, XK_VoidSymbol}, "⑲"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_9, XK_parenright, XK_VoidSymbol}, "⑲"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_9, XK_parenright, XK_VoidSymbol}, "⑲"}, {{XK_dead_tilde, XK_o, XK_VoidSymbol}, "õ"}, // otilde | LATIN SMALL LETTER O WITH TILDE {{XK_Multi_key, XK_asciitilde, XK_o, XK_VoidSymbol}, "õ"}, {{XK_Multi_key, XK_o, XK_asciitilde, XK_VoidSymbol}, "õ"}, {{XK_dead_circumflex, XK_W, XK_VoidSymbol}, "Ŵ"}, // U0174 | LATIN CAPITAL LETTER W WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_W, XK_VoidSymbol}, "Ŵ"}, {{XK_Multi_key, XK_W, XK_asciicircum, XK_VoidSymbol}, "Ŵ"}, {{XK_dead_belowcircumflex, XK_U, XK_VoidSymbol}, "Ṷ"}, // U1E76 | LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW {{XK_Multi_key, XK_parenleft, XK_kana_RE, XK_parenright, XK_VoidSymbol}, "㋹"}, // U32F9 | CIRCLED KATAKANA RE {{XK_dead_circumflex, XK_plus, XK_VoidSymbol}, "⁺"}, // U207A | SUPERSCRIPT PLUS SIGN {{XK_Multi_key, XK_asciicircum, XK_plus, XK_VoidSymbol}, "⁺"}, {{XK_dead_circumflex, XK_KP_Add, XK_VoidSymbol}, "⁺"}, {{XK_Multi_key, XK_asciicircum, XK_KP_Add, XK_VoidSymbol}, "⁺"}, {{XK_dead_acute, XK_oslash, XK_VoidSymbol}, "ǿ"}, // U01FF | LATIN SMALL LETTER O WITH STROKE AND ACUTE {{XK_Multi_key, XK_acute, XK_oslash, XK_VoidSymbol}, "ǿ"}, {{XK_Multi_key, XK_apostrophe, XK_oslash, XK_VoidSymbol}, "ǿ"}, {{XK_dead_acute, XK_dead_stroke, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_dead_acute, XK_Multi_key, XK_slash, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_Multi_key, XK_acute, XK_slash, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_Multi_key, XK_apostrophe, XK_slash, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_dead_acute, XK_Multi_key, XK_KP_Divide, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_Multi_key, XK_acute, XK_KP_Divide, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_Multi_key, XK_apostrophe, XK_KP_Divide, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_dead_stroke, XK_dead_acute, XK_o, XK_VoidSymbol}, "ǿ"}, {{XK_dead_stroke, XK_oacute, XK_VoidSymbol}, "ǿ"}, {{XK_dead_belowring, XK_a, XK_VoidSymbol}, "ḁ"}, // U1E01 | LATIN SMALL LETTER A WITH RING BELOW {{XK_dead_iota, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾀ"}, // U1F80 | GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾀ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_psili, XK_Greek_alpha, XK_VoidSymbol}, "ᾀ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenright, XK_Greek_alpha, XK_VoidSymbol}, "ᾀ"}, {{XK_Multi_key, XK_F, XK_i, XK_VoidSymbol}, "ffi"}, // Ufb03 | LATIN SMALL LIGATURE FFI {{XK_dead_abovedot, XK_W, XK_VoidSymbol}, "Ẇ"}, // U1E86 | LATIN CAPITAL LETTER W WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_W, XK_VoidSymbol}, "Ẇ"}, {{XK_dead_acute, XK_Cyrillic_O, XK_VoidSymbol}, "О́"}, // CYRILLIC CAPITAL LETTER O WITH COMBINING ACUTE ACCENT {{XK_Multi_key, XK_acute, XK_Cyrillic_O, XK_VoidSymbol}, "О́"}, {{XK_Multi_key, XK_apostrophe, XK_Cyrillic_O, XK_VoidSymbol}, "О́"}, {{XK_dead_acute, XK_Greek_EPSILON, XK_VoidSymbol}, "Έ"}, // U0388 | GREEK CAPITAL LETTER EPSILON WITH TONOS {{XK_Multi_key, XK_acute, XK_Greek_EPSILON, XK_VoidSymbol}, "Έ"}, {{XK_Multi_key, XK_apostrophe, XK_Greek_EPSILON, XK_VoidSymbol}, "Έ"}, {{XK_Multi_key, XK_Greek_EPSILON, XK_apostrophe, XK_VoidSymbol}, "Έ"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἃ"}, // U1F0B | GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἃ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἃ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_ALPHA, XK_VoidSymbol}, "Ἃ"}, {{XK_Multi_key, XK_underscore, XK_plus, XK_VoidSymbol}, "₊"}, // U208A | SUBSCRIPT PLUS SIGN {{XK_Multi_key, XK_underscore, XK_KP_Add, XK_VoidSymbol}, "₊"}, {{XK_dead_caron, XK_plus, XK_VoidSymbol}, "₊"}, {{XK_dead_grave, XK_Cyrillic_I, XK_VoidSymbol}, "Ѝ"}, // U040D | CYRILLIC CAPITAL LETTER I WITH GRAVE {{XK_Multi_key, XK_grave, XK_Cyrillic_I, XK_VoidSymbol}, "Ѝ"}, {{XK_dead_caron, XK_d, XK_VoidSymbol}, "ď"}, // U010F | LATIN SMALL LETTER D WITH CARON {{XK_Multi_key, XK_c, XK_d, XK_VoidSymbol}, "ď"}, {{XK_Multi_key, XK_less, XK_d, XK_VoidSymbol}, "ď"}, {{XK_Multi_key, XK_d, XK_less, XK_VoidSymbol}, "ď"}, {{XK_dead_cedilla, XK_d, XK_VoidSymbol}, "ḑ"}, // U1E11 | LATIN SMALL LETTER D WITH CEDILLA {{XK_Multi_key, XK_comma, XK_d, XK_VoidSymbol}, "ḑ"}, {{XK_Multi_key, XK_d, XK_comma, XK_VoidSymbol}, "ḑ"}, {{XK_Multi_key, XK_cedilla, XK_d, XK_VoidSymbol}, "ḑ"}, {{XK_dead_iota, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾐ"}, // U1F90 | GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾐ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_psili, XK_Greek_eta, XK_VoidSymbol}, "ᾐ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenright, XK_Greek_eta, XK_VoidSymbol}, "ᾐ"}, {{XK_Multi_key, XK_slash, XK_Cyrillic_GHE, XK_VoidSymbol}, "Ғ"}, // U0492 | CYRILLIC CAPITAL LETTER GHE WITH STROKE {{XK_Multi_key, XK_KP_Divide, XK_Cyrillic_GHE, XK_VoidSymbol}, "Ғ"}, {{XK_dead_belowmacron, XK_h, XK_VoidSymbol}, "ẖ"}, // U1E96 | LATIN SMALL LETTER H WITH LINE BELOW {{XK_dead_belowcomma, XK_s, XK_VoidSymbol}, "ș"}, // U0219 | LATIN SMALL LETTER S WITH COMMA BELOW {{XK_dead_grave, XK_dead_dasia, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἓ"}, // U1F1B | GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἓ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἓ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_EPSILON, XK_VoidSymbol}, "Ἓ"}, {{XK_dead_breve, XK_g, XK_VoidSymbol}, "ğ"}, // U011F | LATIN SMALL LETTER G WITH BREVE {{XK_Multi_key, XK_U, XK_g, XK_VoidSymbol}, "ğ"}, {{XK_Multi_key, XK_g, XK_U, XK_VoidSymbol}, "ğ"}, {{XK_Multi_key, XK_b, XK_g, XK_VoidSymbol}, "ğ"}, {{XK_Multi_key, XK_breve, XK_g, XK_VoidSymbol}, "ğ"}, {{XK_Multi_key, XK_g, XK_breve, XK_VoidSymbol}, "ğ"}, {{XK_Multi_key, XK_g, XK_parenleft, XK_VoidSymbol}, "ğ"}, {{XK_dead_doublegrave, XK_Cyrillic_I, XK_VoidSymbol}, "И̏"}, // CYRILLIC CAPITAL LETTER I WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_I, XK_VoidSymbol}, "И̏"}, {{XK_dead_macron, XK_g, XK_VoidSymbol}, "ḡ"}, // U1E21 | LATIN SMALL LETTER G WITH MACRON {{XK_Multi_key, XK_macron, XK_g, XK_VoidSymbol}, "ḡ"}, {{XK_Multi_key, XK_underscore, XK_g, XK_VoidSymbol}, "ḡ"}, {{XK_dead_iota, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾠ"}, // U1FA0 | GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI {{XK_dead_iota, XK_Multi_key, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾠ"}, {{XK_Multi_key, XK_Greek_iota, XK_dead_psili, XK_Greek_omega, XK_VoidSymbol}, "ᾠ"}, {{XK_Multi_key, XK_Greek_iota, XK_parenright, XK_Greek_omega, XK_VoidSymbol}, "ᾠ"}, {{XK_dead_belowdot, XK_dead_belowdot, XK_VoidSymbol}, "̣"}, // U0323 | COMBINING DOT BELOW {{XK_dead_belowdot, XK_nobreakspace, XK_VoidSymbol}, "̣"}, {{XK_dead_belowdot, XK_space, XK_VoidSymbol}, "̣"}, {{XK_dead_hook, XK_P, XK_VoidSymbol}, "Ƥ"}, // U01A4 | LATIN CAPITAL LETTER P WITH HOOK {{XK_dead_grave, XK_Acircumflex, XK_VoidSymbol}, "Ầ"}, // U1EA6 | LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE {{XK_Multi_key, XK_grave, XK_Acircumflex, XK_VoidSymbol}, "Ầ"}, {{XK_dead_grave, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ầ"}, {{XK_dead_grave, XK_Multi_key, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ầ"}, {{XK_Multi_key, XK_grave, XK_dead_circumflex, XK_A, XK_VoidSymbol}, "Ầ"}, {{XK_Multi_key, XK_grave, XK_asciicircum, XK_A, XK_VoidSymbol}, "Ầ"}, {{XK_dead_circumflex, XK_Agrave, XK_VoidSymbol}, "Ầ"}, {{XK_dead_circumflex, XK_dead_grave, XK_A, XK_VoidSymbol}, "Ầ"}, {{XK_dead_cedilla, XK_e, XK_VoidSymbol}, "ȩ"}, // U0229 | LATIN SMALL LETTER E WITH CEDILLA {{XK_Multi_key, XK_cedilla, XK_e, XK_VoidSymbol}, "ȩ"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἣ"}, // U1F2B | GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἣ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_ETA, XK_VoidSymbol}, "Ἣ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_ETA, XK_VoidSymbol}, "Ἣ"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_a, XK_VoidSymbol}, "ª"}, // ordfeminine | FEMININE ORDINAL INDICATOR {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_a, XK_VoidSymbol}, "ª"}, {{XK_dead_ogonek, XK_i, XK_VoidSymbol}, "į"}, // U012F | LATIN SMALL LETTER I WITH OGONEK {{XK_Multi_key, XK_semicolon, XK_i, XK_VoidSymbol}, "į"}, {{XK_Multi_key, XK_i, XK_semicolon, XK_VoidSymbol}, "į"}, {{XK_Multi_key, XK_comma, XK_i, XK_VoidSymbol}, "į"}, {{XK_Multi_key, XK_i, XK_comma, XK_VoidSymbol}, "į"}, {{XK_dead_acute, XK_k, XK_VoidSymbol}, "ḱ"}, // U1E31 | LATIN SMALL LETTER K WITH ACUTE {{XK_Multi_key, XK_acute, XK_k, XK_VoidSymbol}, "ḱ"}, {{XK_Multi_key, XK_apostrophe, XK_k, XK_VoidSymbol}, "ḱ"}, {{XK_dead_breve, XK_Greek_alpha, XK_VoidSymbol}, "ᾰ"}, // U1FB0 | GREEK SMALL LETTER ALPHA WITH VRACHY {{XK_Multi_key, XK_U, XK_Greek_alpha, XK_VoidSymbol}, "ᾰ"}, {{XK_Multi_key, XK_b, XK_Greek_alpha, XK_VoidSymbol}, "ᾰ"}, {{XK_dead_voiced_sound, XK_kana_U, XK_VoidSymbol}, "ヴ"}, // U30F4 | KATAKANA LETTER VU {{XK_dead_breve, XK_dead_belowdot, XK_A, XK_VoidSymbol}, "Ặ"}, // U1EB6 | LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW {{XK_dead_breve, XK_Multi_key, XK_exclam, XK_A, XK_VoidSymbol}, "Ặ"}, {{XK_Multi_key, XK_U, XK_dead_belowdot, XK_A, XK_VoidSymbol}, "Ặ"}, {{XK_Multi_key, XK_U, XK_exclam, XK_A, XK_VoidSymbol}, "Ặ"}, {{XK_Multi_key, XK_b, XK_dead_belowdot, XK_A, XK_VoidSymbol}, "Ặ"}, {{XK_Multi_key, XK_b, XK_exclam, XK_A, XK_VoidSymbol}, "Ặ"}, {{XK_dead_belowdot, XK_Abreve, XK_VoidSymbol}, "Ặ"}, {{XK_dead_belowdot, XK_dead_breve, XK_A, XK_VoidSymbol}, "Ặ"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἳ"}, // U1F3B | GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἳ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_IOTA, XK_VoidSymbol}, "Ἳ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_IOTA, XK_VoidSymbol}, "Ἳ"}, {{XK_dead_circumflex, XK_Multi_key, XK_underscore, XK_o, XK_VoidSymbol}, "º"}, // masculine | MASCULINE ORDINAL INDICATOR {{XK_Multi_key, XK_asciicircum, XK_underscore, XK_o, XK_VoidSymbol}, "º"}, {{XK_dead_circumflex, XK_nobreakspace, XK_VoidSymbol}, "̂"}, // U0302 | COMBINING CIRCUMFLEX ACCENT {{XK_dead_abovedot, XK_L, XK_VoidSymbol}, "Ŀ"}, // U013F | LATIN CAPITAL LETTER L WITH MIDDLE DOT {{XK_Multi_key, XK_parenleft, XK_4, XK_9, XK_parenright, XK_VoidSymbol}, "㊾"}, // U32BE | CIRCLED NUMBER FORTY NINE {{XK_Multi_key, XK_parenleft, XK_4, XK_KP_9, XK_parenright, XK_VoidSymbol}, "㊾"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_9, XK_parenright, XK_VoidSymbol}, "㊾"}, {{XK_Multi_key, XK_parenleft, XK_KP_4, XK_KP_9, XK_parenright, XK_VoidSymbol}, "㊾"}, {{XK_dead_abovedot, XK_m, XK_VoidSymbol}, "ṁ"}, // U1E41 | LATIN SMALL LETTER M WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_m, XK_VoidSymbol}, "ṁ"}, {{XK_Multi_key, XK_m, XK_period, XK_VoidSymbol}, "ṁ"}, {{XK_dead_grave, XK_Cyrillic_er, XK_VoidSymbol}, "р̀"}, // CYRILLIC SMALL LETTER ER WITH COMBINING GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_Cyrillic_er, XK_VoidSymbol}, "р̀"}, {{XK_dead_breve, XK_Cyrillic_zhe, XK_VoidSymbol}, "ӂ"}, // U04C2 | CYRILLIC SMALL LETTER ZHE WITH BREVE {{XK_Multi_key, XK_U, XK_Cyrillic_zhe, XK_VoidSymbol}, "ӂ"}, {{XK_Multi_key, XK_b, XK_Cyrillic_zhe, XK_VoidSymbol}, "ӂ"}, {{XK_dead_doublegrave, XK_Cyrillic_O, XK_VoidSymbol}, "О̏"}, // CYRILLIC CAPITAL LETTER O WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_O, XK_VoidSymbol}, "О̏"}, {{XK_dead_macron, XK_Cyrillic_er, XK_VoidSymbol}, "р̄"}, // CYRILLIC SMALL LETTER ER WITH COMBINING MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_er, XK_VoidSymbol}, "р̄"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_er, XK_VoidSymbol}, "р̄"}, {{XK_dead_circumflex, XK_dead_belowdot, XK_E, XK_VoidSymbol}, "Ệ"}, // U1EC6 | LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW {{XK_dead_circumflex, XK_Multi_key, XK_exclam, XK_E, XK_VoidSymbol}, "Ệ"}, {{XK_Multi_key, XK_asciicircum, XK_dead_belowdot, XK_E, XK_VoidSymbol}, "Ệ"}, {{XK_Multi_key, XK_asciicircum, XK_exclam, XK_E, XK_VoidSymbol}, "Ệ"}, {{XK_dead_belowdot, XK_Ecircumflex, XK_VoidSymbol}, "Ệ"}, {{XK_dead_belowdot, XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ệ"}, {{XK_dead_stroke, XK_j, XK_VoidSymbol}, "ɉ"}, // U0249 | LATIN SMALL LETTER J WITH STROKE {{XK_dead_grave, XK_dead_dasia, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὃ"}, // U1F4B | GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὃ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὃ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_OMICRON, XK_VoidSymbol}, "Ὃ"}, {{XK_dead_circumflex, XK_E, XK_VoidSymbol}, "Ê"}, // Ecircumflex | LATIN CAPITAL LETTER E WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_E, XK_VoidSymbol}, "Ê"}, {{XK_Multi_key, XK_greater, XK_E, XK_VoidSymbol}, "Ê"}, {{XK_Multi_key, XK_E, XK_greater, XK_VoidSymbol}, "Ê"}, {{XK_Multi_key, XK_E, XK_asciicircum, XK_VoidSymbol}, "Ê"}, {{XK_dead_doublegrave, XK_Cyrillic_er, XK_VoidSymbol}, "р̏"}, // CYRILLIC SMALL LETTER ER WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_er, XK_VoidSymbol}, "р̏"}, {{XK_dead_breve, XK_o, XK_VoidSymbol}, "ŏ"}, // U014F | LATIN SMALL LETTER O WITH BREVE {{XK_Multi_key, XK_U, XK_o, XK_VoidSymbol}, "ŏ"}, {{XK_Multi_key, XK_b, XK_o, XK_VoidSymbol}, "ŏ"}, {{XK_dead_grave, XK_omacron, XK_VoidSymbol}, "ṑ"}, // U1E51 | LATIN SMALL LETTER O WITH MACRON AND GRAVE {{XK_Multi_key, XK_grave, XK_omacron, XK_VoidSymbol}, "ṑ"}, {{XK_dead_grave, XK_dead_macron, XK_o, XK_VoidSymbol}, "ṑ"}, {{XK_dead_grave, XK_Multi_key, XK_macron, XK_o, XK_VoidSymbol}, "ṑ"}, {{XK_dead_grave, XK_Multi_key, XK_underscore, XK_o, XK_VoidSymbol}, "ṑ"}, {{XK_Multi_key, XK_grave, XK_dead_macron, XK_o, XK_VoidSymbol}, "ṑ"}, {{XK_Multi_key, XK_grave, XK_macron, XK_o, XK_VoidSymbol}, "ṑ"}, {{XK_Multi_key, XK_grave, XK_underscore, XK_o, XK_VoidSymbol}, "ṑ"}, {{XK_dead_macron, XK_ograve, XK_VoidSymbol}, "ṑ"}, {{XK_dead_macron, XK_dead_grave, XK_o, XK_VoidSymbol}, "ṑ"}, {{XK_dead_breve, XK_Greek_iota, XK_VoidSymbol}, "ῐ"}, // U1FD0 | GREEK SMALL LETTER IOTA WITH VRACHY {{XK_Multi_key, XK_U, XK_Greek_iota, XK_VoidSymbol}, "ῐ"}, {{XK_Multi_key, XK_b, XK_Greek_iota, XK_VoidSymbol}, "ῐ"}, {{XK_dead_diaeresis, XK_Cyrillic_A, XK_VoidSymbol}, "Ӓ"}, // U04D2 | CYRILLIC CAPITAL LETTER A WITH DIAERESIS {{XK_Multi_key, XK_quotedbl, XK_Cyrillic_A, XK_VoidSymbol}, "Ӓ"}, {{XK_dead_caron, XK_u, XK_VoidSymbol}, "ǔ"}, // U01D4 | LATIN SMALL LETTER U WITH CARON {{XK_Multi_key, XK_c, XK_u, XK_VoidSymbol}, "ǔ"}, {{XK_dead_tilde, XK_Ocircumflex, XK_VoidSymbol}, "Ỗ"}, // U1ED6 | LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE {{XK_Multi_key, XK_asciitilde, XK_Ocircumflex, XK_VoidSymbol}, "Ỗ"}, {{XK_dead_tilde, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ỗ"}, {{XK_dead_tilde, XK_Multi_key, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ỗ"}, {{XK_Multi_key, XK_asciitilde, XK_dead_circumflex, XK_O, XK_VoidSymbol}, "Ỗ"}, {{XK_Multi_key, XK_asciitilde, XK_asciicircum, XK_O, XK_VoidSymbol}, "Ỗ"}, {{XK_dead_circumflex, XK_Otilde, XK_VoidSymbol}, "Ỗ"}, {{XK_dead_circumflex, XK_dead_tilde, XK_O, XK_VoidSymbol}, "Ỗ"}, {{XK_Multi_key, XK_e, XK_e, XK_VoidSymbol}, "ə"}, // U0259 | LATIN SMALL LETTER SCHWA {{XK_dead_grave, XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὓ"}, // U1F5B | GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὓ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὓ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_UPSILON, XK_VoidSymbol}, "Ὓ"}, {{XK_dead_acute, XK_U, XK_VoidSymbol}, "Ú"}, // Uacute | LATIN CAPITAL LETTER U WITH ACUTE {{XK_Multi_key, XK_acute, XK_U, XK_VoidSymbol}, "Ú"}, {{XK_Multi_key, XK_U, XK_acute, XK_VoidSymbol}, "Ú"}, {{XK_Multi_key, XK_apostrophe, XK_U, XK_VoidSymbol}, "Ú"}, {{XK_Multi_key, XK_U, XK_apostrophe, XK_VoidSymbol}, "Ú"}, {{XK_dead_grave, XK_Cyrillic_i, XK_VoidSymbol}, "ѝ"}, // U045D | CYRILLIC SMALL LETTER I WITH GRAVE {{XK_Multi_key, XK_grave, XK_Cyrillic_i, XK_VoidSymbol}, "ѝ"}, {{XK_dead_cedilla, XK_s, XK_VoidSymbol}, "ş"}, // U015F | LATIN SMALL LETTER S WITH CEDILLA {{XK_Multi_key, XK_comma, XK_s, XK_VoidSymbol}, "ş"}, {{XK_Multi_key, XK_s, XK_comma, XK_VoidSymbol}, "ş"}, {{XK_Multi_key, XK_cedilla, XK_s, XK_VoidSymbol}, "ş"}, {{XK_Multi_key, XK_s, XK_cedilla, XK_VoidSymbol}, "ş"}, {{XK_Multi_key, XK_o, XK_x, XK_VoidSymbol}, "¤"}, // currency | CURRENCY SIGN {{XK_Multi_key, XK_x, XK_o, XK_VoidSymbol}, "¤"}, {{XK_Multi_key, XK_o, XK_X, XK_VoidSymbol}, "¤"}, {{XK_Multi_key, XK_X, XK_o, XK_VoidSymbol}, "¤"}, {{XK_Multi_key, XK_O, XK_X, XK_VoidSymbol}, "¤"}, {{XK_Multi_key, XK_X, XK_O, XK_VoidSymbol}, "¤"}, {{XK_Multi_key, XK_O, XK_x, XK_VoidSymbol}, "¤"}, {{XK_Multi_key, XK_x, XK_O, XK_VoidSymbol}, "¤"}, {{XK_dead_currency, XK_dead_currency, XK_VoidSymbol}, "¤"}, {{XK_dead_currency, XK_nobreakspace, XK_VoidSymbol}, "¤"}, {{XK_dead_currency, XK_space, XK_VoidSymbol}, "¤"}, {{XK_dead_abovedot, XK_s, XK_VoidSymbol}, "ṡ"}, // U1E61 | LATIN SMALL LETTER S WITH DOT ABOVE {{XK_Multi_key, XK_period, XK_s, XK_VoidSymbol}, "ṡ"}, {{XK_Multi_key, XK_s, XK_period, XK_VoidSymbol}, "ṡ"}, {{XK_dead_breve, XK_Greek_upsilon, XK_VoidSymbol}, "ῠ"}, // U1FE0 | GREEK SMALL LETTER UPSILON WITH VRACHY {{XK_Multi_key, XK_U, XK_Greek_upsilon, XK_VoidSymbol}, "ῠ"}, {{XK_Multi_key, XK_b, XK_Greek_upsilon, XK_VoidSymbol}, "ῠ"}, {{XK_Multi_key, XK_asterisk, XK_diaeresis, XK_VoidSymbol}, "⍣"}, // U2363 | * ¨ APL FUNCTIONAL SYMBOL STAR DIAERESIS {{XK_Multi_key, XK_diaeresis, XK_asterisk, XK_VoidSymbol}, "⍣"}, {{XK_dead_macron, XK_Cyrillic_I, XK_VoidSymbol}, "Ӣ"}, // U04E2 | CYRILLIC CAPITAL LETTER I WITH MACRON {{XK_Multi_key, XK_macron, XK_Cyrillic_I, XK_VoidSymbol}, "Ӣ"}, {{XK_Multi_key, XK_underscore, XK_Cyrillic_I, XK_VoidSymbol}, "Ӣ"}, {{XK_dead_stroke, XK_G, XK_VoidSymbol}, "Ǥ"}, // U01E4 | LATIN CAPITAL LETTER G WITH STROKE {{XK_Multi_key, XK_slash, XK_G, XK_VoidSymbol}, "Ǥ"}, {{XK_Multi_key, XK_KP_Divide, XK_G, XK_VoidSymbol}, "Ǥ"}, {{XK_dead_hook, XK_U, XK_VoidSymbol}, "Ủ"}, // U1EE6 | LATIN CAPITAL LETTER U WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_U, XK_VoidSymbol}, "Ủ"}, {{XK_dead_circumflex, XK_parenleft, XK_VoidSymbol}, "⁽"}, // U207D | SUPERSCRIPT LEFT PARENTHESIS {{XK_Multi_key, XK_asciicircum, XK_parenleft, XK_VoidSymbol}, "⁽"}, {{XK_dead_grave, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὣ"}, // U1F6B | GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA {{XK_dead_grave, XK_Multi_key, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὣ"}, {{XK_Multi_key, XK_grave, XK_dead_dasia, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὣ"}, {{XK_Multi_key, XK_grave, XK_parenleft, XK_Greek_OMEGA, XK_VoidSymbol}, "Ὣ"}, {{XK_dead_circumflex, XK_e, XK_VoidSymbol}, "ê"}, // ecircumflex | LATIN SMALL LETTER E WITH CIRCUMFLEX {{XK_Multi_key, XK_asciicircum, XK_e, XK_VoidSymbol}, "ê"}, {{XK_Multi_key, XK_e, XK_asciicircum, XK_VoidSymbol}, "ê"}, {{XK_Multi_key, XK_greater, XK_e, XK_VoidSymbol}, "ê"}, {{XK_Multi_key, XK_e, XK_greater, XK_VoidSymbol}, "ê"}, {{XK_Multi_key, XK_parenleft, XK_1, XK_4, XK_parenright, XK_VoidSymbol}, "⑭"}, // U246D | CIRCLED NUMBER FOURTEEN {{XK_Multi_key, XK_parenleft, XK_1, XK_KP_4, XK_parenright, XK_VoidSymbol}, "⑭"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_4, XK_parenright, XK_VoidSymbol}, "⑭"}, {{XK_Multi_key, XK_parenleft, XK_KP_1, XK_KP_4, XK_parenright, XK_VoidSymbol}, "⑭"}, {{XK_dead_abovering, XK_u, XK_VoidSymbol}, "ů"}, // U016F | LATIN SMALL LETTER U WITH RING ABOVE {{XK_Multi_key, XK_o, XK_u, XK_VoidSymbol}, "ů"}, {{XK_Multi_key, XK_asterisk, XK_u, XK_VoidSymbol}, "ů"}, {{XK_Multi_key, XK_u, XK_asterisk, XK_VoidSymbol}, "ů"}, {{XK_Multi_key, XK_parenleft, XK_kana_MA, XK_parenright, XK_VoidSymbol}, "㋮"}, // U32EE | CIRCLED KATAKANA MA {{XK_dead_belowcircumflex, XK_t, XK_VoidSymbol}, "ṱ"}, // U1E71 | LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW {{XK_dead_doubleacute, XK_Cyrillic_U, XK_VoidSymbol}, "Ӳ"}, // U04F2 | CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE {{XK_Multi_key, XK_equal, XK_Cyrillic_U, XK_VoidSymbol}, "Ӳ"}, {{XK_dead_circumflex, XK_5, XK_VoidSymbol}, "⁵"}, // U2075 | SUPERSCRIPT FIVE {{XK_Multi_key, XK_asciicircum, XK_5, XK_VoidSymbol}, "⁵"}, {{XK_dead_circumflex, XK_KP_5, XK_VoidSymbol}, "⁵"}, {{XK_Multi_key, XK_asciicircum, XK_KP_5, XK_VoidSymbol}, "⁵"}, {{XK_dead_acute, XK_G, XK_VoidSymbol}, "Ǵ"}, // U01F4 | LATIN CAPITAL LETTER G WITH ACUTE {{XK_Multi_key, XK_acute, XK_G, XK_VoidSymbol}, "Ǵ"}, {{XK_Multi_key, XK_apostrophe, XK_G, XK_VoidSymbol}, "Ǵ"}, {{XK_dead_hook, XK_Y, XK_VoidSymbol}, "Ỷ"}, // U1EF6 | LATIN CAPITAL LETTER Y WITH HOOK ABOVE {{XK_Multi_key, XK_question, XK_Y, XK_VoidSymbol}, "Ỷ"}, {{XK_dead_doublegrave, XK_Cyrillic_A, XK_VoidSymbol}, "А̏"}, // CYRILLIC CAPITAL LETTER A WITH COMBINING DOUBLE GRAVE ACCENT {{XK_Multi_key, XK_grave, XK_grave, XK_Cyrillic_A, XK_VoidSymbol}, "А̏"}, {{XK_dead_acute, XK_u, XK_VoidSymbol}, "ú"}, // uacute | LATIN SMALL LETTER U WITH ACUTE {{XK_Multi_key, XK_acute, XK_u, XK_VoidSymbol}, "ú"}, {{XK_Multi_key, XK_u, XK_acute, XK_VoidSymbol}, "ú"}, {{XK_Multi_key, XK_apostrophe, XK_u, XK_VoidSymbol}, "ú"}, {{XK_Multi_key, XK_u, XK_apostrophe, XK_VoidSymbol}, "ú"}, {{XK_dead_currency, XK_i, XK_VoidSymbol}, "﷼"}, // UFDFC | RIAL SIGN {{XK_Multi_key, XK_f, XK_s, XK_VoidSymbol}, "ſ"}, // U017f | LATIN SMALL LETTER LONG S {{XK_Multi_key, XK_f, XK_S, XK_VoidSymbol}, "ſ"}, {{XK_Multi_key, XK_parenleft, XK_kana_WO, XK_parenright, XK_VoidSymbol}, "㋾"}, // U32FE | CIRCLED KATAKANA WO }; } //namespace #endif nux-4.0.6+14.04.20140409/Nux/BaseWindow.cpp0000644000015301777760000003557712321344237020276 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "Layout.h" #include "HLayout.h" #include "WindowCompositor.h" #include "BaseWindow.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(BaseWindow); const int SizeGripWidth = 20; const int SizeGripHeight = 20; const int TitleBarHeight = 20; /* Elements inside the Window have coordinates based on the top-left corner of the window. This is true whether we are drawing or computing the layout. When computing the layout, use x_root and y_root to pass the top-left corner position of the window. When drawing, make a similar adjustment. */ BaseWindow::BaseWindow(const char *WindowName, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , _paint_layer(new ColorLayer(Color(0xFF707070))) , _opacity(1.0f) , _present_in_embedded_mode(false) , _contents_ready_for_presentation(false) { premultiply = true; _name = WindowName; _child_need_redraw = true; m_TopBorder = 0; m_Border = 0; _size_match_layout = false; _is_visible = false; _is_modal = false; #if defined(USE_X11) m_input_window_enabled = false; m_input_window = 0; #endif m_layout = 0; m_configure_notify_callback = NULL; m_configure_notify_callback_data = NULL; _entering_visible_state = false; _entering_hidden_state = false; _enter_focus_input_area = NULL; accept_key_nav_focus_ = false; SetAcceptKeyNavFocusOnMouseDown(false); // Should be at the end of the constructor GetWindowThread()->GetWindowCompositor().RegisterWindow(this); SetMinimumSize(1, 1); SetGeometry(Geometry(100, 100, 320, 200)); } BaseWindow::~BaseWindow() { if (_enter_focus_input_area) { _enter_focus_input_area->UnReference(); } #if defined(USE_X11) if (m_input_window) delete m_input_window; #endif } Area* BaseWindow::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; if (m_layout) { nuxAssert(m_layout->IsLayout()); Area* found_area = m_layout->FindAreaUnderMouse(mouse_position, event_type); if (found_area) return found_area; } if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } void BaseWindow::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); // The elements position inside the window are referenced to top-left window corner. So bring base to(0, 0). base.SetX(0); base.SetY(0); graphics_engine.PushClippingRectangle(base); GetPainter().PushDrawLayer(graphics_engine, base, _paint_layer.get()); GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } void BaseWindow::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); // The elements position inside the window are referenced to top-left window corner. So bring base to(0, 0). base.SetX(0); base.SetY(0); GetPainter().PushLayer(graphics_engine, base, _paint_layer.get()); if (m_layout) { graphics_engine.PushClippingRectangle(base); m_layout->ProcessDraw(graphics_engine, force_draw); graphics_engine.PopClippingRectangle(); } GetPainter().PopBackground(); } void BaseWindow::SetConfigureNotifyCallback(ConfigureNotifyCallback Callback, void *Data) { m_configure_notify_callback = Callback; m_configure_notify_callback_data = Data; } Layout* BaseWindow::GetLayout() { return m_layout; } bool BaseWindow::SetLayout(Layout *layout) { if (View::SetLayout(layout) == false) return false; m_layout = layout; Geometry geo = GetGeometry(); Geometry layout_geo = Geometry(geo.x + m_Border, geo.y + m_TopBorder, geo.GetWidth() - 2 * m_Border, geo.GetHeight() - m_Border - m_TopBorder); m_layout->SetGeometry(layout_geo); // When this call returns the layout computation is done. ComputeContentSize(); // or use //GetWindowThread()->QueueObjectLayout(m_layout); return true; } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. void BaseWindow::PreLayoutManagement() { Geometry geo = GetGeometry(); if (m_configure_notify_callback) { (*m_configure_notify_callback)(GetGraphicsDisplay()->GetWindowWidth(), GetGraphicsDisplay()->GetWindowHeight(), geo, m_configure_notify_callback_data); if (geo.IsNull()) { nuxDebugMsg("[BaseWindow::PreLayoutManagement] Received an invalid Geometry."); geo = GetGeometry(); } else { Area::SetGeometry(geo); // Get the geometry adjusted with respect to min and max dimension of this area. geo = GetGeometry(); } } if (m_layout) { Geometry layout_geo = Geometry(m_Border, m_TopBorder, geo.GetWidth() - 2 * m_Border, geo.GetHeight() - m_Border - m_TopBorder); if (IsSizeMatchContent()) m_layout->SetGeometry(Geometry(0, 0, 1, 1)); else m_layout->SetGeometry(layout_geo); } } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. long BaseWindow::PostLayoutManagement(long /* LayoutResult */) { if (IsSizeMatchContent() && m_layout) { Geometry layout_geometry = m_layout->GetGeometry(); Geometry WindowGeometry = Geometry(GetGeometry().x, GetGeometry().y, layout_geometry.GetWidth() + 2 * m_Border, layout_geometry.GetHeight() + m_Border + m_TopBorder); Area::SetGeometry(WindowGeometry); } // A BaseWindow must kill the result of the management and pass it to the parent Layout. return (eCompliantHeight | eCompliantWidth); //return result; } // Get a change to do any work on an element. // Here we need to position the header by hand because it is not under the control of vlayout. void BaseWindow::ComputeContentPosition(float /* offsetX */, float /* offsetY */) { } #if defined(NUX_OS_LINUX) void BaseWindow::EnableInputWindow(bool b, const char* title, bool take_focus, bool override_redirect) { #if defined(USE_X11) if (b) { if (m_input_window == 0) m_input_window = new XInputWindow(title, take_focus, override_redirect); m_input_window->Show(); m_input_window->SetGeometry(GetGeometry()); m_input_window_enabled = true; } else { if (m_input_window) m_input_window->Hide(); m_input_window_enabled = false; } #endif } bool BaseWindow::InputWindowEnabled() { #if defined(USE_X11) return m_input_window_enabled; #else return false; #endif } void BaseWindow::InputWindowEnableStruts(bool enable) { #if defined(USE_X11) if (m_input_window) m_input_window->EnableStruts(enable); #endif } bool BaseWindow::InputWindowStrutsEnabled() { #if defined(USE_X11) return m_input_window_enabled && m_input_window->StrutsEnabled(); #else return false; #endif } void BaseWindow::InputWindowEnableOverlayStruts(bool enable) { #if defined(USE_X11) if (m_input_window) m_input_window->EnableOverlayStruts(enable); #endif } bool BaseWindow::InputWindowOverlayStrutsEnabled() { #if defined(USE_X11) return m_input_window && m_input_window->OverlayStrutsEnabled(); #else return false; #endif } void BaseWindow::SetInputFocus() { #if defined(USE_X11) if (m_input_window) m_input_window->SetInputFocus(); #endif } Window BaseWindow::GetInputWindowId() { #if defined(USE_X11) if (m_input_window) return m_input_window->GetWindow(); else return 0; #else return 0; #endif } #endif void BaseWindow::SetGeometry(const Geometry &geo) { Area::SetGeometry(geo); #if defined(USE_X11) if (m_input_window) m_input_window->SetGeometry(geo); #endif //LayoutWindowElements(); //ComputeContentSize(); } void BaseWindow::LayoutWindowElements() { // Define the geometry of some of the component of the window. Otherwise, if the composition layout is not set, // then the component won't be correctly placed after a SetGeometry. This can be redondant if the composition layout is set. GetGeometry(); } void BaseWindow::SetBorder(int border) { if (m_Border != border) { m_Border = border; } } void BaseWindow::SetTopBorder(int border) { if (m_TopBorder != border) { m_TopBorder = border; } } int BaseWindow::GetBorder() const { return m_Border; } int BaseWindow::GetTopBorder() const { return m_TopBorder; } void BaseWindow::ShowWindow(bool visible, bool StartModal /* = false */) { if (visible == _is_visible) return; _is_visible = visible; _is_modal = StartModal; if (_is_visible) { if (m_layout) { m_layout->SetGeometry(GetGeometry()); } _entering_visible_state = true; sigVisible.emit(this); GetWindowThread()->GetWindowCompositor().sigVisibleViewWindow.emit(this); ComputeContentSize(); } else { SetEnterFocusInputArea(NULL); _entering_hidden_state = true; sigHidden.emit(this); GetWindowThread()->GetWindowCompositor().sigHiddenViewWindow.emit(this); } if (_is_modal) GetWindowThread()->GetWindowCompositor().StartModalWindow(ObjectWeakPtr(this)); // Whether this view is added or removed, call QueueDraw. in the case where this view is removed, this is a signal // that the region below this view need to be redrawn. QueueDraw(); } bool BaseWindow::IsVisible() const { return _is_visible; } void BaseWindow::StopModal() { _is_visible = false; _is_modal = false; //ShowWindow(false); GetWindowThread()->GetWindowCompositor().StopModalWindow(ObjectWeakPtr (this)); } bool BaseWindow::IsModal() const { return _is_modal; } void BaseWindow::NotifyConfigurationChange(int /* Width */, int /* Height */) { Geometry geo = GetGeometry(); if (m_configure_notify_callback) { (*m_configure_notify_callback) (GetGraphicsDisplay()->GetWindowWidth(), GetGraphicsDisplay()->GetWindowHeight(), geo, m_configure_notify_callback_data); if (geo.IsNull()) { nuxDebugMsg("[BaseWindow::NotifyConfigurationChange] Received an invalid Geometry."); geo = GetGeometry(); } else { Area::SetGeometry(geo); // Get the geometry adjusted with respect to min and max dimension of this area. geo = GetGeometry(); } } else { return; } } void BaseWindow::SetBackgroundLayer(AbstractPaintLayer *layer) { NUX_RETURN_IF_NULL(layer); _paint_layer.reset(layer->Clone()); } void BaseWindow::SetBackgroundColor(const Color &color) { _paint_layer.reset(new ColorLayer(color)); } void BaseWindow::PushHigher(BaseWindow* floating_view) { GetWindowThread()->GetWindowCompositor().PushHigher(this, floating_view); } void BaseWindow::PushToFront() { GetWindowThread()->GetWindowCompositor().PushToFront(this); } void BaseWindow::PushToBack() { GetWindowThread()->GetWindowCompositor().PushToBack(this); } bool BaseWindow::ChildNeedsRedraw() { return _child_need_redraw; } void* BaseWindow::GetBackupTextureData(int &width, int &height, int &format) { return GetWindowThread()->GetWindowCompositor().GetBackupTextureData(this, width, height, format); } void BaseWindow::PresentInEmbeddedModeOnThisFrame(bool force) { nuxAssertMsg (GetWindowThread()->IsEmbeddedWindow(), "[BaseWindow::PresentInEmbeddedModeOnThisFrame] only " "supported in embdded mode"); /* Invisible windows are never presented */ if (!IsVisible()) return; if (nux::GetWindowThread()->AddToPresentationList(this, force)) _present_in_embedded_mode = true; } void BaseWindow::MarkPresentedInEmbeddedMode() { _present_in_embedded_mode = false; _last_presented_geometry_in_embedded_mode = GetAbsoluteGeometry(); } nux::Geometry const& BaseWindow::LastPresentedGeometryInEmbeddedMode() const { return _last_presented_geometry_in_embedded_mode; } bool BaseWindow::AllowPresentationInEmbeddedMode() const { return _present_in_embedded_mode; } void BaseWindow::PrepareParentRedirectedView() { Area::PrepareParentRedirectedView(); if (GetWindowThread()->IsEmbeddedWindow()) PresentInEmbeddedModeOnThisFrame(); } void BaseWindow::SetEnterFocusInputArea(InputArea *input_area) { if (_enter_focus_input_area) { _enter_focus_input_area->UnReference(); } _enter_focus_input_area = input_area; if (_enter_focus_input_area) _enter_focus_input_area->Reference(); } void BaseWindow::SetOpacity(float opacity) { if (_opacity == opacity) return; _opacity = opacity; _opacity = CLAMP(_opacity, 0.0f, 1.0f); QueueDraw(); } float BaseWindow::GetOpacity() { return _opacity; } void BaseWindow::SetAcceptKeyNavFocus(bool accept) { accept_key_nav_focus_ = accept; } bool BaseWindow::AcceptKeyNavFocus() { return accept_key_nav_focus_; } #ifdef NUX_GESTURES_SUPPORT Area* BaseWindow::GetInputAreaHitByGesture(const nux::GestureEvent &event) { if (!IsVisible()) return nullptr; if (!IsGestureInsideArea(event)) return nullptr; if (m_layout) { Area *area_hit = m_layout->GetInputAreaHitByGesture(event); if (area_hit) return area_hit; } if (HasSubscriptionForGesture(event)) return this; else return nullptr; } #endif } nux-4.0.6+14.04.20140409/Nux/HLayout.cpp0000644000015301777760000007266012321344237017613 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "View.h" #include "HLayout.h" #include "VLayout.h" namespace nux { static const int HERROR = 0; NUX_IMPLEMENT_OBJECT_TYPE(HLayout); HLayout::HLayout(NUX_FILE_LINE_DECL) : LinearLayout(NUX_FILE_LINE_PARAM) { #if DEBUG_LAYOUT space_between_children_ = 10; left_padding_ = 10; right_padding_ = 10; m_v_in_margin = 10; top_padding_ = 10; bottom_padding_ = 10; #endif // Start packing the elements from the top. Is the layout has more space than the elements can use, // leave that space at the bottom of the HLayout. m_ContentStacking = eStackLeft; } HLayout::HLayout(std::string name, NUX_FILE_LINE_DECL) : LinearLayout(NUX_FILE_LINE_PARAM) { m_name = name; #if DEBUG_LAYOUT space_between_children_ = 10; left_padding_ = 10; right_padding_ = 10; m_v_in_margin = 10; top_padding_ = 10; bottom_padding_ = 10; #endif m_ContentStacking = eStackLeft; } HLayout::~HLayout() { } void HLayout::GetCompositeList(std::list *ViewList) { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsView()) { View *ic = static_cast(*it); ViewList->push_back(ic); } else if ((*it)->IsLayout()) { Layout *layout = static_cast(*it); layout->GetCompositeList(ViewList); } } } void HLayout::ComputeStacking(int remaining_width, int &offset_space, int &element_margin) { int per_element_space = 0; int total_used_space = 0; int num_elements = 0; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible()) { // gather all the space used by elements total_used_space += (*it)->GetBaseWidth(); num_elements++; } } if (num_elements) { // Compute the space available for each element per_element_space = (remaining_width - total_used_space) / int(num_elements); } if (per_element_space < 0) { per_element_space = 0; } int margin; if (per_element_space > 0) { margin = (per_element_space) / 2; } else { margin = 0; } LayoutContentDistribution stacking = GetContentDistribution(); switch(stacking) { case MAJOR_POSITION_START: { offset_space = 0; element_margin = 0; } break; case MAJOR_POSITION_END: { offset_space = (remaining_width - total_used_space); if (offset_space < 0) offset_space = 0; element_margin = 0; } break; case eStackCenter: { offset_space = (remaining_width - total_used_space) / 2; if (offset_space < 0) offset_space = 0; element_margin = 0; } break; case eStackExpand: default: { offset_space = 0; element_margin = margin; } break; } } long HLayout::ComputeContentSize() { if (_layout_element_list.size() == 0) { return eCompliantHeight | eCompliantWidth; } std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible()) (*it)->SetLayoutDone(false); } int original_height = GetBaseHeight(); if (GetScaleFactor() == 0) { // The size must exactly fit the children. The parent cannot be larger or smaller // than the total width of its children(+ margins). // So set the parent size to Geometry(0,0,1,1) and let the children force it to extend. if (GetParentObject() && GetParentObject()->Type().IsObjectType(HLayout::StaticObjectType)) { // The parent if a HLayout(same type). Then a Stretch factor of 0 means this layout has its width set to 1. Area::SetBaseWidth(1); } else if (GetParentObject() && GetParentObject()->Type().IsObjectType(VLayout::StaticObjectType)) { // The parent if a VLayout. Then a Stretch factor of 0 means this layout has its height set to 1. Area::SetBaseHeight(1); } else { // This is for when a layout is set as a composition layout of an View and its stretch factor is explicitly set to 0. Area::SetBaseWidth(1); Area::SetBaseHeight(1); } //The children will all assume their minimum size. } else { // The total size of the children(+ margins) may be smaller or equal to parent size. } bool unadjusted_layout = false; do { unsigned int num_element = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible()) num_element++; } // Get layout Width and Height int width = GetBaseWidth(); int height = GetBaseHeight(); // Remove the margins. This is the real width and height available to the children. width -= (int) (num_element - 1) * space_between_children_ + (left_padding_ + right_padding_); height -= (top_padding_ + bottom_padding_); // Size the children according to their stretch factor. HLayoutManagement(width, height); // Objects have been resized, now position them. int current_x = GetBaseX() + left_padding_; int current_y = GetBaseY() + top_padding_; int offset_space = 0; int space_after_element = 0; ComputeStacking(width, offset_space, space_after_element); current_x += offset_space; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; current_x += space_after_element; (*it)->SetBaseX(current_x); (*it)->SetBaseY(current_y); MinorDimensionSize extend = (*it)->GetExtend(); MinorDimensionPosition positioning = (*it)->GetPositioning(); float percentage = (*it)->GetPercentage(); // Compute the size of an ellement in the minor dimension(vertical) switch(extend) { case MINOR_SIZE_PERCENTAGE: { // The size of the processed element in the minor dimension is a percentage of layout minor dimension size. // Note that children of the processed element may force it to have a bigger size. int percentage_height = (height * percentage) / 100.0f; (*it)->SetBaseHeight(percentage_height); break; } case MINOR_SIZE_MATCHCONTENT: { // Force the element height to be the minimum has defined with SetMinimumHeight. // The children of this element can force it to get larger. (*it)->ApplyMinHeight(); break; } case eFix: { //do nothing break; } case MINOR_SIZE_FULL: default: { (*it)->SetBaseHeight(height); break; } } // Compute the position of an element in the minor dimension. if ((*it)->GetBaseHeight() < height) { int widget_height = (*it)->GetBaseHeight(); switch(positioning) { case MINOR_POSITION_START: { // do nothing (*it)->SetBaseY(current_y); break; } case MINOR_POSITION_END: { if (widget_height < height) (*it)->SetBaseY(current_y + height - widget_height); else (*it)->SetBaseY(current_y); break; } case MINOR_POSITION_CENTER: default: { if (widget_height < height) (*it)->SetBaseY(current_y + (height - widget_height) / 2); else (*it)->SetBaseY(current_y); } } } current_x += (*it)->GetBaseWidth() + space_after_element + space_between_children_; } // Manage child layout if (num_element == 0) m_fittingWidth = (int) (left_padding_ + right_padding_); else m_fittingWidth = (int) (num_element - 1) * space_between_children_ + (left_padding_ + right_padding_); m_contentHeight = GetBaseHeight() - (top_padding_ + bottom_padding_); // Set to the size of the layout. int element_height = 0; unadjusted_layout = false; // This array is meant to store the sizes of some of the elements height. These elements must have MINOR_SIZE_FULL as extent and // they have not been not been constrained smaller after ComputeContentSize is called. Because the layout may have a stretch factor of 0 // and therefore its size has been set to 1x1 at the start of this function, there is a possibility that some of the elements don't have // the full height of the layout(these elements uses their minimum height because the layout was set to a size 1x1). // We check if that is the case and force a recompute. std::vector FullSizeUnadjusted; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; int ret = 0; if (((*it)->IsLayout() || (*it)->IsView()) /*&& ((*it)->IsLayoutDone() == false)*/ /*&& ((*it)->GetScaleFactor() != 0)*/) { Geometry pre_geo = (*it)->GetGeometry(); ret = (*it)->ComputeContentSize(); Geometry post_geo = (*it)->GetGeometry(); bool larger_width = pre_geo.width < post_geo.width; bool smaller_width = pre_geo.width > post_geo.width; bool larger_height = pre_geo.height < post_geo.height; bool smaller_height = pre_geo.height > post_geo.height; if ((larger_width || smaller_width) && ((*it)->IsLayoutDone() == false)) { // Stop computing the size of this layout. Its size was not convenient to its children. So the children size take priority // over the layout. In ComputeContentSize, the dimension of the layout has been set so it encompasses its children(and the margins). // Now the parent layout cannot be touched again: layout_done_ = true. In VLayoutManagement, it is as if the stretchfactor // of this layout is now 0. // This is the only place where a layout can have layout_done_ set to "true". // If(smaller_width == true) the layout takes less space than anticipated. // Set unadjusted_layout = true, so another pass will allow its sibling to claim more space. { unadjusted_layout = true; (*it)->SetLayoutDone(true); } } if ((smaller_height == false) && ((*it)->GetExtend() == MINOR_SIZE_FULL) && ((*it)->GetBaseHeight() < (*it)->GetMaximumHeight())) { // We catch all object whose size is possibly larger than the layout. We check there size at the end and // recompute the layout if necessary. // For layout elements, make sure that the stretch factor is not 0. If it is, it means it will not use the // size provided by the parent layout. Its size will be adjusted to the minimum size of the layout content. if (! ((*it)->IsLayout() && (*it)->GetScaleFactor() == 0)) FullSizeUnadjusted.push_back((*it)->GetBaseHeight()); } if ((smaller_height || larger_height) && ((*it)->GetExtend() == MINOR_SIZE_MATCHCONTENT)) { (*it)->SetMinimumHeight((*it)->GetBaseHeight()); unadjusted_layout = true; } // Should be reactivate so that if the parent Layout does not call // ComputeContentPosition, at least it is done here to arrange the internal // element of the children. //(*it)->ComputeContentPosition(0,0); } m_fittingWidth += (*it)->GetBaseWidth(); element_height = (*it)->GetBaseHeight(); if ((*it)->IsSpaceLayout() == false) { if ((GetScaleFactor() != 0) && (ret & eSmallerHeight)) { if (m_contentHeight < element_height) { if (m_contentHeight < GetMaximumHeight()) { // An element is larger than the layout height and the layout has not reach its maximum height yet. m_contentHeight = element_height; unadjusted_layout = true; } } } else { if (m_contentHeight <= element_height) { m_contentHeight = element_height; } // else if ((*it)->GetExtend() == MINOR_SIZE_FULL) // { // unadjusted_layout = true; // } } } } // Set the height of the layout to be equal to the largest height it controls. // m_contentHeight is the largest height of an element within this layout. The layout size is then // m_contentHeight + (top_padding_ + bottom_padding_); SetBaseHeight(m_contentHeight + (top_padding_ + bottom_padding_)); // Get back the Height after it has been bounded by [minHeight, maxHeight] in the preceeding call to SetBaseHeight. // Then deduce the height of the content. int temp = GetHeight() - (top_padding_ + bottom_padding_); std::vector::iterator IntIterator = FullSizeUnadjusted.begin(); for (IntIterator = FullSizeUnadjusted.begin(); IntIterator != FullSizeUnadjusted.end(); IntIterator++) { if ((*IntIterator) < temp) { unadjusted_layout = true; } } } while (unadjusted_layout); // m_fittingHeight is sum of the largest element height plus the outer margin. m_fittingHeight = m_contentHeight + (top_padding_ + bottom_padding_); // m_fittingWidth is sum of the element width plus the inner and outer margin. // If the stretch factor is 0 then, the layout height has been set to 1 and need to grow with the elements within. // If the stretch factor is not 0, then the layout height is set to m_fittingHeight only if the its height is less than m_fittingHeight; // This way, if the layout height is greater than m_fittingHeight there is space to compute the content stacking(ComputeStacking). if (GetBaseWidth() < m_fittingWidth) { SetBaseWidth(m_fittingWidth); } m_contentWidth = m_fittingWidth; long size_compliance = 0L; ComputeContentPosition(0, 0); { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: HLayout Width compliant = " << m_fittingWidth << std::endl; #endif size_compliance |= eCompliantWidth; } // The layout has been resized to tightly pack its content if (GetBaseHeight() > original_height + HERROR) { #if DEBUG_LAYOUT_COMPUTATION // The layout has been resized larger in height to tightly pack its content. // Or you can say that the layout refuse to be smaller than total HEIGHT of its elements. std::cout << "ComputeContentSize: HLayout Height block at " << GetBaseHeight() << std::endl; #endif size_compliance |= eLargerHeight; // need scrollbar } else if (GetBaseHeight() + HERROR < original_height) { #if DEBUG_LAYOUT_COMPUTATION // The layout is smaller. std::cout << "ComputeContentSize: HLayout Height is smaller = " << GetBaseHeight() << std::endl; #endif size_compliance |= eSmallerHeight; } else { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: HLayout Height compliant = " << GetBaseHeight() << std::endl; #endif size_compliance |= eCompliantHeight; } return size_compliance; } void HLayout::HLayoutManagement(int width, int /* height */) { bool need_recompute = false; do { need_recompute = false; int available_width = width; unsigned int max_stretchfactor = GetMaxStretchFactor(); std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() == 0) && ((*it)->IsLayoutDone() != true)) { (*it)->ApplyMinWidth(); } } if (max_stretchfactor == 0) { // It means all object are fixed sized or all re-sizable object have been sized to there max or there min. if (GetScaleFactor() == 0) { // It is unlikely that we get here! int w = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; it++) { if (!(*it)->IsVisible()) continue; w += (*it)->GetBaseWidth(); } SetBaseWidth(w); } return; } for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; if ((*it)->GetScaleFactor() == 0 || (*it)->IsLayoutDone() == true) { available_width -= (*it)->GetBaseWidth(); } } if (available_width <= 2) { for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() != 0) && (*it)->IsArea()) { // If it is not an object of type eInputArea, do not set layout_done_ to true, // so, the layout management function will later be called on the object. (*it)->ApplyMinWidth(); (*it)->SetLayoutDone(true); } else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayout()) && ((*it)->IsLayoutDone() == false)) // layout and not fixed by child { // The out of bound must be reset to false. (*it)->ApplyMinWidth(); (*it)->SetLayoutDone(false); } else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) // layout and not fixed { (*it)->ApplyMinWidth(); // A layout must never have layout_done_ set to true "here" because it must continue // doing the layout of its children and finally resize itself to fit them. // The same way, A layout size factor should never be set to 0. } } return; } float cumul = 0; Area *LastElementThatCanBeResized = 0; int total_distributed_size = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) { float sf = (float) (*it)->GetScaleFactor(); cumul += sf / max_stretchfactor; LastElementThatCanBeResized = (*it); } else { total_distributed_size += (*it)->GetBaseWidth(); } } // ----- // \ factor // Ref_Size * \ ------------ = available_width // / max_factor // / // ----- // all element with stretchfactor != 0 unsigned int ref_width = available_width / cumul; need_recompute = false;; for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; it++) { if (!(*it)->IsVisible()) continue; if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) { unsigned int sf = (*it)->GetScaleFactor(); int new_width; if (sf == max_stretchfactor) { new_width = ref_width; } else { new_width = ref_width * sf / max_stretchfactor; } total_distributed_size += new_width; if (LastElementThatCanBeResized == (*it)) { // Redistribute the remaining size to the last element(at the right). // This is necessary because of imprecision. For instance if available_height = 451 and we have 2 elements // with the same stretch factor than each one will have a size of 225. With is correction, the first element will have a size of // 225 while the second one will have a size of 226. if (available_width - total_distributed_size > 0) { new_width += available_width - total_distributed_size; total_distributed_size = available_width; } } int elemt_max_width = (*it)->GetMaximumSize().width; int elemt_min_width = (*it)->GetMinimumSize().width; // A layout must never have layout_done_ set to true "here" because it must continue // doing the layout of its children and finally resize itself to fit them. // The same way, A layout size factor should never be set to 0. // Q: How about SpaceLayout? Should we treat them the same as layout or widget in this particular case? // A: SapceLayout are treated like widgets in this case if (new_width < elemt_min_width) { // assume the minimum width (*it)->SetBaseWidth(elemt_min_width); if ((*it)->IsLayout() == false || (*it)->IsSpaceLayout()) { (*it)->SetLayoutDone(true); need_recompute = true; } } else if (new_width > elemt_max_width) { // assume the maximum width (*it)->SetBaseWidth(elemt_max_width); if ((*it)->IsLayout() == false || (*it)->IsSpaceLayout()) { (*it)->SetLayoutDone(true); need_recompute = true; } // else // { // // set the extra space back in the pool // total_distributed_size -= (new_width - elemt_max_width); // } } else { (*it)->SetBaseWidth(new_width); } } else { // For fixed element, reset their size to the same so it is checked against // the min and max. This is necessary in case you have set the size of the element first then latter, // you define its MinimumSize and/or MaximumSize size. unsigned int w = (*it)->GetBaseWidth(); unsigned int h = (*it)->GetBaseHeight(); (*it)->SetBaseWidth(w); (*it)->SetBaseHeight(h); } } } while (need_recompute); } unsigned int HLayout::GetMaxStretchFactor() { unsigned int value = 0; unsigned int sf; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; // In the recursive process, make sure we get always the highest stretch factor // of an element that has not been bounded. if ((*it)->IsLayoutDone() == false) { sf = (*it)->GetScaleFactor(); if (sf >= value) { value = sf; } } } return value; } void HLayout::ComputeContentPosition(float offsetX, float offsetY) { std::list::iterator it; { unsigned int num_element = 0; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible()) num_element++; } // Get layout Width and Height int width = GetBaseWidth(); int height = GetBaseHeight(); // remove the margins width -= (int) (num_element - 1) * space_between_children_ + (left_padding_ + right_padding_); height -= (top_padding_ + bottom_padding_); // Objects have been resized, now position them. int current_x = GetBaseX() + left_padding_ + offsetX; // add base offset in X(used for scrolling) int current_y = GetBaseY() + top_padding_ + offsetY; // add base offset in Y(used for scrolling) int offset_space = 0; int element_margin = 0; ComputeStacking(width, offset_space, element_margin); current_x += offset_space; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; current_x += element_margin; (*it)->SetBaseX(current_x); (*it)->SetBaseY(current_y); MinorDimensionPosition positioning = (*it)->GetPositioning(); if ((*it)->GetBaseHeight() < height) { int widget_height = (*it)->GetBaseHeight(); switch(positioning) { case MINOR_POSITION_START: { // do nothing (*it)->SetBaseY(current_y); break; } case MINOR_POSITION_END: { if (widget_height < height) (*it)->SetBaseY(current_y + height - widget_height); else (*it)->SetBaseY(current_y); break; } case MINOR_POSITION_CENTER: default: { if (widget_height < height) (*it)->SetBaseY(current_y + (height - widget_height) / 2); else (*it)->SetBaseY(current_y); } } } current_x += (*it)->GetBaseWidth() + element_margin + space_between_children_; } } for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if (!(*it)->IsVisible()) continue; if ((*it)->Type().IsDerivedFromType(Layout::StaticObjectType)) { (*it)->ComputeContentPosition(offsetX, offsetY); } else if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { (*it)->ComputeContentPosition(offsetX, offsetY); } } } Area* HLayout::KeyNavIteration(KeyNavDirection direction) { if (_layout_element_list.size() == 0) return NULL; if (IsVisible() == false) return NULL; if (next_object_to_key_focus_area_) { if ((direction == KEY_NAV_UP) || (direction == KEY_NAV_DOWN)) { // Don't know what to do with this return NULL; } std::list::iterator it; std::list::iterator it_next; it = std::find(_layout_element_list.begin(), _layout_element_list.end(), next_object_to_key_focus_area_); if (it == _layout_element_list.end()) { // Should never happen nuxAssert(0); return NULL; } it_next = it; ++it_next; if ((direction == KEY_NAV_LEFT) && (it == _layout_element_list.begin())) { // can't go further return NULL; } if ((direction == KEY_NAV_RIGHT) && (it_next == _layout_element_list.end())) { // can't go further return NULL; } if (direction == KEY_NAV_LEFT) { --it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { if (it == _layout_element_list.begin()) break; --it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_RIGHT) { ++it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == _layout_element_list.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } } else { Area* key_nav_focus = NULL; if (direction == KEY_NAV_LEFT) { std::list::reverse_iterator it = _layout_element_list.rbegin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == _layout_element_list.rend()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } else { std::list::iterator it = _layout_element_list.begin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == _layout_element_list.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } return key_nav_focus; } return NULL; } } nux-4.0.6+14.04.20140409/Nux/D2DTextRenderer.cpp0000644000015301777760000003316112321344237021124 0ustar pbusernogroup00000000000000 #include "D2DTextRenderer.h" // SafeRelease inline function. template inline void SafeRelease(T **ppT) { if (*ppT) { (*ppT)->Release(); *ppT = NULL; } } /****************************************************************** * * * CustomTextRenderer::CustomTextRenderer * * * * The constructor stores the Direct2D factory, the render * * target, and the outline and fill brushes used for drawing the * * glyphs, underlines, and strikethroughs. * * * ******************************************************************/ CustomTextRenderer::CustomTextRenderer( ID2D1Factory* pD2DFactory, ID2D1RenderTarget* pRT, ID2D1SolidColorBrush* pOutlineBrush, ID2D1BitmapBrush* pFillBrush ) : cRefCount_(0), pD2DFactory_(pD2DFactory), pRT_(pRT), pOutlineBrush_(pOutlineBrush), pFillBrush_(pFillBrush) { if (pD2DFactory_) pD2DFactory_->AddRef(); if (pRT_) pRT_->AddRef(); if (pOutlineBrush_) pOutlineBrush_->AddRef(); if (pFillBrush_) pFillBrush_->AddRef(); } /****************************************************************** * * * CustomTextRenderer::~CustomTextRenderer * * * * The destructor releases the member variables * * * ******************************************************************/ CustomTextRenderer::~CustomTextRenderer() { SafeRelease(&pD2DFactory_); SafeRelease(&pRT_); SafeRelease(&pOutlineBrush_); SafeRelease(&pFillBrush_); } /****************************************************************** * * * CustomTextRenderer::DrawGlyphRun * * * * Gets GlyphRun outlines via IDWriteFontFace::GetGlyphRunOutline * * and then draws and fills them using Direct2D path geometries * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::DrawGlyphRun( __maybenull void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, __in DWRITE_GLYPH_RUN const* glyphRun, __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, IUnknown* clientDrawingEffect ) { HRESULT hr = S_OK; // Create the path geometry. ID2D1PathGeometry* pPathGeometry = NULL; hr = pD2DFactory_->CreatePathGeometry(&pPathGeometry); // Write to the path geometry using the geometry sink. ID2D1GeometrySink* pSink = NULL; if (SUCCEEDED(hr)) { hr = pPathGeometry->Open(&pSink); } // Get the glyph run outline geometries back from DirectWrite and place them within the // geometry sink. if (SUCCEEDED(hr)) { hr = glyphRun->fontFace->GetGlyphRunOutline( glyphRun->fontEmSize, glyphRun->glyphIndices, glyphRun->glyphAdvances, glyphRun->glyphOffsets, glyphRun->glyphCount, glyphRun->isSideways, glyphRun->bidiLevel%2, pSink ); } // Close the geometry sink if (SUCCEEDED(hr)) { hr = pSink->Close(); } // Initialize a matrix to translate the origin of the glyph run. D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F( 1.0f, 0.0f, 0.0f, 1.0f, baselineOriginX, baselineOriginY); // Create the transformed geometry ID2D1TransformedGeometry* pTransformedGeometry = NULL; if (SUCCEEDED(hr)) { hr = pD2DFactory_->CreateTransformedGeometry( pPathGeometry, &matrix, &pTransformedGeometry); } // Draw the outline of the glyph run pRT_->DrawGeometry( pTransformedGeometry, pOutlineBrush_); // Fill in the glyph run pRT_->FillGeometry( pTransformedGeometry, pOutlineBrush_); SafeRelease(&pPathGeometry); SafeRelease(&pSink); SafeRelease(&pTransformedGeometry); return hr; } /****************************************************************** * * * CustomTextRenderer::DrawUnderline * * * * Draws underlines below the text using a Direct2D rectangle * * geometry * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::DrawUnderline( __maybenull void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, __in DWRITE_UNDERLINE const* underline, IUnknown* clientDrawingEffect ) { HRESULT hr; D2D1_RECT_F rect = D2D1::RectF( 0, underline->offset, underline->width, underline->offset + underline->thickness ); ID2D1RectangleGeometry* pRectangleGeometry = NULL; hr = pD2DFactory_->CreateRectangleGeometry( &rect, &pRectangleGeometry ); // Initialize a matrix to translate the origin of the underline D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F( 1.0f, 0.0f, 0.0f, 1.0f, baselineOriginX, baselineOriginY ); ID2D1TransformedGeometry* pTransformedGeometry = NULL; if (SUCCEEDED(hr)) { hr = pD2DFactory_->CreateTransformedGeometry( pRectangleGeometry, &matrix, &pTransformedGeometry ); } // Draw the outline of the rectangle pRT_->DrawGeometry( pTransformedGeometry, pOutlineBrush_ ); // Fill in the rectangle pRT_->FillGeometry( pTransformedGeometry, pFillBrush_ ); SafeRelease(&pRectangleGeometry); SafeRelease(&pTransformedGeometry); return S_OK; } /****************************************************************** * * * CustomTextRenderer::DrawStrikethrough * * * * Draws strike-through below the text using a Direct2D * * rectangle geometry * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::DrawStrikethrough( __maybenull void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, __in DWRITE_STRIKETHROUGH const* strikethrough, IUnknown* clientDrawingEffect ) { HRESULT hr; D2D1_RECT_F rect = D2D1::RectF( 0, strikethrough->offset, strikethrough->width, strikethrough->offset + strikethrough->thickness ); ID2D1RectangleGeometry* pRectangleGeometry = NULL; hr = pD2DFactory_->CreateRectangleGeometry( &rect, &pRectangleGeometry ); // Initialize a matrix to translate the origin of the strikethrough D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F( 1.0f, 0.0f, 0.0f, 1.0f, baselineOriginX, baselineOriginY ); ID2D1TransformedGeometry* pTransformedGeometry = NULL; if (SUCCEEDED(hr)) { hr = pD2DFactory_->CreateTransformedGeometry( pRectangleGeometry, &matrix, &pTransformedGeometry ); } // Draw the outline of the rectangle pRT_->DrawGeometry( pTransformedGeometry, pOutlineBrush_ ); // // Fill in the rectangle // pRT_->FillGeometry( // pTransformedGeometry, // pOutlineBrush_ // ); SafeRelease(&pRectangleGeometry); SafeRelease(&pTransformedGeometry); return S_OK; } /****************************************************************** * * * CustomTextRenderer::DrawInlineObject * * * * This function is not implemented for the purposes of this * * sample. * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::DrawInlineObject( __maybenull void* clientDrawingContext, FLOAT originX, FLOAT originY, IDWriteInlineObject* inlineObject, BOOL isSideways, BOOL isRightToLeft, IUnknown* clientDrawingEffect ) { // Not implemented return E_NOTIMPL; } /****************************************************************** * * * CustomTextRenderer::AddRef * * * * Increments the ref count * * * ******************************************************************/ IFACEMETHODIMP_(unsigned long) CustomTextRenderer::AddRef() { return InterlockedIncrement((LONG *)&cRefCount_); } /****************************************************************** * * * CustomTextRenderer::Release * * * * Decrements the ref count and deletes the instance if the ref * * count becomes 0 * * * ******************************************************************/ IFACEMETHODIMP_(unsigned long) CustomTextRenderer::Release() { unsigned long newCount = InterlockedDecrement((LONG *)&cRefCount_); if (newCount == 0) { delete this; return 0; } return newCount; } /****************************************************************** * * * CustomTextRenderer::IsPixelSnappingDisabled * * * * Determines whether pixel snapping is disabled. The recommended * * default is FALSE, unless doing animation that requires * * subpixel vertical placement. * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::IsPixelSnappingDisabled( __maybenull void* clientDrawingContext, __out BOOL* isDisabled ) { *isDisabled = FALSE; return S_OK; } /****************************************************************** * * * CustomTextRenderer::GetCurrentTransform * * * * Returns the current transform applied to the render target.. * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::GetCurrentTransform( __maybenull void* clientDrawingContext, __out DWRITE_MATRIX* transform ) { //forward the render target's transform pRT_->GetTransform(reinterpret_cast(transform)); return S_OK; } /****************************************************************** * * * CustomTextRenderer::GetPixelsPerDip * * * * This returns the number of pixels per DIP. * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::GetPixelsPerDip( __maybenull void* clientDrawingContext, __out FLOAT* pixelsPerDip ) { float x, yUnused; pRT_->GetDpi(&x, &yUnused); *pixelsPerDip = x / 96; return S_OK; } /****************************************************************** * * * CustomTextRenderer::QueryInterface * * * * Query interface implementation * * * ******************************************************************/ IFACEMETHODIMP CustomTextRenderer::QueryInterface( IID const& riid, void** ppvObject ) { if (__uuidof(IDWriteTextRenderer) == riid) { *ppvObject = this; } else if (__uuidof(IDWritePixelSnapping) == riid) { *ppvObject = this; } else if (__uuidof(IUnknown) == riid) { *ppvObject = this; } else { *ppvObject = NULL; return E_FAIL; } this->AddRef(); return S_OK; } nux-4.0.6+14.04.20140409/Nux/RadioButtonGroup.cpp0000644000015301777760000001207412321344237021466 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "RadioButton.h" #include "RadioButtonGroup.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(RadioButtonGroup); RadioButtonGroup::RadioButtonGroup(NUX_FILE_LINE_DECL) : InitiallyUnownedObject(NUX_FILE_LINE_PARAM) // RadioButtonGroup is created as un-owned , active_button_index_(0) { } RadioButtonGroup::~RadioButtonGroup() { std::vector >::iterator it; for (it = radio_button_array_.begin(); it != radio_button_array_.end(); it++) { if ((*it).IsValid()) { (*it)->SetRadioButtonGroup(NULL); (*it)->radio_group_index_ = -1; } } } void RadioButtonGroup::ConnectButton(RadioButton* radio) { if (radio == NULL) { return; } if (!radio->Type().IsDerivedFromType(RadioButton::StaticObjectType)) { return; } std::vector >::iterator it; for (it = radio_button_array_.begin(); it != radio_button_array_.end(); it++) { if ((*it).IsValid() && ((*it).GetPointer() == radio)) { // already in return; } } size_t index = (unsigned int) radio_button_array_.size(); if (index == 0) { // Inserting the first radio button if (radio->GetRadioButtonGroup().IsValid()) { // Disconnect from the other selector radio->GetRadioButtonGroup()->DisconnectButton(radio); } radio->SetRadioButtonGroup(this); radio->radio_group_index_ = 0; radio->SetStatePrivate(true); radio_button_array_.push_back(ObjectWeakPtr(radio)); active_button_index_ = 0; } else { if (radio->GetRadioButtonGroup().IsValid()) { // Disconnect from the other selector radio->GetRadioButtonGroup()->DisconnectButton(radio); } radio->SetRadioButtonGroup(this); radio->radio_group_index_ = index; // When a radio button is added to a group that is not empty, its check state is set to false. radio->SetStatePrivate(false); radio_button_array_.push_back(ObjectWeakPtr(radio)); } } void RadioButtonGroup::DisconnectButton(RadioButton* radio) { bool found = false; size_t array_size = (unsigned int) radio_button_array_.size(); std::vector >::iterator it; it = radio_button_array_.begin(); size_t i; for (i = 0; i < array_size; i++, it++) { if (radio_button_array_[i] == radio) { radio->radio_group_index_ = -1; radio->SetStatePrivate(false); radio_button_array_.erase(it); found = true; break; } } if (found && (i - 1 > 0) && (!radio_button_array_.empty())) { // The previous button becomes active radio_button_array_[i]->SetStatePrivate(true); } } int RadioButtonGroup::GetNumButtons() { int count = 0; std::vector >::iterator it; for (it = radio_button_array_.begin(); it != radio_button_array_.end(); ++it) { if ((*it).IsValid()) { ++count; } } return count; } void RadioButtonGroup::NotifyClick(RadioButton* radio) { std::vector >::iterator it; for (it = radio_button_array_.begin(); it != radio_button_array_.end(); ++it) { if ((*it).GetPointer() != radio) { if ((*it).IsValid()) { (*it)->SetStatePrivate(false, true); } } else { if ((*it).IsValid()) { (*it)->SetStatePrivate(true, true); } } } } void RadioButtonGroup::SetActiveButton(RadioButton* radio, bool emit_signal) { std::vector >::iterator it = find(radio_button_array_.begin(), radio_button_array_.end(), radio); if (it == radio_button_array_.end()) return; if ((*it).IsValid() == false) { // The button has been destroyed. // Remove it from the array radio_button_array_.erase(it); return; } for (it = radio_button_array_.begin(); it != radio_button_array_.end(); ++it) { if ((*it).IsValid() && ((*it).GetPointer() != radio)) { (*it)->SetStatePrivate(false, emit_signal); } } radio->SetStatePrivate(true, emit_signal); } } nux-4.0.6+14.04.20140409/Nux/ToolButton.h0000644000015301777760000000400512321344237017770 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef TOOLBUTTON_H #define TOOLBUTTON_H #include "ActionItem.h" namespace nux { class HLayout; class ActionItem; class ToolButton : public View { public: ToolButton(const char *BitmapFilename = 0, NUX_FILE_LINE_PROTO); ~ToolButton(); void SetAction(ActionItem *action); void SetState(bool b); void SetBitmap(const BaseTexture* Texture); // emitters void EmitClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseDoubleClick (int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags); // signals sigc::signal sigClick; protected: virtual void Draw(GraphicsEngine &GfxContext, bool force_draw); virtual void DrawContent(GraphicsEngine &GfxContext, bool force_draw); private: ActionItem *m_ActionItem; BaseTexture *m_Texture; }; } #endif // TOOLBUTTON_H nux-4.0.6+14.04.20140409/Nux/RangeValueInteger.h0000644000015301777760000000713112321344237021231 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RANGEVALUEINTEGER_H #define RANGEVALUEINTEGER_H namespace nux { class HLayout; class EditTextBox; class RangeValueInteger : public View { public: RangeValueInteger(int Value = 0, int MinValue = 0, int MaxValue = 100, NUX_FILE_LINE_PROTO); ~RangeValueInteger(); void DrawMarker(GraphicsEngine &graphics_engine); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); ///////////////// // RECEIVERS // ///////////////// void SetRange(int min_value, int max_value); void SetValue(int value); int GetValue() const; int GetMinValue() const { return m_min; } int GetMaxValue() const { return m_max; } void SetBackgroundColor(const Color &color) { m_ValueString->SetTextBackgroundColor(color); } const Color GetBackgroundColor() const { return m_ValueString->GetTextBackgroundColor(); } void setStartToEndColor(Color color_start, Color color_end) { m_StartColor = color_start; m_EndColor = color_end; } void setStartColor(Color color) { m_StartColor = color; } void setEndColor(Color color) { m_EndColor = color; } void setProgressColor(Color color) { m_ProgressColor = color; } void EnableDrawProgress(bool b) { m_EnableDrawProgress = b; } //////////////// // EMITTERS // //////////////// void OnReceiveMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnReceiveMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnKeyboardFocus(); void OnLostKeyboardFocus(); void OnValidateKeyboardEntry(EditTextBox *textbox, const std::string &text); bool IsCtrlKeyPressed() const { return m_CTRL_KEY; } // signals sigc::signal sigValueChanged; sigc::signal sigMouseDown; sigc::signal sigMouseUp; sigc::signal sigMouseDrag; sigc::signal sigSetTypedValue; sigc::signal sigValueChanged2; //sigc::signal sigValidateKeyboarEntry; void BroadcastValue(); protected: void InitializeWidgets(); void InitializeLayout(); protected: HLayout *hlayout; EditTextBox *m_ValueString; BasicView *m_Percentage; Color m_StartColor; Color m_EndColor; Color m_ProgressColor; Color m_BackgroundColor; bool m_EnableDrawProgress; long m_CTRL_KEY; float m_MarkerPosition; int m_Value; int m_min, m_max; }; } #endif // RANGEVALUEINTEGER_H nux-4.0.6+14.04.20140409/Nux/CairoWrapper.h0000644000015301777760000000277312321344237020267 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller #include "Nux/Nux.h" namespace nux { typedef std::function DrawCanvasCallback; class CairoWrapper { public: CairoWrapper (Geometry const& geom, DrawCanvasCallback callback); ~CairoWrapper (); bool Invalidate (Geometry const& geom); void SetDrawCanvasCallback (DrawCanvasCallback callback); cairo_surface_t* GetCairoSurface () const; cairo_t* GetCairoContext () const; bool DumpToFile (std::string const& filename); BaseTexture* GetTexture () const; NBitmapData* GetBitmap () const; bool Recreate (); private: struct Impl; Impl* pimpl; }; } #endif // CAIRO_WRAPPER_H nux-4.0.6+14.04.20140409/Nux/VSplitter.h0000644000015301777760000000600612321344237017616 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef VSPLITTER_H #define VSPLITTER_H namespace nux { class layout; class VSplitter: public View { NUX_DECLARE_OBJECT_TYPE(VSplitter, View); public: VSplitter(NUX_FILE_LINE_PROTO); ~VSplitter(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); void AddWidget(Area *ic, float stretchfactor); void ResetSplitConfig(); void clearContent(); void OnSplitterMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags, int header_pos); void OnSplitterMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, int header_pos); void OnSplitterMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags, int header_pos); virtual void OverlayDrawing(GraphicsEngine &graphics_engine); //! Return true if this object can break the layout. /* Return true if this object can break the layout, meaning, the layout can be done on the composition layout only without recomputing the whole window layout. Inherited from Area */ virtual bool CanBreakLayout() { return true; } virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); protected: virtual long ComputeContentSize(); virtual void DoneRedraw(); void ResizeSplitter(int header_pos); //void ContinuousSplitterAdjustment(); void setResizeOnSplitterRelease(bool b) { m_ResizeOnSplitterRelease = b; } bool getResizeOnSplitterRelease() { return m_ResizeOnSplitterRelease; } virtual bool AcceptKeyNavFocus(); virtual Area* KeyNavIteration(KeyNavDirection direction); private: typedef BasicView MySplitter; std::vector m_InterfaceObject; std::vector m_SplitterObject; std::vector m_SplitConfig; Point m_point; bool new_addition; bool m_ResizeOnSplitterRelease; int m_current_width; int m_current_height; int m_current_x; int m_current_y; bool m_initial_config; // splitter bar differential position; int mvt_dx, mvt_dy; int m_focus_splitter_index; }; } #endif // VSPLITTER_H nux-4.0.6+14.04.20140409/Nux/CairoWrapper.cpp0000644000015301777760000001355312321344237020620 0ustar pbusernogroup00000000000000/* * Copyright (C) 2011 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Mirco Müller namespace nux { struct CairoWrapper::Impl { Impl(CairoWrapper* parent, Geometry const& geo, DrawCanvasCallback callback); ~Impl(); bool CreateBitmap (); bool Invalidate (Geometry const& geom); void SetDrawCanvasCallback (DrawCanvasCallback callback); bool DumpToFile (std::string const& filename); bool Recreate (); void DeleteResources(); CairoWrapper* parent_; Geometry geometry_; DrawCanvasCallback draw_canvas_callback_; cairo_t* cr_; cairo_surface_t* surface_; NBitmapData* bitmap_; BaseTexture* texture_; }; CairoWrapper::Impl::Impl(CairoWrapper* parent, Geometry const& geo, DrawCanvasCallback callback) : parent_(parent) , geometry_(geo) , draw_canvas_callback_(callback) , cr_(0) , surface_(0) , bitmap_(0) , texture_(0) { } CairoWrapper::Impl::~Impl() { DeleteResources(); } void CairoWrapper::Impl::DeleteResources() { if (surface_) { cairo_surface_destroy (surface_); surface_ = 0; } if (cr_) { cairo_destroy (cr_); cr_ = 0; } if (bitmap_) { delete bitmap_; bitmap_ = 0; } if (texture_) { texture_->UnReference (); texture_ = 0; } } bool CairoWrapper::Impl::Recreate () { DeleteResources(); surface_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, geometry_.width, geometry_.height); if (cairo_surface_status (surface_) != CAIRO_STATUS_SUCCESS) { g_debug ("Could not create image-surface!"); return false; } cr_ = cairo_create (surface_); if (cairo_status (cr_) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface_); g_debug ("Could not create cairo-context!"); return false; } if (!draw_canvas_callback_) return false; draw_canvas_callback_ (geometry_, cr_); CreateBitmap (); NBitmapData* bitmap = parent_->GetBitmap (); if (texture_) texture_->UnReference (); if (GetGraphicsDisplay()->GetGraphicsEngine() == 0) return false; texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); texture_->Update (bitmap); return true; } bool CairoWrapper::Impl::CreateBitmap () { if (geometry_.width < 1 || geometry_.height < 1) { g_debug ("Width or height invalid!"); return false; } if (bitmap_) { delete bitmap_; bitmap_ = 0; } BitmapFormat bitmap_format = BITFMT_B8G8R8A8; bitmap_ = new NTextureData (bitmap_format, geometry_.width, geometry_.height, 1); unsigned char* ptr = cairo_image_surface_get_data (surface_); int stride = cairo_image_surface_get_stride (surface_); if (ptr == 0 || stride == 0) { g_debug ("Invalid surface!"); return false; } for (int j = 0; j < geometry_.height; j++) { Memcpy (bitmap_->GetSurface (0).GetPtrRawData() + j * bitmap_->GetSurface (0).GetPitch(), (const void *) (&ptr[j * stride]), geometry_.width * GPixelFormats[bitmap_format].NumComponents); } return true; } void CairoWrapper::Impl::SetDrawCanvasCallback (DrawCanvasCallback callback) { if (!callback) return; draw_canvas_callback_ = callback; Recreate (); } bool CairoWrapper::Impl::DumpToFile (std::string const& filename) { if (!surface_) Recreate(); cairo_surface_write_to_png (surface_, filename.c_str ()); return true; } bool CairoWrapper::Impl::Invalidate (Geometry const& geom) { if (geometry_.width == geom.width && geometry_.height == geom.height) return false; geometry_.x = geom.x; geometry_.y = geom.y; geometry_.width = geom.width; geometry_.height = geom.height; DeleteResources(); return true; } CairoWrapper::CairoWrapper (Geometry const& geom, DrawCanvasCallback callback) : pimpl(new Impl(this, geom, callback)) { Recreate (); } CairoWrapper::~CairoWrapper () { delete pimpl; } bool CairoWrapper::Invalidate (Geometry const& geom) { return pimpl->Invalidate(geom); } void CairoWrapper::SetDrawCanvasCallback (DrawCanvasCallback callback) { pimpl->SetDrawCanvasCallback(callback); } bool CairoWrapper::DumpToFile (std::string const& filename) { return pimpl->DumpToFile(filename); } bool CairoWrapper::Recreate () { return pimpl->Recreate(); } NBitmapData* CairoWrapper::GetBitmap () const { if (!pimpl->bitmap_) pimpl->Recreate(); return pimpl->bitmap_; } BaseTexture* CairoWrapper::GetTexture () const { if (!pimpl->texture_) pimpl->Recreate(); return pimpl->texture_; } cairo_surface_t* CairoWrapper::GetCairoSurface () const { if (!pimpl->surface_) pimpl->Recreate(); return pimpl->surface_; } cairo_t* CairoWrapper::GetCairoContext () const { if (!pimpl->cr_) pimpl->Recreate(); return pimpl->cr_; } } nux-4.0.6+14.04.20140409/Nux/XIMController.h0000644000015301777760000000333412321344237020364 0ustar pbusernogroup00000000000000/* * Copyright 2012-2013 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * */ #ifndef XIMCONTROLLER_H #define XIMCONTROLLER_H #include "XICClient.h" /* Xlib.h is the default header that is included and has the core functionallity */ #include namespace nux { class TextEntry; class XIMController { public: XIMController(Display* display); ~XIMController(); void SetFocusedWindow(Window window); void SetCurrentTextEntry(TextEntry* text_entry_); void RemoveFocusedWindow(); bool IsXICValid() const; XIC GetXIC() const; void FocusInXIC(); void FocusOutXIC(); Window GetCurrentWindow() const; private: void InitXIMCallback(); static void SetupXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data); static void EndXIMClientCallback(Display* dpy, XPointer client_data, XPointer call_data); void SetupXIM(); void SetupXIMDestroyedCallback(); Display* display_; Window window_; XIM xim_; XICClient xic_client_; }; } //namespace nux #endif // XIMController.h nux-4.0.6+14.04.20140409/Nux/NuxGlobalInitializer.cpp0000644000015301777760000000424112321344237022313 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGlobalInitializer.h" namespace nux { static NuxGlobalSingletonInitializer* GNuxGlobalInitializer = 0; static void SystemStart() { static unsigned char StaticBuffer[sizeof(NuxGlobalSingletonInitializer) ]; // Placement new in our reserved buffer. GNuxGlobalInitializer = new(StaticBuffer) NuxGlobalSingletonInitializer(); //GLogDevice.AddOutputDevice( &NUX_GLOBAL_OBJECT_INSTANCE(NOutputLogFile)); //GLogDevice.AddOutputDevice( &NUX_GLOBAL_OBJECT_INSTANCE(NOutputVisualDebugConsole)); } static void SystemShutdown() { // Manually destroy initializer if (GNuxGlobalInitializer) GNuxGlobalInitializer->~NuxGlobalSingletonInitializer(); GNuxGlobalInitializer = 0; } bool NuxGlobalSingletonInitializer::m_NuxGlobalObjectsReady = false; NuxGlobalSingletonInitializer::NuxGlobalSingletonInitializer() { m_NuxGlobalObjectsReady = true; } NuxGlobalSingletonInitializer::~NuxGlobalSingletonInitializer() { m_NuxGlobalObjectsReady = false; } bool NuxGlobalSingletonInitializer::Ready() { return m_NuxGlobalObjectsReady; } int NuxGlobalInitializer::m_Count = 0; NuxGlobalInitializer::NuxGlobalInitializer() { if (m_Count++ == 0) { SystemStart(); } } NuxGlobalInitializer::~NuxGlobalInitializer() { if (--m_Count == 0) { SystemShutdown(); } } } nux-4.0.6+14.04.20140409/Nux/TextEntry.cpp0000644000015301777760000022200412321344237020161 0ustar pbusernogroup00000000000000/* * Copyright 2011-2013 Canonical Ltd. * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0(the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Nux.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "Validator.h" #include "cairo/cairo.h" #include "pango/pango.h" #include "pango/pangocairo.h" #include "NuxGraphics/CairoGraphics.h" #include "TextEntry.h" #if defined(NUX_OS_LINUX) # include "TextEntryComposeSeqs.h" # if defined(USE_X11) # include # include "InputMethodIBus.h" # endif #endif namespace nux { static const int kInnerBorderX = 2; static const int kInnerBorderY = 0; //1; static const int kCursorBlinkTimeout = 400; static const double kStrongCursorLineWidth = 1; static const double kStrongCursorBarWidth = 1; static const double kWeakCursorLineWidth = 3; static const double kWeakCursorBarWidth = 3; static const Color kStrongCursorColor(0.9f, 0.9f, 0.9f, 1.0f); static const Color kWeakCursorColor(1.0f, 1.0f, 1.0f, 0.5f); static const Color kDefaultTextColor(0, 0, 0, 1.0f); static const Color kDefaultBackgroundColor(1, 1, 1, 1.0f); static const Color kDefaultSelectionBackgroundColor(0.5, 0.5, 0.5, 1.0f); static const Color kDefaultSelectionTextColor(1, 1, 1, 1.0f); static const unsigned long long kTripleClickTimeout = 500; static const std::string kDefaultFontName = "Ubuntu"; static unsigned long long GetCurrentTime() { gint64 micro_secs = g_get_real_time(); return static_cast(micro_secs / 1000); } static std::string CleanupLineBreaks(const char *source) { nuxAssert(source); std::string result; while (*source) { if (*source == '\r') { result += ' '; if (source[1] == '\n') source++; } else if (*source == '\n') { result += ' '; } else { result += *source; } source++; } return result; } // Calculate pixel size based on the Windows DPI of 96 for compatibility // reasons. CairoFont::CairoFont(const std::string &family, /*PangoFontDescription *font,*/ double pt_size, Style style, Weight weight) : font_(pango_font_description_new()) , size_(pt_size * PANGO_SCALE * 96 / 72) , style_(style) , weight_(weight) { pango_font_description_set_family(font_, family.c_str()); pango_font_description_set_absolute_size(font_, size_); if (weight_ == CairoFont::WEIGHT_BOLD) { pango_font_description_set_weight(font_, PANGO_WEIGHT_BOLD); } if (style_ == CairoFont::STYLE_ITALIC) { pango_font_description_set_style(font_, PANGO_STYLE_ITALIC); } } CairoFont::~CairoFont() { pango_font_description_free(font_); } NUX_IMPLEMENT_OBJECT_TYPE(TextEntry); TextEntry::TextEntry(const char* text, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , _size_match_text(true) , _texture2D(nullptr) , canvas_(nullptr) , cached_layout_(nullptr) , preedit_attrs_(nullptr) , completion_color_(color::Gray) , last_dblclick_time_(0) , cursor_(0) , preedit_cursor_(0) , selection_bound_(0) , scroll_offset_x_(0) , scroll_offset_y_(0) , cursor_blink_timer_(0) , cursor_blink_status_(0) , visible_(true) , focused_(false) , need_im_reset_(false) , overwrite_(false) , select_words_(false) , select_lines_(false) , button_(false) , bold_(false) , underline_(false) , strikeout_(false) , italic_(false) , multiline_(false) , wrap_(false) , cursor_visible_(false) , readonly_(false) , content_modified_(false) , selection_changed_(false) , cursor_moved_(false) , update_canvas_(true) , font_family_("Ubuntu") , font_size_(12) , font_options_(cairo_font_options_create()) , font_dpi_(96.0) , _text_color(color::White) , align_(CairoGraphics::ALIGN_LEFT) #if defined(USE_X11) , caret_cursor_(None) , ime_(new IBusIMEContext(this)) #endif , ime_active_(false) , text_input_mode_(false) , key_nav_mode_(false) , lose_key_focus_on_key_nav_direction_up_(true) , lose_key_focus_on_key_nav_direction_down_(true) , cursor_visible_on_key_focus_only_(false) { cairo_font_options_set_antialias(font_options_, CAIRO_ANTIALIAS_SUBPIXEL); cairo_font_options_set_hint_style(font_options_, CAIRO_HINT_STYLE_FULL); cairo_font_options_set_hint_metrics(font_options_, CAIRO_HINT_METRICS_ON); cairo_font_options_set_subpixel_order(font_options_, CAIRO_SUBPIXEL_ORDER_RGB); mouse_down.connect(sigc::mem_fun(this, &TextEntry::RecvMouseDown)); mouse_drag.connect(sigc::mem_fun(this, &TextEntry::RecvMouseDrag)); mouse_up.connect(sigc::mem_fun(this, &TextEntry::RecvMouseUp)); mouse_double_click.connect(sigc::mem_fun(this, &TextEntry::RecvMouseDoubleClick)); mouse_enter.connect(sigc::mem_fun(this, &TextEntry::RecvMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &TextEntry::RecvMouseLeave)); key_down.connect(sigc::mem_fun(this, &TextEntry::RecvKeyEvent)); key_up.connect([this] (unsigned int keysym, unsigned long, unsigned long state) { RecvKeyEvent(NUX_KEYUP, keysym, state, nullptr, 0); }); geometry_changed.connect([this] (Area* /*area*/, Geometry& /*geo*/) { QueueRefresh(true, false); }); begin_key_focus.connect(sigc::mem_fun(this, &TextEntry::RecvStartKeyFocus)); end_key_focus.connect(sigc::mem_fun(this, &TextEntry::RecvEndKeyFocus)); SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); SetText(text); SetAcceptKeyboardEvent(true); EnableDoubleClick(true); SetPasswordChar("*"); } TextEntry::~TextEntry() { if (cursor_blink_timer_) g_source_remove(cursor_blink_timer_); cairo_font_options_destroy(font_options_); if (_texture2D) _texture2D->UnReference(); #if defined(USE_X11) if (ime_) delete ime_; #endif delete canvas_; ResetLayout(); } void TextEntry::PreLayoutManagement() { View::PreLayoutManagement(); } long TextEntry::PostLayoutManagement(long layoutResult) { long result = View::PostLayoutManagement(layoutResult); MainDraw(); return result; } void TextEntry::GeometryChanged(bool /*position_has_changed*/, bool /*size_has_changed*/) { update_canvas_ = true; View::GeometryChanged(true, true); } Area* TextEntry::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { Area* area = View::FindAreaUnderMouse(mouse_position, event_type); return area; } void TextEntry::ProcessMouseEvent(int event_type, int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { int X = static_cast(x /*round(event.GetX())*/) - kInnerBorderX - scroll_offset_x_; int Y = static_cast(y /*round(event.GetY())*/) - kInnerBorderY - scroll_offset_y_; int index = XYToTextIndex(X, Y); MouseButton button = GetEventButton(button_flags); if (event_type == NUX_MOUSE_PRESSED && (button == 2 || button == 3)) { SetCursor(index); #if defined(NUX_OS_LINUX) if (button == 2) PastePrimaryClipboard(); #endif QueueRefresh(false, true); return; } if (button != 1 && event_type != NUX_MOUSE_MOVE) return; int sel_start, sel_end; GetSelectionBounds(&sel_start, &sel_end); unsigned long long current_time = GetCurrentTime(); if ((event_type == NUX_MOUSE_PRESSED) && (current_time - last_dblclick_time_ <= kTripleClickTimeout)) { SelectLine(); } else if (event_type == NUX_MOUSE_DOUBLECLICK && !ime_active_) { SelectWord(); last_dblclick_time_ = current_time; } else if (event_type == NUX_MOUSE_PRESSED) { if (key_flags & NUX_STATE_SHIFT) { // If current click position is inside the selection range, then just // cancel the selection. if (index > sel_start && index < sel_end) SetCursor(index); else if (index <= sel_start) SetSelectionBounds(sel_end, index); else if (index >= sel_end) SetSelectionBounds(sel_start, index); } else { SetCursor(index); } } else if (event_type == NUX_MOUSE_MOVE) { SetSelectionBounds(selection_bound_, index); } QueueRefresh(false, true); //return EVENT_RESULT_HANDLED; } void TextEntry::ProcessKeyEvent( unsigned long event_type, /*event type*/ unsigned long keysym , /*event keysym*/ unsigned long state , /*event state*/ const char* character , /*character*/ unsigned short /* keyCount */ /*key repeat count*/) { #if defined(USE_X11) if (im_running()) { // FIXME Have to get the x11_keycode for ibus-hangul/korean input KeyCode keycode = XKeysymToKeycode(GetGraphicsDisplay()->GetX11Display(), keysym); KeyEvent event(static_cast(event_type), keysym, keycode, state, character); if (ime_->FilterKeyEvent(event)) return; } #endif /* Ignore all the keyup events to make Composition and Dead keys to work, * as no one (IBus a part) needs them */ if (event_type == NUX_KEYUP) return; #if !defined(NO_X11) if (IsInCompositionMode() || IsInitialCompositionKeySym(keysym)) { if (HandleComposition(keysym)) return; } #endif if (event_type == NUX_KEYDOWN) text_input_mode_ = true; cursor_blink_status_ = 4; if ((!multiline_) && (!lose_key_focus_on_key_nav_direction_up_) && (keysym == NUX_VK_UP)) { // Ignore key navigation direction 'up' if we are not in multi-line. return; } if ((!multiline_) && (!lose_key_focus_on_key_nav_direction_up_) && (keysym == NUX_VK_DOWN)) { // Ignore key navigation direction 'down' if we are not in multi-line. return; } // we need to ignore some characters if (keysym == NUX_VK_TAB) return; if ((keysym == NUX_VK_ENTER || keysym == NUX_KP_ENTER)) { activated.emit(); return; } unsigned int keyval = keysym; bool shift = (state & NUX_STATE_SHIFT); bool ctrl = (state & NUX_STATE_CTRL); bool handled = false; // DLOG("TextEntry::key_down(%d, shift:%d ctrl:%d)", keyval, shift, ctrl); if (event_type == NUX_KEYDOWN) { if (keyval == NUX_VK_LEFT) { if (!ctrl) MoveCursor(VISUALLY, -1, shift); else MoveCursor(WORDS, -1, shift); handled = true; } else if (keyval == NUX_VK_RIGHT) { if (!ctrl) MoveCursor(VISUALLY, 1, shift); else MoveCursor(WORDS, 1, shift); handled = true; } else if (keyval == NUX_VK_UP) { // move cursor to start of line MoveCursor(DISPLAY_LINES, -1, shift); handled = true; } else if (keyval == NUX_VK_DOWN) { // move cursor to end of line MoveCursor(DISPLAY_LINES, 1, shift); handled = true; } else if (keyval == NUX_VK_HOME) { if (!ctrl) MoveCursor(DISPLAY_LINE_ENDS, -1, shift); else MoveCursor(BUFFER, -1, shift); handled = true; } else if (keyval == NUX_VK_END) { if (!ctrl) MoveCursor(DISPLAY_LINE_ENDS, 1, shift); else MoveCursor(BUFFER, 1, shift); handled = true; } else if (keyval == NUX_VK_PAGE_UP) { if (!ctrl) MoveCursor(PAGES, -1, shift); else MoveCursor(BUFFER, -1, shift); handled = true; } else if (keyval == NUX_VK_PAGE_DOWN) { if (!ctrl) MoveCursor(PAGES, 1, shift); else MoveCursor(BUFFER, 1, shift); handled = true; } else if (((keyval == NUX_VK_x) && ctrl && !shift) || ((keyval == NUX_VK_DELETE) && shift && !ctrl)) { CutClipboard(); handled = true; } else if (((keyval == NUX_VK_c) && ctrl && (!shift)) || ((keyval == NUX_VK_INSERT) && ctrl && (!shift))) { CopyClipboard(); handled = true; } else if (((keyval == NUX_VK_v) && ctrl && (!shift)) || ((keyval == NUX_VK_INSERT) && shift && (!ctrl))) { PasteClipboard(); handled = true; } else if ((keyval == NUX_VK_a) && ctrl) { SelectAll(); handled = true; } else if (keyval == NUX_VK_BACKSPACE) { if (!ctrl) BackSpace(VISUALLY); else BackSpace(WORDS); handled = true; } else if ((keyval == NUX_VK_DELETE) && (!shift)) { if (!ctrl) Delete(VISUALLY); else Delete(WORDS); handled = true; } else if ((keyval == NUX_VK_INSERT) && (!shift) && (!ctrl)) { ToggleOverwrite(); handled = true; } // else // { // return EVENT_RESULT_UNHANDLED; // } } else { // EVENT_KEY_PRESS // if (keyval == GDK_Return || keyval == GDK_KP_Enter) // { // // If multiline_ is unset, just ignore new_line. // if (multiline_) // EnterText("\n"); // else // return; // } // else // { // return; // } } if (!handled && character) { unsigned int utf_char = g_utf8_get_char(character); if (g_unichar_isprint(utf_char)) EnterText(character); } QueueRefresh(false, true); } void TextEntry::RecvMouseDoubleClick(int x, int y, unsigned long button_flags, unsigned long key_flags) { ProcessMouseEvent(NUX_MOUSE_DOUBLECLICK, x, y, 0, 0, button_flags, key_flags); } void TextEntry::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags) { ProcessMouseEvent(NUX_MOUSE_RELEASED, x, y, 0, 0, button_flags, key_flags); } void TextEntry::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags) { ProcessMouseEvent(NUX_MOUSE_PRESSED, x, y, 0, 0, button_flags, key_flags); } void TextEntry::RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) { ProcessMouseEvent(NUX_MOUSE_MOVE, x, y, dx, dy, button_flags, key_flags); } void TextEntry::RecvMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { #if defined(USE_X11) if (caret_cursor_ == None) { Display* display = nux::GetGraphicsDisplay()->GetX11Display(); nux::BaseWindow* window = static_cast(GetTopLevelViewWindow()); if (display && window) { caret_cursor_ = XCreateFontCursor(display, XC_xterm); XDefineCursor(display, window->GetInputWindowId(), caret_cursor_); } } #endif } void TextEntry::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { #if defined(USE_X11) if (caret_cursor_ != None) { Display* display = nux::GetGraphicsDisplay()->GetX11Display(); nux::BaseWindow* window = static_cast(GetTopLevelViewWindow()); if (display && window) { XUndefineCursor(display, window->GetInputWindowId()); XFreeCursor(display, caret_cursor_); caret_cursor_ = None; } } #endif } void TextEntry::RecvKeyEvent( unsigned long eventType , /*event type*/ unsigned long keysym , /*event keysym*/ unsigned long state , /*event state*/ const char* character , /*character*/ unsigned short keyCount /*key repeat count*/) { ProcessKeyEvent(eventType, keysym, state, character, keyCount); } void TextEntry::RecvStartKeyFocus() { key_nav_mode_ = true; text_input_mode_ = false; composition_list_.clear(); FocusInx(); } void TextEntry::RecvEndKeyFocus() { key_nav_mode_ = false; text_input_mode_ = false; composition_list_.clear(); FocusOutx(); } void TextEntry::Draw(GraphicsEngine& gfxContext, bool /* forceDraw */) { MainDraw(); Geometry base = GetGeometry(); gfxContext.PushClippingRectangle(base); nux::GetPainter().PaintBackground(gfxContext, base); Color col = color::Black; col.alpha = 0; gfxContext.QRP_Color(base.x, base.y, base.width, base.height, col); TexCoordXForm texxform; texxform.SetWrap(TEXWRAP_REPEAT, TEXWRAP_REPEAT); texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); gfxContext.QRP_1Tex(base.x, base.y, base.width, base.height, _texture2D->GetDeviceTexture(), texxform, _text_color); gfxContext.PopClippingRectangle(); } void TextEntry::DrawContent(GraphicsEngine& /* gfxContext */, bool /* forceDraw */) { //MainDraw(); } TextEntry::SearchState TextEntry::GetCompositionForList(std::vector const& input, std::string& composition) { SearchState search_state = SearchState::NO_MATCH; #if defined(NUX_OS_LINUX) if (input.size() >= ComposeSequence::MAX_SYMBOLS) return search_state; for (unsigned i = 0; i < COMPOSE_SEQUENCES_SIZE; ++i) { int j = 0; bool valid_seq = false; ComposeSequence const& seq = COMPOSE_SEQUENCES[i]; for (auto key : input) { if (key != seq.symbols[j]) { if (seq.symbols[j] != XK_VoidSymbol) valid_seq = false; break; } valid_seq = true; ++j; } if (valid_seq) { if (seq.symbols[j] == XK_VoidSymbol) { search_state = SearchState::MATCH; composition = seq.result; return search_state; } else { search_state = SearchState::PARTIAL; } } } #endif return search_state; } bool TextEntry::IsInCompositionMode() const { return !composition_list_.empty(); } bool TextEntry::IsInitialCompositionKeySym(unsigned long keysym) const { #if defined(USE_X11) /* Checks if a keysym is a valid initial composition key */ if (keysym == XK_Multi_key || (keysym >= XK_dead_grave && keysym <= XK_dead_currency) || keysym == XK_Greek_accentdieresis) { return true; } #endif return false; } bool TextEntry::HandleComposition(unsigned long keysym) { #if defined(USE_X11) bool composition_mode = IsInCompositionMode(); if (composition_mode && IsModifierKey(keysym)) return true; composition_list_.push_back(keysym); std::string composition_match; auto match = GetCompositionForList(composition_list_, composition_match); if (match == SearchState::PARTIAL) { return true; } else if (match == SearchState::MATCH) { EnterText(composition_match.c_str()); composition_list_.clear(); QueueRefresh(false, true); return true; } else { composition_list_.clear(); return composition_mode; } #endif return false; } void TextEntry::SetText(const char* text) { const char* end = NULL; g_utf8_validate(text, -1, &end); std::string txt((text && *text && end > text) ? std::string(text, end) : ""); if (txt == text_) return; // prevent some redraws text_ = multiline_ ? txt : CleanupLineBreaks(txt.c_str()); cursor_ = 0; selection_bound_ = 0; need_im_reset_ = true; //ResetImContext(); text_input_mode_ = true; QueueRefresh(true, true); text_changed.emit(this); } std::string const& TextEntry::GetText() const { return text_; } std::string TextEntry::GetTextSelection() const { if (text_.size() == 0) { return std::string(""); } int selection_start = 0; int selection_end = 0; if (GetSelectionBounds(&selection_start, &selection_end)) { return text_.substr(selection_start, selection_end); } else { return std::string(""); } } void TextEntry::SetCompletion(const char* text) { const char* end = NULL; g_utf8_validate(text, -1, &end); std::string txt((text && *text && end > text) ? std::string(text, end) : ""); if (txt == completion_) return; completion_ = txt; QueueRefresh(true, true); } std::string const& TextEntry::GetCompletion() const { return completion_; } void TextEntry::SetCompletionColor(const Color &color) { completion_color_ = color; QueueRefresh(true, true); } Color const& TextEntry::GetCompletionColor() const { return completion_color_; } void TextEntry::SetTextColor(const Color &text_color) { if (_text_color != text_color) { _text_color = text_color; QueueRefresh(true, true); } } Color TextEntry::GetTextColor() const { return _text_color; } void TextEntry::MainDraw() { CairoGraphics* edit_canvas = EnsureCanvas(); if (update_canvas_ || !last_selection_region_.empty() || !selection_region_.empty()) { edit_canvas->PushState(); DrawText(edit_canvas); edit_canvas->PopState(); } // if (background_) // background_->Draw(canvas, 0, 0, GetBaseWidth, GetBaseHeight); CairoGraphics* final_canvas = new CairoGraphics(CAIRO_FORMAT_ARGB32, edit_canvas->GetWidth(), edit_canvas->GetHeight()); final_canvas->PushState(); final_canvas->IntersectRectClipRegion(kInnerBorderX, kInnerBorderY, GetBaseWidth() - kInnerBorderX, GetBaseHeight() - kInnerBorderY); final_canvas->DrawCanvas(0, 0, edit_canvas); final_canvas->PopState(); DrawCursor(final_canvas); update_canvas_ = false; last_selection_region_ = selection_region_; last_cursor_region_ = cursor_region_; NBitmapData* bitmap = final_canvas->GetBitmap(); delete final_canvas; if (!_texture2D || _texture2D->GetWidth() != bitmap->GetWidth() || _texture2D->GetHeight() != bitmap->GetHeight()) { if (_texture2D) _texture2D->UnReference(); _texture2D = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); } _texture2D->Update(bitmap); delete bitmap; } void TextEntry::FocusInx() { if (!focused_) { focused_ = true; if (!readonly_ /*&& im_context_*/) { need_im_reset_ = true; #if defined(USE_X11) ime_->Focus(); nux::GetWindowThread()->XICFocus(this); #endif //gtk_im_context_focus_in(im_context_); //UpdateIMCursorLocation(); } cursor_visible_ = true; // show cursor when getting focus selection_changed_ = true; cursor_moved_ = true; // Don't adjust scroll. QueueRefresh(true, false); } } void TextEntry::FocusOutx() { if (focused_) { focused_ = false; if (!readonly_ /*&& im_context_*/) { need_im_reset_ = true; #if defined(USE_X11) ime_->Blur(); nux::GetWindowThread()->XICUnFocus(); #endif //gtk_im_context_focus_out(im_context_); } cursor_visible_ = false; // hide cursor when losing focus selection_changed_ = true; cursor_moved_ = true; if (cursor_visible_on_key_focus_only_ && cursor_blink_timer_) { g_source_remove(cursor_blink_timer_); cursor_blink_timer_ = 0; } // Don't adjust scroll. QueueRefresh(true, false); } } CairoGraphics* TextEntry::EnsureCanvas() { if (canvas_) { if ((GetBaseWidth() == canvas_->GetWidth()) && (GetBaseHeight() == canvas_->GetHeight())) { return canvas_; } else { nuxDebugMsg("[TextEntry::EnsureCanvas] Recreate canvas"); delete canvas_; canvas_ = NULL; } } canvas_ = new CairoGraphics(CAIRO_FORMAT_ARGB32, GetBaseWidth(), GetBaseHeight()); nuxAssert(canvas_); return canvas_; } void TextEntry::AdjustScroll() { int old_offset_x = scroll_offset_x_; int old_offset_y = scroll_offset_y_; int display_width = GetBaseWidth() - kInnerBorderX * 2; int display_height = GetBaseHeight() - kInnerBorderY * 2; PangoLayout* layout = EnsureLayout(); int text_width, text_height; pango_layout_get_pixel_size(layout, &text_width, &text_height); int strong_x, strong_y, strong_height; int weak_x, weak_y, weak_height; GetCursorLocationInLayout(&strong_x, &strong_y, &strong_height, &weak_x, &weak_y, &weak_height); if (!wrap_ && display_width > text_width) { PangoAlignment align = pango_layout_get_alignment(layout); if (align == PANGO_ALIGN_RIGHT) scroll_offset_x_ = display_width - text_width; else if (align == PANGO_ALIGN_CENTER) scroll_offset_x_ = (display_width - text_width) / 2; else scroll_offset_x_ = 0; } else { if (scroll_offset_x_ + strong_x < 0) scroll_offset_x_ = -strong_x; else if (scroll_offset_x_ + strong_x > display_width) scroll_offset_x_ = display_width - strong_x; if (std::abs(weak_x - strong_x) < display_width) { if (scroll_offset_x_ + weak_x < 0) scroll_offset_x_ = - weak_x; else if (scroll_offset_x_ + weak_x > display_width) scroll_offset_x_ = display_width - weak_x; } } if (display_height > text_height) { scroll_offset_y_ = 0; } else { if (scroll_offset_y_ + strong_y + strong_height > display_height) scroll_offset_y_ = display_height - strong_y - strong_height; if (scroll_offset_y_ + strong_y < 0) scroll_offset_y_ = -strong_y; } if (old_offset_x != scroll_offset_x_ || old_offset_y != scroll_offset_y_) content_modified_ = true; } void TextEntry::QueueRefresh(bool relayout, bool adjust_scroll) { if (relayout) ResetLayout(); if (adjust_scroll) AdjustScroll(); QueueTextDraw(); QueueCursorBlink(); } void TextEntry::ResetImContext() { if (need_im_reset_) { need_im_reset_ = false; // if (im_context_) // gtk_im_context_reset(im_context_); ResetPreedit(); } } void TextEntry::ResetPreedit() { // Reset layout if there were some content in preedit string if (preedit_.length()) ResetLayout(); preedit_.clear(); preedit_cursor_ = 0; if (preedit_attrs_) { pango_attr_list_unref(preedit_attrs_); preedit_attrs_ = NULL; } } void TextEntry::PreeditStarted() { ime_active_ = true; } void TextEntry::UpdatePreedit(std::string const& preedit, int cursor) { preedit_ = preedit; preedit_cursor_ = cursor; QueueRefresh(true, true); } void TextEntry::UpdatePreeditAttribs(PangoAttrList* list) { if (preedit_attrs_) { pango_attr_list_unref(preedit_attrs_); preedit_attrs_ = NULL; } preedit_attrs_ = list; } void TextEntry::ClearPreedit() { ResetPreedit(); QueueRefresh(true, true); } void TextEntry::DrawText(CairoGraphics *canvas) { PangoLayout *layout = EnsureLayout(); bool redraw_text = false; if (update_canvas_) { canvas->ClearCanvas(); canvas->PushState(); redraw_text = true; } else if (!last_selection_region_.empty()) { //last_selection_region_.Integerize(); canvas->PushState(); canvas->IntersectGeneralClipRegion(last_selection_region_); canvas->ClearRect(0, 0, GetBaseWidth(), GetBaseHeight()); redraw_text = true; } if (redraw_text) { cairo_set_source_rgb(canvas->GetInternalContext(), _text_color.red, _text_color.green, _text_color.blue); cairo_move_to(canvas->GetInternalContext(), scroll_offset_x_ + kInnerBorderX, scroll_offset_y_ + kInnerBorderY); pango_cairo_show_layout(canvas->GetInternalContext(), layout); canvas->PopState(); } // Draw selection background. // Selection in a single line may be not continual, so we use pango to // get the x-ranges of each selection range in one line, and draw them // separately. if (!selection_region_.empty()) { canvas->PushState(); //selection_region_.Integerize(); canvas->IntersectGeneralClipRegion(selection_region_); Color selection_color = GetSelectionBackgroundColor(); Color text_color = GetSelectionTextColor(); cairo_set_source_rgb(canvas->GetInternalContext(), selection_color.red, selection_color.green, selection_color.blue); cairo_paint(canvas->GetInternalContext()); cairo_move_to(canvas->GetInternalContext(), scroll_offset_x_ + kInnerBorderX, scroll_offset_y_ + kInnerBorderY); cairo_set_source_rgb(canvas->GetInternalContext(), text_color.red, text_color.green, text_color.blue); pango_cairo_show_layout(canvas->GetInternalContext(), layout); canvas->PopState(); } } bool TextEntry::CursorBlinkCallback(TextEntry *self) { if (self->cursor_blink_status_) self->ShowCursor(); else self->HideCursor(); if (--self->cursor_blink_status_ < 0) self->cursor_blink_status_ = 2; return true; } void TextEntry::QueueCursorBlink() { if (cursor_visible_on_key_focus_only_ && !focused_) return; if (!cursor_blink_timer_) cursor_blink_timer_ = g_timeout_add(kCursorBlinkTimeout, (GSourceFunc)&CursorBlinkCallback, this); } void TextEntry::ShowCursor() { if (!cursor_visible_) { cursor_visible_ = true; if (focused_ && !readonly_) { cursor_moved_ = true; QueueRefresh(false, false); } } } void TextEntry::HideCursor() { if (cursor_visible_) { cursor_visible_ = false; if (focused_ && !readonly_) { cursor_moved_ = true; QueueRefresh(false, false); } } } void TextEntry::GetCursorRects(Rect *strong, Rect *weak) { int strong_x, strong_y, strong_height; int weak_x, weak_y, weak_height; GetCursorLocationInLayout(&strong_x, &strong_y, &strong_height, &weak_x, &weak_y, &weak_height); strong->x = strong_x + kInnerBorderX + scroll_offset_x_ - kStrongCursorBarWidth; strong->width = kStrongCursorBarWidth * 2; strong->y = strong_y + kInnerBorderY + scroll_offset_y_; strong->height = strong_height; if (weak_x != strong_x) { weak->x = weak_x+ kInnerBorderX + scroll_offset_x_ - kWeakCursorBarWidth; weak->width = kWeakCursorBarWidth * 2; weak->y = weak_y+ kInnerBorderY + scroll_offset_y_; weak->height = weak_height; } else { *weak = *strong; } } void TextEntry::UpdateCursorRegion() { cursor_region_.clear(); Rect strong, weak; GetCursorRects(&strong, &weak); cursor_region_.push_back(strong); cursor_region_.push_back(weak); } void TextEntry::DrawCursor(CairoGraphics *canvas) { if (!cursor_visible_) return; int strong_x, strong_y, strong_height; int weak_x, weak_y, weak_height; GetCursorLocationInLayout(&strong_x, &strong_y, &strong_height, &weak_x, &weak_y, &weak_height); // Draw strong cursor. // 0.5 is for cairo drawing between the grid canvas->DrawLine(strong_x + kInnerBorderX + scroll_offset_x_ + 0.5, strong_y + kInnerBorderY + scroll_offset_y_, strong_x + kInnerBorderX + scroll_offset_x_ + 0.5, strong_y + strong_height + kInnerBorderY + scroll_offset_y_, kStrongCursorLineWidth, kStrongCursorColor); // Draw a small arror towards weak cursor if (strong_x > weak_x) { canvas->DrawLine( strong_x + kInnerBorderX + scroll_offset_x_ - kStrongCursorBarWidth, strong_y + kInnerBorderY + scroll_offset_y_ + kStrongCursorLineWidth, strong_x + kInnerBorderX + scroll_offset_x_, strong_y + kInnerBorderY + scroll_offset_y_ + kStrongCursorLineWidth, kStrongCursorLineWidth, kStrongCursorColor); } else if (strong_x < weak_x) { canvas->DrawLine( strong_x + kInnerBorderX + scroll_offset_x_, strong_y + kInnerBorderY + scroll_offset_y_ + kStrongCursorLineWidth, strong_x + kInnerBorderX + scroll_offset_x_ + kStrongCursorBarWidth, strong_y + kInnerBorderY + scroll_offset_y_ + kStrongCursorLineWidth, kStrongCursorLineWidth, kStrongCursorColor); } if (strong_x != weak_x ) { // Draw weak cursor. canvas->DrawLine(weak_x + kInnerBorderX + scroll_offset_x_, weak_y + kInnerBorderY + scroll_offset_y_, weak_x + kInnerBorderX + scroll_offset_x_, weak_y + weak_height + kInnerBorderY + scroll_offset_y_, kWeakCursorLineWidth, kWeakCursorColor); // Draw a small arror towards strong cursor if (weak_x > strong_x) { canvas->DrawLine( weak_x + kInnerBorderX + scroll_offset_x_ - kWeakCursorBarWidth, weak_y + kInnerBorderY + scroll_offset_y_ + kWeakCursorLineWidth, weak_x + kInnerBorderX + scroll_offset_x_, weak_y + kInnerBorderY + scroll_offset_y_ + kWeakCursorLineWidth, kWeakCursorLineWidth, kWeakCursorColor); } else { canvas->DrawLine( weak_x + kInnerBorderX + scroll_offset_x_, weak_y + kInnerBorderY + scroll_offset_y_ + kWeakCursorLineWidth, weak_x + kInnerBorderX + scroll_offset_x_ + kWeakCursorBarWidth, weak_y + kInnerBorderY + scroll_offset_y_ + kWeakCursorLineWidth, kWeakCursorLineWidth, kWeakCursorColor); } } } Color TextEntry::GetSelectionBackgroundColor() { return kDefaultSelectionBackgroundColor; } Color TextEntry::GetSelectionTextColor() { return kDefaultSelectionTextColor; } void TextEntry::GetCursorLocationInLayout(int *strong_x, int *strong_y, int *strong_height, int *weak_x, int *weak_y, int *weak_height) { PangoLayout *layout = EnsureLayout(); int cursor_index = TextIndexToLayoutIndex(cursor_, true); PangoRectangle strong, weak; pango_layout_get_cursor_pos(layout, cursor_index, &strong, &weak); if (strong_x) *strong_x = PANGO_PIXELS(strong.x); if (strong_y) *strong_y = PANGO_PIXELS(strong.y); if (strong_height) *strong_height = PANGO_PIXELS(strong.height); if (weak_x) *weak_x = PANGO_PIXELS(weak.x); if (weak_y) *weak_y = PANGO_PIXELS(weak.y); if (weak_height) *weak_height = PANGO_PIXELS(weak.height); } PangoLayout* TextEntry::EnsureLayout() { if (!cached_layout_) { cached_layout_ = CreateLayout(); } return cached_layout_; } void TextEntry::QueueTextDraw() { if (content_modified_) { UpdateSelectionRegion(); UpdateCursorRegion(); QueueDraw(); //owner->QueueDraw(); content_modified_ = false; update_canvas_ = true; } else { if (selection_changed_) { UpdateSelectionRegion(); if (!last_selection_region_.empty()) QueueDraw(); //owner_->QueueDrawRegion(last_selection_region_); if (!selection_region_.empty()) QueueDraw(); //owner_->QueueDrawRegion(selection_region_); selection_changed_ = false; } if (cursor_moved_) { UpdateCursorRegion(); if (!last_cursor_region_.empty()) QueueDraw(); //owner_->QueueDrawRegion(last_cursor_region_); if (!cursor_region_.empty()) QueueDraw(); //owner_->QueueDrawRegion(cursor_region_); cursor_moved_ = false; } } } void TextEntry::ResetLayout() { if (cached_layout_) { g_object_unref(cached_layout_); cached_layout_ = NULL; content_modified_ = true; } } PangoLayout* TextEntry::CreateLayout() { // Creates the pango layout with a temporary canvas that is not zoomed. CairoGraphics *canvas = new CairoGraphics(CAIRO_FORMAT_ARGB32, 1, 1); PangoLayout *layout = pango_cairo_create_layout(canvas->GetInternalContext()); delete canvas; PangoAttrList *tmp_attrs = pango_attr_list_new(); std::string tmp_string; /* Set necessary parameters */ pango_cairo_context_set_font_options(pango_layout_get_context(layout), font_options_); pango_cairo_context_set_resolution(pango_layout_get_context(layout), font_dpi_); if (wrap_) { pango_layout_set_width(layout, (GetBaseWidth() - kInnerBorderX * 2) * PANGO_SCALE); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); } else { pango_layout_set_width(layout, -1); } pango_layout_set_single_paragraph_mode(layout, !multiline_); if (preedit_.length()) { size_t cursor_index = static_cast(cursor_); size_t text_length = text_.length(); size_t preedit_length = preedit_.length(); if (visible_) { tmp_string = text_; tmp_string.insert(cursor_index, preedit_); } else { size_t nchars = g_utf8_strlen(text_.c_str(), text_length); size_t preedit_nchars = g_utf8_strlen(preedit_.c_str(), preedit_length); nchars += preedit_nchars; tmp_string.reserve(password_char_.length() * nchars); for (size_t i = 0; i < nchars; ++i) tmp_string.append(password_char_); size_t cursor_offset = g_utf8_pointer_to_offset(text_.c_str(), text_.c_str() + cursor_index); /* Fix cursor index and preedit_length */ cursor_index = cursor_offset * password_char_.length(); preedit_length = preedit_nchars * password_char_.length(); } if (preedit_attrs_) pango_attr_list_splice(tmp_attrs, preedit_attrs_, static_cast(cursor_index), static_cast(preedit_length)); } else { if (visible_) { tmp_string = text_; } else { size_t nchars = g_utf8_strlen(text_.c_str(), text_.length()); tmp_string.reserve(password_char_.length() * nchars); for (size_t i = 0; i < nchars; ++i) tmp_string.append(password_char_); } } int pre_completion_length = tmp_string.length(); if (!completion_.empty() && !wrap_ && preedit_.empty()) { tmp_string = text_ + completion_; } pango_layout_set_text(layout, tmp_string.c_str(), static_cast(tmp_string.length())); /* Set necessary attributes */ PangoAttribute *attr; if (underline_) { attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); attr->start_index = 0; attr->end_index = static_cast(pre_completion_length); pango_attr_list_insert(tmp_attrs, attr); } if (strikeout_) { attr = pango_attr_strikethrough_new(TRUE); attr->start_index = 0; attr->end_index = static_cast(pre_completion_length); pango_attr_list_insert(tmp_attrs, attr); } if (!completion_.empty() && !wrap_) { attr = pango_attr_foreground_new(65535 * completion_color_.red, 65535 * completion_color_.green, 65535 * completion_color_.blue); attr->start_index = static_cast(pre_completion_length); attr->end_index = static_cast(tmp_string.length()); pango_attr_list_insert(tmp_attrs, attr); } /* Set font desc */ { /* safe to down_cast here, because we know the actual implementation. */ CairoFont *font = new CairoFont( font_family_.empty() ? kDefaultFontName : font_family_.c_str(), font_size_, italic_ ? CairoFont::STYLE_ITALIC : CairoFont::STYLE_NORMAL, bold_ ? CairoFont::WEIGHT_BOLD : CairoFont::WEIGHT_NORMAL); nuxAssert(font); attr = pango_attr_font_desc_new(font->GetFontDescription()); attr->start_index = 0; attr->end_index = static_cast(tmp_string.length()); pango_attr_list_insert(tmp_attrs, attr); pango_layout_set_font_description(layout, font->GetFontDescription()); font->Destroy(); } pango_layout_set_attributes(layout, tmp_attrs); pango_attr_list_unref(tmp_attrs); /* Set alignment according to text direction. Only set layout's alignment * when it's not wrapped and in single line mode. */ if (!wrap_ && pango_layout_get_line_count(layout) <= 1 && align_ != CairoGraphics::ALIGN_CENTER) { PangoDirection dir; if (visible_) dir = pango_find_base_dir(tmp_string.c_str(), static_cast(tmp_string.length())); else dir = PANGO_DIRECTION_NEUTRAL; if (dir == PANGO_DIRECTION_NEUTRAL) { // GtkWidget *widget = GetWidgetAndCursorLocation(NULL); // if (widget && gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) // dir = PANGO_DIRECTION_RTL; // else // dir = PANGO_DIRECTION_LTR; dir = PANGO_DIRECTION_LTR; } // If wordWrap is false then "justify" alignment has no effect. PangoAlignment pango_align = (align_ == CairoGraphics::ALIGN_RIGHT ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT); // Invert the alignment if text direction is right to left. if (dir == PANGO_DIRECTION_RTL) { pango_align = (align_ == CairoGraphics::ALIGN_RIGHT ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT); } pango_layout_set_alignment(layout, pango_align); pango_layout_set_justify(layout, FALSE); } else if (align_ == CairoGraphics::ALIGN_JUSTIFY) { pango_layout_set_justify(layout, TRUE); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); } else if (align_ == CairoGraphics::ALIGN_RIGHT) { pango_layout_set_justify(layout, FALSE); pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); } else if (align_ == CairoGraphics::ALIGN_CENTER) { pango_layout_set_justify(layout, FALSE); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); } else { pango_layout_set_justify(layout, FALSE); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); } { PangoContext *context; PangoFontMetrics *metrics; int ascent, descent; context = pango_layout_get_context(layout); metrics = pango_context_get_metrics(context, pango_layout_get_font_description(layout), pango_context_get_language(context)); ascent = pango_font_metrics_get_ascent(metrics); descent = pango_font_metrics_get_descent(metrics); int full_height = PANGO_PIXELS(ascent + descent) + (kInnerBorderY * 2); SetMinimumHeight(full_height); pango_font_metrics_unref(metrics); } return layout; } int TextEntry::TextIndexToLayoutIndex(int text_index, bool consider_preedit_cursor) { if (visible_) { if (text_index < cursor_) return text_index; if (text_index == cursor_ && consider_preedit_cursor) return text_index + preedit_cursor_; return text_index + static_cast(preedit_.length()); } const char *text = text_.c_str(); int offset = static_cast( g_utf8_pointer_to_offset(text, text + text_index)); int preedit_offset = 0; int preedit_chars = 0; if (preedit_.length()) { const char *preedit_text = preedit_.c_str(); preedit_offset = static_cast(g_utf8_pointer_to_offset( preedit_text, preedit_text + preedit_cursor_)); preedit_chars = static_cast(g_utf8_strlen( preedit_text, preedit_.length())); } int password_char_length = static_cast(password_char_.length()); if (text_index < cursor_) return offset * password_char_length; if (text_index == cursor_ && consider_preedit_cursor) return (offset + preedit_offset) * password_char_length; return (offset + preedit_chars) * password_char_length; } int TextEntry::LayoutIndexToTextIndex(int layout_index) { if (visible_) { if (layout_index < cursor_) return layout_index; int preedit_length = static_cast(preedit_.length()); if (layout_index >= cursor_ + preedit_length) return layout_index - preedit_length; return cursor_; } int password_char_length = static_cast(password_char_.length()); nuxAssert(layout_index % password_char_length == 0); int offset = layout_index / password_char_length; const char *text = text_.c_str(); int cursor_offset = static_cast( g_utf8_pointer_to_offset(text, text + cursor_)); int preedit_chars = static_cast( g_utf8_strlen(preedit_.c_str(), preedit_.length())); if (offset < cursor_offset) return static_cast(g_utf8_offset_to_pointer(text, offset) - text); if (offset >= cursor_offset + preedit_chars) return static_cast( g_utf8_offset_to_pointer(text, offset - preedit_chars) - text); return cursor_; } int TextEntry::GetCharLength(int index) { const char *text = text_.c_str(); const char *ptr = text + index; const char *end = text + text_.length(); const char *next = g_utf8_find_next_char(ptr, end); return static_cast(next ? static_cast(next - ptr) : end - ptr); } int TextEntry::GetPrevCharLength(int index) { const char *text = text_.c_str(); const char *ptr = text + index; const char *prev = g_utf8_find_prev_char(text, ptr); return static_cast(prev ? static_cast(ptr - prev) : ptr - text); } void TextEntry::EnterText(const char *str) { if (readonly_ || !str || !*str) return; if (GetSelectionBounds(NULL, NULL)) { DeleteSelection(); } else if (overwrite_ && cursor_ != static_cast(text_.length())) { DeleteText(cursor_, cursor_ + GetCharLength(cursor_)); } std::string tmp_text; if (!multiline_) { tmp_text = CleanupLineBreaks(str); str = tmp_text.c_str(); } const char *end = NULL; g_utf8_validate(str, -1, &end); if (end > str) { size_t len = end - str; text_.insert(cursor_, str, len); cursor_ += static_cast(len); selection_bound_ += static_cast(len); } ResetLayout(); text_input_mode_ = true; text_changed.emit(this); } void TextEntry::DeleteText(int start, int end) { if (readonly_) return; int text_length = static_cast(text_.length()); if (start < 0) start = 0; else if (start > text_length) start = text_length; if (end < 0) end = 0; else if (end > text_length) end = text_length; if (start > end) std::swap(start, end); else if (start == end) return; text_.erase(start, end - start); if (cursor_ >= end) cursor_ -= (end - start); if (selection_bound_ >= end) selection_bound_ -= (end - start); ResetLayout(); text_input_mode_ = true; text_changed.emit(this); } void TextEntry::SelectWord() { int selection_bound = MoveWords(cursor_, -1); int cursor = MoveWords(selection_bound, 1); SetSelectionBounds(selection_bound, cursor); } void TextEntry::SelectLine() { int selection_bound = MoveLineEnds(cursor_, -1); int cursor = MoveLineEnds(selection_bound, 1); SetSelectionBounds(selection_bound, cursor); } void TextEntry::Select(int start, int end) { int text_length = static_cast(text_.length()); if (start == -1) start = text_length; if (end == -1) end = text_length; start = Clamp(start, 0, text_length); end = Clamp(end, 0, text_length); SetSelectionBounds(start, end); QueueRefresh(false, true); } void TextEntry::SelectAll() { SetSelectionBounds(0, static_cast(text_.length())); QueueRefresh(false, true); } CairoGraphics::Alignment TextEntry::GetAlign() const { return align_; } void TextEntry::SetAlign(CairoGraphics::Alignment align) { align_ = align; QueueRefresh(true, true); } bool TextEntry::im_active() { return ime_active_; } bool TextEntry::im_running() { #if defined(USE_X11) return ime_->IsConnected(); #else return false; #endif } void TextEntry::DeleteSelection() { int start, end; if (GetSelectionBounds(&start, &end)) DeleteText(start, end); } void TextEntry::CopyClipboard() { // int start, end; // if (GetSelectionBounds(&start, &end)) // { // GtkWidget *widget = GetWidgetAndCursorLocation(NULL); // if (widget) // { // if (visible_) // { // gtk_clipboard_set_text( // gtk_widget_get_clipboard(widget, GDK_SELECTION_CLIPBOARD), // text_.c_str() + start, end - start); // } // else // { // // Don't copy real content if it's in invisible. // std::string content; // int nchars = static_cast( // g_utf8_strlen(text_.c_str() + start, end - start)); // for (int i = 0; i < nchars; ++i) // content.append(password_char_); // gtk_clipboard_set_text( // gtk_widget_get_clipboard(widget, GDK_SELECTION_CLIPBOARD), // content.c_str(), static_cast(content.length())); // } // } // } } void TextEntry::CutClipboard() { CopyClipboard(); DeleteSelection(); QueueRefresh(true, true); } void TextEntry::PasteClipboard() { // GtkWidget *widget = GetWidgetAndCursorLocation(NULL); // if (widget) // { // gtk_clipboard_request_text( // gtk_widget_get_clipboard(widget, GDK_SELECTION_CLIPBOARD), // PasteCallback, this); // } } #if defined(NUX_OS_LINUX) void TextEntry::PastePrimaryClipboard() { // TODO } #endif void TextEntry::BackSpace(MovementStep step) { if (GetSelectionBounds(NULL, NULL)) { DeleteSelection(); } else { if (cursor_ == 0) return; if (step == VISUALLY) { DeleteText(cursor_ - GetPrevCharLength(cursor_), cursor_); } else if (step == WORDS) { int new_cursor; new_cursor = MoveWords(cursor_, -1); DeleteText(new_cursor, cursor_); } } } void TextEntry::Delete(MovementStep step) { if (GetSelectionBounds(NULL, NULL)) { DeleteSelection(); } else { if (cursor_ == static_cast(text_.length())) return; if (step == VISUALLY) { DeleteText(cursor_, cursor_ + GetCharLength(cursor_)); } else if (step == WORDS) { int new_cursor; new_cursor = MoveWords(cursor_, 1); DeleteText(cursor_, new_cursor); } } } void TextEntry::ToggleOverwrite() { overwrite_ = !overwrite_; } void TextEntry::UpdateSelectionRegion() { selection_region_.clear(); // Selection in a single line may be not continual, so we use pango to // get the x-ranges of each selection range in one line, and draw them // separately. int start_index, end_index; if (GetSelectionBounds(&start_index, &end_index)) { PangoLayout *layout = EnsureLayout(); PangoRectangle line_extents, pos; int draw_start, draw_end; int *ranges; int n_ranges; int n_lines = pango_layout_get_line_count(layout); start_index = TextIndexToLayoutIndex(start_index, false); end_index = TextIndexToLayoutIndex(end_index, false); for (int line_index = 0; line_index < n_lines; ++line_index) { #if PANGO_VERSION_CHECK(1,16,0) PangoLayoutLine *line = pango_layout_get_line_readonly(layout, line_index); #else PangoLayoutLine *line = pango_layout_get_line(layout, line_index); #endif if (line->start_index + line->length < start_index) continue; if (end_index < line->start_index) break; draw_start = std::max(start_index, line->start_index); draw_end = std::min(end_index, line->start_index + line->length); pango_layout_line_get_x_ranges(line, draw_start, draw_end, &ranges, &n_ranges); pango_layout_line_get_pixel_extents(line, NULL, &line_extents); pango_layout_index_to_pos(layout, line->start_index, &pos); for (int i = 0; i < n_ranges; ++i) { selection_region_.push_back(Rect( kInnerBorderX + scroll_offset_x_ + PANGO_PIXELS(ranges[i * 2]), kInnerBorderY + scroll_offset_y_ + PANGO_PIXELS(pos.y), PANGO_PIXELS(ranges[i * 2 + 1] - ranges[i * 2]), line_extents.height)); } g_free(ranges); } } } void TextEntry::MoveCursor(MovementStep step, int count, bool extend_selection) { ResetImContext(); int new_cursor = 0; // Clear selection first if not extend it. if (!extend_selection) { selection_changed_ = true; cursor_moved_ = true; selection_bound_ = cursor_; cursor_moved.emit(cursor_); } // Calculate the new offset after motion. switch(step) { case VISUALLY: new_cursor = MoveVisually(cursor_, count); break; case WORDS: new_cursor = MoveWords(cursor_, count); break; case DISPLAY_LINES: new_cursor = MoveDisplayLines(cursor_, count); break; case DISPLAY_LINE_ENDS: new_cursor = MoveLineEnds(cursor_, count); break; case PAGES: new_cursor = MovePages(cursor_, count); break; case BUFFER: nuxAssert(count == -1 || count == 1); new_cursor = static_cast(count == -1 ? 0 : text_.length()); break; } if (extend_selection) SetSelectionBounds(selection_bound_, new_cursor); else SetCursor(new_cursor); QueueRefresh(true, true); } int TextEntry::MoveVisually(int current_index, int count) { nuxAssert(current_index >= 0 && current_index <= static_cast(text_.length())); nuxAssert(count); nuxAssert(preedit_.length() == 0); PangoLayout* layout = EnsureLayout(); const char* text = pango_layout_get_text(layout); int index = TextIndexToLayoutIndex(current_index, false); int new_index = 0; int new_trailing = 0; while (count != 0) { if (count > 0) { --count; pango_layout_move_cursor_visually(layout, true, index, 0, 1, &new_index, &new_trailing); } else if (count < 0) { ++count; pango_layout_move_cursor_visually(layout, true, index, 0, -1, &new_index, &new_trailing); } index = new_index; if (index < 0 || index == G_MAXINT) return current_index; index = static_cast(g_utf8_offset_to_pointer(text + index, new_trailing) - text); } return LayoutIndexToTextIndex(index); } int TextEntry::MoveWords(int current_index, int count) { nuxAssert(current_index >= 0 && current_index <= static_cast(text_.length())); nuxAssert(count); nuxAssert(preedit_.length() == 0); if (!visible_) { return static_cast(count > 0 ? text_.length() : 0); } // The cursor movement direction shall be determined by the direction of // current text line. PangoLayout* layout = EnsureLayout(); int n_log_attrs; PangoLogAttr* log_attrs; pango_layout_get_log_attrs(layout, &log_attrs, &n_log_attrs); const char* text = pango_layout_get_text(layout); int index = TextIndexToLayoutIndex(current_index, false); int line_index; pango_layout_index_to_line_x(layout, index, FALSE, &line_index, NULL); // Weird bug: line_index here may be >= than line count? int line_count = pango_layout_get_line_count(layout); if (line_index >= line_count) { line_index = line_count - 1; } #if PANGO_VERSION_CHECK(1,16,0) PangoLayoutLine* line = pango_layout_get_line_readonly(layout, line_index); #else PangoLayoutLine* line = pango_layout_get_line(layout, line_index); #endif bool rtl = (line->resolved_dir == PANGO_DIRECTION_RTL); const char* ptr = text + index; int offset = static_cast(g_utf8_pointer_to_offset(text, ptr)); while (count != 0) { if (((rtl && count < 0) || (!rtl && count > 0)) && *ptr) { if (log_attrs[offset].is_white) { while (ptr && *ptr && log_attrs[offset].is_white) { ptr = g_utf8_find_next_char(ptr, NULL); ++offset; } } else { if (ptr && *ptr) { ptr = g_utf8_find_next_char(ptr, NULL); ++offset; } } while (ptr && *ptr) { ptr = g_utf8_find_next_char(ptr, NULL); ++offset; if (log_attrs[offset].is_word_start || log_attrs[offset].is_word_end) break; } if (!ptr) { ptr = text; while (*ptr) ++ptr; } } else if (((rtl && count > 0) || (!rtl && count < 0)) && (ptr > text)) { if (offset > 0 && log_attrs[offset - 1].is_white) { while (ptr && offset > 0 && log_attrs[offset - 1].is_white) { ptr = g_utf8_find_prev_char(text, ptr); --offset; } } else { if (ptr) { ptr = g_utf8_find_prev_char(text, ptr); --offset; } } while (ptr /*&& *ptr*/) //fix: when at the end of the string, allow ctrl+left arrow to move backward to the start/end of the previous word. { ptr = g_utf8_find_prev_char(text, ptr); --offset; if (log_attrs[offset].is_word_start || log_attrs[offset].is_word_end) break; } if (!ptr) ptr = text; } else { break; } if (count > 0) --count; else ++count; } return LayoutIndexToTextIndex(static_cast(ptr - text)); } int TextEntry::MoveDisplayLines(int current_index, int count) { nuxAssert(current_index >= 0 && current_index <= static_cast(text_.length())); nuxAssert(count); nuxAssert(preedit_.length() == 0); PangoLayout *layout = EnsureLayout(); const char *text = pango_layout_get_text(layout); int index = TextIndexToLayoutIndex(current_index, false); int n_lines = pango_layout_get_line_count(layout); int line_index = 0; int x_off = 0; PangoRectangle rect; // Find the current cursor X position in layout pango_layout_index_to_line_x(layout, index, FALSE, &line_index, &x_off); // Weird bug: line_index here may be >= than line count? if (line_index >= n_lines) { line_index = n_lines - 1; } pango_layout_get_cursor_pos(layout, index, &rect, NULL); x_off = rect.x; line_index += count; if (line_index < 0) { return 0; } else if (line_index >= n_lines) { return static_cast(text_.length()); } int trailing; #if PANGO_VERSION_CHECK(1,16,0) PangoLayoutLine *line = pango_layout_get_line_readonly(layout, line_index); #else PangoLayoutLine *line = pango_layout_get_line(layout, line_index); #endif // Find out the cursor x offset related to the new line position. if (line->resolved_dir == PANGO_DIRECTION_RTL) { pango_layout_get_cursor_pos(layout, line->start_index + line->length, &rect, NULL); } else { pango_layout_get_cursor_pos(layout, line->start_index, &rect, NULL); } // rect.x is the left edge position of the line in the layout x_off -= rect.x; if (x_off < 0) x_off = 0; pango_layout_line_x_to_index(line, x_off, &index, &trailing); index = static_cast(g_utf8_offset_to_pointer(text + index, trailing) - text); return LayoutIndexToTextIndex(index); } int TextEntry::MovePages(int current_index, int count) { nuxAssert(current_index >= 0 && current_index <= static_cast(text_.length())); nuxAssert(count); nuxAssert(preedit_.length() == 0); // Transfer pages to display lines. PangoLayout *layout = EnsureLayout(); int layout_height; pango_layout_get_pixel_size(layout, NULL, &layout_height); int n_lines = pango_layout_get_line_count(layout); int line_height = layout_height / n_lines; int page_lines = (GetBaseHeight() - kInnerBorderY * 2) / line_height; return MoveDisplayLines(current_index, count * page_lines); } int TextEntry::MoveLineEnds(int current_index, int count) { nuxAssert(current_index >= 0 && current_index <= static_cast(text_.length())); nuxAssert(count); nuxAssert(preedit_.length() == 0); PangoLayout *layout = EnsureLayout(); int index = TextIndexToLayoutIndex(current_index, false); int line_index = 0; // Find current line pango_layout_index_to_line_x(layout, index, FALSE, &line_index, NULL); // Weird bug: line_index here may be >= than line count? int line_count = pango_layout_get_line_count(layout); if (line_index >= line_count) { line_index = line_count - 1; } // #if PANGO_VERSION_CHECK(1,16,0) // PangoLayoutLine *line = pango_layout_get_line_readonly(layout, line_index); // #else PangoLayoutLine *line = pango_layout_get_line(layout, line_index); // #endif if (line->length == 0) return current_index; if ((line->resolved_dir == PANGO_DIRECTION_RTL && count < 0) || (line->resolved_dir != PANGO_DIRECTION_RTL && count > 0)) { index = line->start_index + line->length; } else { index = line->start_index; } return LayoutIndexToTextIndex(index); } void TextEntry::SetCursor(int cursor) { if (cursor != cursor_) { ResetImContext(); // If there was a selection range, then the selection range will be cleared. // Then content_modified_ shall be set to true to force redrawing the text. if (cursor_ != selection_bound_) selection_changed_ = true; cursor_ = cursor; selection_bound_ = cursor; cursor_moved_ = true; cursor_moved.emit(cursor); } } int TextEntry::XYToTextIndex(int x, int y) { int width, height; PangoLayout *layout = EnsureLayout(); const char *text = pango_layout_get_text(layout); pango_layout_get_pixel_size(layout, &width, &height); if (y < 0) { return 0; } else if (y >= height) { return static_cast(text_.length()); } int trailing; int index; pango_layout_xy_to_index(layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); index = static_cast( g_utf8_offset_to_pointer(text + index, trailing) - text); index = LayoutIndexToTextIndex(index); // Adjust the offset if preedit is not empty and if the offset is after // current cursor. int preedit_length = static_cast(preedit_.length()); if (preedit_length && index > cursor_) { if (index >= cursor_ + preedit_length) index -= preedit_length; else index = cursor_; } return Clamp(index, 0, static_cast(text_.length())); } bool TextEntry::GetSelectionBounds(int* start, int* end) const { if (start) { *start = std::min(selection_bound_, cursor_); } if (end) { *end = std::max(selection_bound_, cursor_); } return (selection_bound_ != cursor_); } void TextEntry::SetSelectionBounds(int selection_bound, int cursor) { if (selection_bound_ != selection_bound || cursor_ != cursor) { selection_changed_ = true; selection_bound_ = selection_bound; if (cursor_ != cursor) { cursor_ = cursor; cursor_moved_ = true; cursor_moved.emit(cursor); } //ResetImContext(); } } void TextEntry::SetFontFamily(const char *font) { font_family_ = font; QueueRefresh(true, true); } void TextEntry::SetFontSize(double font_size) { font_size_ = font_size; QueueRefresh(true, true); } void TextEntry::SetFontOptions(const cairo_font_options_t *options) { g_return_if_fail(options); cairo_font_options_destroy(font_options_); font_options_ = cairo_font_options_copy(options); QueueRefresh(true, true); } bool TextEntry::InspectKeyEvent(unsigned int /* eventType */, unsigned int /* key_sym */, const char* /* character */) { nux::Event const& cur_event = GetGraphicsDisplay()->GetCurrentEvent(); return InspectKeyEvent(cur_event); } bool TextEntry::InspectKeyEvent(nux::Event const& event) { unsigned int eventType = event.type; unsigned int key_sym = event.GetKeySym(); #if defined(USE_X11) if (im_running()) { // Always allow IBus hotkey events if (ime_->IsHotkeyEvent(static_cast(eventType), key_sym, event.key_modifiers)) return true; } #endif // Ignore events when Alt or Super are pressed if (event.GetKeyModifierState(KEY_MODIFIER_SUPER) || event.GetKeyModifierState(KEY_MODIFIER_ALT)) return false; if ((eventType == NUX_KEYDOWN) && (key_nav_mode_ == true) && (text_input_mode_ == false) && (ime_active_ == false)) { if (key_sym == NUX_VK_ENTER || key_sym == NUX_KP_ENTER || key_sym == NUX_VK_UP || key_sym == NUX_VK_DOWN || key_sym == NUX_VK_LEFT || key_sym == NUX_VK_RIGHT || key_sym == NUX_VK_LEFT_TAB || key_sym == NUX_VK_TAB || key_sym == NUX_VK_ESCAPE) { if (key_sym == NUX_VK_LEFT || key_sym == NUX_VK_RIGHT || key_sym == NUX_VK_ENTER || key_sym == NUX_KP_ENTER) { return true; } if (multiline_ && (key_sym == NUX_VK_UP)) { // Navigate between the lines of the text entry. // This will move the cursor one line up. return true; } if (multiline_ && (key_sym == NUX_VK_DOWN)) { // Navigate between the lines of the text entry. // This will move the cursor one line down. return true; } if ((!multiline_) && (!lose_key_focus_on_key_nav_direction_up_) && (key_sym == NUX_VK_UP)) { // By returning true, the text entry signals that it want to receive the signal for this event. // Otherwise, the parent view of the text entry would be looking for another view to receive keynav focus to. return true; } if ((!multiline_) && (!lose_key_focus_on_key_nav_direction_down_) && (key_sym == NUX_VK_DOWN)) { // By returning true, the text entry signals that it want to receive the signal for this event. // Otherwise, the parent view of the text entry would be looking for another view to receive keynav focus to. return true; } return false; } } if ((eventType == NUX_KEYDOWN) && (key_nav_mode_ == true) && (text_input_mode_ == true) && (ime_active_ == false)) { // Enable to exit the TextEntry when in write mode(hack for unity dash) if (key_sym == NUX_VK_UP || key_sym == NUX_VK_DOWN || key_sym == NUX_VK_ESCAPE) { if ((!multiline_) && (!lose_key_focus_on_key_nav_direction_up_) && NUX_VK_UP) { // By returning true, the text entry signals that it want to receive the signal for this event. // Otherwise, the parent view of the text entry would be looking for another view to receive keynav focus to. return true; } if ((!multiline_) && (!lose_key_focus_on_key_nav_direction_down_) && NUX_VK_DOWN) { // By returning true, the text entry signals that it want to receive the signal for this event. // Otherwise, the parent view of the text entry would be looking for another view to receive keynav focus to. return true; } return false; } } if ((eventType == NUX_KEYDOWN) && (key_nav_mode_ == false) && (text_input_mode_ == false)) { return false; } return true; } /// Public API void TextEntry::MoveCursorToLineStart() { MoveCursor(DISPLAY_LINE_ENDS, -1, 0); } void TextEntry::MoveCursorToLineEnd() { MoveCursor(DISPLAY_LINE_ENDS, 1, 0); } void TextEntry::SetLoseKeyFocusOnKeyNavDirectionUp(bool b) { lose_key_focus_on_key_nav_direction_up_ = b; } bool TextEntry::GetLoseKeyFocusOnKeyNavDirectionUp() const { return lose_key_focus_on_key_nav_direction_up_; } void TextEntry::SetLoseKeyFocusOnKeyNavDirectionDown(bool b) { lose_key_focus_on_key_nav_direction_down_ = b; } bool TextEntry::GetLoseKeyFocusOnKeyNavDirectionDown() const { return lose_key_focus_on_key_nav_direction_down_; } void TextEntry::SetToggleCursorVisibilityOnKeyFocus(bool b) { if (cursor_visible_on_key_focus_only_ == b) return; cursor_visible_on_key_focus_only_ = b; if (cursor_visible_on_key_focus_only_) { if (!focused_) { if (cursor_blink_timer_) { g_source_remove(cursor_blink_timer_); cursor_blink_timer_ = 0; } cursor_visible_ = false; QueueDraw(); } } else { if (!focused_) { QueueCursorBlink(); } } } bool TextEntry::GetToggleCursorVisibilityOnKeyFocus() const { return cursor_visible_on_key_focus_only_; } bool TextEntry::IsInTextInputMode() const { return text_input_mode_; } void TextEntry::SetVisibility(bool visible) { if (visible_ != visible) { visible_ = visible; if (!readonly_) { if (focused_) { //gtk_im_context_focus_out(im_context_); } //InitImContext(); ResetPreedit(); if (focused_) { //gtk_im_context_focus_in(im_context_); } } ResetLayout(); } } typedef unsigned short UTF16Char; typedef unsigned int UTF32Char; typedef unsigned char UTF8Char; static const UTF8Char kTrailingBytesForUTF8[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; // http://google-gadgets-for-linux.googlecode.com/svn-history/r97/trunk/ggadget/unicode_utils.cc size_t GetUTF8CharLength(const char *src) { return src ? (kTrailingBytesForUTF8[static_cast(*src)] + 1) : 0; } bool IsLegalUTF8Char(const char *src, size_t length) { if (!src || !length) return false; const UTF8Char *srcptr = reinterpret_cast(src); UTF8Char a; UTF8Char ch = *srcptr; srcptr += length; switch (length) { default: return false; // Everything else falls through when "true"... case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; case 2: if ((a = (*--srcptr)) > 0xBF) return false; switch (ch) { // No fall-through in this inner switch case 0xE0: if (a < 0xA0) return false; break; case 0xED: if (a > 0x9F) return false; break; case 0xF0: if (a < 0x90) return false; break; case 0xF4: if (a > 0x8F) return false; break; default: if (a < 0x80) return false; } case 1: if (ch >= 0x80 && ch < 0xC2) return false; } if (ch > 0xF4) return false; return true; } void TextEntry::SetPasswordChar(const char* c) { if (c == NULL || *c == 0 || !IsLegalUTF8Char(c, GetUTF8CharLength(c))) { password_char_.clear(); } else { password_char_.assign(c, GetUTF8CharLength(c)); } QueueRefresh(true, true); } std::string TextEntry::GetPasswordChar() { return password_char_; } void TextEntry::SetPasswordMode(bool visible) { SetVisibility(!visible); } bool TextEntry::PasswordMode() const { return !visible_; } } nux-4.0.6+14.04.20140409/Nux/PangoText.h0000644000015301777760000000666512321344237017606 0ustar pbusernogroup00000000000000#ifndef PANGOTEXT_H #define PANGOTEXT_H #include "pango/pango.h" #include "pango/pango-fontmap.h" #include namespace nux { // taken from inkscape typedef struct { int gl; // glyph_id double x,y; // glyph position in the layout(nominal sizes, in the [0..1] range) bool char_start; // is this glyph the beginning of a letter(rtl is taken in account) bool word_start; // is this glyph the beginning of a word bool para_start; // is this glyph the beginning of a paragraph(for indentation) char uni_dir; // bidi orientation of the run containing this glyph int uni_st,uni_en; // start and end positions of the text corresponding to this glyph: you always have uni_st < uni_en PangoFont* font; // font this glyph uses(for bidi text, you need several fonts) } pango_glyph; class CairoGraphics; class PangoText: public View { public: PangoText(const char* text, NUX_FILE_LINE_PROTO); ~PangoText(); //! Set size of widget according to the text extent. /*! @param size_match_text If true, the widget size is set to match the size of the text on the screen. */ void SetSizeMatchText(bool size_match_text); //! Return true if the widget with changes to match the text width. bool GetSizeMatchText() const; void SetText(std::string text); void SetTextColor(Color textColor); sigc::signal sigTextChanged; sigc::signal sigTextColorChanged; protected: void PreLayoutManagement(); long PostLayoutManagement(long layoutResult); void Draw(GraphicsEngine& gfxContext, bool forceDraw); void DrawContent(GraphicsEngine& gfxContext, bool forceDraw); void GetTextExtents(int &width, int &height); typedef struct { int gl; // glyph_id double x,y; // glyph position in the layout(nominal sizes, in the [0..1] range) bool char_start; // is this glyph the beginning of a letter(rtl is taken in account) bool word_start; // is this glyph the beginning of a word bool para_start; // is this glyph the beginning of a paragraph(for indentation) char uni_dir; // bidi orientation of the run containing this glyph int uni_st,uni_en; // start and end positions of the text corresponding to this glyph // you always have uni_st < uni_en PangoFont* font; // font this glyph uses(for bidi text, you need several fonts) } pango_glyph; std::string _text; Color _textColor; CairoGraphics *_cairoGraphics; BaseTexture *_texture2D; int _pre_layout_width; int _pre_layout_height; bool _size_match_text; PangoLayout* _pango_layout; PangoContext* _pango_context; PangoFontMap* _pango_font_map; PangoFontDescription* _pango_font_desc; pango_glyph* _glyph_text; // glyph string computed for uni32_text int _glyph_length; // number of glyph in the glyph_text array void ComputeTextLayout(); void GetTextExtents(const char* font, int& width, int& height); void DrawText(void* cairo_context, int width, int height, Color color); void UpdateTextLayout(); }; } #endif // PANGOTEXT_H nux-4.0.6+14.04.20140409/Nux/LinearLayout.h0000644000015301777760000001033112321344237020266 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef LINEARLAYOUT_H #define LINEARLAYOUT_H #include "Layout.h" namespace nux { // The Space layout is a layout object that is used to create fixed or re-sizable empty space. class LinearLayout: public Layout { NUX_DECLARE_OBJECT_TYPE(LinearLayout, Layout); public: virtual void AddLayout(Layout *, unsigned int stretchFactor = 1, MinorDimensionPosition = eAbove, MinorDimensionSize extend = eFull, float percentage = 100.0f, LayoutPosition = NUX_LAYOUT_END); //! Add an object to the layout. /*! Add an object to the layout. A baseobject minor dimension with respect to a layout object is the dimension opposite to the layout flow. A baseobject major dimension with respect to a layout object is the dimension aligned with the layout flow. A layout object minor dimension is the dimension opposite to the layout flow. A layout object major dimension is the dimension aligned with the layout flow. Add an object to the layout. The added object get its size and position managed by the layout. When a baseobject is added with a stretches factor equal to 0, its major dimension assumes its minimum value. For instance, if the layout is a vertical layout and the added object has a stretch factor equal 0, then during the layout, the added object height will be set to its minimum value using ApplyMinHeight(). The positioning parameter controls how the layout will place the object within itself. A vertical layout object controls the horizontal positioning of its children baseobject, While an horizontal layout object controls the vertical positioning of its children baseobject. The extend parameter controls how much size the baseobject minor dimension gets from the layout minor dimension. See MinorDimensionSize. /param baseobject The object that is being added. /param stretchFactor This value controls how the layout object share space between its children baseobject. /param positioning Controls how the layout position the object. /param extend Controls the object minor dimension size. /param percentage Controls the object minor dimension size in percentage of the layout minor dimension size. /param index Controls the object position in the layout. */ virtual void AddView(Area *baseobject, unsigned int stretchFactor = 1, MinorDimensionPosition positioning = eAbove, MinorDimensionSize extend = eFull, float percentage = 100.0f, LayoutPosition index = NUX_LAYOUT_END); virtual void AddSpace(unsigned int width, unsigned int stretchFactor = 0, LayoutPosition index = NUX_LAYOUT_END); //! Deprecated. Use SetSpaceBetweenChildren; void SetHorizontalInternalMargin(int space); //! Deprecated. Use SetSpaceBetweenChildren; void SetVerticalInternalMargin(int space); //! Set the space between the children of a HLayout or VLayout. /*! Set the horizontal space between the children of the layout. In a VLayout, children of the layout are placed horizontally, on after the other, from left to right. This function set the space allowed between the children. Valid only for HLayout and VLayout. @param horizontal_space The horizontal space between the children of the layout. */ void SetSpaceBetweenChildren(int space); protected: LinearLayout(NUX_FILE_LINE_PROTO); virtual ~LinearLayout(); }; } #endif // LINEARLAYOUT_H nux-4.0.6+14.04.20140409/Nux/SpinBox.cpp0000644000015301777760000001616312321344237017604 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "TimerProc.h" #include "HLayout.h" #include "VLayout.h" #include "IntegerValidator.h" #include "SpinBox.h" namespace nux { const Color SPINBOX_BUTTON_COLOR = Color(0xFF4D4D4D); const Color SPINBOX_BUTTON_MOUSEOVER_COLOR = Color(0xFF222222); SpinBox::SpinBox(int Value, int Step, int MinValue, int MaxValue, NUX_FILE_LINE_DECL) : SpinBox_Logic(NUX_FILE_LINE_PARAM) , m_IntValidator(MinValue, MaxValue) , m_Step(Step) { hlayout = new HLayout(NUX_TRACKER_LOCATION); vlayout = new VLayout(NUX_TRACKER_LOCATION); m_EditLine->SetValidator(&m_IntValidator); m_EditLine->SetSuffix(""); m_EditLine->SetPrefix(""); m_EditLine->SetText(std::to_string((long long)m_IntValidator.GetMinimum())); m_EditLine->SetMinimumSize(1.5 * DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT); m_EditLine->SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); m_SpinnerUpBtn->SetMinimumSize(15, 10); m_SpinnerUpBtn->SetGeometry(Geometry(0, 0, 15, 10)); m_SpinnerDownBtn->SetMinimumSize(15, 10); m_SpinnerDownBtn->SetGeometry(Geometry(0, 0, 15, 10)); // Set the minimum size of this widget. // This is use by TextLineEditPropertyItem::GetItemBestHeight SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); hlayout->AddView(m_EditLine, 1); vlayout->AddView(m_SpinnerUpBtn, 1); vlayout->AddView(m_SpinnerDownBtn, 1); hlayout->AddLayout(vlayout, 0); SetLayout(hlayout); SetValue(Value); } SpinBox::~SpinBox() { } void SpinBox::InitializeWidgets() { } void SpinBox::InitializeLayout() { } void SpinBox::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); GetPainter().PaintBackground(graphics_engine, base); if (m_EditLine->IsMouseInside() || m_SpinnerUpBtn->IsMouseInside() || m_SpinnerDownBtn->IsMouseInside()) { GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerUpBtn->GetGeometry(), SPINBOX_BUTTON_MOUSEOVER_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopRight, false); GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerDownBtn->GetGeometry(), SPINBOX_BUTTON_MOUSEOVER_COLOR, eSHAPE_CORNER_ROUND4, eCornerBottomRight, false); } else { GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerUpBtn->GetGeometry(), SPINBOX_BUTTON_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopRight, false); GetPainter().PaintShapeCorner(graphics_engine, m_SpinnerDownBtn->GetGeometry(), SPINBOX_BUTTON_COLOR, eSHAPE_CORNER_ROUND4, eCornerBottomRight, false); } GeometryPositioning gp(eHACenter, eVACenter); Geometry GeoPo = ComputeGeometryPositioning(m_SpinnerUpBtn->GetGeometry(), GetTheme().GetImageGeometry(eSPINER_UP), gp); if (m_SpinnerUpBtn->IsMouseInside()) GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_UP); else GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_UP); gp.SetAlignment(eHACenter, eVACenter); GeoPo = ComputeGeometryPositioning(m_SpinnerDownBtn->GetGeometry(), GetTheme().GetImageGeometry(eSPINER_DOWN), gp); if (m_SpinnerDownBtn->IsMouseInside()) GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_DOWN); else GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eSPINER_DOWN); m_EditLine->QueueDraw(); } void SpinBox::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { m_EditLine->ProcessDraw(graphics_engine, force_draw); } void SpinBox::SetValue(int value) { m_iValue = m_IntValidator.GetClampedValue(value); m_EditLine->SetText(std::to_string((long long)m_iValue)); sigValueChanged.emit(this); sigValue.emit(m_iValue); QueueDraw(); } int SpinBox::GetValue() const { return m_iValue; } void SpinBox::SetStep(int i) { m_Step = i; if (m_Step <= 0) m_Step = 1; QueueDraw(); } int SpinBox::GetStep() const { return m_Step; } int SpinBox::GetMinValue() const { return m_IntValidator.GetMinimum(); } int SpinBox::GetMaxValue() const { return m_IntValidator.GetMaximum(); } void SpinBox::SetRange(int MinValue, int Maxvalue) { m_IntValidator.SetMinimum(MinValue); m_IntValidator.SetMaximum(Maxvalue); m_iValue = m_IntValidator.GetClampedValue(m_iValue); sigValueChanged.emit(this); sigValue.emit(m_iValue); QueueDraw(); } void SpinBox::ImplementIncrementBtn() { SetValue(m_iValue + m_Step); if (m_iValue < m_IntValidator.GetMaximum()) { if (m_UpTimerHandler.IsValid()) m_UpTimerHandler = GetTimer().AddOneShotTimer(100, m_UpTimerCallback, 0); else m_UpTimerHandler = GetTimer().AddOneShotTimer(800, m_UpTimerCallback, 0); QueueDraw(); } sigValueChanged.emit(this); sigIncrement.emit(this); sigValue.emit(m_iValue); } void SpinBox::ImplementDecrementBtn() { SetValue(m_iValue - m_Step); if (m_iValue > m_IntValidator.GetMinimum()) { if (m_DownTimerHandler.IsValid()) m_DownTimerHandler = GetTimer().AddOneShotTimer(100, m_DownTimerCallback, 0); else m_DownTimerHandler = GetTimer().AddOneShotTimer(800, m_DownTimerCallback, 0); QueueDraw(); } sigValueChanged.emit(this); sigDecrement.emit(this); sigValue.emit(m_iValue); } void SpinBox::ImplementValidateEntry() { double ret = 0; ret = CharToDouble(m_EditLine->GetCleanText().c_str()); { m_iValue = m_IntValidator.GetClampedValue(ret); m_EditLine->SetText(std::to_string((long long)m_iValue)); sigValueChanged.emit(this); sigValue.emit(m_iValue); // // if (m_iValue < m_IntValidator.GetMinimum()) // { // m_iValue = m_IntValidator.GetMinimum(); // m_EditLine->SetText(std::string::Printf("%d", m_iValue)); // } // if (m_iValue > m_IntValidator.GetMaximum()) // { // m_iValue = m_IntValidator.GetMaximum(); // m_EditLine->SetText(std::string::Printf("%d", m_iValue)); // } } // else // { // m_EditLine->SetText(std::string::Printf("%d", m_iValue)); // sigValueChanged.emit(this); // sigValue.emit(m_iValue); // } } } nux-4.0.6+14.04.20140409/Nux/TimelineEasings.h0000644000015301777760000000221712321344237020742 0ustar pbusernogroup00000000000000#ifndef TIMELINEEASINGS_H #define TIMELINEEASINGS_H namespace nux { class TimelineEaseInOutQuad : public Timeline { public: TimelineEaseInOutQuad(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL); double GetEasing(); }; class TimelineEaseInQuad : public Timeline { public: TimelineEaseInQuad(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL); double GetEasing(); }; class TimelineEaseOutQuad : public Timeline { public: TimelineEaseOutQuad(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL); double GetEasing(); }; class TimelineEaseInOutCubic : public Timeline { public: TimelineEaseInOutCubic(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL); double GetEasing(); }; class TimelineEaseInCubic : public Timeline { public: TimelineEaseInCubic(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL); double GetEasing(); }; class TimelineEaseOutCubic : public Timeline { public: TimelineEaseOutCubic(unsigned int msecs, const char *Caption, NUX_FILE_LINE_DECL); double GetEasing(); }; }; #endif // TIMELINEEASINGS_H nux-4.0.6+14.04.20140409/Nux/CoverflowItem.h0000755000015301777760000000243612321344237020455 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2012 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Jason Smith */ #ifndef NUX_COVERFLOWITEM_H #define NUX_COVERFLOWITEM_H #include #include #include "Nux.h" #include namespace nux { class CoverflowItem : public InitiallyUnownedObject { NUX_DECLARE_OBJECT_TYPE(CoverflowItem, InitiallyUnownedObject); public: typedef ObjectPtr Ptr; CoverflowItem(std::string const& name); Property name; Property > text_texture; virtual ObjectPtr GetTexture() const = 0; virtual void Activate(int /* button */) {} }; } #endif nux-4.0.6+14.04.20140409/Nux/WindowCompositor.cpp0000644000015301777760000026436312321344237021557 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2010,2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "WindowCompositor.h" #include "NuxCore/Logger.h" #include "NuxGraphics/GLError.h" #include "WindowThread.h" #include "BaseWindow.h" #include "InputAreaProximity.h" #if !defined(NUX_MINIMAL) #include "MenuPage.h" #endif #include "PaintLayer.h" #include "Painter.h" #include "Layout.h" #include "NuxGraphics/FontTexture.h" namespace nux { DECLARE_LOGGER(logger, "nux.window"); WindowCompositor::WindowCompositor(WindowThread* window_thread) : draw_reference_fbo_(0) , read_reference_fbo_(0) , window_thread_(window_thread) , currently_rendering_windows_(nullptr) , current_global_clip_rect_(nullptr) { m_OverlayWindow = NULL; _tooltip_window = NULL; m_TooltipArea = NULL; m_Background = NULL; _tooltip_window = NULL; OverlayDrawingCommand = NULL; m_CurrentWindow = NULL; m_MenuWindow = NULL; _always_on_front_window = NULL; inside_event_cycle_ = false; inside_rendering_cycle_ = false; _dnd_area = NULL; _starting_menu_event_cycle = false; _menu_is_active = false; on_menu_closure_continue_with_event_ = false; _mouse_position_on_owner = Point(0, 0); platform_support_for_depth_texture_ = GetGraphicsDisplay()->GetGpuDevice()->GetGpuInfo().Support_Depth_Buffer(); m_FrameBufferObject = GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject(); // Do not leave the Fbo binded. Deactivate it. m_FrameBufferObject->Deactivate(); // At this stage, the size of the window may not be known yet. // FormatRenderTargets will be called the first time runtime gets into WindowThread::ExecutionLoop m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(2, 2, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); if (platform_support_for_depth_texture_) { m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(2, 2, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } #if !defined(NUX_MINIMAL) _mouse_over_menu_page = NULL; _mouse_owner_menu_page = NULL; _menu_chain = NULL; _menu_chain = new std::list; #endif m_MenuRemoved = false; m_Background = new ColorLayer(Color(0xFF4D4D4D)); #ifdef NUX_GESTURES_SUPPORT gesture_broker_.reset(new DefaultGestureBroker(this)); #endif } void WindowCompositor::BeforeDestructor() { key_focus_area_ = NULL; } WindowCompositor::~WindowCompositor() { _window_to_texture_map.clear(); m_FrameBufferObject.Release(); m_MainColorRT.Release(); m_MainDepthRT.Release(); _view_window_list.clear(); _modal_view_window_list.clear(); #if !defined(NUX_MINIMAL) _menu_chain->clear(); delete _menu_chain; #endif delete m_Background; } WindowCompositor::RenderTargetTextures& WindowCompositor::GetWindowBuffer(BaseWindow* window) { static RenderTargetTextures invalid; std::map< BaseWindow*, RenderTargetTextures>::iterator it = _window_to_texture_map.find(window); if (it != _window_to_texture_map.end()) { return it->second; } LOG_WARN(logger) << "No RenderTargetTextures for window."; return invalid; } void WindowCompositor::RegisterWindow(BaseWindow* window) { LOG_DEBUG_BLOCK(logger); if (!window) return; WindowList::iterator it = find(_view_window_list.begin(), _view_window_list.end(), window); if (it == _view_window_list.end()) { _view_window_list.push_front(WeakBaseWindowPtr(window)); RenderTargetTextures rt; // Don't size the texture to the dimension of the window yet. this will be done later. auto device = GetGraphicsDisplay()->GetGpuDevice(); rt.color_rt = device->CreateSystemCapableDeviceTexture(2, 2, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); rt.depth_rt = device->CreateSystemCapableDeviceTexture(2, 2, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); _window_to_texture_map[window] = rt; window->object_destroyed.connect(sigc::mem_fun(this, &WindowCompositor::UnRegisterWindow)); } } void WindowCompositor::UnRegisterWindow(Object* obj) { LOG_DEBUG_BLOCK(logger); WeakBaseWindowPtr window(obj); if (window.IsNull()) return; WindowList::iterator it = find(_view_window_list.begin(), _view_window_list.end(), window); if (it == _view_window_list.end()) { // look for a weak pointer that has been cleared out. it = find(_view_window_list.begin(), _view_window_list.end(), WeakBaseWindowPtr()); } if (it != _view_window_list.end()) _view_window_list.erase(it); _window_to_texture_map.erase(window.GetPointer()); } //! Get Mouse position relative to the top left corner of the window. Point WindowCompositor::GetMousePosition() { return _mouse_position; } void WindowCompositor::ResetMousePointerAreas() { mouse_over_area_ = NULL; SetMouseOwnerArea(NULL); #if !defined(NUX_MINIMAL) _mouse_over_menu_page = NULL; _mouse_owner_menu_page = NULL; #endif } void WindowCompositor::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type, ObjectWeakPtr& area_under_mouse_pointer) { WeakBaseWindowPtr window; GetAreaUnderMouse(mouse_position, event_type, area_under_mouse_pointer, window); } void WindowCompositor::GetAreaUnderMouse(const Point& mouse_position, NuxEventType event_type, ObjectWeakPtr& area_under_mouse_pointer, WeakBaseWindowPtr& window) { window = NULL; area_under_mouse_pointer = NULL; // Go through the list of BaseWindo and find the first area over which the // mouse pointer is. for (auto const& window_it : _view_window_list) { // Since the mouse is really an input-level thing, we want to know // if the underlying input window is enabled or if the window is // visible if (!window_it.IsValid()) continue; if (window_it->InputWindowEnabled() || window_it->IsVisible()) { Area* area = window_it->FindAreaUnderMouse(mouse_position, event_type); if (area) { area_under_mouse_pointer = static_cast(area); window = window_it; return; } } } // If area_under_mouse_pointer is NULL, then the mouse pointer is not over // any of the BaseWindow. Try the main window layout. if (!area_under_mouse_pointer.IsValid()) { Layout* main_window_layout = window_thread_->GetLayout(); if (main_window_layout) area_under_mouse_pointer = static_cast(main_window_layout->FindAreaUnderMouse(mouse_position, event_type)); } } void WindowCompositor::SetMouseOwnerArea(InputArea* area) { if (mouse_owner_area_ == area) return; mouse_owner_area_ = area; dnd_safety_x_ = 0; dnd_safety_y_ = 0; } ObjectWeakPtr const& WindowCompositor::GetMouseOwnerArea() const { return mouse_owner_area_; } void WindowCompositor::DndEventCycle(Event& event) { if (event.type == NUX_DND_MOVE) { ObjectWeakPtr hit_area; FindAreaUnderMouse(Point(event.x, event.y), event.type, hit_area); if (hit_area.IsValid()) { SetDnDArea(hit_area.GetPointer()); hit_area->HandleDndMove(event); } else { ResetDnDArea(); } } else if (event.type == NUX_DND_ENTER_WINDOW) { // do nothing for now } else if (event.type == NUX_DND_LEAVE_WINDOW) { ResetDnDArea(); } else if (event.type == NUX_DND_DROP) { InputArea* current_dnd_area = GetDnDArea(); if (current_dnd_area->GetAbsoluteGeometry().IsPointInside(event.x - event.x_root, event.y - event.y_root)) current_dnd_area->HandleDndDrop(event); } } void WindowCompositor::UpdateKeyNavFocusOnMouseDown() { /* In the case of a mouse down event, if there is currently a keyboard event receiver and it is different from the area returned by FindAreaUnderMouse, then stop that receiver from receiving anymore keyboard events and switch make mouse_over_area_ the new receiver(if it accept keyboard events). */ if (mouse_over_area_.IsValid() && mouse_over_area_ != GetKeyFocusArea() && mouse_over_area_->AcceptKeyNavFocusOnMouseDown()) { InputArea* grab_area = GetKeyboardGrabArea(); if (grab_area) { if (mouse_over_area_->IsChildOf(grab_area) /*&& mouse_over_area_->AcceptKeyboardEvent()*/) { SetKeyFocusArea(mouse_over_area_.GetPointer()); } else { SetKeyFocusArea(grab_area); } } else { SetKeyFocusArea(mouse_over_area_.GetPointer()); } } } void WindowCompositor::TrackMouseMovement(const Event &event, bool area_under_mouse_changed) { if (!mouse_owner_area_.IsValid()) { if (mouse_over_area_.IsValid()) { if (event.type == NUX_MOUSE_MOVE) { Geometry hit_view_geo = mouse_over_area_->GetAbsoluteGeometry(); int hit_view_x = event.x - hit_view_geo.x; int hit_view_y = event.y - hit_view_geo.y; int dx = event.x - _mouse_position.x; int dy = event.y - _mouse_position.y; mouse_over_area_->EmitMouseMoveSignal(hit_view_x, hit_view_y, area_under_mouse_changed ? 0 : dx, area_under_mouse_changed ? 0 : dy, event.GetMouseState(), event.GetKeyState()); } } } else { if (event.type == NUX_MOUSE_PRESSED || event.type == NUX_MOUSE_DOUBLECLICK) { // We just got a new mouse owner. Let's update the mouse position on him. Geometry const& mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry(); int mouse_owner_x = event.x - mouse_owner_geo.x; int mouse_owner_y = event.y - mouse_owner_geo.y; _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y); } else if (event.type == NUX_MOUSE_MOVE) { Geometry const& mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry(); int mouse_owner_x = event.x - mouse_owner_geo.x; int mouse_owner_y = event.y - mouse_owner_geo.y; int dx = mouse_owner_x - _mouse_position_on_owner.x; int dy = mouse_owner_y - _mouse_position_on_owner.y; if (mouse_owner_area_->_dnd_enabled_as_source) { dnd_safety_x_ += dx; dnd_safety_y_ += dy; if (abs(dnd_safety_y_) > 30 || abs(dnd_safety_x_) > 30) { #if defined(DRAG_AND_DROP_SUPPORTED) mouse_owner_area_->StartDragAsSource(); #endif ResetMousePointerAreas(); return; } } else { mouse_owner_area_->EmitMouseDragSignal(mouse_owner_x, mouse_owner_y, dx, dy, event.GetMouseState(), event.GetKeyState()); } _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y); } else if (event.type == NUX_MOUSE_RELEASED) { _mouse_position_on_owner = Point(0, 0); } } _mouse_position = Point(event.x, event.y); } bool WindowCompositor::UpdateWhatAreaIsUnderMouse(const Event& event) { ObjectWeakPtr new_area_under_mouse; ObjectWeakPtr old_mouse_over_area = mouse_over_area_; if (mouse_owner_area_.IsValid()) { FindAreaUnderMouse(Point(event.x, event.y), event.type, new_area_under_mouse); } else { // Look for the area below the mouse pointer in the BaseWindow. Area* pointer_grab_area = GetPointerGrabArea(); if (pointer_grab_area) { // If there is a pending mouse pointer grab, test that area only new_area_under_mouse = NUX_STATIC_CAST(InputArea*, pointer_grab_area->FindAreaUnderMouse(Point(event.x, event.y), event.type)); } else { FindAreaUnderMouse(Point(event.x, event.y), event.type, new_area_under_mouse); } } if (!mouse_owner_area_.IsValid()) { if (event.type == NUX_WINDOW_MOUSELEAVE) { if (mouse_over_area_.IsValid()) { // The area where the mouse was in the previous cycle and the area // returned by GetAreaUnderMouse are different. // The area from the previous cycle receive a "mouse leave signal". Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry(); int x = event.x - geo.x; int y = event.y - geo.y; mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState()); mouse_over_area_ = NULL; } } if (new_area_under_mouse.IsValid()) { if (new_area_under_mouse != mouse_over_area_) { if (mouse_over_area_.IsValid()) { // The area where the mouse was in the previous cycle and the area // returned by FindAreaUnderMouse are different. // The area from the previous cycle receive a "mouse leave signal". Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry(); int x = event.x - geo.x; int y = event.y - geo.y; mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState()); } // The area we found under the mouse pointer receives a "mouse enter signal". mouse_over_area_ = new_area_under_mouse; if (mouse_over_area_.IsValid() && mouse_over_area_ != GetKeyFocusArea() && mouse_over_area_->AcceptKeyNavFocusOnMouseEnter()) { SetKeyFocusArea(mouse_over_area_.GetPointer()); } Geometry hit_view_geo = new_area_under_mouse->GetAbsoluteGeometry(); int hit_view_x = event.x - hit_view_geo.x; int hit_view_y = event.y - hit_view_geo.y; mouse_over_area_->EmitMouseEnterSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState()); } } else { if (mouse_over_area_.IsValid()) { // Mouse wheel events are stationary. The mouse can remain inside an // area while the mouse wheel is spinning. // This shouldn't qualify as a mouse leave event. if (event.type != NUX_MOUSE_WHEEL) { Geometry const& geo = mouse_over_area_->GetAbsoluteGeometry(); int x = event.x - geo.x; int y = event.y - geo.y; mouse_over_area_->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState()); } } mouse_over_area_ = NULL; } } else { // Context: The left mouse button down over an area. All events goes to // that area. Geometry const& mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry(); int mouse_owner_x = event.x - mouse_owner_geo.x; int mouse_owner_y = event.y - mouse_owner_geo.y; if (event.type == NUX_MOUSE_MOVE) { if (mouse_over_area_ == mouse_owner_area_ && new_area_under_mouse != mouse_owner_area_) { mouse_owner_area_->EmitMouseLeaveSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); mouse_over_area_ = new_area_under_mouse; } else if (mouse_over_area_ != mouse_owner_area_ && new_area_under_mouse == mouse_owner_area_) { mouse_owner_area_->EmitMouseEnterSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); mouse_over_area_ = new_area_under_mouse; } } else if (event.type == NUX_MOUSE_RELEASED) { mouse_over_area_ = new_area_under_mouse; } } return mouse_over_area_ != old_mouse_over_area; } void WindowCompositor::ProcessMouseWheelEvent(Event& event) { if (mouse_over_area_.IsValid()) { Geometry hit_view_geo = mouse_over_area_->GetAbsoluteGeometry(); int hit_view_x = event.x - hit_view_geo.x; int hit_view_y = event.y - hit_view_geo.y; mouse_over_area_->EmitMouseWheelSignal(hit_view_x, hit_view_y, event.wheel_delta, event.GetMouseState(), event.GetKeyState()); } } void WindowCompositor::UpdateMouseOwner(const Event& event, bool area_under_mouse_changed) { if (!mouse_owner_area_.IsValid()) { if (mouse_over_area_.IsValid()) { Geometry hit_view_geo = mouse_over_area_->GetAbsoluteGeometry(); int hit_view_x = event.x - hit_view_geo.x; int hit_view_y = event.y - hit_view_geo.y; if (event.type == NUX_MOUSE_PRESSED || event.type == NUX_MOUSE_DOUBLECLICK) { SetMouseOwnerArea(mouse_over_area_.GetPointer()); UpdateKeyNavFocusOnMouseDown(); if (event.type == NUX_MOUSE_DOUBLECLICK && mouse_over_area_->DoubleClickEnabled() && !area_under_mouse_changed) { mouse_over_area_->EmitMouseDoubleClickSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState()); } else { mouse_over_area_->EmitMouseDownSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState()); } } else if (event.type == NUX_MOUSE_RELEASED) { // We only get a NUX_MOUSE_RELEASED event when the mouse was pressed // over another area and released here. There are a few situations that // can cause mouse_owner_area_ to be NULL on a NUX_MOUSE_RELEASED event: // - The mouse down event happens on a area. That area is set into // mouse_owner_area_ // Then the area is destroyed, before the mouse is released // - The mouse down event happens. Then a call to AddGrabPointer triggers // a call to ResetMousePointerAreas. mouse_owner_area_ is then set to // NULL. mouse_over_area_->EmitMouseUpSignal(hit_view_x, hit_view_y, event.GetMouseState(), event.GetKeyState()); } } else { Area* pointer_grab_area = GetPointerGrabArea(); if (event.type == NUX_MOUSE_PRESSED && pointer_grab_area) { Geometry geo = pointer_grab_area->GetAbsoluteGeometry(); int x = event.x - geo.x; int y = event.y - geo.y; NUX_STATIC_CAST(InputArea*, pointer_grab_area)-> EmitMouseDownOutsideArea(x, y, event.GetMouseState(), event.GetKeyState()); } } } else { if (event.type == NUX_MOUSE_RELEASED) { Geometry const& mouse_owner_geo = mouse_owner_area_->GetAbsoluteGeometry(); int mouse_owner_x = event.x - mouse_owner_geo.x; int mouse_owner_y = event.y - mouse_owner_geo.y; mouse_owner_area_->EmitMouseUpSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); if (mouse_owner_area_.IsValid() && mouse_over_area_ == mouse_owner_area_ && (!mouse_over_area_->DoubleClickEnabled() || (event.mouse_state & NUX_STATE_FIRST_EVENT) != 0)) { mouse_owner_area_->EmitMouseClickSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); } SetMouseOwnerArea(NULL); } } } void WindowCompositor::FindAncestorInterestedInChildMouseEvents(Area *area) { if (!area) return; Area *parent = area->GetParentObject(); if (!parent) return; if (parent->IsInputArea()) { InputArea *parent_input_area = static_cast(parent); if (parent_input_area->IsTrackingChildMouseEvents()) interested_mouse_owner_ancestor_ = parent_input_area; } if (!interested_mouse_owner_ancestor_.IsValid()) { // Keep searching... FindAncestorInterestedInChildMouseEvents(parent); } } void WindowCompositor::UpdateEventTrackingByMouseOwnerAncestor(const Event& event) { if (event.type == NUX_MOUSE_PRESSED || event.type == NUX_MOUSE_DOUBLECLICK) FindAncestorInterestedInChildMouseEvents(mouse_owner_area_.GetPointer()); if (!interested_mouse_owner_ancestor_.IsValid()) return; bool wants_ownership = interested_mouse_owner_ancestor_->ChildMouseEvent(event); if (wants_ownership) { mouse_owner_area_->EmitMouseCancelSignal(); SetMouseOwnerArea(interested_mouse_owner_ancestor_.GetPointer()); _mouse_position_on_owner = Point(event.x - mouse_owner_area_->GetAbsoluteX(), event.y - mouse_owner_area_->GetAbsoluteY()); interested_mouse_owner_ancestor_ = NULL; } if (event.type == NUX_MOUSE_RELEASED) interested_mouse_owner_ancestor_ = NULL; } void WindowCompositor::MouseEventCycle(Event& event) { // Checks the area_proximities_ list for any mouse near/beyond signals if (event.type == NUX_MOUSE_MOVE || event.type == NUX_WINDOW_MOUSELEAVE) { CheckMouseNearArea(event); } // Updates mouse_over_area_ and emits mouse_enter and mouse_leave signals // accordingly. bool area_under_mouse_changed = UpdateWhatAreaIsUnderMouse(event); // Updates mouse_owner_area_ and emits mouse_down, mouse_up, // mouse_click and mouse_double_click accordingly. UpdateMouseOwner(event, area_under_mouse_changed); // Keeps track of mouse movement and emits mouse_move and mouse_drag // accordingly. TrackMouseMovement(event, area_under_mouse_changed); if (event.type == NUX_MOUSE_WHEEL) ProcessMouseWheelEvent(event); // Feed the appropriate InputArea::ChildMouseEvent() and switch mouse // ownership (including the emission of mouse_cancel) if asked to. UpdateEventTrackingByMouseOwnerAncestor(event); } #if !defined(NUX_MINIMAL) void WindowCompositor::MenuEventCycle(Event& event) { // _mouse_owner_menu_page: the menu page that has the mouse down // _mouse_over_menu_page: the menu page that is directly below the mouse pointer _mouse_position = Point(event.x, event.y); if (_mouse_owner_menu_page == NULL) { if ((event.type == NUX_MOUSE_PRESSED) || (event.type == NUX_MOUSE_RELEASED) || (event.type == NUX_MOUSE_MOVE) || (event.type == NUX_MOUSE_DOUBLECLICK) || (event.type == NUX_MOUSE_WHEEL)) { // Find the MenuPage under the mouse MenuPage* hit_menu_page = NULL; std::list::iterator menu_it; for (menu_it = _menu_chain->begin(); menu_it != _menu_chain->end(); ++menu_it) { // The leaf of the menu chain is in the front of the list. hit_menu_page = NUX_STATIC_CAST(MenuPage*, (*menu_it)->FindAreaUnderMouse(Point(event.x, event.y), event.type)); if (hit_menu_page) { break; } } Geometry hit_menu_page_geo; int hit_menu_page_x = 0; int hit_menu_page_y = 0; if (hit_menu_page) { hit_menu_page_geo = hit_menu_page->GetAbsoluteGeometry(); hit_menu_page_x = event.x - hit_menu_page_geo.x; hit_menu_page_y = event.y - hit_menu_page_geo.y; } if (hit_menu_page && (event.type == NUX_MOUSE_RELEASED)) { hit_menu_page->EmitMouseUpSignal(hit_menu_page_x, hit_menu_page_y, event.GetMouseState(), event.GetKeyState()); (*_menu_chain->begin())->sigClosingMenu(*_menu_chain->begin()); (*_menu_chain->begin())->StopMenu(); } else if (hit_menu_page && (event.type == NUX_MOUSE_MOVE)) { if (hit_menu_page != _mouse_over_menu_page) { if (_mouse_over_menu_page != 0) { Geometry geo = _mouse_over_menu_page->GetAbsoluteGeometry(); int x = event.x - geo.x; int y = event.y - geo.y; _mouse_over_menu_page->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState()); } _mouse_over_menu_page = hit_menu_page; _mouse_over_menu_page->EmitMouseEnterSignal(hit_menu_page_x, hit_menu_page_y, event.GetMouseState(), event.GetKeyState()); } _mouse_over_menu_page->EmitMouseMoveSignal(hit_menu_page_x, hit_menu_page_y, event.dx, event.dy, event.GetMouseState(), event.GetKeyState()); } else if (hit_menu_page && ((event.type == NUX_MOUSE_PRESSED) || (event.type == NUX_MOUSE_DOUBLECLICK))) { if (!hit_menu_page->DoubleClickEnabled()) { } if (_mouse_over_menu_page && (hit_menu_page != _mouse_over_menu_page)) { Geometry geo = _mouse_over_menu_page->GetAbsoluteGeometry(); int x = event.x - geo.x; int y = event.y - geo.y; _mouse_over_menu_page->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState()); } _mouse_over_menu_page = hit_menu_page; _mouse_owner_menu_page = hit_menu_page; _mouse_position_on_owner = Point(hit_menu_page_x, hit_menu_page_y); if (_mouse_over_menu_page != GetKeyFocusArea()) { if (_mouse_over_menu_page->AcceptKeyboardEvent()) SetKeyFocusArea(_mouse_over_menu_page); } _mouse_over_menu_page->EmitMouseDownSignal(hit_menu_page_x, hit_menu_page_y, event.GetMouseState(), event.GetKeyState()); } else if (hit_menu_page && (event.type == NUX_MOUSE_WHEEL)) { hit_menu_page->EmitMouseWheelSignal(hit_menu_page_x, hit_menu_page_y, event.wheel_delta, event.GetMouseState(), event.GetKeyState()); } else if (hit_menu_page == NULL) { if (_mouse_over_menu_page) { Geometry geo = _mouse_over_menu_page->GetAbsoluteGeometry(); int x = event.x - geo.x; int y = event.y - geo.y; _mouse_over_menu_page->EmitMouseLeaveSignal(x, y, event.GetMouseState(), event.GetKeyState()); } if (event.type == NUX_MOUSE_PRESSED || event.type == NUX_MOUSE_DOUBLECLICK) { (*_menu_chain->begin())->sigClosingMenu(*_menu_chain->begin()); (*_menu_chain->begin())->StopMenu(); on_menu_closure_continue_with_event_ = (*_menu_chain->begin())->OnClosureContinueEventCycle(); } _mouse_over_menu_page = 0; } } } else { // We should never get here for a NUX_MOUSE_PRESSED event. MenuPage* hit_menu_page = NULL; std::list::iterator menu_it; for (menu_it = _menu_chain->begin(); menu_it != _menu_chain->end(); ++menu_it) { // The leaf of the menu chain is in the front of the list. hit_menu_page = NUX_STATIC_CAST(MenuPage*, (*menu_it)->FindAreaUnderMouse(Point(event.x, event.y), event.type)); if (hit_menu_page) { break; } } Geometry mouse_owner_geo = _mouse_owner_menu_page->GetAbsoluteGeometry(); int mouse_owner_x = event.x - mouse_owner_geo.x; int mouse_owner_y = event.y - mouse_owner_geo.y; // the mouse is down over a view if (event.type == NUX_MOUSE_MOVE) { int dx = mouse_owner_x - _mouse_position_on_owner.x; int dy = mouse_owner_y - _mouse_position_on_owner.y; _mouse_owner_menu_page->EmitMouseDragSignal(mouse_owner_x, mouse_owner_y, dx, dy, event.GetMouseState(), event.GetKeyState()); if ((_mouse_over_menu_page == _mouse_owner_menu_page) && (hit_menu_page != _mouse_owner_menu_page)) { _mouse_owner_menu_page->EmitMouseLeaveSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); _mouse_over_menu_page = hit_menu_page; } else if ((_mouse_over_menu_page != _mouse_owner_menu_page) && (hit_menu_page == _mouse_owner_menu_page)) { _mouse_owner_menu_page->EmitMouseEnterSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); _mouse_over_menu_page = _mouse_owner_menu_page; } _mouse_position_on_owner = Point(mouse_owner_x, mouse_owner_y); } else if (event.type == NUX_MOUSE_RELEASED) { _mouse_owner_menu_page->EmitMouseUpSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); if (hit_menu_page == _mouse_owner_menu_page) { _mouse_owner_menu_page->EmitMouseClickSignal(mouse_owner_x, mouse_owner_y, event.GetMouseState(), event.GetKeyState()); _mouse_over_menu_page = _mouse_owner_menu_page; } else { _mouse_over_menu_page = hit_menu_page; } (*_menu_chain->begin())->sigClosingMenu(*_menu_chain->begin()); (*_menu_chain->begin())->StopMenu(); _mouse_owner_menu_page = NULL; _mouse_position_on_owner = Point(0, 0); } } } #endif void WindowCompositor::FindKeyFocusArea(NuxEventType event_type, unsigned int key_symbol, unsigned int special_keys_state, ObjectWeakPtr& key_focus_area, WeakBaseWindowPtr& window) { key_focus_area = NULL; window = NULL; // Go through the list of BaseWindos and find the first area over which the mouse pointer is. for (auto const& window_it : _view_window_list) { if (window_it.IsValid() && window_it->IsVisible()) { key_focus_area = NUX_STATIC_CAST(InputArea*, window_it->FindKeyFocusArea(event_type, key_symbol, special_keys_state)); if (key_focus_area.IsValid()) { // We have found an area. We are going to exit the while loop. window = window_it; break; } } } // If key_focus_area is NULL, then try the main window layout. if (!key_focus_area.IsValid()) { Layout* main_window_layout = window_thread_->GetLayout(); if (main_window_layout) { key_focus_area = NUX_STATIC_CAST(InputArea*, main_window_layout->FindKeyFocusArea(event_type, key_symbol, special_keys_state)); } } } void WindowCompositor::FindKeyFocusAreaFrom(NuxEventType event_type, unsigned int key_symbol, unsigned int special_keys_state, InputArea* root_search_area, ObjectWeakPtr& key_focus_area, WeakBaseWindowPtr& window) { key_focus_area = NULL; window = NULL; if (root_search_area == NULL) { return; } key_focus_area = NUX_STATIC_CAST(InputArea*, root_search_area->FindKeyFocusArea(event_type, key_symbol, special_keys_state)); if (key_focus_area.IsValid()) { window = NUX_STATIC_CAST(BaseWindow*, root_search_area->GetTopLevelViewWindow()); } } void WindowCompositor::SendKeyEvent(InputArea* input_area, NuxEventType event_type, unsigned int key_sym, unsigned long x11_key_code, unsigned long special_keys_state, const char* text, int key_repeat_count) { if (input_area == NULL) return; if (event_type == NUX_KEYDOWN) { input_area->EmitKeyEventSignal(event_type, key_sym, special_keys_state, text, key_repeat_count); } else if (event_type == NUX_KEYUP) { input_area->EmitKeyUpSignal(key_sym, x11_key_code, special_keys_state); } } void WindowCompositor::KeyboardEventCycle(Event& event) { InputArea* keyboard_event_grab_view = GetKeyboardGrabArea(); ObjectWeakPtr focus_area; // The view under the mouse WeakBaseWindowPtr base_window; // The BaseWindow below the mouse pointer. if (keyboard_event_grab_view) { // There is a keyboard grab. // Find the key focus area, under the keyboard grab area. That is to say, the key focus area is in the widget tree // whose root is the keyboard grab area. This phase is known as the capture phase. FindKeyFocusAreaFrom(event.type, event.GetKeySym(), event.GetKeyState(), keyboard_event_grab_view, focus_area, base_window); } else { FindKeyFocusArea(event.type, event.GetKeySym(), event.GetKeyState(), focus_area, base_window); } KeyNavDirection direction = KEY_NAV_NONE; if (event.type == EVENT_KEY_DOWN) { switch(event.GetKeySym()) { case NUX_VK_UP: direction = KEY_NAV_UP; break; case NUX_VK_DOWN: direction = KEY_NAV_DOWN; break; case NUX_VK_LEFT: direction = KEY_NAV_LEFT; break; case NUX_VK_RIGHT: direction = KEY_NAV_RIGHT; break; case NUX_VK_LEFT_TAB: direction = KEY_NAV_TAB_PREVIOUS; break; case NUX_VK_TAB: direction = KEY_NAV_TAB_NEXT; break; case NUX_VK_ENTER: case NUX_KP_ENTER: // Not sure if Enter should be a navigation key direction = KEY_NAV_ENTER; break; default: direction = KEY_NAV_NONE; break; } } if (focus_area.IsValid()) { SetKeyFocusArea(focus_area.GetPointer(), direction); } else { SetKeyFocusArea(NULL, KEY_NAV_NONE); } if (key_focus_area_.IsValid()) { if (key_focus_area_->InspectKeyEvent(event.type, event.GetKeySym(), event.GetText())) { SendKeyEvent(key_focus_area_.GetPointer(), event.type, event.GetKeySym(), #if defined(NUX_OS_WINDOWS) event.win32_keycode, #elif defined(USE_X11) event.x11_keycode, #else 0, #endif event.GetKeyState(), event.GetText(), event.GetKeyRepeatCount()); } else if (direction == KEY_NAV_NONE) { Area* parent = key_focus_area_->GetParentObject(); while (parent && !parent->InspectKeyEvent(event.type, event.GetKeySym(), event.GetText())) { parent = parent->GetParentObject(); } if (parent) { SendKeyEvent(static_cast(parent), event.type, event.GetKeySym(), #if defined(NUX_OS_WINDOWS) event.win32_keycode, #elif defined(USE_X11) event.x11_keycode, #else 0, #endif event.GetKeyState(), event.GetText(), event.GetKeyRepeatCount()); } } else if (event.type == NUX_KEYDOWN) { if (direction == KEY_NAV_ENTER) { if (key_focus_area_.IsValid() && key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType)) { // Signal emitted from the WindowCompositor. key_nav_focus_activate.emit(key_focus_area_.GetPointer()); // Signal emitted from the area itsel. key_focus_area_->key_nav_focus_activate.emit(key_focus_area_.GetPointer()); } } else { InputArea* key_nav_focus = NULL; Area* parent = key_focus_area_->GetParentObject(); if (parent) key_nav_focus = NUX_STATIC_CAST(InputArea*, parent->KeyNavIteration(direction)); while (key_nav_focus == NULL && parent != NULL) { parent = parent->GetParentObject(); if (parent) key_nav_focus = NUX_STATIC_CAST(InputArea*, parent->KeyNavIteration(direction)); } if (key_nav_focus) { SetKeyFocusArea(key_nav_focus, direction); } } } } else { // The event is for the Application itself } } // NUXTODO: rename as EventCycle void WindowCompositor::ProcessEvent(Event& event) { inside_event_cycle_ = true; if (((event.type >= NUX_MOUSE_PRESSED) && (event.type <= NUX_MOUSE_WHEEL)) || (event.type == NUX_WINDOW_MOUSELEAVE)) { #if !defined(NUX_MINIMAL) bool menu_active = false; if (!_menu_chain->empty()) { menu_active = true; MenuEventCycle(event); CleanMenu(); } if ((menu_active && on_menu_closure_continue_with_event_) || !(menu_active)) #endif { MouseEventCycle(event); } on_menu_closure_continue_with_event_ = false; if (_starting_menu_event_cycle) { _starting_menu_event_cycle = false; } } else if ((event.type >= NUX_KEYDOWN) && (event.type <= NUX_KEYUP)) { KeyboardEventCycle(event); } else if ((event.type >= NUX_DND_MOVE) && (event.type <= NUX_DND_LEAVE_WINDOW)) { DndEventCycle(event); } #ifdef NUX_GESTURES_SUPPORT else if (event.type == EVENT_GESTURE_BEGIN) { gesture_broker_->ProcessGestureBegin(static_cast(event)); } else if (event.type == EVENT_GESTURE_UPDATE) { gesture_broker_->ProcessGestureUpdate(static_cast(event)); } else if (event.type == EVENT_GESTURE_END) { gesture_broker_->ProcessGestureEnd(static_cast(event)); } #endif inside_event_cycle_ = false; } void WindowCompositor::StartModalWindow(WeakBaseWindowPtr window) { if (window == 0) return; WindowList::iterator it = find(_modal_view_window_list.begin(), _modal_view_window_list.end(), window); if (it == _modal_view_window_list.end()) { _modal_view_window_list.push_front(window); } } void WindowCompositor::StopModalWindow(WeakBaseWindowPtr window) { if (!_modal_view_window_list.empty()) { if (*_modal_view_window_list.begin() == window) _modal_view_window_list.pop_front(); } } //! Push a floating view at the top of the stack. void WindowCompositor::PushToFront(BaseWindow* window) { if (window == 0) return; WindowList::iterator it = find(_view_window_list.begin(), _view_window_list.end(), window); if (it != _view_window_list.end()) { _view_window_list.erase(it); _view_window_list.push_front(WeakBaseWindowPtr(window)); } EnsureAlwaysOnFrontWindow(); } //! Push a floating view at the bottom of the stack. void WindowCompositor::PushToBack(BaseWindow* window) { if (window == 0) return; if (window == _always_on_front_window) return; WindowList::iterator it = find(_view_window_list.begin(), _view_window_list.end(), window); if (it != _view_window_list.end()) { _view_window_list.erase(it); _view_window_list.push_back(WeakBaseWindowPtr(window)); } EnsureAlwaysOnFrontWindow(); } //! Push a floating view just above another floating view. void WindowCompositor::PushHigher(BaseWindow* top_floating_view, BaseWindow* bottom_floating_view, bool strict) { NUX_RETURN_IF_NULL(bottom_floating_view); NUX_RETURN_IF_NULL(top_floating_view); NUX_RETURN_IF_FALSE(bottom_floating_view != top_floating_view) WindowList::iterator it; WindowList::iterator it_top; WindowList::iterator it_bot; int i = 0; int top_pos = -1; int bot_pos = -1; for (it_top = _view_window_list.begin(), i = 0; it_top != _view_window_list.end(); ++it_top, ++i) { if (*it == bottom_floating_view) { it_bot = it; bot_pos = i; } if (*it == top_floating_view) { it_top = it; top_pos = i; } if ((top_pos >= 0) && (bot_pos >= 0)) break; } if ((it_top == _view_window_list.end()) || (it_bot == _view_window_list.end())) { return; } if ((top_pos < bot_pos) && (strict == false)) { _view_window_list.erase(it_top); _view_window_list.insert(it_bot, WeakBaseWindowPtr(top_floating_view)); } EnsureAlwaysOnFrontWindow(); } void WindowCompositor::SetAlwaysOnFrontWindow(BaseWindow* window) { _always_on_front_window = WeakBaseWindowPtr(window); EnsureAlwaysOnFrontWindow(); } void WindowCompositor::EnsureAlwaysOnFrontWindow() { // Do not re-order while we are traversing the list of BaseWindow. if (inside_event_cycle_) return; if (_always_on_front_window == NULL) return; WindowList::iterator always_top_it = find(_view_window_list.begin(), _view_window_list.end(), _always_on_front_window); if ((always_top_it != _view_window_list.end()) && (always_top_it != _view_window_list.begin()) && _always_on_front_window.IsValid()) { _view_window_list.erase(always_top_it); _view_window_list.push_front(_always_on_front_window); } } int WindowCompositor::GetProximityListSize() const { return area_proximities_.size(); } void WindowCompositor::AddAreaInProximityList(InputAreaProximity* prox_area) { if (prox_area) { area_proximities_.push_back(prox_area); } else { LOG_ERROR(logger) << "Error, attempted to add a NULL InputAreaProximity to the list."; } } void WindowCompositor::RemoveAreaInProximityList(InputAreaProximity* prox_area) { if (prox_area) { area_proximities_.remove(prox_area); } } void WindowCompositor::CheckMouseNearArea(Event const& event) { for (auto area : area_proximities_) { if (area) { area->CheckMousePosition(Point(event.x, event.y)); } } } namespace { void AssignWeakBaseWindowMatchingRaw(WindowCompositor::WeakBaseWindowPtr const& w, BaseWindow* bw, WindowCompositor::WeakBaseWindowPtr *ptr) { if (w.IsValid() && w.GetPointer() == bw) *ptr = w; } } void WindowCompositor::ForEachBaseWindow(ForEachBaseWindowFunc const& func) { for (auto const& window : _view_window_list) { if (window.IsValid()) func(window); } for (auto const& window : _modal_view_window_list) { if (window.IsValid()) func(window); } if (m_MenuWindow.IsValid()) func(m_MenuWindow); if (_tooltip_window.IsValid()) func(_tooltip_window); if (m_OverlayWindow.IsValid()) func(m_OverlayWindow); } void WindowCompositor::Draw(bool SizeConfigurationEvent, bool force_draw) { inside_rendering_cycle_ = true; if (!window_thread_->GetGraphicsDisplay().isWindowMinimized()) { //int w, h; window_thread_->GetGraphicsEngine().GetContextSize(m_Width, m_Height); window_thread_->GetGraphicsEngine().SetViewport(0, 0, m_Width, m_Height); // Reset the Model view Matrix and the projection matrix window_thread_->GetGraphicsEngine().ResetProjectionMatrix(); window_thread_->GetGraphicsEngine().ResetModelViewMatrixStack(); window_thread_->GetGraphicsEngine().Push2DTranslationModelViewMatrix(0.0f, 0.0f, 0.0f); if (force_draw || SizeConfigurationEvent) { // We fall here after something dramatic has happen to the window such as a resizing. In this case // everything must be rendered. This is very costly and should happen rarely. if (!window_thread_->IsEmbeddedWindow()) RenderMainWindowComposition(true); { RenderTopViews(true, _view_window_list, false); RenderTopViews(true, _modal_view_window_list, true); DrawMenu(true); DrawTooltip(true); DrawOverlay(true); } } else if (m_MenuRemoved) { // A popup removed cause the whole window to be dirty(at least some part of it). // So exchange DrawList with a real Draw. if (!window_thread_->IsEmbeddedWindow()) RenderMainWindowComposition(false); { RenderTopViews(false, _view_window_list, false); RenderTopViews(false, _modal_view_window_list, true); DrawMenu(true); DrawTooltip(true); DrawOverlay(true); } } else { if (!window_thread_->IsEmbeddedWindow()) RenderMainWindowComposition(false); { RenderTopViews(false, _view_window_list, false); RenderTopViews(false, _modal_view_window_list, true); DrawMenu(true); DrawTooltip(true); DrawOverlay(true); } } m_MenuRemoved = false; window_thread_->GetGraphicsEngine().Pop2DWindow(); } inside_rendering_cycle_ = false; } void WindowCompositor::DrawMenu(bool force_draw) { #if !defined(NUX_MINIMAL) WeakBaseWindowPtr window(m_MenuWindow); if (window.IsValid()) { //window_thread_->GetGraphicsEngine().SetContext(x, y, buffer_width, buffer_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(window_thread_->GetGraphicsEngine().GetWindowWidth(), window_thread_->GetGraphicsEngine().GetWindowHeight()); window_thread_->GetGraphicsEngine().EmptyClippingRegion(); } else { window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(window_thread_->GetGraphicsEngine().GetWindowWidth(), window_thread_->GetGraphicsEngine().GetWindowHeight()); window_thread_->GetGraphicsEngine().EmptyClippingRegion(); } std::list::reverse_iterator rev_it_menu; for (rev_it_menu = _menu_chain->rbegin(); rev_it_menu != _menu_chain->rend( ); ++rev_it_menu) { SetProcessingTopView(m_MenuWindow.GetPointer()); (*rev_it_menu)->ProcessDraw(window_thread_->GetGraphicsEngine(), force_draw); SetProcessingTopView(NULL); } #endif } void WindowCompositor::DrawOverlay(bool /* force_draw */) { int buffer_width = window_thread_->GetGraphicsEngine().GetWindowWidth(); int buffer_height = window_thread_->GetGraphicsEngine().GetWindowHeight(); if (m_OverlayWindow.IsValid()) { //window_thread_->GetGraphicsEngine().SetContext(x, y, buffer_width, buffer_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height); window_thread_->GetGraphicsEngine().EmptyClippingRegion(); } else window_thread_->GetGraphicsEngine().SetOpenGLClippingRectangle(0, 0, buffer_width, buffer_height); if (OverlayDrawingCommand) { SetProcessingTopView(m_OverlayWindow.GetPointer()); OverlayDrawingCommand->OverlayDrawing(window_thread_->GetGraphicsEngine()); SetProcessingTopView(NULL); } //GetGraphicsDisplay()->GetGraphicsEngine()->SetContext(0, 0, buffer_width, buffer_height); } void WindowCompositor::DrawTooltip(bool /* force_draw */) { int buffer_width = window_thread_->GetGraphicsEngine().GetWindowWidth(); int buffer_height = window_thread_->GetGraphicsEngine().GetWindowHeight(); if (_tooltip_window.IsValid()) { //window_thread_->GetGraphicsEngine().SetContext(x, y, buffer_width, buffer_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height); window_thread_->GetGraphicsEngine().EmptyClippingRegion(); } else window_thread_->GetGraphicsEngine().SetOpenGLClippingRectangle(0, 0, buffer_width, buffer_height); if (m_TooltipText.size()) { //SetProcessingTopView(_tooltip_window); GetPainter().PaintShape(window_thread_->GetGraphicsEngine(), _tooltip_geometry, Color(0xA0000000), eSHAPE_CORNER_ROUND10, true); GetPainter().PaintTextLineStatic(window_thread_->GetGraphicsEngine(), GetSysBoldFont(), _tooltip_text_geometry, m_TooltipText, Color(0xFFFFFFFF)); //SetProcessingTopView(NULL); } //GetGraphicsDisplay()->GetGraphicsEngine()->SetContext(0, 0, buffer_width, buffer_height); } void WindowCompositor::RenderTopViewContent(BaseWindow* window, bool force_draw) { GetPainter().EmptyBackgroundStack(); SetProcessingTopView(window); window->ProcessDraw(window_thread_->GetGraphicsEngine(), force_draw || window->IsRedrawNeeded()); SetProcessingTopView(NULL); GetPainter().EmptyBackgroundStack(); } void WindowCompositor::PresentAnyReadyWindows() { if (!currently_rendering_windows_ || !current_global_clip_rect_) return; GraphicsEngine& graphics_engine = window_thread_->GetGraphicsEngine(); // Present all buffers to the screen graphics_engine.ApplyClippingRectangle(); CHECKGL(glDepthMask(GL_FALSE)); WindowList &windows = *currently_rendering_windows_; Geometry &global_clip_rect = *current_global_clip_rect_; for (auto const& window_ptr : windows) { if (window_ptr.IsNull()) continue; BaseWindow* window = window_ptr.GetPointer(); if (window->IsVisible()) { auto const& win_geo = window->GetGeometry(); if (!global_clip_rect.IsIntersecting(win_geo)) { // The global clipping area can be seen as a per monitor clipping // region. It is mostly used in embedded mode with compiz. If we // get here, it means that the BaseWindow we want to render is not // in area of the monitor that compiz is currently rendering. So // skip it. continue; } RenderTargetTextures& rt = GetWindowBuffer(window); if (rt.color_rt.IsValid()) { /* Already been presented */ if (!window->_contents_ready_for_presentation) continue; /* Caller doesn't want us to render this yet */ if (window_thread_->IsEmbeddedWindow() && !window->AllowPresentationInEmbeddedMode()) continue; // Nux is done rendering a BaseWindow into a texture. The previous call to Deactivate // has cancelled any opengl framebuffer object that was set. PresentBufferToScreen(rt.color_rt, win_geo.x, win_geo.y, false, false, window->GetOpacity(), window->premultiply()); window->_contents_ready_for_presentation = false; } } } } void WindowCompositor::RenderTopViews(bool force_draw, WindowList& windows_to_render, bool drawModal) { // Before anything, deactivate the current frame buffer, set the viewport // to the size of the display and call EmptyClippingRegion(). // Then call GetScissorRect() to get the size of the global clipping area. // This is is hack until we implement SetGlobalClippingRectangle() (the opposite of SetGlobalClippingRectangle). GraphicsEngine& graphics_engine = window_thread_->GetGraphicsEngine(); unsigned int window_width = graphics_engine.GetWindowWidth(); unsigned int window_height = graphics_engine.GetWindowHeight(); graphics_engine.SetViewport(0, 0, window_width, window_height); graphics_engine.EmptyClippingRegion(); Geometry global_clip_rect = graphics_engine.GetScissorRect(); global_clip_rect.y = window_height - global_clip_rect.y - global_clip_rect.height; current_global_clip_rect_ = &global_clip_rect; // We don't need to restore framebuffers if we didn't update any windows bool updated_any_windows = false; // Always make a copy of the windows to render. We have no control over // the windows we are actually drawing. It has been observed that some // windows modify the windows stack during the draw process. // // So... we take a copy of the window list. As much as I'd love to just // have BaseWindow* in the container, again, we have no control over the // windows we are drawing and one may just decide to unregister or destroy // another window mid-render. Since we are contructing a copy of the // list, lets reverse it as we are constructing, as we want to draw the // windows from back to front. WindowList windows(windows_to_render.rbegin(), windows_to_render.rend()); currently_rendering_windows_ = &windows; for (auto const& window_ptr : windows) { if (window_ptr.IsNull()) continue; BaseWindow* window = window_ptr.GetPointer(); if (!drawModal && window->IsModal()) continue; if (window->IsVisible()) { auto const& win_geo = window->GetGeometry(); if (!global_clip_rect.IsIntersecting(win_geo)) { // The global clipping area can be seen as a per monitor clipping // region. It is mostly used in embedded mode with compiz. If we // get here, it means that the BaseWindow we want to render is not // in area of the monitor that compiz is currently rendering. So // skip it. continue; } RenderTargetTextures& rt = GetWindowBuffer(window); // Based on the areas that requested a rendering inside the // BaseWindow, render the BaseWindow or just use its cache. if (force_draw || window->IsRedrawNeeded() || window->ChildNeedsRedraw()) { if (rt.color_rt.IsValid() /*&& rt.depth_rt.IsValid()*/) { int buffer_width = window->GetBaseWidth(); int buffer_height = window->GetBaseHeight(); if ((rt.color_rt->GetWidth() != buffer_width) || (rt.color_rt->GetHeight() != buffer_height)) { rt.color_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); rt.depth_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8); m_FrameBufferObject->SetTextureAttachment(0, rt.color_rt, 0); m_FrameBufferObject->SetDepthTextureAttachment(rt.depth_rt, 0); m_FrameBufferObject->Activate(); graphics_engine.SetViewport(0, 0, buffer_width, buffer_height); graphics_engine.SetOrthographicProjectionMatrix(buffer_width, buffer_height); graphics_engine.EmptyClippingRegion(); graphics_engine.SetOpenGLClippingRectangle(0, 0, buffer_width, buffer_height); CHECKGL( glClearColor(0, 0, 0, 0)); GLuint clear_color_buffer_bit = (force_draw || window->IsRedrawNeeded()) ? GL_COLOR_BUFFER_BIT : 0; CHECKGL( glClear(clear_color_buffer_bit | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); } else { Matrix4 mat; mat.Translate(win_geo.x, win_geo.y, 0); graphics_engine.SetOrthographicProjectionMatrix(window_width, window_height); } RenderTopViewContent(window, force_draw); m_FrameBufferObject->Deactivate(); CHECKGL(glDepthMask(GL_TRUE)); graphics_engine.GetRenderStates().SetBlend(false); updated_any_windows = true; } window->_child_need_redraw = false; window->_contents_ready_for_presentation = true; } else { // Invisible window, nothing to draw. window->_child_need_redraw = false; window->DoneRedraw(); } } /* If any windows were updated, then we need to rebind our * reference framebuffer */ if (updated_any_windows) { if (GetWindowThread()->IsEmbeddedWindow()) { // Restore the reference framebuffer if (!RestoreReferenceFramebuffer()) { LOG_DEBUG(logger) << "RenderTopViews: Setting the Reference fbo has failed."; } } else { GetGraphicsDisplay()->GetGpuDevice()->DeactivateFrameBuffer(); } } /* Present any windows which haven't yet been presented */ PresentAnyReadyWindows(); currently_rendering_windows_ = nullptr; current_global_clip_rect_ = nullptr; } void WindowCompositor::RenderMainWindowComposition(bool force_draw) { int buffer_width, buffer_height; buffer_width = window_thread_->GetGraphicsEngine().GetWindowWidth(); buffer_height = window_thread_->GetGraphicsEngine().GetWindowHeight(); if ((!m_MainColorRT.IsValid()) || (m_MainColorRT->GetWidth() != buffer_width) || (m_MainColorRT->GetHeight() != buffer_height)) { m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); } if (platform_support_for_depth_texture_) { if ((!m_MainDepthRT.IsValid()) || (m_MainDepthRT->GetWidth() != buffer_width) || (m_MainDepthRT->GetHeight() != buffer_height)) { m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } } m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8); m_FrameBufferObject->SetTextureAttachment(0, m_MainColorRT, 0); m_FrameBufferObject->SetDepthTextureAttachment(m_MainDepthRT, 0); m_FrameBufferObject->Activate(); window_thread_->GetGraphicsEngine().EmptyClippingRegion(); window_thread_->GetGraphicsEngine().SetOpenGLClippingRectangle(0, 0, buffer_width, buffer_height); window_thread_->GetGraphicsEngine().SetViewport(0, 0, buffer_width, buffer_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height); { CHECKGL(glClear(/*GL_COLOR_BUFFER_BIT |*/ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); //Begin 2D Drawing { if (force_draw) { GetPainter().PushDrawLayer(window_thread_->GetGraphicsEngine(), Geometry(0, 0, buffer_width, buffer_height), m_Background); //GetPainter().PushBackground(window_thread_->GetGraphicsEngine(), Geometry(0, 0, buffer_width, buffer_height), m_Background, true); window_thread_->ProcessDraw(window_thread_->GetGraphicsEngine(), true); nuxAssert(window_thread_->GetGraphicsEngine().GetNumberOfClippingRegions() == 0); GetPainter().PopBackground(); GetPainter().EmptyBackgroundStack(); } else { GetPainter().PushLayer(window_thread_->GetGraphicsEngine(), Geometry(0, 0, buffer_width, buffer_height), m_Background); //GetPainter().PushBackground(window_thread_->GetGraphicsEngine(), Geometry(0, 0, buffer_width, buffer_height), m_Background, false); window_thread_->ProcessDraw(window_thread_->GetGraphicsEngine(), false); nuxAssert(window_thread_->GetGraphicsEngine().GetNumberOfClippingRegions() == 0); GetPainter().PopBackground(); GetPainter().EmptyBackgroundStack(); } } // End 2D Drawing } window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height); m_FrameBufferObject->Deactivate(); unsigned int window_width, window_height; window_width = window_thread_->GetGraphicsEngine().GetWindowWidth(); window_height = window_thread_->GetGraphicsEngine().GetWindowHeight(); window_thread_->GetGraphicsEngine().EmptyClippingRegion(); window_thread_->GetGraphicsEngine().SetOpenGLClippingRectangle(0, 0, window_width, window_height); window_thread_->GetGraphicsEngine().SetViewport(0, 0, window_width, window_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(window_width, window_height); PresentBufferToScreen(m_MainColorRT, 0, 0, false); } void WindowCompositor::PresentBufferToScreen(ObjectPtr HWTexture, int x, int y, bool RenderToMainTexture, bool /* BluredBackground */, float opacity, bool premultiply) { nuxAssert(HWTexture.IsValid()); if (HWTexture.IsNull()) return; int window_width, window_height; window_width = window_thread_->GetGraphicsEngine().GetWindowWidth(); window_height = window_thread_->GetGraphicsEngine().GetWindowHeight(); if (RenderToMainTexture && (HWTexture != m_MainColorRT)) { nuxAssert(m_MainColorRT->GetWidth() == window_width); nuxAssert(m_MainColorRT->GetHeight() == window_height); m_FrameBufferObject->FormatFrameBufferObject(window_width, window_height, BITFMT_R8G8B8A8); m_FrameBufferObject->SetTextureAttachment(0, m_MainColorRT, 0); m_FrameBufferObject->SetDepthTextureAttachment(m_MainDepthRT, 0); m_FrameBufferObject->Activate(); } // Reference framebuffer is already restored window_thread_->GetGraphicsEngine().EmptyClippingRegion(); window_thread_->GetGraphicsEngine().SetOpenGLClippingRectangle(0, 0, window_width, window_height); window_thread_->GetGraphicsEngine().SetViewport(0, 0, window_width, window_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(window_width, window_height); // Render the MAINFBO { int src_width, src_height; src_width = HWTexture->GetWidth(); src_height = HWTexture->GetHeight(); TexCoordXForm texxform0; texxform0.FlipVCoord(true); if (premultiply) { window_thread_->GetGraphicsEngine().GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(x, y, src_width, src_height, HWTexture, texxform0, Color(opacity, opacity, opacity, opacity)); } else { window_thread_->GetGraphicsEngine().GetRenderStates().SetBlend(false); GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(x, y, src_width, src_height, HWTexture, texxform0, Color(1.0f, 1.0f, 1.0f, opacity)); } window_thread_->GetGraphicsEngine().GetRenderStates().SetBlend(false); } } #if !defined(NUX_MINIMAL) void WindowCompositor::AddMenu(MenuPage* menu, BaseWindow* window, bool OverrideCurrentMenuChain) { if (_menu_chain->empty()) { // A menu is opening. _starting_menu_event_cycle = true; _menu_is_active = true; } std::list::iterator it = find(_menu_chain->begin(), _menu_chain->end(), menu); if (it == _menu_chain->end()) { // When adding a MenuPage, make sure that it is a child of the MenuPage in _menu_chain->begin(). if (!_menu_chain->empty()) { if (menu->GetParentMenu() != (*_menu_chain->begin())) { if (OverrideCurrentMenuChain) { // Remove the current menu chain for (it = _menu_chain->begin(); it != _menu_chain->end(); ++it) { // Stop all pages (*it)->StopMenu(); } _menu_chain->clear(); } else { // The MenuPage argument is not a descendent of the current menu chain. return; } } } m_MenuWindow = window; // The deepest menu is added in front of the list and tested first for events. _menu_chain->push_front(menu); } } // Be careful never call this function while you are iterating through the elements of _menu_chain. void WindowCompositor::RemoveMenu(MenuPage* menu) { std::list::iterator it = find(_menu_chain->begin(), _menu_chain->end(), menu); if (it == _menu_chain->end()) { return; } _menu_chain->erase(it); m_MenuRemoved = true; if (_menu_is_active && (_menu_chain->empty())) { // The menu is closed _menu_is_active = false; ResetMousePointerAreas(); m_MenuWindow = NULL; } } void WindowCompositor::CleanMenu() { if (_menu_chain->empty()) return; std::list::iterator menu_it = _menu_chain->begin(); while (menu_it != _menu_chain->end()) { if ((*menu_it)->IsActive() == false) { menu_it = _menu_chain->erase(menu_it); m_MenuRemoved = true; } else { ++menu_it; } } if (_menu_is_active && (_menu_chain->empty())) { _menu_is_active = false; ResetMousePointerAreas(); m_MenuWindow = NULL; } } #endif void WindowCompositor::SetWidgetDrawingOverlay(InputArea* ic, BaseWindow* OverlayWindow) { OverlayDrawingCommand = ic; m_OverlayWindow = OverlayWindow; } InputArea* WindowCompositor::GetWidgetDrawingOverlay() { return OverlayDrawingCommand; } void WindowCompositor::SetTooltip(InputArea* TooltipArea, const char* TooltipText, int x, int y) { _tooltip_window = GetProcessingTopView(); m_TooltipArea = TooltipArea; m_TooltipText = TooltipText; m_TooltipX = x; m_TooltipY = y; if (m_TooltipText.size()) { int w = GetSysBoldFont()->GetCharStringWidth(m_TooltipText.c_str()); int h = GetSysBoldFont()->GetFontHeight(); _tooltip_text_geometry = Geometry( m_TooltipX + 10, m_TooltipY - h/2 - 2, w, h + 4); _tooltip_geometry = _tooltip_text_geometry; _tooltip_geometry.OffsetSize(20, 8); _tooltip_geometry.OffsetPosition(-10, -4); _tooltip_mainwindow_geometry = _tooltip_geometry; if (_tooltip_window.IsValid()) { _tooltip_mainwindow_geometry.OffsetPosition(_tooltip_window->GetBaseX(), _tooltip_window->GetBaseY()); } } else { _tooltip_mainwindow_geometry = _tooltip_geometry = _tooltip_text_geometry = Geometry(0, 0, 0, 0); } } Geometry WindowCompositor::GetTooltipGeometry() const { return _tooltip_geometry; } Geometry WindowCompositor::GetTooltipMainWindowGeometry() const { return _tooltip_mainwindow_geometry; } void WindowCompositor::CancelTooltip() { _tooltip_window = NULL; m_TooltipArea = NULL; m_TooltipText = ""; } bool WindowCompositor::ValidateMouseInsideTooltipArea(int x, int y) { NUX_RETURN_VALUE_IF_FALSE(m_TooltipArea, false); NUX_RETURN_VALUE_IF_FALSE(_tooltip_window.IsValid(), false); Geometry geo = m_TooltipArea->GetGeometry(); geo.OffsetPosition(_tooltip_window->GetBaseX(), _tooltip_window->GetBaseY()); return geo.IsPointInside(x, y); } bool WindowCompositor::IsTooltipActive() { NUX_RETURN_VALUE_IF_FALSE(m_TooltipArea, false); return true; } bool WindowCompositor::SetKeyFocusArea(InputArea* area, KeyNavDirection direction) { InputArea* keyboard_grab_area = GetKeyboardGrabArea(); if (keyboard_grab_area && area && (area != keyboard_grab_area) && (!area->IsChildOf(keyboard_grab_area))) { // There is a keyboard grab pending. Only an area that is a child of the area that has // the keyboard grab can be set to receive keyboard events. LOG_DEBUG(logger) << "SetKeyFocusArea: There is a keyboard grab pending. Cannot change the keyboard event receiver."; return false; } if (key_focus_area_ == area) { // Already has the keyboard focus. return true; } if (area && (area->AcceptKeyNavFocus() == false)) { // Area does not want the keyboard focus. return false; } if (key_focus_area_.IsValid()) { // This is the area that has the keyboard focus. Emit the signal 'end_key_focus'. key_focus_area_->end_key_focus.emit(); // From the area that has the keyboard focus to the top level parent, delete the path that // leads to the keyboard focus area. key_focus_area_->ResetUpwardPathToKeyFocusArea(); if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType)) { // Signal emitted from the WindowCompositor. key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, direction); // Signal emitted from the area itself. key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, direction); // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Lost key nav focus.", // key_focus_area_->Type().name, // key_focus_area_->GetBaseString().c_str()); } if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType)) { static_cast(key_focus_area_.GetPointer())->QueueDraw(); } } if (area) { key_focus_area_ = area; // From the area that has the keyboard focus to the top level parent, mark the path that // leads to the keyboard focus area. key_focus_area_->SetPathToKeyFocusArea(); // Emit the signal 'begin_key_focus'. key_focus_area_->begin_key_focus.emit(); if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType)) { // Signal emitted from the WindowCompositor. key_nav_focus_change.emit(key_focus_area_.GetPointer(), true, direction); // Signal emitted from the area itself. key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), true, direction); // nuxDebugMsg("[WindowCompositor::SetKeyFocusArea] Area type '%s' named '%s': Has key nav focus.", // key_focus_area_->Type().name, // key_focus_area_->GetBaseString().c_str()); } if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType)) { static_cast(key_focus_area_.GetPointer())->QueueDraw(); } key_focus_area_->ChildFocusChanged.emit(key_focus_area_.GetPointer()); } else { key_focus_area_ = NULL; // Signal emitted from the area itself. key_nav_focus_change.emit(NULL, false, direction); } return key_focus_area_.IsValid(); } InputArea* WindowCompositor::GetKeyFocusArea() { return key_focus_area_.GetPointer(); } void WindowCompositor::SetBackgroundPaintLayer(AbstractPaintLayer* bkg) { NUX_SAFE_DELETE(m_Background); m_Background = bkg->Clone(); } void WindowCompositor::FloatingAreaConfigureNotify(int Width, int Height) { WindowList::iterator it; for (auto const& win : _view_window_list) { if (!win.IsValid()) continue; if (win->IsVisible()) win->NotifyConfigurationChange(Width, Height); } } void WindowCompositor::FormatRenderTargets(int /* width */, int /* height */) { int buffer_width = window_thread_->GetGraphicsEngine().GetWindowWidth(); int buffer_height = window_thread_->GetGraphicsEngine().GetWindowHeight(); nuxAssert(buffer_width >= 1); nuxAssert(buffer_height >= 1); m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); if (platform_support_for_depth_texture_) { m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } // Clear the buffer the first time... m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8); m_FrameBufferObject->SetTextureAttachment(0, m_MainColorRT, 0); m_FrameBufferObject->SetDepthTextureAttachment(m_MainDepthRT, 0); m_FrameBufferObject->Activate(); CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); CHECKGL(glClearDepth(1.0f)); CHECKGL(glClearStencil(0)); CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); m_FrameBufferObject->Deactivate(); CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); CHECKGL(glClearDepth(1.0f)); CHECKGL(glClearStencil(0)); CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); // m_BlurTexture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(Max(buffer_width, 1), Max(buffer_height, 1), 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); // m_FullSceneMip0 = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(Max(buffer_width / 2, 1), Max(buffer_height / 2, 1), 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); // m_FullSceneMip1 = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(Max(buffer_width / 4, 1), Max(buffer_height / 4, 1), 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); // m_FullSceneMip2 = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(Max(buffer_width / 8, 1), Max(buffer_height / 8, 1), 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); } void WindowCompositor::RestoreRenderingSurface() { BaseWindow* top_view = GetProcessingTopView(); if (top_view && inside_rendering_cycle_) { nuxAssert(top_view->Type().IsDerivedFromType(BaseWindow::StaticObjectType)); RenderTargetTextures rt = GetWindowBuffer(top_view); int buffer_width = top_view->GetBaseWidth(); int buffer_height = top_view->GetBaseHeight(); nuxAssert(buffer_width >= 1); nuxAssert(buffer_height >= 1); if ((rt.color_rt->GetWidth() != buffer_width) || (rt.color_rt->GetHeight() != buffer_height)) { rt.color_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); } if (platform_support_for_depth_texture_) { if ((rt.depth_rt->GetWidth() != buffer_width) || (rt.depth_rt->GetHeight() != buffer_height)) { rt.depth_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } } m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8); m_FrameBufferObject->SetTextureAttachment(0, rt.color_rt, 0); m_FrameBufferObject->SetDepthTextureAttachment(rt.depth_rt, 0); m_FrameBufferObject->Activate(); window_thread_->GetGraphicsEngine().SetViewport(0, 0, buffer_width, buffer_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height); window_thread_->GetGraphicsEngine().ApplyClippingRectangle(); //window_thread_->GetGraphicsEngine().ApplyModelViewMatrix(); ??? } else { int buffer_width = window_thread_->GetGraphicsEngine().GetWindowWidth(); int buffer_height = window_thread_->GetGraphicsEngine().GetWindowHeight(); nuxAssert(buffer_width >= 1); nuxAssert(buffer_height >= 1); // Restore Main Frame Buffer if not in embedded mode if (!GetWindowThread()->IsEmbeddedWindow()) { m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8); m_FrameBufferObject->SetTextureAttachment(0, m_MainColorRT, 0); m_FrameBufferObject->SetDepthTextureAttachment(m_MainDepthRT, 0); m_FrameBufferObject->Activate(); } else { // Restore reference framebuffer RestoreReferenceFramebuffer(); // Present any ready windows PresentAnyReadyWindows(); } window_thread_->GetGraphicsEngine().SetViewport(0, 0, buffer_width, buffer_height); window_thread_->GetGraphicsEngine().SetOrthographicProjectionMatrix(buffer_width, buffer_height); window_thread_->GetGraphicsEngine().ApplyClippingRectangle(); //window_thread_->GetGraphicsEngine().ApplyModelViewMatrix(); ??? } } void* WindowCompositor::GetBackupTextureData(BaseWindow* base_window, int& width, int& height, int& format) { width = height = format = 0; NUX_RETURN_VALUE_IF_NULL(base_window, 0); std::map::iterator it; it = _window_to_texture_map.find(base_window); if (it == _window_to_texture_map.end()) { return 0; } if ((*it).second.color_rt.IsNull()) { return 0; } return (*it).second.color_rt->GetSurfaceData(0, width, height, format); } void WindowCompositor::ResetDnDArea() { SetDnDArea(NULL); } void WindowCompositor::SetDnDArea(InputArea* area) { #if defined(DRAG_AND_DROP_SUPPORTED) if (_dnd_area == area) return; if (_dnd_area) { _dnd_area->HandleDndLeave(); _dnd_area->UnReference(); } _dnd_area = area; if (_dnd_area) { _dnd_area->Reference(); _dnd_area->HandleDndEnter(); } #endif } InputArea* WindowCompositor::GetDnDArea() { return _dnd_area; } bool WindowCompositor::GrabPointerAdd(InputArea* area) { NUX_RETURN_VALUE_IF_NULL(area, false); bool result = true; if (GetPointerGrabArea() == area) { LOG_DEBUG(logger) << "GrabPointerAdd: The area already has the grab"; return result; } if (window_thread_->GetGraphicsDisplay().PointerGrabData() != this) result = window_thread_->GetGraphicsDisplay().GrabPointer(NULL, this, true); if (result) pointer_grab_stack_.push_front(area); // reset the mouse pointers areas. ResetMousePointerAreas(); return result; } bool WindowCompositor::GrabPointerRemove(InputArea* area) { NUX_RETURN_VALUE_IF_NULL(area, false); std::list::iterator it; // find the first instance of the area pointer in the stack it = find(pointer_grab_stack_.begin(), pointer_grab_stack_.end(), area); if (it == pointer_grab_stack_.end()) return false; pointer_grab_stack_.erase(it); if (pointer_grab_stack_.empty()) window_thread_->GetGraphicsDisplay().UngrabPointer(this); // reset the mouse pointers areas. ResetMousePointerAreas(); return true; } bool WindowCompositor::IsInPointerGrabStack(InputArea* area) { NUX_RETURN_VALUE_IF_NULL(area, false); std::list::iterator it; it = find(pointer_grab_stack_.begin(), pointer_grab_stack_.end(), area); if (it == pointer_grab_stack_.end()) return false; return true; } InputArea* WindowCompositor::GetPointerGrabArea() { if (pointer_grab_stack_.empty()) return NULL; return (*pointer_grab_stack_.begin()); } bool WindowCompositor::GrabKeyboardAdd(InputArea* area) { NUX_RETURN_VALUE_IF_NULL(area, false); bool result = true; if (GetKeyboardGrabArea() == area) { LOG_DEBUG(logger) << "GrabKeyboardAdd: The area already has the grab"; return result; } if (window_thread_->GetGraphicsDisplay().KeyboardGrabData() != this) { result = window_thread_->GetGraphicsDisplay().GrabKeyboard(NULL, this, true); } if (result) { InputArea* current_keyboard_grab = GetKeyboardGrabArea(); if (current_keyboard_grab) current_keyboard_grab->end_keyboard_grab.emit(current_keyboard_grab); keyboard_grab_stack_.push_front(area); // If there is any area with the key focus, cancel it. if (key_focus_area_.IsValid()) { key_focus_area_->end_key_focus.emit(); key_focus_area_->ResetUpwardPathToKeyFocusArea(); if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType)) { // Signal emitted from the WindowCompositor. key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE); // Signal emitted from the area itself. key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE); // nuxDebugMsg("[WindowCompositor::GrabKeyboardAdd] Area type '%s' named '%s': Lost key nav focus.", // key_focus_area_->Type().name, // key_focus_area_->GetBaseString().c_str()); } if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType)) { static_cast(key_focus_area_.GetPointer())->QueueDraw(); } key_focus_area_ = NULL; } // Must be called only after the area has been added to the front of keyboard_grab_stack_. SetKeyFocusArea(area); area->start_keyboard_grab.emit(area); } return result; } bool WindowCompositor::GrabKeyboardRemove(InputArea* area) { NUX_RETURN_VALUE_IF_NULL(area, false); std::list::iterator it; // find the first instance of the area keyboard in the stack it = find(keyboard_grab_stack_.begin(), keyboard_grab_stack_.end(), area); if (it == keyboard_grab_stack_.end()) return false; InputArea* current_keyboard_grab = (*it); bool has_grab = false; if (it == keyboard_grab_stack_.begin()) { // At the top of the keyboard_grab_stack_. Means it has the keyboard grab. has_grab = true; } // First remove the area from the grab list keyboard_grab_stack_.erase(it); // Then emit end_keyboard_grab if the area had the keyboard grab if (has_grab && current_keyboard_grab) { current_keyboard_grab->end_keyboard_grab.emit(current_keyboard_grab); } if (keyboard_grab_stack_.empty()) { window_thread_->GetGraphicsDisplay().UngrabKeyboard(this); } // Must be called only after the area has been added to the front of keyboard_grab_stack_. if (keyboard_grab_stack_.empty()) { SetKeyFocusArea(NULL); } else { // If there is any area with the key focus, cancel it. if (key_focus_area_.IsValid()) { key_focus_area_->end_key_focus.emit(); key_focus_area_->ResetUpwardPathToKeyFocusArea(); if (key_focus_area_->Type().IsDerivedFromType(InputArea::StaticObjectType)) { // Signal emitted from the WindowCompositor. key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE); // Signal emitted from the area itself. key_focus_area_->key_nav_focus_change.emit(key_focus_area_.GetPointer(), false, KEY_NAV_NONE); // nuxDebugMsg("[WindowCompositor::GrabKeyboardRemove] Area type '%s' named '%s': Lost key nav focus.", // key_focus_area_->Type().name, // key_focus_area_->GetBaseString().c_str()); } if (key_focus_area_->Type().IsDerivedFromType(View::StaticObjectType)) { static_cast(key_focus_area_.GetPointer())->QueueDraw(); } key_focus_area_ = NULL; } it = keyboard_grab_stack_.begin(); SetKeyFocusArea(*it); InputArea* new_keyboard_grab = (*it); new_keyboard_grab->start_keyboard_grab.emit(new_keyboard_grab); } return true; } bool WindowCompositor::IsInKeyboardGrabStack(InputArea* area) { NUX_RETURN_VALUE_IF_NULL(area, false); std::list::iterator it; it = find(keyboard_grab_stack_.begin(), keyboard_grab_stack_.end(), area); if (it == keyboard_grab_stack_.end()) return false; return true; } InputArea* WindowCompositor::GetKeyboardGrabArea() { if (keyboard_grab_stack_.empty()) return NULL; return (*keyboard_grab_stack_.begin()); } void WindowCompositor::SetReferenceFramebuffer(unsigned int draw_fbo_object, unsigned int read_fbo_object, Geometry const& fbo_geometry) { draw_reference_fbo_ = draw_fbo_object; read_reference_fbo_ = read_fbo_object; reference_fbo_geometry_ = fbo_geometry; } namespace { bool CheckExternalFramebufferStatus (GLenum binding) { bool ok = false; // Nux does some sanity checks to make sure that the FBO is in good condition. GLenum status; status = glCheckFramebufferStatusEXT(binding); CHECKGL_MSG(glCheckFramebufferStatusEXT); switch(status) { case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK ok = true; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT"); ok = false; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT"); ok = false; break; // See issue(87) of http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt // case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: // nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT"); // ok = false; // break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT"); ok = false; break; #ifndef NUX_OPENGLES_20 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT"); ok = false; break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT"); ok = false; break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT"); ok = false; break; #endif // case GL_FRAMEBUFFER_STATUS_ERROR_EXT: // nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_STATUS_ERROR_EXT"); // ok = false; // break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_UNSUPPORTED_EXT"); ok = false; break; default: nuxError("[GLFramebufferObject::IsValid] Unknown ERROR"); ok = false; } return ok; } void SetReferenceFramebufferViewport(const nux::Geometry &reference_fbo_geometry_) { CHECKGL(glViewport(reference_fbo_geometry_.x, reference_fbo_geometry_.y, reference_fbo_geometry_.width, reference_fbo_geometry_.height)); } } bool WindowCompositor::RestoreReferenceFramebuffer() { // It is assumed that the reference fbo contains valid textures. // Nux does the following: // - Bind the reference fbo (reference_fbo_) // - Call glDrawBuffer with GL_COLOR_ATTACHMENT0 // - Set the opengl viewport size (reference_fbo_geometry_) #ifndef NUX_OPENGLES_20 CHECKGL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, draw_reference_fbo_)); CHECKGL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, read_reference_fbo_)); if (draw_reference_fbo_) { CHECKGL(glDrawBuffer(GL_COLOR_ATTACHMENT0)); } else { CHECKGL(glDrawBuffer(GL_BACK)); } if (read_reference_fbo_) { CHECKGL(glReadBuffer(GL_COLOR_ATTACHMENT0)); } else { CHECKGL(glReadBuffer(GL_BACK)); } #else nuxAssertMsg(draw_reference_fbo_ == read_reference_fbo_, "[WindowCompositor::RestoreReferenceFramebuffer]: OpenGL|ES does not"\ " support separate draw and read framebuffer bindings, using the supplied"\ " draw binding"); CHECKGL(glBindFramebufferEXT(GL_FRAMEBUFFER, draw_reference_fbo_)); #endif SetReferenceFramebufferViewport(reference_fbo_geometry_); #ifndef NUX_OPENGLES_20 int restore_status = (!draw_reference_fbo_ || CheckExternalFramebufferStatus(GL_DRAW_FRAMEBUFFER_EXT)) && (!read_reference_fbo_ || CheckExternalFramebufferStatus(GL_READ_FRAMEBUFFER_EXT)); #else int restore_status = CheckExternalFramebufferStatus(GL_FRAMEBUFFER); #endif return restore_status; } void WindowCompositor::RestoreMainFramebuffer() { // This is a bit inefficient as we unbind and then rebind nux::GetGraphicsDisplay()->GetGpuDevice()->DeactivateFrameBuffer (); RestoreReferenceFramebuffer (); /* Present any ready windows after restoring * the reference framebuffer. This ensures that if * we need to restore the reference framebuffer to * get access to its contents through glCopyTexSubImage2D * that it will also have any rendered views in it too */ PresentAnyReadyWindows(); } #ifdef NUX_GESTURES_SUPPORT void WindowCompositor::SetGestureBroker(std::unique_ptr gesture_broker) { gesture_broker_ = std::move(gesture_broker); } InputArea *WindowCompositor::LocateGestureTarget(const GestureEvent &event) { InputArea *input_area = nullptr; for (auto const& window : _view_window_list) { if (!window.IsValid()) continue; input_area = static_cast(window->GetInputAreaHitByGesture(event)); if (input_area) break; } // If a target InputArea wasn't found in any of the BaseWindows, then check // the InputAreas in the layout of the main window. if (!input_area) { Layout* main_window_layout = window_thread_->GetLayout(); if (main_window_layout) input_area = static_cast( main_window_layout->GetInputAreaHitByGesture(event)); } return input_area; } DefaultGestureBroker::DefaultGestureBroker(WindowCompositor *window_compositor) : window_compositor_(window_compositor) { } std::vector DefaultGestureBroker::FindGestureTargets(const nux::GestureEvent &event) { std::vector targets; InputArea *target_area = window_compositor_->LocateGestureTarget(event); if (target_area) targets.push_back(ShPtGestureTarget(new InputAreaTarget(target_area))); return targets; } #endif } nux-4.0.6+14.04.20140409/Nux/D2DTextRenderer.h0000644000015301777760000000612112321344237020565 0ustar pbusernogroup00000000000000#pragma once #include #include #include #include "Wincodec.h" /****************************************************************** * * * CustomTextRenderer * * * * The IDWriteTextRenderer interface is an input parameter to * * IDWriteTextLayout::Draw. This interfaces defines a number of * * callback functions that the client application implements for * * custom text rendering. This sample renderer implementation * * renders text using text outlines and Direct2D. * * A more sophisticated client would also support bitmap * * renderings. * * * ******************************************************************/ class CustomTextRenderer : public IDWriteTextRenderer { public: CustomTextRenderer( ID2D1Factory* pD2DFactory, ID2D1RenderTarget* pRT, ID2D1SolidColorBrush* pOutlineBrush, ID2D1BitmapBrush* pFillBrush ); ~CustomTextRenderer(); IFACEMETHOD(IsPixelSnappingDisabled)( __maybenull void* clientDrawingContext, __out BOOL* isDisabled ); IFACEMETHOD(GetCurrentTransform)( __maybenull void* clientDrawingContext, __out DWRITE_MATRIX* transform ); IFACEMETHOD(GetPixelsPerDip)( __maybenull void* clientDrawingContext, __out FLOAT* pixelsPerDip ); IFACEMETHOD(DrawGlyphRun)( __maybenull void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, __in DWRITE_GLYPH_RUN const* glyphRun, __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, IUnknown* clientDrawingEffect ); IFACEMETHOD(DrawUnderline)( __maybenull void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, __in DWRITE_UNDERLINE const* underline, IUnknown* clientDrawingEffect ); IFACEMETHOD(DrawStrikethrough)( __maybenull void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, __in DWRITE_STRIKETHROUGH const* strikethrough, IUnknown* clientDrawingEffect ); IFACEMETHOD(DrawInlineObject)( __maybenull void* clientDrawingContext, FLOAT originX, FLOAT originY, IDWriteInlineObject* inlineObject, BOOL isSideways, BOOL isRightToLeft, IUnknown* clientDrawingEffect ); public: IFACEMETHOD_(unsigned long, AddRef) (); IFACEMETHOD_(unsigned long, Release) (); IFACEMETHOD(QueryInterface) ( IID const& riid, void** ppvObject ); private: unsigned long cRefCount_; ID2D1Factory* pD2DFactory_; ID2D1RenderTarget* pRT_; ID2D1SolidColorBrush* pOutlineBrush_; ID2D1BitmapBrush* pFillBrush_; }; nux-4.0.6+14.04.20140409/Nux/WidgetMetrics.cpp0000644000015301777760000000517512321344237020775 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "WidgetMetrics.h" namespace nux { const Color COLOR_BLACK = Color(0xFF000000); const Color COLOR_RED = Color(0xFFFF0000); const Color COLOR_GREEN = Color(0xFF00FF00); const Color COLOR_BLUE = Color(0xFF0000FF); const Color COLOR_WHITE = Color(0xFFFFFFFF); const Color COLOR_BACKGROUND_PRIMARY = Color(0xFF4D4D4D); const Color COLOR_BACKGROUND_SECONDARY = Color(0xFF868686); const Color COLOR_FOREGROUND_PRIMARY = Color(0xFF424242); //0xFFCFCFCF; const Color COLOR_FOREGROUND_SECONDARY = Color(0xFFEFEFEF); const Color COLOR_SELECTION_SECONDARY = Color(0xFFAAAAAA); // Text color const Color COLOR_TEXTEDIT_BACKGROUNG = Color(0xFF9F9F9F); const Color COLOR_TEXTSTATIC_BACKGROUNG = Color(0xFF909090); // General background color const Color COLOR_WIDGET_BACKGROUND = Color(0xFF6E6E6E); const Color COLOR_WIDGET_MOUSEOVER = Color(0xFF969664); const Color COLOR_WINDOW_BACKGROUND = Color(0xFFa0a0a0); // Widget control background color const Color COLOR_PRIMARY_LEFT = Color(0xFFC0C0C0); const Color COLOR_PRIMARY_RIGHT = Color(0xFF7D7D7D); // ScrollBar color const Color COLOR_SCROLLBAR_TRACK = Color(0xFF636363); const Color COLOR_SCROLLBAR_SLIDER = Color(0xFF373737); const Color COLOR_DARK_0 = Color(0xFF575757); const Color COLOR_LIGHT_0 = Color(0xFF737373); const int AREA_MIN_WIDTH = 1; const int AREA_MAX_WIDTH = 0x7FFFFFFF; const int AREA_MIN_HEIGHT = 1; const int AREA_MAX_HEIGHT = 0x7FFFFFFF; const int DEFAULT_WIDGET_HEIGHT = 8; const int PRACTICAL_WIDGET_HEIGHT = 18; const int DEFAULT_WIDGET_WIDTH = 32; const int PRACTICAL_WIDGET_WIDTH = 32; const int DEFAULT_TEXT_X_MARGIN = 0; const int DEFAULT_TEXT_Y_MARGIN = 0; const float DEFAULT_REPEAT_DELAY = 150; //milliseconds } nux-4.0.6+14.04.20140409/Nux/ClientArea.cpp0000644000015301777760000001714012321344237020225 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #if defined(NUX_OS_WINDOWS) #include "NuxGraphics/GraphicsDisplay.h" #elif defined(NUX_OS_LINUX) #include "NuxGraphics/GraphicsDisplay.h" #endif #include "NuxGraphics/GraphicsEngine.h" #include "TimerProc.h" #include "ClientArea.h" namespace nux { ClientArea::ClientArea(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { m_IsClientAreaEnabled = false; SetMinimumSize(DEFAULT_WIDGET_WIDTH, 4 * PRACTICAL_WIDGET_HEIGHT); mouse_down.connect(sigc::mem_fun(this, &ClientArea::RecvMouseDown)); mouse_up.connect(sigc::mem_fun(this, &ClientArea::RecvMouseUp)); mouse_drag.connect(sigc::mem_fun(this, &ClientArea::RecvMouseDrag)); mouse_move.connect(sigc::mem_fun(this, &ClientArea::RecvMouseMove)); key_down.connect(sigc::mem_fun(this, &ClientArea::RecvKeyEvent)); } ClientArea::~ClientArea() { } void ClientArea::BeginDraw(GraphicsEngine& graphics_engine, bool force_draw) { // if ((IsRedrawNeeded() == false) && (force_draw == false)) // return; // Save blend states unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); ObjectPtr prev_fbo_ = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); Geometry prev_viewport_ = graphics_engine.GetViewportRect(); if (GetWindowThread()->GetGraphicsDisplay().HasFrameBufferSupport()) { int width = GetWidth(); int height = GetHeight(); m_ctx.x = GetX(); m_ctx.y = GetY(); m_ctx.width = width; m_ctx.height = height; // A is obtained from graphics_engine. So A dimension's are in relative window coordinates. Rect A = graphics_engine.GetClippingRegion(); Rect B = Rect(m_ctx.x, m_ctx.y, m_ctx.width, m_ctx.height); Rect C = A.Intersect(B); m_ctx.x_clipregion = C.x; m_ctx.y_clipregion = C.y; m_ctx.width_clipregion = C.GetWidth(); m_ctx.height_clipregion = C.GetHeight(); //ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); if (m_FrameBufferObject.IsNull()) { // Create the fbo before using it for the first time. m_FrameBufferObject = GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject(); } if (!m_MainColorRT.IsValid() || (m_MainColorRT->GetWidth() != width) || (m_MainColorRT->GetHeight() != height)) { // Create or resize the color and depth textures before using them. m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } m_FrameBufferObject->FormatFrameBufferObject(width, height, BITFMT_R8G8B8A8); m_FrameBufferObject->EmptyClippingRegion(); m_FrameBufferObject->SetTextureAttachment(0, m_MainColorRT, 0); m_FrameBufferObject->SetDepthTextureAttachment(m_MainDepthRT, 0); m_FrameBufferObject->Activate(); graphics_engine.SetViewport(0, 0, width, height); ClientDraw(graphics_engine, m_ctx, force_draw); } if (prev_fbo_.IsValid()) { // Restore the previous fbo prev_fbo_->Activate(); prev_fbo_->ApplyClippingRegion(); } // Restore the matrices and the view port. graphics_engine.ApplyModelViewMatrix(); graphics_engine.SetOrthographicProjectionMatrix(prev_viewport_.width, prev_viewport_.height); graphics_engine.SetViewport(prev_viewport_.x, prev_viewport_.y, prev_viewport_.width, prev_viewport_.height); { unsigned int w, h; w = m_MainColorRT->GetWidth(); h = m_MainColorRT->GetHeight(); int x = m_ctx.x; int y = m_ctx.y; TexCoordXForm texxform0; texxform0.uwrap = TEXWRAP_CLAMP; texxform0.vwrap = TEXWRAP_CLAMP; texxform0.FlipVCoord(true); GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(x, y, w, h, m_MainColorRT, texxform0, Color(color::White)); } // restore blend states graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } void ClientArea::Draw(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { // don't draw here or we risk drawing more than one time. //BeginDraw(graphics_engine, force_draw); } void ClientArea::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { BeginDraw(graphics_engine, force_draw); } void ClientArea::ClientDraw(GraphicsEngine & /* graphics_engine */, DrawAreaContext & /* ctx */, bool /* force_draw */) { glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); } void ClientArea::SetClientViewport(GraphicsEngine &graphics_engine) { if (GetWindowThread()->GetGraphicsDisplay().HasFrameBufferSupport()) { graphics_engine.SetViewport(0, 0, m_FrameBufferObject->GetWidth(), m_FrameBufferObject->GetHeight()); m_FrameBufferObject->EmptyClippingRegion(); } else { int window_height = graphics_engine.GetViewportHeight(); graphics_engine.SetViewport( m_ctx.x, window_height - m_ctx.y - m_ctx.height, m_ctx.width, m_ctx.height); graphics_engine.SetOpenGLClippingRectangle( m_ctx.x_clipregion, window_height - m_ctx.y_clipregion - m_ctx.height_clipregion, m_ctx.width_clipregion, m_ctx.height_clipregion); } } void ClientArea::Setup2DMode(GraphicsEngine &graphics_engine) { //Restore 2D ViewPort graphics_engine.SetViewport(0, 0, GetBaseWidth(), GetBaseHeight()); graphics_engine.Push2DWindow(GetBaseWidth(), GetBaseHeight()); } void ClientArea::RecvMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } void ClientArea::RecvMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } void ClientArea::RecvMouseDrag(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } void ClientArea::RecvMouseMove(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } void ClientArea::RecvKeyEvent( unsigned long /* event_type */, /*event type*/ unsigned long /* GetKeySym */, /*event keysym*/ unsigned long /* event_state */, /*event state*/ const char* /* event_char */, /*character*/ unsigned short /* repeat_count */ /*key repeat count*/ ) { } bool ClientArea::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/FileSelector.cpp0000644000015301777760000001036612321344237020601 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "FileSelector.h" #include "EditTextBox.h" #include "HLayout.h" #include "Button.h" namespace nux { Color FILESELECTOR_BUTTON_COLOR = Color(0xFF4D4D4D); Color FILESELECTOR_BUTTON_MOUSEOVER_COLOR = Color(0xFF222222); FileSelector::FileSelector(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { m_hlayout = new HLayout(NUX_TRACKER_LOCATION); m_OpenButton = new Button("", NUX_TRACKER_LOCATION); m_FileEditTextBox = new EditTextBox("", NUX_TRACKER_LOCATION); m_hlayout->AddView(m_FileEditTextBox, 1, eCenter); m_hlayout->AddView(m_OpenButton, 0, eCenter); //m_OpenButton->setCaption("..."); m_OpenButton->SetMinimumWidth(20); m_OpenButton->mouse_enter.connect(sigc::mem_fun(this, &FileSelector::RecvMouseEnter)); m_OpenButton->mouse_leave.connect(sigc::mem_fun(this, &FileSelector::RecvMouseLeave)); m_OpenButton->mouse_click.connect(sigc::mem_fun(this, &FileSelector::RecvOpenButtonClick)); SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); SetLayout(m_hlayout); std::string Path = NUX_FINDRESOURCELOCATION("Icons/Folder-16x16.png"); m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); m_Texture->Update(Path.c_str()); } FileSelector::~FileSelector() { m_Texture->UnReference(); } void FileSelector::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); GetPainter().PaintBackground(graphics_engine, base); if (m_OpenButton->IsMouseInside()) { GetPainter().PaintShapeCorner(graphics_engine, m_OpenButton->GetGeometry(), FILESELECTOR_BUTTON_MOUSEOVER_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopRight | eCornerBottomRight, false); } else { GetPainter().PaintShapeCorner(graphics_engine, m_OpenButton->GetGeometry(), FILESELECTOR_BUTTON_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopRight | eCornerBottomRight, false); } GeometryPositioning gp(eHACenter, eVACenter); Geometry TextureGeo = Geometry(0, 0, m_Texture->GetWidth(), m_Texture->GetHeight()); Geometry GeoPo = ComputeGeometryPositioning(m_OpenButton->GetGeometry(), TextureGeo, gp); GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetBlend(TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetColorMask(TRUE, TRUE, TRUE, FALSE); nux::TexCoordXForm texxform; graphics_engine.QRP_1Tex(GeoPo.x, GeoPo.y, GeoPo.width, GeoPo.height, m_Texture->GetDeviceTexture(), texxform, nux::color::White); GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetColorMask(TRUE, TRUE, TRUE, TRUE); GetGraphicsDisplay()->GetGraphicsEngine()->GetRenderStates().SetBlend(FALSE); m_FileEditTextBox->QueueDraw(); } void FileSelector::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { m_FileEditTextBox->ProcessDraw(graphics_engine, force_draw); } void FileSelector::RecvMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void FileSelector::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void FileSelector::RecvOpenButtonClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); sigClick.emit(); } } nux-4.0.6+14.04.20140409/Nux/PopUpWindow.h0000644000015301777760000000243212321344237020114 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef POPUPWINDOW_H #define POPUPWINDOW_H #include "FloatingWindow.h" namespace nux { class Layout; // This class implements a window without a taskbar. It can contain any can of layout. // The purpose is to implement a window that pop ups with complexe widget inside. // The basic popup widget only displays text options. class PopUpWindow : public FloatingWindow { public: PopUpWindow(); ~PopUpWindow(); void Show(); void Hide(); private: }; } #endif // POPUPWINDOW_H nux-4.0.6+14.04.20140409/Nux/XICClient.cpp0000644000015301777760000001671312321344237020005 0ustar pbusernogroup00000000000000/* * Copyright 2012-2013 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * */ #include "XICClient.h" #include "NuxCore/Logger.h" DECLARE_LOGGER(logger, "xic.client"); using namespace std; namespace nux { int const FEEDBACK_MASK = (XIMUnderline | XIMReverse); XICClient::XICClient() : xic_(nullptr) , xim_style_(0) , focused_(false) { } void XICClient::ResetXIC(XIM xim, Window window, Display* display) { if (!xim_style_) SetupXIMStyle(xim); SetupXIC(xim, window, display); } void XICClient::SetCurrentTextEntry(TextEntry* text_entry) { text_entry_ = text_entry; } static int preedit_caret_callback(XIC xic, XPointer clientdata, XIMPreeditCaretCallbackStruct* call_data) { return 0; } static int status_start_callback(XIC xic, XPointer clientdata, XIMPreeditDrawCallbackStruct* call_data) { return 0; } static void status_draw_callback(XIC xic, XPointer clientdata, XPointer* call_data) { } static void status_done_callback(XIC xic, XPointer clientdata, XPointer* call_data) { } XVaNestedList XICClient::GetPreeditCallbacks() { preedit_start_cb_.callback = (XIMProc)XICClient::PreeditStartCallback; preedit_start_cb_.client_data = nullptr; preedit_done_cb_.callback = (XIMProc)XICClient::PreeditDoneCallback; preedit_done_cb_.client_data = (XPointer)text_entry_; preedit_draw_cb_.callback = (XIMProc)XICClient::PreeditDrawCallback; preedit_draw_cb_.client_data = (XPointer)text_entry_; preedit_caret_cb_.callback = (XIMProc)preedit_caret_callback; preedit_caret_cb_.client_data = nullptr; XVaNestedList p_list = nullptr; p_list = XVaCreateNestedList(0, XNPreeditStartCallback, &preedit_start_cb_, XNPreeditDoneCallback, &preedit_done_cb_, XNPreeditDrawCallback, &preedit_draw_cb_, XNPreeditCaretCallback, &preedit_caret_cb_, nullptr); return p_list; } XVaNestedList XICClient::GetStatusCallbacks() { status_start_cb_.callback = (XIMProc)status_start_callback; status_start_cb_.client_data = nullptr; status_done_cb_.callback = (XIMProc)status_done_callback; status_done_cb_.client_data = nullptr; status_draw_cb_.callback = (XIMProc)status_draw_callback; status_draw_cb_.client_data = nullptr; XVaNestedList s_list = nullptr; s_list = XVaCreateNestedList(0, XNStatusStartCallback, &status_start_callback, XNStatusDoneCallback, &status_done_callback, XNStatusDrawCallback, &status_draw_callback, nullptr); return s_list; } XIMStyle XICClient::FilterXIMStyle() { XIMStyle style = 0; if (xim_style_ & XIMPreeditCallbacks) { style |= XIMPreeditCallbacks; } else if (xim_style_ & XIMPreeditNone) { style |= XIMPreeditNone; } else { style |= XIMPreeditNothing; } if (xim_style_ & XIMStatusCallbacks) { style |= XIMStatusCallbacks; } else if (xim_style_ & XIMStatusNone) { style |= XIMStatusNone; } else { style |= XIMStatusNothing; } return style; } void XICClient::SetupXIC(XIM xim, Window window, Display* display) { if (xic_) DestroyXIC(); XIMStyle style = FilterXIMStyle(); const char* p_name = nullptr; XVaNestedList p_list = nullptr; if (style & XIMPreeditCallbacks) { p_list = GetPreeditCallbacks(); p_name = XNPreeditAttributes; } const char* s_name = nullptr; XVaNestedList s_list = nullptr; if (style & XIMStatusCallbacks) { s_list = GetStatusCallbacks(); s_name = XNStatusAttributes; } xic_ = XCreateIC(xim, XNInputStyle, style, XNClientWindow, window, p_name, p_list, s_name, s_list, nullptr); if (p_list) XFree(p_list); if (s_list) XFree(s_list); xim_style_ = style; } XIMStyle ChooseBetterStyle(XIMStyle style1, XIMStyle style2) { XIMStyle s,t; XIMStyle preedit = XIMPreeditArea | XIMPreeditCallbacks | XIMPreeditPosition | XIMPreeditNothing | XIMPreeditNone; XIMStyle status = XIMStatusArea | XIMStatusCallbacks | XIMStatusNothing | XIMStatusNone; if (style1 == 0) return style2; if (style2 == 0) return style1; if ((style1 & (preedit | status)) == (style2 & (preedit | status))) return style1; s = style1 & preedit; t = style2 & preedit; if (s != t) { if (s | t | XIMPreeditCallbacks) return (s == XIMPreeditCallbacks) ? style1 : style2; else if (s | t | XIMPreeditPosition) return (s == XIMPreeditPosition) ? style1 : style2; else if (s | t | XIMPreeditArea) return (s == XIMPreeditArea) ? style1 : style2; else if (s | t | XIMPreeditNothing) return (s == XIMPreeditNothing) ? style1 : style2; else if (s | t | XIMPreeditNone) return (s == XIMPreeditNone) ? style1 : style2; } else { s = style1 & status; t = style2 & status; if (s | t | XIMStatusCallbacks) return (s == XIMStatusCallbacks) ? style1 : style2; else if (s | t | XIMStatusArea) return (s == XIMStatusArea) ? style1 : style2; else if (s | t | XIMStatusNothing) return (s == XIMStatusNothing) ? style1 : style2; else if (s | t | XIMStatusNone) return (s == XIMStatusNone) ? style1 : style2; } } void XICClient::SetupXIMStyle(XIM xim) { int i; XIMStyles *xim_styles = nullptr; XIMStyle prefered_style = XIMPreeditCallbacks | XIMStatusCallbacks; XGetIMValues(xim, XNQueryInputStyle, &xim_styles, nullptr); XIMStyle best = 0, style = 0; for (i = 0; i < xim_styles->count_styles; ++i) { style = xim_styles->supported_styles[i]; if ((style & prefered_style) == style) { best = ChooseBetterStyle(style, best); break; } else { best = ChooseBetterStyle(style, best); } } xim_style_ = best; XFree(xim_styles); } bool XICClient::HasXIC() const { return xic_ != nullptr; } XIC XICClient::GetXIC() const { return xic_; } void XICClient::Reinitialize() { xic_ = nullptr; xim_style_ = 0; focused_ = false; } void XICClient::FocusInXIC() { if (xic_ && !focused_) { XSetICFocus(xic_); focused_ = true; } } void XICClient::FocusOutXIC() { if (xic_ && focused_) { XUnsetICFocus(xic_); focused_ = false; } } bool XICClient::IsFocused() const { return focused_; } void XICClient::DestroyXIC() { if (xic_) { XDestroyIC(xic_); xic_ = nullptr; } } } //namespace nux nux-4.0.6+14.04.20140409/Nux/KeyboardHandler.h0000644000015301777760000001060412321344237020717 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef KEYBOARDHANDLER_H #define KEYBOARDHANDLER_H #include #include "Utils.h" #include "NuxGraphics/FontTexture.h" #if defined(NUX_OS_WINDOWS) #include "NuxGraphics/Events.h" #elif defined(NUX_OS_LINUX) #include "NuxGraphics/Events.h" #endif #include "NuxCore/Color.h" namespace nux { class GraphicsEngine; class BaseKeyboardHandler { public: enum eKeyEntryType { eAlphaNumeric, eDecimalNumber, eIntegerNumber, eHexadecimalNumber, eBinaryNumber }; BaseKeyboardHandler(); virtual ~BaseKeyboardHandler(); virtual long ProcessKey( unsigned long eventType /*event type*/, unsigned long keysym /*event keysym*/, unsigned long state /*event state*/, char character /*character*/, const Geometry &g); std::string GetTextLine() const { return m_textline; } unsigned int GetLength() const { return (unsigned int) m_textline.length(); } unsigned int GetCursorPosition() const { return m_caret; } bool QueueDraw() const { return m_need_redraw; } int GetPositionX() const { return m_text_positionx; } int GetPositionY() const { return m_text_positiony; } void SetText(const char *str); void SetText(const std::string &s); void ClearText(); void PlaceCaret(unsigned int cp); void MoveCursorAtStart(); void MoveCursorAtEnd(); void SetKeyEntryType(eKeyEntryType keytype); eKeyEntryType GetKeyEntryType(); void SetClipRegion(const Geometry &g); void GetTextSelection(int *start, int *end) const; int GetTextSelectionStart() const; int GetTextSelectionEnd() const; std::string GetSelectedText() const; void SelectAllText(); void UnselectAllText(); bool IsTextSelected(); void SetPrefix(std::string); // 0x865, 25 rad, 25 degree... void SetPostfix(std::string); void EnterFocus(); unsigned int NextWordPosition(unsigned int cp); unsigned int PrevWordPosition(unsigned int cp); void ResolveCaretPosition(int x, int y); void CaretAutoScroll(int x, int y, Geometry geo); void MouseDown(int x, int y); void MouseUp(int x, int y); void MouseDrag(int x, int y); //bool IsMouseDrag(); void SetFont(ObjectPtr Font); ObjectPtr GetFont() const; protected: ObjectPtr m_Font; std::string m_textline; int m_previous_cursor_position; bool m_need_redraw; int m_text_positionx; int m_text_positiony; Geometry m_clip_region; eKeyEntryType m_KeyType; int m_caret; //!< Caret position, in characters bool m_insert_mode; //!< If true, control is in insert mode. Else, overwrite mode. int m_selection_start; //!< Starting position of the selection. The caret marks the end. int m_first_visible_char; //!< First visible character in the edit control void DeleteSelectionText(); void InsertChar(unsigned int character); void AdjustCursorAndTextPosition(); bool m_entering_focus; bool m_mouse_drag; // m_mouse_inside_text_area Detects the fast transition of the mouse from inside the text area to outside bool m_mouse_inside_text_area; /*! When the caret reaches the left or right border of the control and there are more characters to reveals, the caret jumps back in the opposite direction by a number of pixel at the same moment when new characters are revealed. */ static int s_jump_offset_at_borders; static int s_cursor_width; }; } #endif // KEYBOARDHANDLER_H nux-4.0.6+14.04.20140409/Nux/TabView.cpp0000644000015301777760000004317412321344237017565 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "TabView.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" namespace nux { int TabView::TAB_BUTTON_WIDTH = 12; int TabView::TAB_BUTTON_HEIGHT = 20; int TabView::TAB_HEIGHT = 24; int TabView::TAB_X_BORDER = 4; int TabView::TAB_Y_BORDER = 4; Color TabView::TAB_HEADER_BACKGROUND_COLOR = Color(0xFF000000); Color TabView::TAB_BACKGROUND_COLOR = Color(0xFF191919); Color TabView::TAB_HEADER_COLOR = Color(0xFF333333); Color TabView::TAB_HEADER_FOCUS_COLOR = Color(0xFF5D5D5D); TabView::TabElement::TabElement(std::string TabName, Layout *TabLayout) { _index = 0; _tab_name = TabName; _tab_content_layout = TabLayout; _tab_area = new BasicView(NUX_TRACKER_LOCATION); _tab_content_layout->Reference(); _tab_area->Reference(); } TabView::TabElement::~TabElement() { _index = 0; _tab_content_layout->UnReference(); _tab_area->UnReference(); } void TabView::TabElement::SetIndex(int index) { _index = index; } int TabView::TabElement::GetIndex() const { return _index; } void TabView::TabElement::SetGeometry(const Geometry &geo) { _tab_area->SetGeometry(geo); } Geometry const& TabView::TabElement::GetGeometry() const { return _tab_area->GetGeometry(); } const std::string &TabView::TabElement::GetName() const { return _tab_name; } TabView::TabView(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { _scroll_right = NULL; _scroll_left = NULL; _visible_tab_content_layout = NULL; _tabview_heads_layout = NULL; _tabview_scroll_button_layout = NULL; m_FocusTabIndex = 0; m_TabPositionOffset = 0; m_DrawBackgroundOnPreviousGeometry = false; _tabview_heads_layout = new HLayout(NUX_TRACKER_LOCATION); //_tabview_heads_layout->SetParentObject(this); _tabview_scroll_button_layout = new HLayout(NUX_TRACKER_LOCATION); _tabview_scroll_button_layout->SetParentObject(this); _scroll_right = new BasicView(NUX_TRACKER_LOCATION); _scroll_left = new BasicView(NUX_TRACKER_LOCATION); _scroll_right->SetMinimumSize(TAB_BUTTON_WIDTH, TAB_BUTTON_HEIGHT); _scroll_left->SetMinimumSize(TAB_BUTTON_WIDTH, TAB_BUTTON_HEIGHT); _scroll_right->SetMaximumSize(TAB_BUTTON_WIDTH, TAB_BUTTON_HEIGHT); _scroll_left->SetMaximumSize(TAB_BUTTON_WIDTH, TAB_BUTTON_HEIGHT); _scroll_right->mouse_enter.connect(sigc::mem_fun(this, &TabView::RecvMouseEnter)); _scroll_right->mouse_leave.connect(sigc::mem_fun(this, &TabView::RecvMouseLeave)); _scroll_left->mouse_enter.connect(sigc::mem_fun(this, &TabView::RecvMouseEnter)); _scroll_left->mouse_leave.connect(sigc::mem_fun(this, &TabView::RecvMouseLeave)); _scroll_right->mouse_down.connect(sigc::mem_fun(this, &TabView::RecvTabRightMouseDown)); _scroll_left->mouse_down.connect(sigc::mem_fun(this, &TabView::RecvTabLeftMouseDown)); _scroll_right->mouse_up.connect(sigc::mem_fun(this, &TabView::RecvTabButtonMouseUp)); _scroll_left->mouse_up.connect(sigc::mem_fun(this, &TabView::RecvTabButtonMouseUp)); _tabview_scroll_button_layout->AddView(_scroll_left, 1, eCenter); _tabview_scroll_button_layout->AddView(_scroll_right, 1, eCenter); tabright_callback = new TimerFunctor; tabright_callback->tick.connect(sigc::mem_fun(this, &TabView::RecvTabRightTimerExpired)); tableft_callback = new TimerFunctor; tableft_callback->tick.connect(sigc::mem_fun(this, &TabView::RecvTabLeftTimerExpired)); } TabView::~TabView() { _tabview_heads_layout->UnReference(); _tabview_scroll_button_layout->UnReference(); RemoveCompositionLayout(); delete(tabright_callback); delete(tableft_callback); std::vector::iterator it; for (it = _tab_array.begin(); it != _tab_array.end(); it++) { (*it)->_tab_area->UnParentObject(); (*it)->_tab_content_layout->UnParentObject(); delete(*it); } _tab_array.clear(); } Area* TabView::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; NUX_RETURN_VALUE_IF_TRUE(_scroll_right->TestMousePointerInclusion(mouse_position, event_type), _scroll_right); NUX_RETURN_VALUE_IF_TRUE(_scroll_left->TestMousePointerInclusion(mouse_position, event_type), _scroll_left); unsigned int vector_size = (unsigned int) _tab_array.size(); for (unsigned int i = 0; i < vector_size; i++) { NUX_RETURN_VALUE_IF_TRUE(_tab_array[i]->_tab_area->TestMousePointerInclusion(mouse_position, event_type), _tab_array[i]->_tab_area); } if (_visible_tab_content_layout) { nuxAssert(_visible_tab_content_layout->IsLayout()); Area* found_area = _visible_tab_content_layout->FindAreaUnderMouse(mouse_position, event_type); if (found_area) return found_area; } return this; } void TabView::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { if (m_DrawBackgroundOnPreviousGeometry) { GetPainter().PaintBackground(graphics_engine, m_PreviousGeometry); m_DrawBackgroundOnPreviousGeometry = false; } graphics_engine.PushClippingRectangle(GetGeometry()); Geometry base = GetGeometry(); GetPainter().PushDrawShapeLayer(graphics_engine, Geometry(base.x, base.y, base.GetWidth(), TAB_HEIGHT), eSHAPE_CORNER_ROUND4, TAB_HEADER_BACKGROUND_COLOR, eCornerTopLeft | eCornerTopRight); if (_visible_tab_content_layout) _visible_tab_content_layout->QueueDraw(); unsigned int vector_size = (unsigned int) _tab_array.size(); Geometry geo = GetGeometry(); Geometry clip_geo; clip_geo.SetX(geo.x); clip_geo.SetY(geo.y); clip_geo.SetWidth(geo.GetWidth() - 2 * TAB_BUTTON_WIDTH); clip_geo.SetHeight(_tabview_heads_layout->GetBaseHeight()); graphics_engine.PushClippingRectangle(clip_geo); for (unsigned int i = 0; i < vector_size; i++) { Geometry tab_geo = _tab_array[i]->_tab_area->GetGeometry(); const char *tab_text = _tab_array[i]->GetName().c_str(); if (_tab_array[i]->_index == m_FocusTabIndex) { tab_geo.OffsetSize(-2, 0); GetPainter().PaintShapeCorner(graphics_engine, tab_geo, TAB_HEADER_FOCUS_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopLeft | eCornerTopRight, false); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), tab_geo, tab_text, Color(0xFFFFFFFF), true, eAlignTextCenter); } else { tab_geo.OffsetSize(-2, 0); GetPainter().PaintShapeCorner(graphics_engine, tab_geo, TAB_HEADER_COLOR, eSHAPE_CORNER_ROUND4, eCornerTopLeft | eCornerTopRight, false); GetPainter().PaintTextLineStatic(graphics_engine, GetSysBoldFont(), tab_geo, tab_text, Color(0xFF000000), true, eAlignTextCenter); } } graphics_engine.PopClippingRectangle(); GetPainter().PaintShapeCorner(graphics_engine, Geometry(base.x, base.y + TAB_HEIGHT, base.GetWidth(), base.GetHeight() - TAB_HEIGHT), TAB_BACKGROUND_COLOR, eSHAPE_CORNER_ROUND4, eCornerBottomLeft | eCornerBottomRight, false); GetPainter().Paint2DQuadColor(graphics_engine, _scroll_right->GetGeometry(), TAB_HEADER_BACKGROUND_COLOR); GeometryPositioning gp(eHACenter, eVACenter); Geometry GeoPo = ComputeGeometryPositioning(_scroll_right->GetGeometry(), GetTheme().GetImageGeometry(eTAB_RIGHT), gp); if (_scroll_right->IsMouseInside()) GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eTAB_RIGHT); else GetPainter().PaintShape(graphics_engine, GeoPo, TAB_HEADER_FOCUS_COLOR, eTAB_RIGHT); GetPainter().Paint2DQuadColor(graphics_engine, _scroll_left->GetGeometry(), TAB_HEADER_BACKGROUND_COLOR); gp.SetAlignment(eHACenter, eVACenter); GeoPo = ComputeGeometryPositioning(_scroll_left->GetGeometry(), GetTheme().GetImageGeometry(eTAB_LEFT), gp); if (_scroll_left->IsMouseInside()) GetPainter().PaintShape(graphics_engine, GeoPo, Color(0xFFFFFFFF), eTAB_LEFT); else GetPainter().PaintShape(graphics_engine, GeoPo, TAB_HEADER_FOCUS_COLOR, eTAB_LEFT); GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } void TabView::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(GetGeometry()); GetPainter().PushShapeLayer(graphics_engine, Geometry(base.x, base.y + TAB_HEIGHT, base.GetWidth(), base.GetHeight() - TAB_HEIGHT), eSHAPE_CORNER_ROUND4, TAB_BACKGROUND_COLOR, eCornerBottomLeft | eCornerBottomRight); if (_visible_tab_content_layout) { graphics_engine.PushClippingRectangle(_visible_tab_content_layout->GetGeometry()); _visible_tab_content_layout->ProcessDraw(graphics_engine, force_draw); graphics_engine.PopClippingRectangle(); } GetPainter().PopBackground(); graphics_engine.PopClippingRectangle(); } void TabView::PreLayoutManagement() { // Give the managed layout appropriate size and position.. if (view_layout_) { Geometry layout_geo = GetGeometry(); layout_geo.OffsetPosition(TAB_X_BORDER, TAB_HEIGHT); layout_geo.OffsetSize(-2 * TAB_X_BORDER, - (TAB_HEIGHT) - TAB_Y_BORDER); view_layout_->SetGeometry(layout_geo); } } long TabView::PostLayoutManagement(long LayoutResult) { // Set the geometry of the control to be the same as the managed layout. // Only the size is changed. The position of the composition layout hasn't // been changed by ComputeContentSize. if (view_layout_) { Geometry base = view_layout_->GetGeometry(); base.OffsetPosition(-TAB_X_BORDER, -TAB_HEIGHT); base.OffsetSize(2 * TAB_X_BORDER, TAB_HEIGHT + TAB_Y_BORDER); Area::SetGeometry(base); } Geometry base = GetGeometry(); int tab_x = view_layout_->GetGeometry().x + view_layout_->GetGeometry().GetWidth() - 2 * TAB_BUTTON_WIDTH; int tab_y = base.y; _scroll_left->SetBaseXY(tab_x, tab_y); _scroll_left->SetBaseSize(TAB_BUTTON_WIDTH, TAB_BUTTON_HEIGHT); _scroll_right->SetBaseXY(tab_x + TAB_BUTTON_WIDTH, tab_y); _scroll_right->SetBaseSize(TAB_BUTTON_WIDTH, TAB_BUTTON_HEIGHT); _tabview_heads_layout->SetBaseY(tab_y); _tabview_heads_layout->SetBaseHeight(TAB_HEIGHT); TranslateTabLayout(0); _tabview_scroll_button_layout->SetBaseXY(tab_x, tab_y); _tabview_scroll_button_layout->SetBaseSize(2 * TAB_BUTTON_WIDTH, TAB_HEIGHT); GetWindowThread()->ComputeElementLayout(_tabview_scroll_button_layout); if (_visible_tab_content_layout) { // _visible_tab_content_layout->SetGeometry(view_layout_->GetGeometry()); // GetWindowThread()->ComputeElementLayout(_visible_tab_content_layout); _visible_tab_content_layout->QueueDraw(); } return LayoutResult; } void TabView::ComputeContentPosition(float offsetX, float offsetY) { if (view_layout_) { view_layout_->SetBaseX(GetBaseX() + TAB_X_BORDER); view_layout_->SetBaseY(GetBaseY() + TAB_HEIGHT); view_layout_->ComputeContentPosition(offsetX, offsetY); } } void TabView::AddTab(const char *tab_name, Layout *tab_layout) { if (tab_layout == 0) return; TabElement *Tab = new TabElement(tab_name, tab_layout); Tab->SetIndex(_tab_array.size()); if (Tab->GetIndex() == 0) { m_FocusTabIndex = 0; _visible_tab_content_layout = Tab->_tab_content_layout; //_visible_tab_content_layout->SetGeometry(view_layout_->GetGeometry()); SetCompositionLayout(_visible_tab_content_layout); GetWindowThread()->ComputeElementLayout(this); } Tab->_tab_area->SetMinimumSize(6 + GetSysBoldFont()->GetStringWidth(tab_name), PRACTICAL_WIDGET_HEIGHT); Tab->_tab_area->SetMaximumSize(6 + GetSysBoldFont()->GetStringWidth(tab_name), PRACTICAL_WIDGET_HEIGHT); Tab->_tab_area->mouse_down.connect(sigc::bind(sigc::mem_fun(this, &TabView::RecvTabMouseDown), Tab)); Tab->_tab_area->mouse_up.connect(sigc::bind(sigc::mem_fun(this, &TabView::RecvTabMouseUp), Tab)); _tabview_heads_layout->AddView(Tab->_tab_area, 1, eCenter); GetWindowThread()->ComputeElementLayout(_tabview_heads_layout); _tab_array.push_back(Tab); } void TabView::SetActiveTad(int index) { if (index >= (int) _tab_array.size()) { m_FocusTabIndex = (int) _tab_array.size() - 1; } else { m_FocusTabIndex = index; } _visible_tab_content_layout = _tab_array[m_FocusTabIndex]->_tab_content_layout; if (_visible_tab_content_layout) SetCompositionLayout(_visible_tab_content_layout); GetWindowThread()->ComputeElementLayout(this); sigTabChanged(this); sigTabIndexChanged(m_FocusTabIndex); QueueDraw(); } void TabView::TranslateLeft(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { TranslateTabLayout(-5); } void TabView::TranslateRight(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { TranslateTabLayout(5); } void TabView::TranslateTabLayout(int offset) { // if ((m_TabPositionOffset == 0) && (offset > 0)) // return; m_TabPositionOffset += offset; int lx = view_layout_->GetBaseX() + m_TabPositionOffset; if (lx > view_layout_->GetBaseX()) { // end of scroll left; m_TabPositionOffset = 0; lx = view_layout_->GetBaseX() + m_TabPositionOffset; } if (lx + _tabview_heads_layout->GetBaseWidth() < view_layout_->GetBaseX() + view_layout_->GetBaseWidth() - 2 * TAB_BUTTON_WIDTH) { lx = (view_layout_->GetBaseX() + view_layout_->GetBaseWidth() - 2 * TAB_BUTTON_WIDTH) - _tabview_heads_layout->GetBaseWidth(); if (lx > view_layout_->GetBaseX()) { m_TabPositionOffset = 0; lx = view_layout_->GetBaseX() + m_TabPositionOffset; } else m_TabPositionOffset = - (view_layout_->GetBaseX() - lx); } _tabview_heads_layout->SetBaseX(lx); GetWindowThread()->ComputeElementLayout(_tabview_heads_layout); QueueDraw(); } void TabView::RecvTabMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */, TabElement *tab) { m_FocusTabIndex = tab->_index; _visible_tab_content_layout = tab->_tab_content_layout; if (_visible_tab_content_layout) { SetCompositionLayout(_visible_tab_content_layout); } //_visible_tab_content_layout->SetGeometry(view_layout_->GetGeometry()); m_PreviousGeometry = GetGeometry(); int PrevWidth = GetBaseWidth(); int PrevHeight = GetBaseHeight(); GetWindowThread()->ComputeElementLayout(this, true); int NewWidth = GetBaseWidth(); int NewHeight = GetBaseHeight(); if ((NewWidth != PrevWidth) || (NewHeight != PrevHeight)) { // We need to draw the background on the previous size of the Table if its // size is set to match the content(IsSizeMatchContent) and an item is close. //m_PreviousGeometry; m_DrawBackgroundOnPreviousGeometry = true; } m_DrawBackgroundOnPreviousGeometry = true; sigTabChanged(this); sigTabIndexChanged(m_FocusTabIndex); QueueDraw(); } void TabView::RecvTabMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */, TabElement * /* tab */) { } void TabView::RecvMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void TabView::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void TabView::RecvTabRightMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { RecvTabRightTimerExpired(tabright_callback); } void TabView::RecvTabLeftMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { RecvTabLeftTimerExpired(tableft_callback); } void TabView::RecvTabButtonMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_TabRightTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_TabRightTimerHandler); if (m_TabLeftTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_TabLeftTimerHandler); m_TabRightTimerHandler = 0; m_TabLeftTimerHandler = 0; } void TabView::RecvTabRightTimerExpired(void * /* v */) { TranslateTabLayout(-10); m_TabRightTimerHandler = GetTimer().AddOneShotTimer(10, tabright_callback, this); } void TabView::RecvTabLeftTimerExpired(void * /* v */) { TranslateTabLayout(10); m_TabLeftTimerHandler = GetTimer().AddOneShotTimer(10, tableft_callback, this); } bool TabView::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/ScrollView.cpp0000644000015301777760000005551512321344237020317 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2010-2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HScrollBar.h" #include "VScrollBar.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "ScrollView.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(ScrollView); ScrollView::ScrollView(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_MouseWheelScrollSize(32) // TODO: these should really be Rects. , m_ViewContentX(0) , m_ViewContentY(0) , m_ViewContentWidth(0) , m_ViewContentHeight(0) , m_ViewX(0) , m_ViewY(0) , m_ViewWidth(0) , m_ViewHeight(0) , m_TextureIndex(0) , m_ReformatTexture(true) , m_horizontal_scrollbar_enable(true) , m_vertical_scrollbar_enable(true) , m_top_border(0) , m_border(0) , _delta_x(0) , _delta_y(0) , m_bSizeMatchContent(false) , m_ViewContentLeftMargin(0) , m_ViewContentRightMargin(0) , m_ViewContentTopMargin(0) , m_ViewContentBottomMargin(0) { _hscrollbar = new HScrollBar(NUX_TRACKER_LOCATION); _vscrollbar = new VScrollBar(NUX_TRACKER_LOCATION); // _hscrollbar and _vscrollbar have to be parented so they are correctly // rendered and so that GetRootGeometry/GetAbsoluteGeometry returns the // correct Geometry. This is necessary in embedded mode. _hscrollbar->SetParentObject(this); _vscrollbar->SetParentObject(this); _hscrollbar->SetReconfigureParentLayoutOnGeometryChange(false); _vscrollbar->SetReconfigureParentLayoutOnGeometryChange(false); SetMinimumSize(30, 30); SetGeometry(Geometry(0, 0, 400, 200)); _hscrollbar->OnScrollLeft.connect(sigc::mem_fun(this, &ScrollView::ScrollLeft)); _hscrollbar->OnScrollRight.connect(sigc::mem_fun(this, &ScrollView::ScrollRight)); _vscrollbar->OnScrollUp.connect(sigc::mem_fun(this, &ScrollView::ScrollUp)); _vscrollbar->OnScrollDown.connect(sigc::mem_fun(this, &ScrollView::ScrollDown)); mouse_wheel.connect(sigc::mem_fun(this, &ScrollView::RecvMouseWheel)); _vscrollbar->mouse_wheel.connect(sigc::mem_fun(this, &ScrollView::RecvMouseWheel)); FormatContent(); SetAcceptMouseWheelEvent(true); } // customization for Unity void ScrollView::SetVScrollBar(VScrollBar* newVScrollBar) { if (_vscrollbar) { // disconnect old _vscrollbar _vscrollbar->OnScrollUp.connect(sigc::mem_fun(this, &ScrollView::ScrollUp)); _vscrollbar->OnScrollDown.connect(sigc::mem_fun(this, &ScrollView::ScrollDown)); _vscrollbar->mouse_wheel.connect(sigc::mem_fun(this, &ScrollView::RecvMouseWheel)); _vscrollbar->UnReference(); } _vscrollbar = newVScrollBar; _vscrollbar->SetParentObject(this); _vscrollbar->SetReconfigureParentLayoutOnGeometryChange(false); // connect new _vscrollbar _vscrollbar->OnScrollUp.connect(sigc::mem_fun(this, &ScrollView::ScrollUp)); _vscrollbar->OnScrollDown.connect(sigc::mem_fun(this, &ScrollView::ScrollDown)); _vscrollbar->mouse_wheel.connect(sigc::mem_fun(this, &ScrollView::RecvMouseWheel)); } ScrollView::~ScrollView() { // Delete all the interface object: This is a problem... The widget should be destroy by there associated parameters _hscrollbar->UnReference(); _vscrollbar->UnReference(); } Area* ScrollView::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { // Test if the mouse is inside the ScrollView. // The last parameter of TestMousePointerInclusion is a boolean used to test if the case // of mouse wheel events. If that boolean value is true, then TestMousePointerInclusion // returns true only if the mouse pointer is over this area and the the area accepts // mouse wheel events(see Area::SetAcceptMouseWheelEvent) bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) { // The mouse pointer is not over this Area. return NULL. return NULL; } Area* found_area; // Recursively go over the ui element that are managed by this ScrollView and look // for the area that is below the mouse. // Test the vertical scrollbar if (m_vertical_scrollbar_enable) { found_area = _vscrollbar->FindAreaUnderMouse(mouse_position, event_type); NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); } // Test the horizontal scrollbar if (m_horizontal_scrollbar_enable) { found_area = _hscrollbar->FindAreaUnderMouse(mouse_position, event_type); NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area); } // If the code gets here, it means that no area has been found yet. // Test the layout of the ScrollView return View::FindAreaUnderMouse(mouse_position, event_type); } bool ScrollView::SetLayout(Layout *layout) { if (View::SetLayout(layout) == false) { return false; } FormatContent(); return true; } void ScrollView::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { graphics_engine.PushClippingRectangle(GetGeometry()); Geometry base = GetGeometry(); if (view_layout_) view_layout_->QueueDraw(); GetPainter().PaintBackground(graphics_engine, base); if (m_vertical_scrollbar_enable) { _vscrollbar->QueueDraw(); } if (m_horizontal_scrollbar_enable) { _hscrollbar->QueueDraw(); } graphics_engine.PopClippingRectangle(); } void ScrollView::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { if (IsFullRedraw()) GetPainter().PushBackgroundStack(); graphics_engine.PushClippingRectangle(GetGeometry()); graphics_engine.PushClippingRectangle(Rect(m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight)); if (view_layout_) view_layout_->ProcessDraw(graphics_engine, force_draw); graphics_engine.PopClippingRectangle(); if (m_vertical_scrollbar_enable) { _vscrollbar->ProcessDraw(graphics_engine, force_draw); } if (m_horizontal_scrollbar_enable) { _hscrollbar->ProcessDraw(graphics_engine, force_draw); } graphics_engine.PopClippingRectangle(); if (IsFullRedraw()) GetPainter().PopBackgroundStack(); } ///////// // API // ///////// void ScrollView::EnableVerticalScrollBar(bool b) { if (b == m_vertical_scrollbar_enable) return; m_vertical_scrollbar_enable = b; ComputeContentSize(); } void ScrollView::EnableHorizontalScrollBar(bool b) { if (m_horizontal_scrollbar_enable == b) return; m_horizontal_scrollbar_enable = b; ComputeContentSize(); } /////////////////////// // Internal function // /////////////////////// void ScrollView::FormatContent() { Geometry geo; geo = GetGeometry(); ComputeContentSize(); } void ScrollView::PreLayoutManagement() { // Give the managed layout the same size and position as the Control. Geometry geo = GetGeometry(); int ScrollBarWidth = _vscrollbar->GetBaseWidth(); int ScrollBarHeight = _hscrollbar->GetBaseHeight(); nuxAssertMsg(ScrollBarWidth > 0, "[ScrollView::PreLayoutManagement] Invalid scrollbar width: %d", ScrollBarWidth); nuxAssertMsg(ScrollBarHeight > 0, "[ScrollView::PreLayoutManagement] Invalid scrollbar height: %d", ScrollBarHeight); m_ViewX = GetBaseX() + m_border + m_ViewContentLeftMargin; m_ViewY = GetBaseY() + m_top_border + m_ViewContentTopMargin; if (m_vertical_scrollbar_enable == false) m_ViewWidth = GetBaseWidth() - 2 * m_border - m_ViewContentRightMargin - m_ViewContentLeftMargin; else m_ViewWidth = GetBaseWidth() - ScrollBarWidth - 2 * m_border - m_ViewContentRightMargin - m_ViewContentLeftMargin; nuxAssertMsg(m_ViewWidth > 0, "[ScrollView::PreLayoutManagement] Invalid view width: %d", m_ViewWidth); if (m_horizontal_scrollbar_enable == false) m_ViewHeight = GetBaseHeight() - m_top_border - m_border - m_ViewContentBottomMargin - m_ViewContentTopMargin; else m_ViewHeight = GetBaseHeight() - ScrollBarHeight - m_top_border - m_border - m_ViewContentBottomMargin - m_ViewContentTopMargin; nuxAssertMsg(m_ViewHeight > 0, "[ScrollView::PreLayoutManagement] Invalid view height: %d", m_ViewHeight); if (m_ViewX + _delta_x + m_ViewContentWidth < m_ViewX + m_ViewWidth) { // The position of the end of the content is smaller than the view right border position // Compute _delta_x so the end of the content match exactly the view right border position _delta_x = - (m_ViewContentWidth > m_ViewWidth ? m_ViewContentWidth - m_ViewWidth : 0); nuxAssert(_delta_x <= 0); } if (m_ViewY + _delta_y + m_ViewContentHeight < m_ViewY + m_ViewHeight) { // The position of the end of the content is smaller than the view right border position // Compute _delta_y so the end of the content match exactly the view right border position _delta_y = - (m_ViewContentHeight > m_ViewHeight ? m_ViewContentHeight - m_ViewHeight : 0); nuxAssert(_delta_y <= 0); } if (view_layout_) { // Set the composition layout to the size of the view area and offset it by(_delta_x, _delta_y) if (view_layout_->GetScaleFactor() != 0) { view_layout_->SetGeometry( m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight); } view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); } // Horizontal scrollbar Geometry if (m_horizontal_scrollbar_enable) { if (m_vertical_scrollbar_enable == false) { // If there is no vertical scrollbar, take all the width available. _hscrollbar->SetBaseWidth(GetBaseWidth() - 2 * m_border); } else _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollBarWidth - 2 * m_border); _hscrollbar->SetBaseX(geo.x + m_border); _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border); _hscrollbar->ComputeContentSize(); } else { // The horizontal scrollbar won't be visible but give it a proper size anyway. _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollBarWidth - 2 * m_border); _hscrollbar->SetBaseX(geo.x + m_border); _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border); _hscrollbar->ComputeContentSize(); } // Vertical scrollbar Geometry if (m_vertical_scrollbar_enable) { if (m_horizontal_scrollbar_enable == false) { // If there is no horizontal scrollbar, take all the width available. _vscrollbar->SetBaseHeight(GetBaseHeight() - m_top_border - m_border); } else _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollBarHeight - m_top_border - m_border); _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollBarWidth - m_border); _vscrollbar->SetBaseY(geo.y + m_top_border); _vscrollbar->ComputeContentSize(); } else { // The vertical scrollbar won't be visible but give it a proper size anyway. _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollBarHeight - m_top_border - m_border); _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollBarWidth - m_border); _vscrollbar->SetBaseY(geo.y + m_top_border); _vscrollbar->ComputeContentSize(); } } long ScrollView::PostLayoutManagement(long LayoutResult) { int ScrollBarWidth = 0; int ScrollBarHeight = 0; if (view_layout_) { m_ViewContentX = view_layout_->GetBaseX(); m_ViewContentY = view_layout_->GetBaseY(); m_ViewContentWidth = view_layout_->GetBaseWidth(); m_ViewContentHeight = view_layout_->GetBaseHeight(); } if (m_horizontal_scrollbar_enable) ScrollBarHeight = _hscrollbar->GetBaseHeight(); if (m_vertical_scrollbar_enable) ScrollBarWidth = _vscrollbar->GetBaseWidth(); _hscrollbar->SetContainerSize(GetBaseX() + m_border + m_ViewContentLeftMargin, GetBaseY() + m_top_border + m_ViewContentTopMargin, GetBaseWidth() - ScrollBarWidth - 2 * m_border - m_ViewContentRightMargin - m_ViewContentLeftMargin, GetBaseHeight() - ScrollBarHeight - m_top_border - m_border - m_ViewContentBottomMargin - m_ViewContentTopMargin); if (m_horizontal_scrollbar_enable) { if (view_layout_) { _hscrollbar->SetContentSize(view_layout_->GetBaseX(), view_layout_->GetBaseY(), view_layout_->GetBaseWidth(), view_layout_->GetBaseHeight()); } else { _hscrollbar->SetContentSize(GetBaseX() + m_border + m_ViewContentLeftMargin, GetBaseY() + m_top_border + m_ViewContentTopMargin, 0, 0); } _hscrollbar->SetContentOffset(_delta_x, _delta_y); } else { _hscrollbar->SetContentSize(GetBaseX() + m_border + m_ViewContentLeftMargin, GetBaseY() + m_top_border + m_ViewContentTopMargin, 0, 0); _hscrollbar->SetContentOffset(0, 0); } _vscrollbar->SetContainerSize(GetBaseX() + m_border + m_ViewContentLeftMargin, GetBaseY() + m_top_border + m_ViewContentTopMargin, GetBaseWidth() - ScrollBarWidth - 2 * m_border - m_ViewContentRightMargin - m_ViewContentLeftMargin, GetBaseHeight() - ScrollBarHeight - m_top_border - m_border - m_ViewContentBottomMargin - m_ViewContentTopMargin); if (m_vertical_scrollbar_enable) { if (view_layout_) { _vscrollbar->SetContentSize(view_layout_->GetBaseX(), view_layout_->GetBaseY(), view_layout_->GetBaseWidth(), view_layout_->GetBaseHeight()); } else { _vscrollbar->SetContentSize(GetBaseX() + m_border + m_ViewContentLeftMargin, GetBaseY() + m_top_border + m_ViewContentTopMargin, 0, 0); } _vscrollbar->SetContentOffset(_delta_x, _delta_y); } else { _vscrollbar->SetContentSize(GetBaseX() + m_border + m_ViewContentLeftMargin, GetBaseY() + m_top_border + m_ViewContentTopMargin, 0, 0); _vscrollbar->SetContentOffset(0, 0); } // I may not be necessary to call this function here since ComputeContentPosition was called on ComputeContentPosition // during the layout process. if (view_layout_) view_layout_->ComputeContentPosition(0, 0); // The ScrollView always returns complient width and height to its parent layout. return (eCompliantHeight | eCompliantWidth); } // When the ScrollView is in a Layout object, and that layout call View::ComputeContentPosition // the ScrollView must call its own ComputeContentPosition so it can properly do the positioning of the inner object. // Otherwise, view_layout_->ComputeContentPosition is called but it doesn't know that it may not contain all the // object of the ScrollView. Which result in incorrect positioning. // Here we touch only the position. Do not touch the width or height of object. // This function is called when the ScrollView is embedded within a Layout. void ScrollView::ComputeContentPosition(float /* offsetX */, float /* offsetY */) { Geometry geo = GetGeometry(); int w = 0; int h = 0; w = _vscrollbar->GetBaseWidth(); h = _hscrollbar->GetBaseHeight(); m_ViewX = GetBaseX() + m_border + m_ViewContentLeftMargin; m_ViewY = GetBaseY() + m_top_border + m_ViewContentTopMargin; if (m_vertical_scrollbar_enable == false) m_ViewWidth = GetBaseWidth() - 2 * m_border - m_ViewContentRightMargin - m_ViewContentLeftMargin; else m_ViewWidth = GetBaseWidth() - w - 2 * m_border - m_ViewContentRightMargin - m_ViewContentLeftMargin; if (m_horizontal_scrollbar_enable == false) m_ViewHeight = GetBaseHeight() - m_top_border - m_border - m_ViewContentBottomMargin - m_ViewContentTopMargin; else m_ViewHeight = GetBaseHeight() - h - m_top_border - m_border - m_ViewContentBottomMargin - m_ViewContentTopMargin; if (m_ViewX + _delta_x + m_ViewContentWidth < m_ViewX + m_ViewWidth) { _delta_x = - (m_ViewContentWidth > m_ViewWidth ? m_ViewContentWidth - m_ViewWidth : 0); } if (m_ViewY + _delta_y + m_ViewContentHeight < m_ViewY + m_ViewHeight) { _delta_y = - (m_ViewContentHeight > m_ViewHeight ? m_ViewContentHeight - m_ViewHeight : 0); } if (view_layout_) { view_layout_->SetBaseX(m_ViewX); view_layout_->SetBaseY(m_ViewY); } // Horizontal scrollbar Geometry if (m_horizontal_scrollbar_enable) { if (m_vertical_scrollbar_enable == false) _hscrollbar->SetBaseWidth(GetBaseWidth() - 2 * m_border); else _hscrollbar->SetBaseWidth(GetBaseWidth() - w - 2 * m_border); _hscrollbar->SetBaseX(geo.x + m_border); _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border); _hscrollbar->ComputeContentSize(); } // Vertical scrollbar Geometry if (m_vertical_scrollbar_enable) { if (m_horizontal_scrollbar_enable == false) _vscrollbar->SetBaseHeight(GetBaseHeight() - m_top_border - m_border); else _vscrollbar->SetBaseHeight(GetBaseHeight() - h - m_top_border - m_border); _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - w - m_border); _vscrollbar->SetBaseY(geo.y + m_top_border); _vscrollbar->ComputeContentSize(); } if (view_layout_) { m_ViewContentX = view_layout_->GetBaseX(); m_ViewContentY = view_layout_->GetBaseY(); } else { m_ViewContentX = m_ViewX; m_ViewContentY = m_ViewY; } _vscrollbar->SetContentOffset(_delta_x, _delta_y); _hscrollbar->SetContentOffset(_delta_x, _delta_y); if (view_layout_) { view_layout_->ComputeContentPosition(0, 0); } } void ScrollView::ScrollLeft(float stepx, int mousedx) { if (view_layout_) { _delta_x += (float) stepx * (float) mousedx;; if (_delta_x > 0) { _delta_x = 0; } view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); scrolling.emit(_delta_x, _delta_y); } if (view_layout_) { _hscrollbar->SetContentOffset(_delta_x, _delta_y); _hscrollbar->QueueDraw(); } QueueDraw(); } void ScrollView::ScrollRight(float stepx, int mousedx) { if (view_layout_) { _delta_x -= (float) stepx * (float) mousedx; if (m_ViewX + _delta_x + m_ViewContentWidth < m_ViewX + m_ViewWidth) { _delta_x = - (m_ViewContentWidth > m_ViewWidth ? m_ViewContentWidth - m_ViewWidth : 0); } view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); scrolling.emit(_delta_x, _delta_y); } if (view_layout_) { _hscrollbar->SetContentOffset(_delta_x, _delta_y); _hscrollbar->QueueDraw(); } QueueDraw(); } void ScrollView::ScrollUp(float stepy, int mousedy) { if (m_ViewContentHeight <= m_ViewHeight) return; if (view_layout_) { int last_delta_y = _delta_y; _delta_y += stepy * mousedy; if (_delta_y > 0) { _delta_y = 0; } if (last_delta_y != _delta_y) { QueueDraw(); _vscrollbar->QueueDraw(); } view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); _vscrollbar->SetContentOffset(_delta_x, _delta_y); scrolling.emit(_delta_x, _delta_y); } } void ScrollView::ScrollDown(float stepy, int mousedy) { if (m_ViewContentHeight <= m_ViewHeight) return; if (view_layout_) { int last_delta_y = _delta_y; _delta_y -= stepy * mousedy; if (m_ViewY + _delta_y + m_ViewContentHeight < m_ViewY + m_ViewHeight) { _delta_y = - (m_ViewContentHeight > m_ViewHeight ? m_ViewContentHeight - m_ViewHeight : 0); } if (last_delta_y != _delta_y) { QueueDraw(); _vscrollbar->QueueDraw(); } view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); _vscrollbar->SetContentOffset(_delta_x, _delta_y); scrolling.emit(_delta_x, _delta_y); } } void ScrollView::ResetScrollToLeft() { _delta_x = 0; if (view_layout_) view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); _hscrollbar->SetContentOffset(_delta_x, _delta_y); _hscrollbar->QueueDraw(); QueueDraw(); } void ScrollView::ResetScrollToRight() { if (view_layout_) { _delta_x = - (m_ViewContentWidth > m_ViewWidth ? m_ViewContentWidth - m_ViewWidth : 0); view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); } else { _delta_x = 0; } _hscrollbar->SetContentOffset(_delta_x, _delta_y); _hscrollbar->QueueDraw(); QueueDraw(); } void ScrollView::ResetScrollToUp() { _delta_y = 0; if (view_layout_) view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); _vscrollbar->SetContentOffset(_delta_x, _delta_y); _vscrollbar->QueueDraw(); QueueDraw(); } void ScrollView::ResetScrollToDown() { if (view_layout_) { _delta_y = - (m_ViewContentHeight > m_ViewHeight ? m_ViewContentHeight - m_ViewHeight : 0); view_layout_->Set2DTranslation(_delta_x, _delta_y, 0); } else { _delta_y = 0; } _vscrollbar->SetContentOffset(_delta_x, _delta_y); _vscrollbar->QueueDraw(); QueueDraw(); } void ScrollView::RecvMouseWheel(int /* x */, int /* y */, int wheel_delta, long /* button_flags */, unsigned long /* key_flags */) { // nux can't tell the difference between horizontal and vertical mouse wheel events // so we are only going to support vertical if (wheel_delta < 0) { ScrollDown(abs(wheel_delta / NUX_MOUSEWHEEL_DELTA), m_MouseWheelScrollSize); } else { ScrollUp(abs(wheel_delta / NUX_MOUSEWHEEL_DELTA), m_MouseWheelScrollSize); } } bool ScrollView::AcceptKeyNavFocus() { return false; } } nux-4.0.6+14.04.20140409/Nux/MainLoopGLib.cpp0000644000015301777760000003314412321344237020474 0ustar pbusernogroup00000000000000#include "Nux.h" #include "Layout.h" #include "NuxCore/Logger.h" #include "NuxGraphics/GraphicsEngine.h" #include "ClientArea.h" #include "WindowCompositor.h" #include "TimerProc.h" #include "SystemThread.h" #include "FloatingWindow.h" #include "WindowThread.h" #include "MainLoopGLib.h" namespace nux { DECLARE_LOGGER(logger, "nux.windows.thread"); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) static GMutex *gLibEventMutex = 0; static void nux_glib_threads_lock(void) { if (gLibEventMutex) g_mutex_lock(gLibEventMutex); } static void nux_glib_threads_unlock(void) { if (gLibEventMutex) g_mutex_unlock(gLibEventMutex); } struct NuxEventSource { GSource source; GPollFD event_poll_fd; }; typedef struct { WindowThread *window_thread; unsigned int id; } TimeoutData; Event GetSystemEvent(WindowThread* window_thread) { return window_thread->GetNextEvent(); } gboolean nux_timeout_dispatch(gpointer user_data) { bool repeat = false; TimeoutData* dd = NUX_STATIC_CAST(TimeoutData*, user_data); unsigned int return_code = 1; dd->window_thread->_inside_timer_loop = true; repeat = GetTimer().ExecTimerHandler(dd->id); dd->window_thread->_inside_timer_loop = false; if (dd->window_thread->IsEmbeddedWindow()) { dd->window_thread->RedrawRequested.emit(); } else { Event event = GetSystemEvent(dd->window_thread); return_code = dd->window_thread->ProcessEvent(event); } if ((return_code == 0) && !dd->window_thread->IsEmbeddedWindow()) { g_main_loop_quit(dd->window_thread->main_loop_glib_); } if (!repeat) delete dd; return repeat; } static gboolean nux_event_prepare(GSource * /* source */, gint *timeout) { nux_glib_threads_lock(); gboolean retval; *timeout = -1; #if defined(NUX_OS_WINDOWS) MSG msg; retval = PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE) ? TRUE : FALSE; #elif defined(NUX_OS_LINUX) # if defined(USE_X11) retval = GetGraphicsDisplay()->HasXPendingEvent() ? TRUE : FALSE; # else retval = false; # endif #else # error Not implemented. #endif nux_glib_threads_unlock(); return retval; } static gboolean nux_event_check(GSource *source) { nux_glib_threads_lock(); gboolean retval = FALSE; NuxEventSource *event_source = (NuxEventSource*) source; if ((event_source->event_poll_fd.revents & G_IO_IN)) { #if defined(NUX_OS_WINDOWS) MSG msg; retval = PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE) ? TRUE : FALSE; #elif defined(NUX_OS_LINUX) # if defined(USE_X11) retval = GetGraphicsDisplay()->HasXPendingEvent() ? TRUE : FALSE; # endif #else # error Not implemented. #endif } nux_glib_threads_unlock(); return retval; } gboolean nux_event_dispatch(GSource * /* source */, GSourceFunc /* callback */, gpointer user_data) { nux_glib_threads_lock(); WindowThread *window_thread = NUX_STATIC_CAST(WindowThread *, user_data); Event event = GetSystemEvent(window_thread); unsigned int return_code = window_thread->ProcessEvent(event); if (return_code == 0 && !window_thread->IsEmbeddedWindow()) { g_main_loop_quit(window_thread->main_loop_glib_); } nux_glib_threads_unlock(); return return_code || window_thread->IsEmbeddedWindow(); } static GSourceFuncs event_funcs = { nux_event_prepare, nux_event_check, nux_event_dispatch, NULL, NULL, NULL }; // Timeline source functions static gboolean nux_timeline_prepare (GSource * /* source */, gint *timeout) { // right now we are assuming that we are v-synced, so that will handle synchronizations // we could guess how long we have to wait for the next frame but thats rather ugly // ideally we need some more API that ensures that timeline/event/re-layout/draws are all in sync *timeout = 0; return TRUE; } static gboolean nux_timeline_check(GSource * /* source */) { return TRUE; } static gboolean nux_timeline_dispatch(GSource *source, GSourceFunc /* callback */, gpointer user_data) { #if !defined(NUX_MINIMAL) bool has_timelines_left = false; nux_glib_threads_lock(); gint64 micro_secs = g_source_get_time(source); WindowThread *window_thread = NUX_STATIC_CAST(WindowThread *, user_data); // pump the timelines has_timelines_left = window_thread->ProcessTimelines(micro_secs); if (!has_timelines_left) { // no timelines left on the stack so lets go ahead and remove the // master clock, to save on wakeups window_thread->StopMasterClock(); } nux_glib_threads_unlock(); #endif return TRUE; } static GSourceFuncs timeline_funcs = { nux_timeline_prepare, nux_timeline_check, nux_timeline_dispatch, NULL, NULL, NULL }; void WindowThread::InitGlibLoop() { static bool main_context_created = false; if (!IsEmbeddedWindow()) { #if GLIB_MAJOR_VERSION < 2 || GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32 static bool gthread_initialized = false; if (!gthread_initialized) g_thread_init(NULL); gthread_initialized = true; #endif if (((main_loop_glib_context_ == 0) || (main_loop_glib_ == 0)) && (main_context_created == false)) { //create a context main_loop_glib_context_ = g_main_context_default(); //create a main loop with context main_loop_glib_ = g_main_loop_new(main_loop_glib_context_, TRUE); } else if ((main_loop_glib_context_ == 0) || (main_loop_glib_ == 0)) { // Secondary physical windows goes in here //create a context main_loop_glib_context_ = g_main_context_new(); //create a main loop with context main_loop_glib_ = g_main_loop_new(main_loop_glib_context_, TRUE); } else { return; } } main_context_created = true; gLibEventMutex = 0; //g_mutex_new(); } void WindowThread::RunGlibLoop() { GSource *source = g_source_new(&event_funcs, sizeof(NuxEventSource)); NuxEventSource *event_source = (NuxEventSource*) source; g_source_set_priority(source, G_PRIORITY_DEFAULT); #if defined(NUX_OS_WINDOWS) event_source->event_poll_fd.fd = G_WIN32_MSG_HANDLE; #elif defined(NUX_OS_LINUX) # if defined(USE_X11) event_source->event_poll_fd.fd = ConnectionNumber(GetGraphicsDisplay().GetX11Display()); # endif #else # error Not implemented. #endif event_source->event_poll_fd.events = G_IO_IN; g_source_add_poll(source, &event_source->event_poll_fd); g_source_set_can_recurse(source, TRUE); g_source_set_callback(source, 0, this, 0); if (IsEmbeddedWindow()) g_source_attach(source, NULL); else g_source_attach(source, main_loop_glib_context_); #ifdef NUX_GESTURES_SUPPORT //TODO: Some people say that it's much faster to share a GSource among many // file descriptors than having a separate GSource for each file descriptor. // See if it would be better to have GeisAdapter sharing the same GSource with // WindowThread/Nux/X if (IsEmbeddedWindow()) geis_adapter_->CreateGSource(nullptr); else geis_adapter_->CreateGSource(main_loop_glib_context_); geis_adapter_->event_ready.connect( sigc::mem_fun(this, &WindowThread::ProcessGestureEvent)); #endif #if !defined(NUX_MINIMAL) if (!_Timelines->empty()) StartMasterClock(); #endif if (!IsEmbeddedWindow()) { g_main_loop_run(main_loop_glib_); g_main_loop_unref(main_loop_glib_); } } namespace { typedef struct _ExternalNuxSource { GSource source; GPollFD pfd; } ExternalNuxSource; gboolean ExternalSourcePrepareFunc(GSource *source, gint *timeout) { /* Always block for new events */ *timeout = -1; return FALSE; } gboolean ExternalSourceCheckFunc(GSource *source) { /* Only return true if there are events waiting for us */ ExternalNuxSource *extSource = reinterpret_cast (source); return extSource->pfd.revents == G_IO_IN; } gboolean ExternalSourceDispatchFunc(GSource *source, GSourceFunc callback, gpointer user_data) { return (*callback) (user_data); } static GSourceFuncs externalGLibFuncs = { &ExternalSourcePrepareFunc, &ExternalSourceCheckFunc, &ExternalSourceDispatchFunc, NULL, /* Technically we shouldn't be touching these, but the compiler * will complain if we don't */ 0, 0 }; } gboolean WindowThread::ExternalSourceCallback(gpointer user_data) { WindowThread::ExternalFdData *data = reinterpret_cast (user_data); data->cb (); return TRUE; } void ExternalGLibSources::AddFdToGLibLoop(gint fd, gpointer data, GSourceFunc callback, GMainContext *context) { GSource *source = g_source_new(&externalGLibFuncs, sizeof (ExternalNuxSource)); ExternalNuxSource *extSource = reinterpret_cast (source); extSource->pfd.fd = fd; extSource->pfd.events = G_IO_IN; extSource->pfd.revents = 0; g_source_add_poll (source, &extSource->pfd); g_source_set_callback (source, callback, data, NULL); g_source_attach (source, context); } void ExternalGLibSources::RemoveFdFromGLibLoop(gpointer data) { g_source_remove_by_user_data(data); } void WindowThread::AddFdToGLibLoop(int fd, gpointer data, GSourceFunc callback) { external_glib_sources_->AddFdToGLibLoop(fd, data, callback, main_loop_glib_context_); } void WindowThread::RemoveFdFromGLibLoop(gpointer data) { external_glib_sources_->RemoveFdFromGLibLoop(data); } void WindowThread::CleanupGlibLoop() { g_source_remove_by_funcs_user_data(&event_funcs, this); for (std::list::iterator it = _external_fds.begin(); it != _external_fds.end(); ++it) { gpointer data = reinterpret_cast(&(*it)); external_glib_sources_->RemoveFdFromGLibLoop(data); } } unsigned int WindowThread::AddGLibTimeout(unsigned int duration) { if (IsEmbeddedWindow()) { TimeoutData* dd = new TimeoutData; dd->window_thread = this; dd->id = g_timeout_add(duration, nux_timeout_dispatch, dd); return dd->id; } else { if ((main_loop_glib_context_ == 0) || (main_loop_glib_ == 0)) { //LOG_WARNING(logger) << "Trying to set a timeout before GLib Context is created.\n"; return 0; } GSource* timeout_source; //create a new time-out source timeout_source = g_timeout_source_new(duration); TimeoutData* dd = new TimeoutData; dd->window_thread = this; dd->id = 0; //set the callback for this source g_source_set_callback(timeout_source, nux_timeout_dispatch, dd, NULL); //attach source to context dd->id = g_source_attach(timeout_source, main_loop_glib_context_); return dd->id; } } #if defined(NUX_OS_WINDOWS) bool WindowThread::AddChildWindowGlibLoop(WindowThread* wnd_thread) #else bool WindowThread::AddChildWindowGlibLoop(WindowThread* /* wnd_thread */) #endif { #if defined(NUX_OS_WINDOWS) if (wnd_thread == NULL) { return false; } if (main_loop_glib_context_ == NULL) { InitGlibLoop(); } GSource *source = g_source_new(&event_funcs, sizeof(NuxEventSource)); NuxEventSource *event_source = (NuxEventSource*) source; g_source_set_priority(source, G_PRIORITY_DEFAULT); event_source->event_poll_fd.fd = (int)((int*)wnd_thread->GetThreadHandle()); event_source->event_poll_fd.events = G_IO_IN; g_source_add_poll(source, &event_source->event_poll_fd); g_source_set_can_recurse(source, TRUE); g_source_set_callback(source, 0, this, 0); if (IsEmbeddedWindow()) g_source_attach(source, NULL); else g_source_attach(source, main_loop_glib_context_); #endif return true; } void WindowThread::StartMasterClock() { // if we are not embedded and don't have a context yet if (!IsEmbeddedWindow() && main_loop_glib_context_ == 0) return; if (_MasterClock == NULL) { // make a source for our master clock _MasterClock = g_source_new(&timeline_funcs, sizeof(GSource)); g_source_set_priority(_MasterClock, G_PRIORITY_DEFAULT + 10); g_source_set_callback(_MasterClock, 0, this, 0); g_source_set_can_recurse(_MasterClock, TRUE); if (IsEmbeddedWindow()) g_source_attach(_MasterClock, NULL); else if (main_loop_glib_context_ != 0) g_source_attach(_MasterClock, main_loop_glib_context_); #if !defined(NUX_MINIMAL) gint64 micro_secs = g_source_get_time(_MasterClock); last_timeline_frame_time_sec_ = micro_secs / 1000000; last_timeline_frame_time_usec_ = micro_secs % 1000000; #endif } } void WindowThread::StopMasterClock() { if (_MasterClock) { g_source_remove(g_source_get_id(_MasterClock)); _MasterClock = NULL; } } void WindowThread::StopGLibLoop() { // woo no more main loop! this is prolly bad for nux, so erm // FIXME!! - Jay take a look at this, make sure just quitting the mainloop // is an idea that makes sense(needed for testing) if (!IsEmbeddedWindow()) g_main_loop_quit(main_loop_glib_); } #endif } nux-4.0.6+14.04.20140409/Nux/VScrollBar.cpp0000644000015301777760000003375312321344237020237 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "VScrollBar.h" namespace nux { const int VSCROLLBAR_WIDTH = 5; const int VSCROLLBAR_HEIGHT = 10; VScrollBar::VScrollBar(NUX_FILE_LINE_DECL) : ScrollBar(NUX_FILE_LINE_PARAM) { content_width_ = 0; content_height_ = 0; container_width_ = 0; container_height_ = 0; m_TrackWidth = 0; m_TrackHeight = 0; m_SlideBarOffsetX = 0; m_SlideBarOffsetY = 0; content_offset_x_ = 0; content_offset_y_ = 0; b_MouseUpTimer = false; b_MouseDownTimer = false; m_color_factor = 1.0f; m_UpTimerHandler = 0; m_DownTimerHandler = 0; vlayout = new VLayout(NUX_TRACKER_LOCATION); _scroll_up_button = new BasicView(NUX_TRACKER_LOCATION); _track = new BasicView(NUX_TRACKER_LOCATION); _scroll_down_button = new BasicView(NUX_TRACKER_LOCATION); _slider = new BasicView(NUX_TRACKER_LOCATION); _slider->SetParentObject(this); // Set Original State SetMinimumSize(VSCROLLBAR_WIDTH, AREA_MIN_HEIGHT); SetMaximumSize(VSCROLLBAR_WIDTH, AREA_MAX_HEIGHT); // Set Signals //_scroll_down_button->mouse_down.connect(sigc::mem_fun(this, &VScrollBar::RecvStartScrollDown)); //_scroll_down_button->mouse_up.connect(sigc::mem_fun(this, &VScrollBar::RecvEndScrollDown)); //_scroll_up_button->mouse_down.connect(sigc::mem_fun(this, &VScrollBar::RecvStartScrollUp)); //_scroll_up_button->mouse_up.connect(sigc::mem_fun(this, &VScrollBar::RecvEndScrollUp)); _slider->mouse_down.connect(sigc::mem_fun(this, &VScrollBar::OnSliderMouseDown)); _slider->mouse_up.connect(sigc::mem_fun(this, &VScrollBar::OnSliderMouseUp)); _slider->mouse_drag.connect(sigc::mem_fun(this, &VScrollBar::OnSliderMouseDrag)); _track->mouse_down.connect(sigc::mem_fun(this, &VScrollBar::RecvTrackMouseDown)); _track->mouse_up.connect(sigc::mem_fun(this, &VScrollBar::RecvTrackMouseUp)); _track->mouse_drag.connect(sigc::mem_fun(this, &VScrollBar::RecvTrackMouseDrag)); //_track->mouse_down.connect(sigc::mem_fun(this, &VScrollBar::OnSliderMouseDown)); // Set Geometry _scroll_down_button->SetMinimumSize(VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); _scroll_down_button->SetMaximumSize(VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); _scroll_down_button->SetGeometry(Geometry(0, 0, VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT)); _scroll_up_button->SetMinimumSize(VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); _scroll_up_button->SetMaximumSize(VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); _scroll_up_button->SetGeometry(Geometry(0, 0, VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT)); vlayout->AddView(_scroll_up_button, 0, eCenter, eFix); vlayout->AddView(_track, 1, eCenter, eFull); vlayout->AddView(_scroll_down_button, 0, eCenter, eFix); callback = new TimerFunctor; callback->tick.connect(sigc::mem_fun(this, &VScrollBar::VScrollBarHandler)); up_callback = new TimerFunctor; up_callback->tick.connect(sigc::mem_fun(this, &VScrollBar::ScrollUp)); down_callback = new TimerFunctor; down_callback->tick.connect(sigc::mem_fun(this, &VScrollBar::ScrollDown)); trackup_callback = new TimerFunctor; trackup_callback->tick.connect(sigc::mem_fun(this, &VScrollBar::TrackUp)); trackdown_callback = new TimerFunctor; trackdown_callback->tick.connect(sigc::mem_fun(this, &VScrollBar::TrackDown)); SetLayout(vlayout); SetAcceptMouseWheelEvent(true); } VScrollBar::~VScrollBar() { _slider->UnReference(); delete callback; delete up_callback; delete trackup_callback; delete down_callback; delete trackdown_callback; } void VScrollBar::VScrollBarHandler(void *v) { VScrollBar *scrollbar = static_cast (v); if (scrollbar->b_MouseUpTimer && scrollbar->m_color_factor < 1) { scrollbar->m_color_factor += 0.1f; if (scrollbar->m_color_factor >= 1) { scrollbar->m_color_factor = 1; scrollbar->b_MouseUpTimer = false; } else { scrollbar->QueueDraw(); GetTimer().AddOneShotTimer(10, callback, scrollbar); } } if (scrollbar->b_MouseDownTimer && scrollbar->m_color_factor > 0) { scrollbar->m_color_factor -= 0.09f; if (scrollbar->m_color_factor <= 0) { scrollbar->m_color_factor = 0; scrollbar->b_MouseUpTimer = false; } else { scrollbar->QueueDraw(); GetTimer().AddOneShotTimer(10, callback, scrollbar); } } QueueDraw(); } void VScrollBar::ScrollDown(void * /* v */) { OnScrollDown.emit(m_ScrollUnit, 1); if (AtMaximum()) RecvEndScrollDown(0, 0, 0, 0); else m_DownTimerHandler = GetTimer().AddOneShotTimer(10, down_callback, this); QueueDraw(); } void VScrollBar::ScrollUp(void * /* v */) { OnScrollUp.emit(m_ScrollUnit, 1); if (AtMaximum()) RecvEndScrollUp(0, 0, 0, 0); else m_UpTimerHandler = GetTimer().AddOneShotTimer(10, up_callback, this); QueueDraw(); } void VScrollBar::TrackUp(void * /* v */) { if (m_TrackMouseCoord.y < _slider->GetBaseY() - _track->GetBaseY()) { OnScrollUp.emit(container_height_, 1); m_TrackUpTimerHandler = GetTimer().AddOneShotTimer(10, trackup_callback, this); QueueDraw(); } } void VScrollBar::TrackDown(void * /* v */) { if (m_TrackMouseCoord.y > _slider->GetBaseY() + _slider->GetBaseHeight() - _track->GetBaseY()) { OnScrollDown.emit(container_height_, 1); m_TrackDownTimerHandler = GetTimer().AddOneShotTimer(10, trackdown_callback, this); QueueDraw(); } } void VScrollBar::RecvStartScrollUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (!AtMinimum()) ScrollUp(this); } void VScrollBar::RecvEndScrollUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_UpTimerHandler.IsValid()) { GetTimer().RemoveTimerHandler(m_UpTimerHandler); m_UpTimerHandler = 0; } } void VScrollBar::RecvStartScrollDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (!AtMaximum()) ScrollDown(this); } void VScrollBar::RecvEndScrollDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_DownTimerHandler.IsValid()) { GetTimer().RemoveTimerHandler(m_DownTimerHandler); m_DownTimerHandler = 0; } } void VScrollBar::RecvTrackMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { m_TrackMouseCoord = Point(x, y); int Y = _slider->GetBaseY() - _track->GetBaseY(); if (y < Y) { // move the slide bar up TrackUp(this); } else { TrackDown(this); // move the slide bar down } } void VScrollBar::RecvTrackMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (m_TrackUpTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_TrackUpTimerHandler); if (m_TrackDownTimerHandler.IsValid()) GetTimer().RemoveTimerHandler(m_TrackDownTimerHandler); m_TrackUpTimerHandler = 0; m_TrackDownTimerHandler = 0; } void VScrollBar::RecvTrackMouseDrag(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } Area* VScrollBar::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; NUX_RETURN_VALUE_IF_TRUE(_scroll_down_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_down_button); NUX_RETURN_VALUE_IF_TRUE(_scroll_up_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_up_button); NUX_RETURN_VALUE_IF_TRUE(_slider->TestMousePointerInclusion(mouse_position, event_type), _slider); NUX_RETURN_VALUE_IF_TRUE(_track->TestMousePointerInclusion(mouse_position, event_type), _track); if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } void VScrollBar::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); GetPainter().PaintBackground(graphics_engine, base); base.OffsetPosition(0, VSCROLLBAR_HEIGHT); base.OffsetSize(0, -2 * VSCROLLBAR_HEIGHT); //GetPainter().PaintShape(graphics_engine, base, Color(COLOR_SCROLLBAR_TRACK), eVSCROLLBAR, false); //graphics_engine.QRP_Color(base.x, base.y, base.width, base.height, Color(COLOR_SCROLLBAR_TRACK)); //GetPainter().PaintShape(graphics_engine, _scroll_up_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_UP); //GetPainter().PaintShape(graphics_engine, _scroll_down_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_DOWN); /*GetPainter().PaintShape(graphics_engine, _slider->GetGeometry(), Color(0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f), eVSCROLLBAR, true);*/ if (content_height_ > container_height_) { Geometry slider_geo = _slider->GetGeometry(); graphics_engine.QRP_Color(slider_geo.x, slider_geo.y, slider_geo.width, slider_geo.height, Color(1.0f, 1.0f, 1.0f, 0.8f)); } //Color(0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f)); } void VScrollBar::SetContainerSize(int /* x */, int /* y */, int w, int h) { container_width_ = w; container_height_ = h; ComputeScrolling(); } void VScrollBar::SetContentSize(int /* x */, int /* y */, int w, int h) { // x and y are not needed content_width_ = w; content_height_ = h; ComputeScrolling(); } void VScrollBar::SetContentOffset(float dx, float dy) { content_offset_x_ = dx; content_offset_y_ = dy; ComputeScrolling(); } void VScrollBar::ComputeScrolling() { if (content_height_ == 0) { visibility_percentage_ = 100.0f; } else { visibility_percentage_ = Clamp(100.0f * (float) container_height_ / (float) content_height_, 0.0f, 100.0f); } m_TrackHeight = _track->GetBaseHeight(); int slider_width = _scroll_up_button->GetBaseWidth(); int slider_height = m_TrackHeight * visibility_percentage_ / 100.0f; if (slider_height < 15) { slider_height = 15; } _slider->SetBaseWidth(slider_width); _slider->SetBaseHeight(slider_height); _slider->SetBaseX(_scroll_up_button->GetBaseX()); float pct; if (content_height_ - container_height_ > 0) pct = - (float) content_offset_y_ / (float) (content_height_ - container_height_); else pct = 0; int y = _track->GetBaseY() + pct * (m_TrackHeight - slider_height); _slider->SetBaseY(y); } ///////////////// // RECEIVERS // ///////////////// void VScrollBar::SetValue(float /* value */) { //m_ValueString.setCaption(value); } void VScrollBar::SetParameterName(const char * /* parameter_name */) { //m_ParameterName.setCaption(parameter_name); } //////////////// // EMITTERS // //////////////// //void VScrollBar::EmitScrollUp(int x, int y, unsigned long button_flags, unsigned long key_flags) //{ // OnScrollUp.emit(m_ScrollUnit, 1); //} //void VScrollBar::EmitScrollDown(int x, int y, unsigned long button_flags, unsigned long key_flags) //{ // OnScrollDown.emit(m_ScrollUnit, 1); //} void VScrollBar::OnSliderMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */) { m_SliderDragPositionX = x; m_SliderDragPositionY = y; //sigVScrollBarSliderMouseDown.emit(); b_MouseDownTimer = true; b_MouseUpTimer = false; GetTimer().AddOneShotTimer(10, callback, this); } void VScrollBar::OnSliderMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { b_MouseDownTimer = false; b_MouseUpTimer = true; GetTimer().AddOneShotTimer(10, callback, this); } void VScrollBar::OnSliderMouseDrag(int /* x */, int y, int /* dx */, int dy, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (_track->GetBaseHeight() - _slider->GetBaseHeight() > 0) { stepY = (float) (content_height_ - container_height_) / (float) (_track->GetBaseHeight() - _slider->GetBaseHeight()); } else { return; } if ((dy > 0) && (y > m_SliderDragPositionY)) { OnScrollDown.emit(stepY, y - m_SliderDragPositionY); } if ((dy < 0) && (y < m_SliderDragPositionY)) { OnScrollUp.emit(stepY, m_SliderDragPositionY - y); } QueueDraw(); } bool VScrollBar::AtMaximum() { if (_slider->GetBaseY() + _slider->GetBaseHeight() == _track->GetBaseY() + _track->GetBaseHeight()) return TRUE; return FALSE; } bool VScrollBar::AtMinimum() { if (_slider->GetBaseY() == _track->GetBaseY()) return TRUE; return FALSE; } long VScrollBar::PostLayoutManagement(long LayoutResult) { long ret = ScrollBar::PostLayoutManagement(LayoutResult); ComputeScrolling(); return ret; } } nux-4.0.6+14.04.20140409/Nux/Area.cpp0000644000015301777760000006624312321344237017076 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "Area.h" #include "NuxGraphics/GraphicsEngine.h" #include "Layout.h" #include "BaseWindow.h" #if !defined(NUX_MINIMAL) # include "VSplitter.h" # include "HSplitter.h" # include "MenuPage.h" #endif #ifdef NUX_GESTURES_SUPPORT #include "NuxGraphics/GestureEvent.h" #endif namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(Area); Area::Area(NUX_FILE_LINE_DECL) : InitiallyUnownedObject(NUX_FILE_LINE_PARAM) , redirect_rendering_to_texture_(false) , update_backup_texture_(false) , present_redirected_view_(true) , copy_previous_fbo_for_background_(true) , geometry_(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT) , min_size_(AREA_MIN_WIDTH, AREA_MIN_HEIGHT) , max_size_(AREA_MAX_WIDTH, AREA_MAX_HEIGHT) , layout_done_(true) { window_thread_ = GetWindowThread(); visible_ = true; view_enabled_ = true; parent_area_ = NULL; next_object_to_key_focus_area_ = NULL; has_key_focus_ = false; scale_factor_ = 1; sensitive_ = true; on_geometry_change_reconfigure_parent_layout_ = true; accept_mouse_wheel_event_ = false; accept_keyboard_event_ = false; _2d_xform.Identity(); _3d_xform.Identity(); _3d_area = false; } Area::~Area() { ResetDownwardPathToKeyFocusArea(); ResetUpwardPathToKeyFocusArea(); } std::string const& Area::GetBaseString() const { return base_string_; } void Area::SetBaseString(std::string const& caption) { base_string_ = caption; } void Area::CheckMinSize() { int w = min_size_.width; w = Max(AREA_MIN_WIDTH, w); int h = min_size_.height; h = Max(AREA_MIN_HEIGHT, h); min_size_ = Size(w, h); if (min_size_.width > max_size_.width) { max_size_.width = min_size_.width; } if (min_size_.height > max_size_.height) { max_size_.height = min_size_.height; } if (geometry_.width < min_size_.width) { geometry_.width = min_size_.width; } if (geometry_.height < min_size_.height ) { geometry_.height = min_size_.height; } } void Area::CheckMaxSize() { int w = max_size_.width; w = w <= AREA_MAX_WIDTH ? w : AREA_MAX_WIDTH; int h = max_size_.height; h = h <= AREA_MAX_HEIGHT ? h: AREA_MAX_HEIGHT; max_size_ = Size(w, h); if (min_size_.width > max_size_.width) { min_size_.width = max_size_.width; } if (min_size_.height > max_size_.height) { min_size_.height = max_size_.height; } if (geometry_.width > max_size_.width) { geometry_.width = max_size_.width; } if (geometry_.height > max_size_.height) { geometry_.height = max_size_.height; } } void Area::SetMinimumSize(int w, int h) { nuxAssert(w >= 0); nuxAssert(h >= 0); min_size_ = Size(w, h); CheckMinSize(); ReconfigureParentLayout(); } void Area::SetMaximumSize(int w, int h) { nuxAssert(w >= 0); nuxAssert(h >= 0); max_size_ = Size(w, h); CheckMaxSize(); ReconfigureParentLayout(); } void Area::SetMinMaxSize(int w, int h) { nuxAssert(w >= 0); nuxAssert(h >= 0); SetMinimumSize(w, h); SetMaximumSize(w, h); //ReconfigureParentLayout(); } void Area::ApplyMinWidth() { geometry_.width = min_size_.width; ReconfigureParentLayout(); } void Area::ApplyMinHeight() { geometry_.height = min_size_.height; ReconfigureParentLayout(); } void Area::ApplyMaxWidth() { geometry_.width = max_size_.width; ReconfigureParentLayout(); } void Area::ApplyMaxHeight() { geometry_.height = max_size_.height; ReconfigureParentLayout(); } Size Area::GetMinimumSize() const { return min_size_; } Size Area::GetMaximumSize() const { return max_size_; } void Area::SetMinimumWidth(int w) { nuxAssert(w >= 0); min_size_.width = w; CheckMinSize(); ReconfigureParentLayout(); } void Area::SetMaximumWidth(int w) { nuxAssert(w >= 0); max_size_.width = w; CheckMaxSize(); ReconfigureParentLayout(); } void Area::SetMinimumHeight(int h) { nuxAssert(h >= 0); min_size_.height = h; CheckMinSize(); ReconfigureParentLayout(); } void Area::SetMaximumHeight(int h) { nuxAssert(h >= 0); max_size_.height = h; CheckMaxSize(); ReconfigureParentLayout(); } int Area::GetMinimumWidth() const { return min_size_.width; } int Area::GetMaximumWidth() const { return max_size_.width; } int Area::GetMinimumHeight() const { return min_size_.height; } int Area::GetMaximumHeight() const { return max_size_.height; } unsigned int Area::GetScaleFactor() { return scale_factor_; } void Area::SetScaleFactor(unsigned int sf) { // re implemented by Layout scale_factor_ = sf; } bool Area::SetParentObject(Area *parent) { if (parent == 0) { nuxAssertMsg(0, "[Area::SetParentObject] Invalid parent obejct."); return false; } if (parent_area_ && (parent_area_ != parent)) { nuxAssertMsg(0, "[Area::SetParentObject] Object already has a parent. You must UnParent the object before you can parenting again."); return false; } if (parent_area_) { // Already parented to the same area. Return. return true; } parent_area_ = parent; Reference(); return true; } void Area::UnParentObject() { // If the area is on the path to the key focus area, or has focus, reset it. if (has_key_focus_ || next_object_to_key_focus_area_) { GetWindowThread()->GetWindowCompositor().SetKeyFocusArea(NULL, KEY_NAV_NONE); } if (parent_area_) { parent_area_ = 0; UnReference(); } } Area *Area::GetParentObject() const { return parent_area_; } int Area::GetX() const { return geometry_.x; } int Area::GetBaseX() const { return GetX(); } int Area::GetY() const { return geometry_.y; } int Area::GetBaseY() const { return GetY(); } int Area::GetWidth() const { return geometry_.width; } int Area::GetBaseWidth() const { return GetWidth(); } int Area::GetHeight() const { return geometry_.height; } int Area::GetBaseHeight() const { return GetHeight(); } void Area::SetGeometry(int x, int y, int w, int h) { h = nux::Clamp (h, min_size_.height, max_size_.height); w = nux::Clamp (w, min_size_.width, max_size_.width); bool detected_size_change = false; bool detected_position_change = false; if (geometry_.x != x || geometry_.y != y) detected_position_change = true; if (geometry_.width != w || geometry_.height != h) detected_size_change = true; if (!detected_position_change && !detected_size_change) return; GeometryChangePending(detected_position_change, detected_size_change); geometry_.Set(x, y, w, h); ReconfigureParentLayout(); GeometryChanged(detected_position_change, detected_size_change); geometry_changed.emit(this, geometry_); if (detected_position_change) position_changed.emit(this, x, y); if (detected_size_change) size_changed.emit(this, w, h); } void Area::SetGeometry(const Geometry &geo) { SetGeometry(geo.x, geo.y, geo.width, geo.height); } Geometry const& Area::GetGeometry() const { return geometry_; } void Area::SetX(int x) { SetGeometry(x, geometry_.y, geometry_.width, geometry_.height); } void Area::SetY (int y) { SetGeometry(geometry_.x, y, geometry_.width, geometry_.height); } void Area::SetBaseX(int x) { SetX(x); } void Area::SetBaseY(int y) { SetY(y); } void Area::SetXY(int x, int y) { SetGeometry(x, y, geometry_.width, geometry_.height); } void Area::SetBaseXY(int x, int y) { SetXY(x, y); } void Area::SetSize(int w, int h) { SetGeometry(geometry_.x, geometry_.y, w, h); } void Area::SetBaseSize(int w, int h) { SetSize(w, h); } void Area::SetWidth(int w) { SetGeometry(geometry_.x, geometry_.y, w, geometry_.height); } void Area::SetBaseWidth(int w) { SetWidth(w); } void Area::SetHeight(int h) { SetGeometry(geometry_.x, geometry_.y, geometry_.width, h); } void Area::SetBaseHeight(int h) { SetHeight(h); } long Area::ComputeContentSize() { return (eCompliantWidth | eCompliantHeight); } void Area::ComputeContentPosition(float /* offsetX */, float /* offsetY */) { } void Area::SetReconfigureParentLayoutOnGeometryChange(bool reconfigure_parent_layout) { on_geometry_change_reconfigure_parent_layout_ = reconfigure_parent_layout; } bool Area::ReconfigureParentLayoutOnGeometryChange() { return on_geometry_change_reconfigure_parent_layout_; } void Area::ReconfigureParentLayout(Area *child) { if (on_geometry_change_reconfigure_parent_layout_ == false) return; if (window_thread_ && window_thread_->IsComputingLayout()) { // there is no need to do the following while we are already computing the layout. // If we do, we will end up in an infinite loop. return; } if (this->Type().IsDerivedFromType(View::StaticObjectType)) { // The object that is being resized is a View object and it has a parent. if (this->OwnsTheReference() == false && this->GetParentObject()) { // Only reference parented areas. this->Reference(); } View *ic = static_cast(this); if (ic->CanBreakLayout()) { #if !defined(NUX_MINIMAL) if ((child != 0) && (ic->Type().IsObjectType(VSplitter::StaticObjectType) || ic->Type().IsObjectType(HSplitter::StaticObjectType))) { // If this element is a Splitter, then we submit its child to the refresh list. We don't want to submit the // splitter because this will cause a redraw of all parts of the splitter(costly and unnecessary). window_thread_->QueueObjectLayout(child); } else #endif { window_thread_->QueueObjectLayout(ic); } } else if (ic->parent_area_) { ic->parent_area_->ReconfigureParentLayout(this); } else { window_thread_->QueueObjectLayout(ic); } } else if (this->Type().IsDerivedFromType(Layout::StaticObjectType)) { // The object that is being resized is a View object and it has a parent. if (this->OwnsTheReference() == false && this->GetParentObject()) { // Only reference parented areas. this->Reference(); } Layout *layout = static_cast(this); if (layout->parent_area_) { if (layout->parent_area_->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = (View *) (layout->parent_area_); if (ic->CanBreakLayout()) { #if !defined(NUX_MINIMAL) if ((child != 0) && (ic->Type().IsObjectType(VSplitter::StaticObjectType) || ic->Type().IsObjectType(HSplitter::StaticObjectType))) { // If the parent of this element is a splitter, then we submit // its child to the refresh list. We don't want to submit the // splitter because this will cause a redraw of all parts of the // splitter(costly and unnecessary). window_thread_->QueueObjectLayout(this); } else #endif { window_thread_->QueueObjectLayout(ic); } } else { // The parent object of an object of type View is a Layout object type. layout->parent_area_->ReconfigureParentLayout(this); } } else { layout->parent_area_->ReconfigureParentLayout(this); } } else { // This is possibly the Main layout or the layout of a floating object(popup for example) unless the layout is not part of the object tree. window_thread_->QueueObjectLayout(layout); } } else { // The object that is being resized is a InputArea object. if (this->parent_area_) { // The object that is being resized is a View object and it has a parent. if (this->OwnsTheReference() == false && this->GetParentObject()) { // Only reference parented areas. this->Reference(); } // The parent object of an object of type InputArea is a Layout object type. this->parent_area_->ReconfigureParentLayout(this); } } } void Area::RequestBottomUpLayoutComputation(Area *bo_initiator) { if (parent_area_ && parent_area_->IsLayout()) { parent_area_->RequestBottomUpLayoutComputation(bo_initiator); } } void Area::SetVisible(bool visible) { if (IsLayout()) return; if (visible_ == visible) return; visible_ = visible; OnVisibleChanged.emit(this, visible_); } bool Area::IsVisible() { return visible_; } void Area::SetSensitive(bool sensitive) { SetInputEventSensitivity(sensitive); } void Area::SetInputEventSensitivity(bool sensitive) { if (IsLayout()) return; if (sensitive_ == sensitive) return; sensitive_ = sensitive; OnSensitiveChanged.emit(this, sensitive_); } bool Area::IsSensitive() const { return GetInputEventSensitivity(); } bool Area::GetInputEventSensitivity() const { return sensitive_; } MinorDimensionPosition Area::GetPositioning() { return minor_axis_position_; } void Area::SetPositioning(MinorDimensionPosition p) { minor_axis_position_ = p; } MinorDimensionSize Area::GetExtend() { return minor_axis_size_; } void Area::SetExtend(MinorDimensionSize ext) { minor_axis_size_ = ext; } float Area::GetPercentage() { return minor_axis_size_scale_; } void Area::SetPercentage(float p) { minor_axis_size_scale_ = p; } bool Area::IsLayoutDone() { return layout_done_; } void Area::SetLayoutDone(bool b) { layout_done_ = b; } bool Area::IsArea() const { return this->Type().IsDerivedFromType(Area::StaticObjectType); } bool Area::IsInputArea() const { return this->Type().IsDerivedFromType(InputArea::StaticObjectType); } bool Area::IsView() const { return this->Type().IsDerivedFromType(View::StaticObjectType); } bool Area::IsLayout() const { return this->Type().IsDerivedFromType(Layout::StaticObjectType); } bool Area::IsViewWindow() const { return this->Type().IsDerivedFromType(BaseWindow::StaticObjectType); } bool Area::IsSpaceLayout() const { return this->Type().IsDerivedFromType(SpaceLayout::StaticObjectType); } void Area::Set2DMatrix(const Matrix4 &mat) { _2d_xform = mat; } void Area::Set2DTranslation(float tx, float ty, float tz) { _2d_xform.Translate(tx, ty, tz); } Matrix4 Area::Get2DMatrix() const { return _2d_xform; } Matrix4 Area::Get3DMatrix() const { return _3d_xform; } bool Area::Is3DArea() const { return _3d_area; } static void MatrixXFormGeometry(const Matrix4 &matrix, Geometry &geo) { Vector4 in(geo.x, geo.y, 0, 1); // This is mean only for translation matrices. It will not work with matrices containing rotations or scalings. Vector4 out = matrix * in; geo.x = out.x; geo.y = out.y; } void Area::InnerGetAbsoluteGeometry(Geometry &geometry) { if (this->Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout())) { geometry.OffsetPosition(geometry_.x, geometry_.y); return; } MatrixXFormGeometry(_2d_xform, geometry); Area *parent = GetParentObject(); if (parent) parent->InnerGetAbsoluteGeometry(geometry); } Geometry Area::GetAbsoluteGeometry() const { if (Type().IsDerivedFromType(BaseWindow::StaticObjectType) || #if !defined(NUX_MINIMAL) Type().IsDerivedFromType(MenuPage::StaticObjectType) || #endif (this == window_thread_->GetLayout())) { // Do not apply the _2D_xform matrix to a BaseWindow or the main layout return geometry_; } else { nux::Geometry geo = geometry_; MatrixXFormGeometry(_2d_xform, geo); Area *parent = GetParentObject(); if (parent) parent->InnerGetAbsoluteGeometry(geo); return geo; } } int Area::GetAbsoluteX() const { return GetAbsoluteGeometry().x; } int Area::GetAbsoluteY() const { return GetAbsoluteGeometry().y; } int Area::GetAbsoluteWidth() const { return GetAbsoluteGeometry().width; } int Area::GetAbsoluteHeight() const { return GetAbsoluteGeometry().height; } void Area::InnerGetRootGeometry(Geometry &geometry) { if (this->Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout())) return; MatrixXFormGeometry(_2d_xform, geometry); Area *parent = GetParentObject(); if (parent) parent->InnerGetRootGeometry(geometry); } Geometry Area::GetRootGeometry() const { nux::Geometry geo = geometry_; MatrixXFormGeometry(_2d_xform, geo); if (Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout())) { return geo; } else { Area *parent = GetParentObject(); if (parent) parent->InnerGetRootGeometry(geo); return geo; } } int Area::GetRootX() const { return GetRootGeometry().x; } int Area::GetRootY() const { return GetRootGeometry().y; } int Area::GetRootWidth() const { return GetRootGeometry().width; } int Area::GetRootHeight() const { return GetRootGeometry().height; } Area* Area::GetToplevel() { return GetRootParent(); } Area* Area::GetRootParent() { if (Type().IsDerivedFromType(BaseWindow::StaticObjectType) || (this == window_thread_->GetLayout())) { return this; } Area* parent = GetParentObject(); if (!parent) //we didn't find a way to salvation! { return 0; } return parent->GetRootParent(); } Area* Area::GetTopLevelViewWindow() { Area* area = GetRootParent(); if (area && area->IsViewWindow()) return area; return NULL; } bool Area::HasTopLevelParent() { if (GetRootParent()) { return true; } return false; } bool Area::IsChildOf(Area* parent) { if (this == parent) return true; if (!parent || !parent_area_) return false; return parent_area_->IsChildOf(parent); } void Area::QueueRelayout() { window_thread_->QueueObjectLayout(this); } void Area::SetAcceptKeyboardEvent(bool accept_keyboard_event) { accept_keyboard_event_ = accept_keyboard_event; } bool Area::AcceptKeyboardEvent() const { return accept_keyboard_event_; } void Area::SetAcceptMouseWheelEvent(bool accept_mouse_wheel_event) { accept_mouse_wheel_event_ = accept_mouse_wheel_event; } bool Area::AcceptMouseWheelEvent() const { return accept_mouse_wheel_event_; } bool Area::TestMousePointerInclusion(const Point& mouse_position, NuxEventType event_type) { if ((IsLayout() == false) && ((visible_ == false) || (sensitive_ == false) || (view_enabled_ == false))) { // If this area is not a view and: // - it is insensitive to input event // - it is not enabled // - it is not visible // then return false. return false; } bool mouse_pointer_inside_area = false; #if !defined(NUX_MINIMAL) if (Type().IsDerivedFromType(MenuPage::StaticObjectType)) { // A MenuPage geometry is already in absolute coordinates. mouse_pointer_inside_area = geometry_.IsInside(mouse_position); } else #endif { mouse_pointer_inside_area = GetAbsoluteGeometry().IsInside(mouse_position); } if ((event_type == NUX_MOUSE_WHEEL) && mouse_pointer_inside_area) { if (accept_mouse_wheel_event_ == false) return false; } return mouse_pointer_inside_area; } bool Area::TestMousePointerInclusionFilterMouseWheel(const Point& mouse_position, NuxEventType /* event_type */) { if ((IsLayout() == false) && ((visible_ == false) || (sensitive_ == false) || (view_enabled_ == false))) { // If this area is not a view and: // - it is insensitive to input event // - it is not enabled // - it is not visible // then return false. return false; } bool mouse_pointer_inside_area = false; #if !defined(NUX_MINIMAL) if (Type().IsDerivedFromType(MenuPage::StaticObjectType)) { // A MenuPage geometry is already in absolute coordinates. mouse_pointer_inside_area = geometry_.IsInside(mouse_position); } else #endif { mouse_pointer_inside_area = GetAbsoluteGeometry().IsInside(mouse_position); } return mouse_pointer_inside_area; } Area* Area::FindAreaUnderMouse(const Point& /* mouse_position */, NuxEventType /* event_type */) { return NULL; } Area* Area::FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state) { if (has_key_focus_) { return this; } else if (next_object_to_key_focus_area_) { return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state); } return NULL; } void Area::SetNextObjectToKeyFocusArea(Area* area) { next_object_to_key_focus_area_ = area; } Area* Area::GetNextObjectToKeyFocusArea() { return next_object_to_key_focus_area_; } void Area::SetPathToKeyFocusArea() { has_key_focus_ = true; next_object_to_key_focus_area_ = NULL; Area* child = this; Area* parent = GetParentObject(); while (parent) { parent->next_object_to_key_focus_area_ = child; parent->next_object_to_key_focus_area_->Reference(); parent->has_key_focus_ = false; child = parent; parent = parent->GetParentObject(); } } void Area::ResetDownwardPathToKeyFocusArea() { has_key_focus_ = false; if (next_object_to_key_focus_area_) { next_object_to_key_focus_area_->ResetDownwardPathToKeyFocusArea(); } if (next_object_to_key_focus_area_) next_object_to_key_focus_area_->UnReference(); next_object_to_key_focus_area_ = NULL; } void Area::ResetUpwardPathToKeyFocusArea() { has_key_focus_ = false; if (parent_area_) { parent_area_->ResetUpwardPathToKeyFocusArea(); } if (next_object_to_key_focus_area_) next_object_to_key_focus_area_->UnReference(); next_object_to_key_focus_area_ = NULL; } bool Area::InspectKeyEvent(unsigned int /* event_type */, unsigned int /* keysym */, const char* /* character */) { return false; } Area* Area::KeyNavIteration(KeyNavDirection /* direction */) { return NULL; } bool Area::HasKeyFocus() const { return has_key_focus_; } bool Area::IsMousePointerInside() const { Geometry geo = GetAbsoluteGeometry(); Point position = GetWindowThread()->GetWindowCompositor().GetMousePosition(); if (geo.IsInside(position)) return true; return false; } /*** Support for redirected rendering ***/ void Area::SetRedirectRenderingToTexture(bool redirect) { if (redirect_rendering_to_texture_ == redirect) { return; } if (!redirect_rendering_to_texture_ && redirect) { update_backup_texture_ = true; } redirect_rendering_to_texture_ = redirect; if (redirect == false) { // Free the texture of this view backup_fbo_.Release(); backup_texture_.Release(); backup_depth_texture_.Release(); prev_fbo_.Release(); } } bool Area::RedirectRenderingToTexture() const { return redirect_rendering_to_texture_; } void Area::SetUpdateBackupTextureForChildRendering(bool update) { update_backup_texture_ = update; } ObjectPtr Area::BackupTexture() const { // if RedirectRenderingToTexture() is false, then backup_texture_ is not a valid smart pointer. return backup_texture_; } bool Area::UpdateBackupTextureForChildRendering() const { return update_backup_texture_; } void Area::PrepareParentRedirectedView() { Area* parent = GetParentObject(); while (parent) { if (parent->RedirectRenderingToTexture()) { if (parent->UpdateBackupTextureForChildRendering()) break; parent->SetUpdateBackupTextureForChildRendering(true); parent->PrepareParentRedirectedView(); } else { parent->PrepareParentRedirectedView(); break; } } } bool Area::HasParentRedirectedView() { Area* parent = GetParentObject(); while (parent && !parent->Type().IsDerivedFromType(View::StaticObjectType)) { parent = parent->GetParentObject(); } if (parent) { View* view = static_cast(parent); if (view->RedirectRenderingToTexture()) { return true; } else { return view->HasParentRedirectedView(); } } return false; } Area* Area::RedirectedAncestor() { Area* parent = GetParentObject(); while (parent) { if (parent->RedirectRenderingToTexture()) { return parent; } parent = parent->GetParentObject(); } return NULL; } void Area::SetCopyPreviousFboTexture(bool copy_background) { copy_previous_fbo_for_background_ = copy_background; } void Area::SetPresentRedirectedView(bool present_redirected_view) { present_redirected_view_ = present_redirected_view; } bool Area::PresentRedirectedView() const { return present_redirected_view_; } #ifdef NUX_GESTURES_SUPPORT Area* Area::GetInputAreaHitByGesture(const GestureEvent & /* event */) { return nullptr; } bool Area::IsGestureInsideArea(const nux::GestureEvent &event) const { if (event.IsDirectTouch()) { Geometry geometry = GetAbsoluteGeometry(); Point p; for (const auto touch_point : event.GetTouches()) { p.x = (int)touch_point.x; p.y = (int)touch_point.y; if (!geometry.IsInside(p)) return false; } return true; } else { return GetAbsoluteGeometry().IsInside(event.GetFocus()); } } #endif // NUX_GESTURES_SUPPORT } nux-4.0.6+14.04.20140409/Nux/GesturesSubscription.h0000644000015301777760000001354412321344237022075 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #ifndef NUX_GESTURES_SUBSCRIPTION_H #define NUX_GESTURES_SUBSCRIPTION_H #include "Features.h" #ifdef NUX_GESTURES_SUPPORT #include #include // For the GestureClass enumeration. #include "NuxGraphics/GestureEvent.h" namespace nux { //! Represents a subscription to multitouch gestures /*! Typical usage: GesturesSubscription *subscription = new GesturesSubscription; subscription->SetGestureClass(TAP_GESTURE); subscription->SetNumTouches(2); subscription->Activate(); */ /* Wraps all the complexity involved in directly manipulating a GeisSubscription and exposes a simpler, C++, API. */ class GesturesSubscription { public: //! Creates a new, inactive, gestures subscription GesturesSubscription(); //! Destroys this gestures subscription. virtual ~GesturesSubscription(); //! Activates the subscription void Activate(); //! Deactivates the subscription void Deactivate(); //! Returns whether the subscription is active /*! Nux only get gesture events that matches active subscriptions. Subscriptions are inactive by default. */ bool IsActive() const {return is_active_;} //! Sets the classes of gestures this subscription is interested on void SetGestureClasses(int gesture_classes); //! Returns the gesture class that this subscription is interested on /*! By default it's set to DRAG_GESTURE|PINCH_GESTURE|ROTATE_GESTURE */ int GetGestureClasses() const {return gesture_classes_;} //! The subscription will be interested in gestures with the given number of touches void SetNumTouches(unsigned int num_touches); //! Returns the number of touches that this subscription is interested on /*! By default it is set to two touches. */ unsigned int GetNumTouches() const {return num_touches_;} //! Specifies the native window from which touch events will be gathered /*! See also GetWindowId() */ void SetWindowId(int window_id); //! Returns the native window id from which touch events are gathered. /*! By default this is the same native window that Nux uses for rendering. But in cases they differ you should speficy the native window that will provide the touch events with SetWindowId(). */ int GetWindowId() const {return window_id_;} //! Sets the recognition threshold for a given gesture class /*! For the pinch gesture class, the threshold is the current radius divided by the initial radius and should be bigger than one. Its default value is 1.1. For the drag gesture class, the threshold is in meters and represents the minimum amount of movement required for a drag to be recognized. Its default value is 0.0026 For the tap gesture class, the threshold is in meters and represents the maximum amount of movement allowed for a tap to be recognized. Its default value is 0.0026 For the rotate gesture class, the threshold is in radians and represents the mimimum amout of rotation required for a rotation gesture to be recognized. Its default value is (2*PI)/50. It has no effect or meaning for the touch gesture class. */ void SetRecognitionThreshold(GestureClass gesture_class, float threshold); //! Sets the recognition timeout for a given gesture class /*! The timeout is in milliseconds. Setting 0 (zero) means that the recognition never times out. The default timeout for drag, pinch and rotate gesture classes is 0 (zero). Fot taps it's 300. It has no effect or meaning for the touch gesture class. */ void SetRecognitionTimeout(GestureClass gesture_class, int timeout); //! Returns whether the gesture from the given event matches this subscription bool MatchesGesture(const GestureEvent &event) const; private: std::vector CreateGeisGestureClasses(); GeisStatus AddGestureClassAndNumTouchesTerm(GeisFilter filter); void CreateGeisSubscription(); void CreateGeisSubscriptionWhenPossible(); void UpdateGeisSubscription(); void ConfigureGeisSubscription(); template void SetProperty(T& prop, T new_value) { if (prop == new_value) return; prop = new_value; if (sub_) UpdateGeisSubscription(); } int gesture_classes_; int unwanted_gesture_classes_; unsigned int num_touches_; int window_id_; GeisSubscription sub_; bool is_active_; float drag_threshold_; int drag_timeout_; float pinch_threshold_; int pinch_timeout_; float rotate_threshold_; int rotate_timeout_; float tap_threshold_; int tap_timeout_; }; typedef std::shared_ptr ShGesturesSubscription; } // namespace nux #endif // NUX_GESTURES_SUPPORT #endif // NUX_GESTURES_SUBSCRIPTION_H nux-4.0.6+14.04.20140409/Nux/VSplitter.cpp0000644000015301777760000005012212321344237020147 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "VSplitter.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "WindowCompositor.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(VSplitter); static const int VSPLITTERWIDTH = 5; static const int VSTICK_SIZE = 5; VSplitter::VSplitter(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { new_addition = false; m_initial_config = true; m_focus_splitter_index = -1; m_ResizeOnSplitterRelease = true; mvt_dx = 0; mvt_dy = 0; m_current_x = 0; m_current_y = 0; m_current_width = 100; m_current_height = 100; //SetMinimumSize(m_current_width, m_current_height); SetGeometry(Geometry(m_current_x, m_current_y, m_current_width, m_current_height)); } VSplitter::~VSplitter() { // Delete all the interface object: This is a problem... The widget should be destroy by there associated parameters //delete vlayout; std::vector< Area* >::iterator it0; for (it0 = m_InterfaceObject.begin(); it0 != m_InterfaceObject.end(); ++it0) { (*it0)->UnParentObject(); } m_InterfaceObject.clear(); std::vector< MySplitter* >::iterator it2; for (it2 = m_SplitterObject.begin(); it2 != m_SplitterObject.end(); ++it2) { (*it2)->UnParentObject(); } m_SplitterObject.clear(); m_SplitConfig.clear(); } void VSplitter::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); graphics_engine.PushClippingRectangle(base); std::vector::iterator it; GetPainter().PaintBackground(graphics_engine, base); std::vector::iterator it_splitter; for (it_splitter = m_SplitterObject.begin(); it_splitter != m_SplitterObject.end(); ++it_splitter) { Geometry geo = (*it_splitter)->GetGeometry(); Geometry grip_geo; int h = 20; if (geo.GetHeight() > h) { grip_geo.SetX(geo.x); grip_geo.SetY(geo.y + (geo.GetHeight() - h) / 2); grip_geo.SetWidth(geo.GetWidth()); grip_geo.SetHeight(h); } else { grip_geo.SetX(geo.x); grip_geo.SetY(geo.y + (h - geo.GetHeight()) / 2); grip_geo.SetWidth(geo.GetWidth()); grip_geo.SetHeight(h); } GetPainter().Draw2DLine(graphics_engine, grip_geo.x + 1, grip_geo.y, grip_geo.x + 1, grip_geo.y + grip_geo.GetHeight(), Color(0xFF111111)); GetPainter().Draw2DLine(graphics_engine, grip_geo.x + 3, grip_geo.y, grip_geo.x + 3, grip_geo.y + grip_geo.GetHeight(), Color(0xFF111111)); } graphics_engine.PopClippingRectangle(); } void VSplitter::DrawContent(GraphicsEngine &graphics_engine, bool force_draw) { graphics_engine.PushClippingRectangle(GetGeometry()); Geometry base = GetGeometry(); bool need_redraw = IsRedrawNeeded(); std::vector::iterator it_splitter; std::vector::iterator it; for (it = m_InterfaceObject.begin(), it_splitter = m_SplitterObject.begin(); it != m_InterfaceObject.end(); ++it, ++it_splitter) { Geometry sgeo = (*it_splitter)->GetGeometry(); graphics_engine.PushClippingRectangle(Rect( base.x, base.y, sgeo.x - base.x, base.GetHeight())); base.SetX(sgeo.x + sgeo.GetWidth()); if (force_draw || need_redraw) { if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = NUX_STATIC_CAST(View *, (*it)); ic->ProcessDraw(graphics_engine, true); } else if ((*it)->Type().IsObjectType(HLayout::StaticObjectType)) { HLayout *layout = NUX_STATIC_CAST(HLayout *, (*it)); layout->ProcessDraw(graphics_engine, true); } else if ((*it)->Type().IsObjectType(VLayout::StaticObjectType)) { VLayout *layout = NUX_STATIC_CAST(VLayout *, (*it)); layout->ProcessDraw(graphics_engine, true); } } else { if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = NUX_STATIC_CAST(View *, (*it)); ic->ProcessDraw(graphics_engine, false); } else if ((*it)->Type().IsObjectType(HLayout::StaticObjectType)) { HLayout *layout = NUX_STATIC_CAST(HLayout *, (*it)); layout->ProcessDraw(graphics_engine, false); } else if ((*it)->Type().IsObjectType(VLayout::StaticObjectType)) { VLayout *layout = NUX_STATIC_CAST(VLayout *, (*it)); layout->ProcessDraw(graphics_engine, false); } } graphics_engine.PopClippingRectangle(); } graphics_engine.PopClippingRectangle(); } void VSplitter::OverlayDrawing(GraphicsEngine &graphics_engine) { unsigned int num_element = (unsigned int) m_SplitterObject.size(); Geometry base = GetGeometry(); if (m_focus_splitter_index >= 0) { Geometry geo = m_SplitterObject[m_focus_splitter_index]->GetGeometry(); geo.OffsetPosition(mvt_dx, mvt_dy); if (m_focus_splitter_index == 0 && num_element > 1) { if (geo.x < base.x) { geo.SetX(base.x); } if (geo.x + VSPLITTERWIDTH > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x) { geo.SetX(m_SplitterObject[m_focus_splitter_index+1]->GetGeometry().x - VSPLITTERWIDTH); } } if ((m_focus_splitter_index > 0) && m_focus_splitter_index < (int) num_element - 1) { if (geo.x < m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().x + VSPLITTERWIDTH) { geo.SetX(m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().x + VSPLITTERWIDTH); } if (geo.x + VSPLITTERWIDTH > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x) { geo.SetX(m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x - VSPLITTERWIDTH); } } graphics_engine.GetRenderStates().SetBlend(true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); { GetPainter().Paint2DQuadColor(graphics_engine, geo, Color(0xBB868686)); } graphics_engine.GetRenderStates().SetBlend(false); } } void VSplitter::AddWidget(Area *ic, float stretchfactor) { if (ic) { MySplitter* splitter = new MySplitter; splitter->SetParentObject(this); //splitter->SinkReference(); unsigned int no = (unsigned int) m_InterfaceObject.size(); splitter->mouse_down.connect(sigc::bind(sigc::mem_fun(this, &VSplitter::OnSplitterMouseDown), no)); splitter->mouse_up.connect(sigc::bind(sigc::mem_fun(this, &VSplitter::OnSplitterMouseUp), no)); splitter->mouse_drag.connect(sigc::bind(sigc::mem_fun(this, &VSplitter::OnSplitterMouseDrag), no)); ic->SetParentObject(this); m_InterfaceObject.push_back(ic); m_SplitterObject.push_back(splitter); m_SplitConfig.push_back(stretchfactor); new_addition = true; ComputeContentSize(); } } void VSplitter::clearContent() { m_InterfaceObject.clear(); } long VSplitter::ComputeContentSize() { unsigned int num_element = (unsigned int) m_InterfaceObject.size(); int x = GetBaseX(); int y = GetBaseY(); int w = GetBaseWidth(); int h = GetBaseHeight(); if ((w == 0) || (h == 0)) { return eCompliantHeight | eCompliantWidth; } if (num_element < 1) { m_current_height = h; m_current_width = w; m_current_x = x; m_current_y = y; new_addition = false; return eCompliantHeight | eCompliantWidth; } std::vector::iterator it; std::vector::iterator it_splitter; if (new_addition) { ResetSplitConfig(); new_addition = false; } if (m_current_height != h) { for (unsigned int i = 0; i < num_element; i++) { Geometry splitter_geo = m_SplitterObject[i]->GetGeometry(); splitter_geo.SetHeight(h); splitter_geo.SetY(y); m_SplitterObject[i]->SetGeometry(splitter_geo); } } if (m_current_width != w) { int size_to_distribute = w - num_element * VSPLITTERWIDTH; int previous_spliter_end = m_current_x; int new_spliter_end = x; for (unsigned int i = 0; i < num_element; i++) { Geometry splitter_geo = m_SplitterObject[i]->GetGeometry(); // compute percentage of space occupied by the element i; // width of element i = m_SplitterObject[i]->GetX() - previous_splliter_end int splitter_start = m_SplitterObject[i]->GetBaseX(); float percent = float(splitter_start - previous_spliter_end) / float(m_current_width - num_element * VSPLITTERWIDTH); if (percent > 1.0f) percent = 1.0f; splitter_geo.SetX(new_spliter_end + size_to_distribute * percent); previous_spliter_end = splitter_start + VSPLITTERWIDTH; new_spliter_end = new_spliter_end + size_to_distribute * percent + VSPLITTERWIDTH; m_SplitterObject[i]->SetGeometry(splitter_geo); } if (m_SplitterObject[0]->GetBaseX() < x) { m_SplitterObject[0]->SetBaseX(x); } m_SplitterObject[num_element-1]->SetBaseX(x + w - VSPLITTERWIDTH); } int accwidth = x; for (unsigned int i = 0; i < num_element; i++) { Geometry splitter_geo = m_SplitterObject[i]->GetGeometry(); //m_InterfaceObject[i]->SetGeometry(Geometry(accwidth, y, splitter_geo.x - accwidth, h)); if (m_InterfaceObject[i]->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = NUX_STATIC_CAST(View *, m_InterfaceObject[i]); ic->SetGeometry(Geometry(accwidth, y, splitter_geo.x - accwidth, h)); // if we are already computing the layout from the main window down, we need to call // ComputeElementLayout to force the computing of this element layout. GetWindowThread()->ComputeElementLayout(ic); } else if (m_InterfaceObject[i]->Type().IsDerivedFromType(Layout::StaticObjectType)) { Layout *layout = NUX_STATIC_CAST(Layout *, m_InterfaceObject[i]); layout->SetGeometry(Geometry(accwidth, y, splitter_geo.x - accwidth, h)); // if we are already computing the layout from the main window down, we need to call // ComputeElementLayout to force the computing of this element layout. GetWindowThread()->ComputeElementLayout(layout); } accwidth += splitter_geo.x - accwidth + VSPLITTERWIDTH; } m_current_height = h; m_current_width = w; m_current_x = x; m_current_y = y; return eCompliantHeight | eCompliantWidth; } void VSplitter::ResetSplitConfig() { int x = GetBaseX(); int y = GetBaseY(); int w = GetBaseWidth(); int h = GetBaseHeight(); unsigned int num_element = (unsigned int) m_InterfaceObject.size(); if (num_element < 1) { return; } float max_stretch = 0.0f; float stretchfactor; for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++) { stretchfactor = m_SplitConfig[i]; if (max_stretch < stretchfactor) { max_stretch = stretchfactor; } } float total = 0; for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++) { stretchfactor = m_SplitConfig[i]; total += stretchfactor / max_stretch; } int availableheight = (w - num_element * VSPLITTERWIDTH); float max_size = float(availableheight) / total; for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++) { stretchfactor = m_SplitConfig[i]; x += stretchfactor * max_size / max_stretch; Geometry geo(x, y, VSPLITTERWIDTH, h); m_SplitterObject[i]->SetGeometry(geo); } m_SplitterObject[num_element-1]->SetBaseX(x + w - VSPLITTERWIDTH); m_initial_config = true; } void VSplitter::OnSplitterMouseDown(int x, int y, unsigned long /* button_flags */, unsigned long /* key_flags */, int header_pos) { m_point = Point(x, y); m_focus_splitter_index = header_pos; GetWindowThread()->GetWindowCompositor().SetWidgetDrawingOverlay(this, GetWindowThread()->GetWindowCompositor().GetProcessingTopView()); // Hint for the window to initiate a redraw GetWindowThread()->RequestRedraw(); } void VSplitter::OnSplitterMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */, int header_pos) { if (mvt_dx) { Geometry geo = m_SplitterObject[header_pos]->GetGeometry(); geo.OffsetPosition(mvt_dx, 0); unsigned int num_element = (unsigned int) m_SplitterObject.size(); if (header_pos < (int) num_element - 1) { // Make the splitter bar stick to the next one if the distance between them is less than VSTICK_SIZE if (m_SplitterObject[header_pos + 1]->GetGeometry().x - geo.x - VSPLITTERWIDTH < VSTICK_SIZE) geo.SetX( m_SplitterObject[header_pos + 1]->GetGeometry().x - VSPLITTERWIDTH ); } m_SplitterObject[header_pos]->SetGeometry(geo); ResizeSplitter(header_pos); } m_focus_splitter_index = -1; mvt_dx = 0; mvt_dy = 0; // End overlay drawing; GetWindowThread()->GetWindowCompositor().SetWidgetDrawingOverlay(0, GetWindowThread()->GetWindowCompositor().GetProcessingTopView()); // Hint for the window to initiate a redraw GetWindowThread()->RequestRedraw(); } void VSplitter::OnSplitterMouseDrag(int x, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */, int header_pos) { Geometry geo = m_SplitterObject[header_pos]->GetGeometry(); int num_element = (int) m_SplitterObject.size(); if (header_pos == num_element - 1) { // The last splitter cannot be moved return; } mvt_dx = x - m_point.x; mvt_dy = 0; if (m_ResizeOnSplitterRelease == false) { // Continuously redraw resize and redraw the 2 parts of the widget. // This is slow. geo.OffsetPosition(mvt_dx, mvt_dy); m_SplitterObject[header_pos]->SetGeometry(geo); ResizeSplitter(header_pos); mvt_dx = 0; mvt_dy = 0; } // Hint for the window to initiate a redraw GetWindowThread()->RequestRedraw(); } void VSplitter::ResizeSplitter(int header_pos) { int num_element = (int) m_SplitterObject.size(); if ((header_pos == 0) && (m_SplitterObject[header_pos]->GetBaseX() < GetBaseX())) { m_SplitterObject[header_pos]->SetBaseX(GetBaseX()); } if ((header_pos == num_element - 1) && (m_SplitterObject[header_pos]->GetBaseX() > GetBaseX() + GetBaseWidth() - VSPLITTERWIDTH)) { m_SplitterObject[header_pos]->SetBaseX(GetBaseX() + GetBaseWidth() - VSPLITTERWIDTH); } if (header_pos < (int) num_element - 1) { int posx0, posx1; posx0 = m_SplitterObject[header_pos]->GetBaseX(); posx1 = m_SplitterObject[header_pos + 1]->GetBaseX(); if (posx0 > posx1 - VSPLITTERWIDTH) { posx0 = posx1 - VSPLITTERWIDTH; m_SplitterObject[header_pos]->SetBaseX(posx0); } } if (0 < header_pos) { int posx0, posx1; posx0 = m_SplitterObject[header_pos]->GetBaseX(); posx1 = m_SplitterObject[header_pos - 1]->GetBaseX(); if (posx0 < posx1 + VSPLITTERWIDTH) { posx0 = posx1 + VSPLITTERWIDTH; m_SplitterObject[header_pos]->SetBaseX(posx0); } } m_initial_config = false; ComputeContentSize(); QueueDraw(); } // VSplitter need to re implement DoneRedraw because it does not // have a m_compositionlayout where its child are located; void VSplitter::DoneRedraw() { std::vector::iterator it; for (it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); ++it) { //(*it)->DoneRedraw(); if ((*it)->Type().IsDerivedFromType(View::StaticObjectType)) { View *ic = NUX_STATIC_CAST(View *, (*it)); ic->DoneRedraw(); } } } Area* VSplitter::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; std::vector::iterator splitter_it; for (splitter_it = m_SplitterObject.begin(); splitter_it != m_SplitterObject.end(); ++splitter_it) { Area* found_area = (*splitter_it)->FindAreaUnderMouse(mouse_position, event_type); if (found_area) return found_area; } std::vector::iterator it; for (it = m_InterfaceObject.begin(); it != m_InterfaceObject.end(); ++it) { Area* found_area = (*it)->FindAreaUnderMouse(mouse_position, event_type); if (found_area) return found_area; } if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } bool VSplitter::AcceptKeyNavFocus() { return false; } Area* VSplitter::KeyNavIteration(KeyNavDirection direction) { if (m_InterfaceObject.empty()) return NULL; if (next_object_to_key_focus_area_) { if ((direction == KEY_NAV_UP) || (direction == KEY_NAV_DOWN)) { // Don't know what to do with this return NULL; } std::vector::iterator it; std::vector::iterator it_next; it = std::find(m_InterfaceObject.begin(), m_InterfaceObject.end(), next_object_to_key_focus_area_); if (it == m_InterfaceObject.end()) { // Should never happen nuxAssert(0); return NULL; } it_next = it; ++it_next; if ((direction == KEY_NAV_LEFT) && (it == m_InterfaceObject.begin())) { // can't go further return NULL; } if ((direction == KEY_NAV_RIGHT) && (it_next == m_InterfaceObject.end())) { // can't go further return NULL; } if (direction == KEY_NAV_LEFT) { --it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { if (it == m_InterfaceObject.begin()) break; --it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_RIGHT) { ++it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == m_InterfaceObject.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } } else { Area* key_nav_focus = NULL; if (direction == KEY_NAV_LEFT) { std::vector::reverse_iterator it = m_InterfaceObject.rbegin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == m_InterfaceObject.rend()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } else { std::vector::iterator it = m_InterfaceObject.begin(); key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; if (it == m_InterfaceObject.end()) break; key_nav_focus = (*it)->KeyNavIteration(direction); } } return key_nav_focus; } return NULL; } } nux-4.0.6+14.04.20140409/Nux/InputAreaProximity.cpp0000644000015301777760000000467612321344237022045 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Brandon Schaefer * */ #include "WindowCompositor.h" #include "WindowThread.h" #include "InputAreaProximity.h" #include "NuxCore/Logger.h" namespace nux { DECLARE_LOGGER(logger, "nux.inputarea_proximity"); InputAreaProximity::InputAreaProximity(InputArea* area, unsigned int proximity) : area_(area) , proximity_(proximity) , is_mouse_near_(false) { if(area) GetWindowThread()->GetWindowCompositor().AddAreaInProximityList(this); else LOG_ERROR(logger) << "Error, passing in NULL value for InputArea*"; } InputAreaProximity::~InputAreaProximity() { GetWindowThread()->GetWindowCompositor().RemoveAreaInProximityList(this); } Point GetOffsetFromRect(Rect const& rect, Point const& mouse) { Point offset; if (rect.x > mouse.x) { offset.x = rect.x - mouse.x; } else if (rect.x + rect.width < mouse.x) { offset.x = rect.x + rect.width - mouse.x; } if (rect.y > mouse.y) { offset.y = rect.y - mouse.y; } else if (rect.y + rect.height < mouse.y) { offset.y = rect.y + rect.height - mouse.y; } return offset; } void InputAreaProximity::CheckMousePosition(Point const& mouse) { if (!area_.IsValid()) return; Geometry const& geo = area_->GetAbsoluteGeometry(); Geometry const& expanded = geo.GetExpand(proximity_, proximity_); if (!is_mouse_near_ && expanded.IsInside(mouse)) { is_mouse_near_ = true; mouse_near.emit(mouse); } else if (is_mouse_near_ && !expanded.IsInside(mouse)) { is_mouse_near_ = false; mouse_beyond.emit(mouse); } if (is_mouse_near_ && !geo.IsInside(mouse)) { nux::Point const& offset = GetOffsetFromRect(geo, mouse); mouse_approaching.emit(mouse, offset); } } } nux-4.0.6+14.04.20140409/Nux/MainLoopGLib.h0000644000015301777760000000064012321344237020134 0ustar pbusernogroup00000000000000#ifndef _NUX_MAIN_LOOP_GLIB_H #define _NUX_MAIN_LOOP_GLIB_H #include #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) namespace nux { class ExternalGLibSources { public: void AddFdToGLibLoop(gint fd, gpointer data, GSourceFunc callback, GMainContext *context); void RemoveFdFromGLibLoop(gpointer data); }; } #endif #endif nux-4.0.6+14.04.20140409/Nux/ComboBoxSimple.h0000644000015301777760000000560512321344237020550 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef COMBOBOX_LOGIC_H #define COMBOBOX_LOGIC_H #include "AbstractComboBox.h" #include "ActionItem.h" namespace nux { class MenuPage; class ActionItem; class TableItem; class TableCtrl; class ComboBoxSimple : public AbstractComboBox { public: ComboBoxSimple(NUX_FILE_LINE_PROTO); ~ComboBoxSimple(); // make the class abstract // virtual void Draw(GraphicsEngine& graphics_engine, bool force_draw); // virtual void DrawContent(GraphicsEngine& graphics_engine, bool force_draw); public: ActionItem *AddItem(const char *label, int Uservalue = 0); void RemoveItem(ActionItem *item); void RemoveAllItem(); // emitters void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnPopupStop(); // signals void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvSigActionTriggered(MenuPage *, ActionItem *); void RecvSigActionTriggered2(TableCtrl *table, TableItem *item, unsigned int row, unsigned int column); void RecvSigTerminateMenuCascade(); void RecvGeometryChanged(Area *area, Geometry &geo); const char *GetSelectionLabel() const; int GetSelectionUserValue() const; int GetNumItem() const; ActionItem *GetItem(int index) const; int GetSelectionIndex() const; void SetSelectionIndex(int index); // moves the currently selected item up/down - just shorthand for SetSelectionIndex void MoveSelectionUp(); void MoveSelectionDown(); MenuPage * GetMenuPage() { return m_CurrentMenu; } sigc::signal sigTriggered; sigc::signal sigActionTriggered; protected: virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); void RecvClosingMenuSignal(MenuPage* menu_page); MenuPage *m_CurrentMenu; ActionItem *m_SelectedAction; }; } #endif // COMBOBOX_LOGIC_H nux-4.0.6+14.04.20140409/Nux/SpinBoxDouble.h0000644000015301777760000000403512321344237020377 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef SPINBOXDOUBLE_H #define SPINBOXDOUBLE_H #include "EditTextBox.h" namespace nux { class SpinBoxDouble: public SpinBox_Logic { public: SpinBoxDouble(double Value = 0, double Step = 1, double MinValue = 0, double MaxValue = 100, NUX_FILE_LINE_PROTO); virtual ~SpinBoxDouble(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void ImplementIncrementBtn(); virtual void ImplementDecrementBtn(); virtual void ImplementValidateEntry(); void SetValue(double value); double GetValue() const; void SetStep(double i); double GetStep() const; double GetMinValue() const; double GetMaxValue() const; void SetRange(double MinValue, double Maxvalue); sigc::signal sigIncrement; sigc::signal sigDecrement; sigc::signal sigValueChanged; sigc::signal sigValue; protected: void InitializeWidgets(); void InitializeLayout(); private: HLayout *m_hlayout; VLayout *m_vlayout; DoubleValidator m_DoubleValidator; double m_Value; double m_Step; }; } #endif // SPINBOXDOUBLE_H nux-4.0.6+14.04.20140409/Nux/View.cpp0000644000015301777760000005031412321344237017130 0ustar pbusernogroup00000000000000/* * Copyright 2010, 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "WindowCompositor.h" #include "Layout.h" #include "View.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(View); View::View(NUX_FILE_LINE_DECL) : InputArea(NUX_FILE_LINE_PARAM) , m_TextColor(1.0f, 1.0f, 1.0f, 1.0f) , view_layout_(nullptr) , draw_cmd_queued_(false) , child_draw_cmd_queued_(false) { } View::~View() { backup_fbo_.Release(); backup_texture_.Release(); backup_depth_texture_.Release(); background_texture_.Release(); // It is possible that the window thread has been deleted before the view // itself, so check prior to calling. WindowThread* wt = GetWindowThread(); if (wt) { // It is possible that the object is in the refresh list. Remove it here // before it is deleted. wt->RemoveObjectFromLayoutQueue(this); } RemoveLayout(); } long View::ComputeContentSize() { if (view_layout_) { PreLayoutManagement(); int PreWidth = GetBaseWidth(); int PreHeight = GetBaseHeight(); long ret = view_layout_->ComputeContentSize(); PostLayoutManagement(ret); int PostWidth = GetBaseWidth(); int PostHeight = GetBaseHeight(); long size_compliance = 0; // The layout has been resized to tightly pack its content if (PostWidth > PreWidth) { size_compliance |= eLargerWidth; // need scrollbar } else if (PostWidth < PreWidth) { size_compliance |= eSmallerWidth; } else { size_compliance |= eCompliantWidth; } // The layout has been resized to tightly pack its content if (PostHeight > PreHeight) { size_compliance |= eLargerHeight; // need scrollbar } else if (PostHeight < PreHeight) { size_compliance |= eSmallerHeight; } else { size_compliance |= eCompliantHeight; } return size_compliance; } else { PreLayoutManagement(); int ret = PostLayoutManagement(eCompliantHeight | eCompliantWidth); return ret; } return 0; } void View::ComputeContentPosition(float offsetX, float offsetY) { if (view_layout_) { view_layout_->SetBaseX(GetBaseX()); view_layout_->SetBaseY(GetBaseY()); view_layout_->ComputeContentPosition(offsetX, offsetY); } } void View::PreLayoutManagement() { // Give the managed layout the same size and position as the Control. if (view_layout_) view_layout_->SetGeometry(GetGeometry()); } long View::PostLayoutManagement(long LayoutResult) { // Set the geometry of the control to be the same as the managed layout. // Only the size is changed. The position of the composition layout hasn't // been changed by ComputeContentSize. if (view_layout_) { // If The layout is empty, do not change the size of the parent element. if (!view_layout_->IsEmpty()) Area::SetGeometry(view_layout_->GetGeometry()); } return LayoutResult; } void View::PreResizeGeometry() { } void View::PostResizeGeometry() { } void View::ProcessDraw(GraphicsEngine& graphics_engine, bool force_draw) { full_view_draw_cmd_ = false; if (RedirectRenderingToTexture()) { if (update_backup_texture_ || force_draw || draw_cmd_queued_) { GetPainter().PushPaintLayerStack(); BeginBackupTextureRendering(graphics_engine, force_draw); { graphics_engine.PushModelViewMatrix(Get2DMatrix()); if (force_draw) { draw_cmd_queued_ = true; full_view_draw_cmd_ = true; Draw(graphics_engine, force_draw); DrawContent(graphics_engine, force_draw); } else { if (draw_cmd_queued_) { full_view_draw_cmd_ = true; Draw(graphics_engine, false); DrawContent(graphics_engine, false); } else if (update_backup_texture_) { DrawContent(graphics_engine, false); } } graphics_engine.PopModelViewMatrix(); } EndBackupTextureRendering(graphics_engine, force_draw); GetPainter().PopPaintLayerStack(); } if (PresentRedirectedView()) { unsigned int current_alpha_blend; unsigned int current_src_blend_factor; unsigned int current_dest_blend_factor; // Be a good citizen, get a copy of the current GPU sates according to Nux graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); TexCoordXForm texxform; if ((force_draw || draw_cmd_queued_) && (background_texture_.IsValid())) { graphics_engine.GetRenderStates().SetBlend(false); texxform.FlipVCoord(true); // Draw the background of this view. GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(GetX(), GetY(), background_texture_->GetWidth(), background_texture_->GetHeight(), background_texture_, texxform, color::White); } texxform.uwrap = TEXWRAP_CLAMP; texxform.vwrap = TEXWRAP_CLAMP; texxform.FlipVCoord(true); graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(GetX(), GetY(), GetWidth(), GetHeight(), backup_texture_, texxform, Color(color::White)); // Be a good citizen, restore the Nux blending states. graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } } else { graphics_engine.PushModelViewMatrix(Get2DMatrix()); if (force_draw) { GetPainter().PaintBackground(graphics_engine, GetGeometry()); GetPainter().PushPaintLayerStack(); draw_cmd_queued_ = true; full_view_draw_cmd_ = true; Draw(graphics_engine, force_draw); DrawContent(graphics_engine, force_draw); GetPainter().PopPaintLayerStack(); } else { if (draw_cmd_queued_) { GetPainter().PaintBackground(graphics_engine, GetGeometry()); GetPainter().PushPaintLayerStack(); full_view_draw_cmd_ = true; Draw(graphics_engine, false); DrawContent(graphics_engine, false); GetPainter().PopPaintLayerStack(); } else { DrawContent(graphics_engine, false); } } graphics_engine.PopModelViewMatrix(); } if (view_layout_) { view_layout_->ResetQueueDraw(); } draw_cmd_queued_ = false; child_draw_cmd_queued_ = false; full_view_draw_cmd_ = false; update_backup_texture_ = false; } void View::BeginBackupTextureRendering(GraphicsEngine& graphics_engine, bool force_draw) { ObjectPtr active_fbo_texture; if (force_draw || draw_cmd_queued_) { // Get the active fbo color texture active_fbo_texture = GetGraphicsDisplay()->GetGpuDevice()->ActiveFboTextureAttachment(0); } Geometry xform_geo; // Compute position in the active fbo texture. xform_geo = graphics_engine.ModelViewXFormRect(GetGeometry()); // Get the active fbo... prev_fbo_ = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); // ... and the size of the view port rectangle. prev_viewport_ = graphics_engine.GetViewportRect(); const int width = GetWidth(); const int height = GetHeight(); // Compute intersection with active fbo. Geometry intersection = xform_geo; if (active_fbo_texture.IsValid()) { Geometry active_fbo_geo(0, 0, active_fbo_texture->GetWidth(), active_fbo_texture->GetHeight()); intersection = active_fbo_geo.Intersect(xform_geo); } if (backup_fbo_.IsNull()) { // Create the fbo before using it for the first time. backup_fbo_ = GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject(); } if (!backup_texture_.IsValid() || (backup_texture_->GetWidth() != width) || (backup_texture_->GetHeight() != height)) { // Create or resize the color and depth textures before using them. backup_texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); backup_depth_texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } if (!background_texture_.IsValid() || (background_texture_->GetWidth() != intersection.width) || (background_texture_->GetHeight() != intersection.height)) { background_texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(intersection.width, intersection.height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); } backup_fbo_->FormatFrameBufferObject(width, height, BITFMT_R8G8B8A8); backup_fbo_->EmptyClippingRegion(); graphics_engine.SetViewport(0, 0, width, height); graphics_engine.SetOrthographicProjectionMatrix(width, height); // Draw the background on the previous fbo texture if ((force_draw || draw_cmd_queued_) && background_texture_.IsValid()) { backup_fbo_->FormatFrameBufferObject(intersection.width, intersection.height, BITFMT_R8G8B8A8); backup_fbo_->EmptyClippingRegion(); graphics_engine.SetViewport(0, 0, intersection.width, intersection.height); graphics_engine.SetOrthographicProjectionMatrix(intersection.width, intersection.height); // Set the background texture in the fbo backup_fbo_->SetTextureAttachment(0, background_texture_, 0); backup_fbo_->SetDepthTextureAttachment(ObjectPtr(0), 0); backup_fbo_->Activate(); graphics_engine.SetViewport(0, 0, background_texture_->GetWidth(), background_texture_->GetHeight()); // Clear surface // Clear surface CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); CHECKGL(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); TexCoordXForm texxform; texxform.uoffset = xform_geo.x / (float) active_fbo_texture->GetWidth(); texxform.voffset = xform_geo.y / (float) active_fbo_texture->GetHeight(); texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD); texxform.flip_v_coord = true; // Temporarily change the model-view matrix to copy the texture background texture. // This way we are not affceted by the regular model-view matrix. graphics_engine.SetModelViewMatrix(Matrix4::IDENTITY()); // Copy the texture from the previous fbo attachment into our background texture. if (copy_previous_fbo_for_background_) { graphics_engine.QRP_1Tex(0, 0, intersection.width, intersection.height, active_fbo_texture, texxform, color::White); } else { graphics_engine.QRP_Color(0, 0, intersection.width, intersection.height, Color(0.0f, 0.0f, 0.0f, 0.0f)); } // Restore the model-view matrix. graphics_engine.ApplyModelViewMatrix(); } backup_fbo_->FormatFrameBufferObject(width, height, BITFMT_R8G8B8A8); backup_fbo_->EmptyClippingRegion(); backup_fbo_->SetTextureAttachment(0, backup_texture_, 0); backup_fbo_->SetDepthTextureAttachment(backup_depth_texture_, 0); backup_fbo_->Activate(); if (force_draw || draw_cmd_queued_) { CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); CHECKGL(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); } graphics_engine.SetViewport(0, 0, width, height); graphics_engine.SetOrthographicProjectionMatrix(width, height); // Transform the geometry of this area through the current model view matrix. This gives the // the position of the view in the active fbo texture. Geometry offset_rect = graphics_engine.ModelViewXFormRect(GetGeometry()); int x_offset = -offset_rect.x; int y_offset = -offset_rect.y; graphics_engine.PushModelViewMatrix(Matrix4::TRANSLATE(x_offset, y_offset, 0)); } void View::EndBackupTextureRendering(GraphicsEngine& graphics_engine, bool /* force_draw */) { graphics_engine.PopModelViewMatrix(); if (prev_fbo_.IsValid()) { // Restore the previous fbo prev_fbo_->Activate(); prev_fbo_->ApplyClippingRegion(); } // Release the reference on the previous fbo prev_fbo_.Release(); // Restore the matrices and the view port. graphics_engine.ApplyModelViewMatrix(); graphics_engine.SetOrthographicProjectionMatrix(prev_viewport_.width, prev_viewport_.height); graphics_engine.SetViewport(prev_viewport_.x, prev_viewport_.y, prev_viewport_.width, prev_viewport_.height); } void View::Draw(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void View::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void View::QueueDraw() { // Report to a parent view with redirect_rendering_to_texture_ set to true that one of its children // needs to be redrawn. // // We should always do this, as the conditions for parent rendering may have // changed between child QueueDraw calls (eg window visibility) PrepareParentRedirectedView(); if (draw_cmd_queued_) return; WindowThread* application = GetWindowThread(); if (application) { application->AddToDrawList(this); application->RequestRedraw(); } if (view_layout_) { // If this view has requested a draw, then all of it children in the view_layout_ // need to be redrawn as well. view_layout_->QueueDraw(); } draw_cmd_queued_ = true; queue_draw.emit(this); } void View::NeedSoftRedraw() { //GetWindowCompositor()..AddToDrawList(this); WindowThread* application = GetWindowThread(); if (application) { application->AddToDrawList(this); application->RequestRedraw(); } //draw_cmd_queued_ = false; } bool View::IsRedrawNeeded() { return draw_cmd_queued_; } bool View::IsFullRedraw() const { return full_view_draw_cmd_; } void View::DoneRedraw() { draw_cmd_queued_ = false; if (view_layout_) { view_layout_->DoneRedraw(); } } Layout* View::GetLayout() { return view_layout_; } Layout *View::GetCompositionLayout() { return GetLayout(); } bool View::SetLayout(Layout *layout) { NUX_RETURN_VALUE_IF_NULL(layout, false); nuxAssert(layout->IsLayout()); NUX_RETURN_VALUE_IF_TRUE(view_layout_ == layout, true); Area *parent = layout->GetParentObject(); if (parent == this) { nuxAssert(view_layout_ == layout); return false; } else if (parent != 0) { nuxDebugMsg(0, "[View::SetCompositionLayout] Object already has a parent. You must UnParent the object before you can parenting again."); return false; } if (view_layout_) { /* we need to emit the signal before the unparent, just in case one of the callbacks wanted to use this object */ LayoutRemoved.emit(this, view_layout_); view_layout_->UnParentObject(); } layout->SetParentObject(this); view_layout_ = layout; GetWindowThread()->QueueObjectLayout(this); LayoutAdded.emit(this, view_layout_); view_layout_->queue_draw.connect(sigc::mem_fun(this, &View::ChildViewQueuedDraw)); view_layout_->child_queue_draw.connect(sigc::mem_fun(this, &View::ChildViewQueuedDraw)); return true; } void View::ChildViewQueuedDraw(Area* area) { if (child_draw_cmd_queued_) return; child_draw_cmd_queued_ = true; child_queue_draw.emit(area); } void View::OnChildFocusChanged(/*Area *parent,*/ Area *child) { ChildFocusChanged.emit(/*parent,*/ child); } bool View::SetCompositionLayout(Layout *layout) { return SetLayout(layout); } void View::RemoveLayout() { NUX_RETURN_IF_NULL(view_layout_); if (view_layout_) view_layout_->UnParentObject(); view_layout_ = 0; } void View::RemoveCompositionLayout() { RemoveLayout(); } bool View::SearchInAllSubNodes(Area *bo) { if (view_layout_) return view_layout_->SearchInAllSubNodes(bo); return false; } bool View::SearchInFirstSubNodes(Area *bo) { if (view_layout_) return view_layout_->SearchInFirstSubNodes(bo); return false; } // void View::SetGeometry(int x, int y, int w, int h) // { // Area::SetGeometry(x, y, w, h); // ComputeContentSize(); // PostResizeGeometry(); // } void View::SetGeometry(const Geometry& geo) { Area::SetGeometry(geo.x, geo.y, geo.width, geo.height); ComputeContentSize(); PostResizeGeometry(); } void View::SetFont(ObjectPtr font) { _font = font; } ObjectPtr View::GetFont() { if (!_font.IsValid()) _font = GetSysFont(); return _font; } void View::SetTextColor(const Color &color) { m_TextColor = color; } Color View::GetTextColor() const { return m_TextColor; } void View::EnableView() { view_enabled_ = true; } void View::DisableView() { view_enabled_ = false; } void View::SetEnableView(bool enable) { if (enable) { EnableView(); } else { DisableView(); } } bool View::IsViewEnabled() const { return view_enabled_; } void View::GeometryChangePending(bool /* position_about_to_change */, bool /* size_about_to_change */) { if (IsLayoutDone()) QueueDraw(); } void View::GeometryChanged(bool /* position_has_changed */, bool size_has_changed) { if (RedirectedAncestor()) { if (size_has_changed) QueueDraw(); return; } if (IsLayoutDone()) QueueDraw(); } Area* View::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; if (view_layout_) { Area* view = view_layout_->FindAreaUnderMouse(mouse_position, event_type); if (view) return view; } if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } Area* View::FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state) { if (has_key_focus_) { return this; } else if (next_object_to_key_focus_area_) { return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state); } return NULL; } Area* View::KeyNavIteration(KeyNavDirection direction) { if (next_object_to_key_focus_area_) { return NULL; } if (IsVisible() == false) return NULL; if (AcceptKeyNavFocus()) { QueueDraw(); return this; } else if (view_layout_) { return view_layout_->KeyNavIteration(direction); } return NULL; } bool View::AcceptKeyNavFocus() { return true; } #ifdef NUX_GESTURES_SUPPORT Area* View::GetInputAreaHitByGesture(const nux::GestureEvent &event) { if (!IsVisible()) return nullptr; if (!IsGestureInsideArea(event)) return nullptr; if (view_layout_) { Area *area = view_layout_->GetInputAreaHitByGesture(event); if (area) return area; } if (HasSubscriptionForGesture(event)) return this; else return nullptr; } #endif } nux-4.0.6+14.04.20140409/Nux/WidgetMetrics.h0000644000015301777760000000446212321344237020440 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef WIDGETMETRICS_H #define WIDGETMETRICS_H namespace nux { extern const Color COLOR_BLACK ; extern const Color COLOR_RED; extern const Color COLOR_GREEN;; extern const Color COLOR_BLUE; extern const Color COLOR_WHITE; extern const Color COLOR_BACKGROUND_PRIMARY; extern const Color COLOR_BACKGROUND_SECONDARY; extern const Color COLOR_FOREGROUND_PRIMARY; extern const Color COLOR_FOREGROUND_SECONDARY; extern const Color COLOR_SELECTION_SECONDARY; // Text color extern const Color COLOR_TEXTEDIT_BACKGROUNG; extern const Color COLOR_TEXTSTATIC_BACKGROUNG; // General background color extern const Color COLOR_WIDGET_BACKGROUND; extern const Color COLOR_WIDGET_MOUSEOVER; extern const Color COLOR_WINDOW_BACKGROUND; // Widget control background color extern const Color COLOR_PRIMARY_LEFT; extern const Color COLOR_PRIMARY_RIGHT; // ScrollBar color extern const Color COLOR_SCROLLBAR_TRACK; extern const Color COLOR_SCROLLBAR_SLIDER; extern const Color COLOR_DARK_0; extern const Color COLOR_LIGHT_0; extern const int AREA_MIN_WIDTH; extern const int AREA_MAX_WIDTH; extern const int AREA_MIN_HEIGHT; extern const int AREA_MAX_HEIGHT; extern const int DEFAULT_WIDGET_HEIGHT; extern const int PRACTICAL_WIDGET_HEIGHT; extern const int DEFAULT_WIDGET_WIDTH; extern const int PRACTICAL_WIDGET_WIDTH; extern const int DEFAULT_TEXT_X_MARGIN; extern const int DEFAULT_TEXT_Y_MARGIN; extern const float DEFAULT_REPEAT_DELAY; } #endif // WIDGETMETRICS_H nux-4.0.6+14.04.20140409/Nux/SpinBox_Logic.h0000644000015301777760000000602612321344237020363 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef SPINBOX_LOGIC_H #define SPINBOX_LOGIC_H #include "EditTextBox.h" #include "View.h" namespace nux { class SpinBox_Logic: public View { public: SpinBox_Logic(NUX_FILE_LINE_PROTO); virtual ~SpinBox_Logic(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw) = 0; virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw) = 0; // RECEIVERS void RecvMouseMove(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvIncrement(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvDecrement(int x, int y, unsigned long button_flags, unsigned long key_flags); void TimerSpinUpBtn(void *v); void TimerSpinDownBtn(void *v); void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); /* The spinner buttons need to be redrawn when they are released. Their color may have changed when the mouse down was initiated. This receiver is going to initiate the redraw of the whole SpinBox_Logic. */ void RecvSpinnerMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvStartKeyboardFocus(EditTextBox *textbox); void RecvEndKeyboardFocus(EditTextBox *textbox); void RecvEscapeKeyboardFocus(EditTextBox *textbox); void RecvEditChange(EditTextBox *textbox); void RecvValidateEntry(EditTextBox *textbox); virtual void ImplementIncrementBtn() = 0; virtual void ImplementDecrementBtn() = 0; virtual void ImplementValidateEntry() = 0; // SIGNALS sigc::signal sigClick; sigc::signal sigIncrement; sigc::signal sigDecrement; sigc::signal sigValueChanged; sigc::signal sigIntValueChanged; protected: EditTextBox *m_EditLine; BasicView *m_SpinnerUpBtn; BasicView *m_SpinnerDownBtn; TimerFunctor *m_UpTimerCallback; TimerFunctor *m_DownTimerCallback; TimerHandle m_UpTimerHandler; TimerHandle m_DownTimerHandler; }; } #endif // SPINBOX_LOGIC_H nux-4.0.6+14.04.20140409/Nux/ProgramFramework/0000755000015301777760000000000012321344711020771 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/Nux/ProgramFramework/TestTextEntry.h0000644000015301777760000000514112321344237023754 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #ifndef TEST_TEXT_ENTRY_H #define TEST_TEXT_ENTRY_H #include "Nux/TextEntry.h" namespace nux { class TestTextEntry: public nux::TextEntry { NUX_DECLARE_OBJECT_TYPE(TestTextEntry, TextEntry); public: TestTextEntry(NUX_FILE_LINE_PROTO); ~TestTextEntry(); void ResetEvents(); void ResetKeyFocusEvents(); bool has_focus_; bool registered_mouse_down_; bool registered_mouse_up_; bool registered_mouse_drag_; bool registered_mouse_click_; bool registered_mouse_double_click_; bool registered_mouse_move_; bool registered_mouse_enter_; bool registered_mouse_leave_; bool registered_object_destroyed_; bool registered_begin_keynav_focus_; bool registered_end_keynav_focus_; bool registered_text_changed_; nux::KeyNavDirection key_nav_direction_; //!< The key nav direction received when the view obtained the focus. protected: bool mouse_in_; bool mouse_mouse_drag_; bool mouse_mouse_down_; void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnMouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseDoubleClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnKeyNavFocusChange(nux::Area* area, bool has_focus, nux::KeyNavDirection direction); void OnBeginKeyFocus(); void OnEndKeyFocus(); void OnObjectDestroyed(Object* object); void OnTextChanged(TextEntry* text_entry); }; } #endif // TEST_TEXT_ENTRY_H nux-4.0.6+14.04.20140409/Nux/ProgramFramework/ProgramTemplate.h0000644000015301777760000000503612321344237024254 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "Nux/VLayout.h" #include "Nux/HLayout.h" #include "Nux/WindowThread.h" #include "Nux/TextEntry.h" #ifndef PROGRAMTEMPLATE_H #define PROGRAMTEMPLATE_H class ProgramTemplate { public: ProgramTemplate(const char* program_name, int window_width, int window_height, int program_life_span); virtual ~ProgramTemplate(); virtual void Startup(); virtual void UserInterfaceSetup(); virtual void Run(); bool ReadyToGo(); //!< Use with caution // // This WindowThread here will be valid, but if you call it from // another thread, and the call has a side-effect of calling // nux::GetWindowThread, it will likely result in undefined behaviour // since nux::GetWindowThread depends on the same thread that // GetWindowThread () here provides being the currently running // thread, as nux::GetWindowThread operates in terms of thread // local storage. nux::WindowThread* GetWindowThread(); //!< Tells the program to do something, depending on the defined protocol // implemented in HandleProgramMessage void SendMessageToProgram (const std::string &msg); void WaitForMessageFromProgram (const std::string &msg); public: std::string program_name_; int program_life_span_; //!< The program will auto-terminate after a delay in milliseconds. nux::TimeOutSignal* timeout_signal_; nux::WindowThread* window_thread_; int window_width_; int window_height_; protected: void SendMessageToTest(const std::string &msg); private: void MessageReceivedFromTest(); static void ThreadInitializer(nux::NThread *, void *); virtual void HandleProgramMessage(const std::string &); void ProgramExitCall(void* data); void WaitForConfigureEvent(int x, int y, int width, int height); bool ready_to_go_; int program_pipe_[2]; int test_pipe_[2]; }; #endif // PROGRAMTEMPLATE_H nux-4.0.6+14.04.20140409/Nux/ProgramFramework/TestTextEntry.cpp0000644000015301777760000001221212321344237024304 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "TestTextEntry.h" /* TestTextEntry: This class is a Nux view that processes all mouse events that it receives. It is meant for testing simulated mouse events. */ namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(TestTextEntry); TestTextEntry::TestTextEntry(NUX_FILE_LINE_DECL) : nux::TextEntry("", NUX_FILE_LINE_PARAM) { ResetEvents(); ResetKeyFocusEvents(); key_nav_direction_ = nux::KEY_NAV_NONE; has_focus_ = false; mouse_in_ = false; mouse_mouse_drag_ = false; mouse_mouse_down_ = false; mouse_down.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseDown)); mouse_up.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseUp)); mouse_drag.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseDrag)); mouse_click.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseClick)); mouse_double_click.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseDoubleClick)); mouse_move.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseMove)); mouse_enter.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &TestTextEntry::OnMouseLeave)); key_nav_focus_change.connect(sigc::mem_fun(this, &TestTextEntry::OnKeyNavFocusChange)); begin_key_focus.connect(sigc::mem_fun(this, &TestTextEntry::OnBeginKeyFocus)); end_key_focus.connect(sigc::mem_fun(this, &TestTextEntry::OnEndKeyFocus)); object_destroyed.connect(sigc::mem_fun(this, &TestTextEntry::OnObjectDestroyed)); text_changed.connect(sigc::mem_fun(this, &TestTextEntry::OnTextChanged)); } TestTextEntry::~TestTextEntry() { } void TestTextEntry::ResetEvents() { registered_mouse_down_ = false; registered_mouse_up_ = false; registered_mouse_drag_ = false; registered_mouse_enter_ = false; registered_mouse_leave_ = false; registered_mouse_click_ = false; registered_mouse_double_click_ = false; registered_mouse_move_ = false; registered_mouse_enter_ = false; registered_mouse_leave_ = false; registered_object_destroyed_ = false; registered_text_changed_ = false; } void TestTextEntry::ResetKeyFocusEvents() { registered_begin_keynav_focus_ = false; registered_end_keynav_focus_ = false; } void TestTextEntry::OnMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_down_ = true; mouse_mouse_down_ = true; QueueDraw(); } void TestTextEntry::OnMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_up_ = true; mouse_mouse_down_ = false; mouse_mouse_drag_ = false; QueueDraw(); } void TestTextEntry::OnMouseDrag(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_drag_ = true; mouse_mouse_drag_ = true; QueueDraw(); } void TestTextEntry::OnMouseClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_click_ = true; QueueDraw(); } void TestTextEntry::OnMouseDoubleClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_double_click_ = true; mouse_mouse_down_ = true; QueueDraw(); } void TestTextEntry::OnMouseMove(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_move_ = true; QueueDraw(); } void TestTextEntry::OnMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_enter_ = true; mouse_in_ = true; QueueDraw(); } void TestTextEntry::OnMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_leave_ = true; mouse_in_ = false; QueueDraw(); } void TestTextEntry::OnKeyNavFocusChange(nux::Area* /* area */, bool has_focus, nux::KeyNavDirection direction) { has_focus_ = HasKeyFocus(); has_focus_ = has_focus; key_nav_direction_ = direction; QueueDraw(); } void TestTextEntry::OnBeginKeyFocus() { registered_begin_keynav_focus_ = true; } void TestTextEntry::OnEndKeyFocus() { registered_end_keynav_focus_ = true; } void TestTextEntry::OnObjectDestroyed(nux::Object* /* object */) { registered_object_destroyed_ = true; } void TestTextEntry::OnTextChanged(TextEntry* /* text_entry */) { registered_text_changed_ = true; } } nux-4.0.6+14.04.20140409/Nux/ProgramFramework/TestView.cpp0000644000015301777760000001344112321344237023255 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "TestView.h" /* TestView: This class is a Nux view that processes all mouse events that it receives. It is meant for testing simulated mouse events. */ namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(TestView); TestView::TestView(NUX_FILE_LINE_DECL) : nux::View(NUX_FILE_LINE_PARAM) , can_focus_(true) , calls_to_queue_draw_(0) { ResetEvents(); ResetKeyFocusEvents(); key_nav_direction_ = nux::KEY_NAV_NONE; normal_color_ = nux::color::Green; mouse_down_color_ = nux::color::Red; mouse_drag_color_ = nux::color::Yellow; mouse_in_color_ = nux::color::Blue; current_color_ = normal_color_; with_key_focus_color_ = nux::color::White; without_key_focus_color_ = normal_color_; has_focus_ = false; mouse_in_ = false; mouse_mouse_drag_ = false; mouse_mouse_down_ = false; mouse_down.connect(sigc::mem_fun(this, &TestView::OnMouseDown)); mouse_up.connect(sigc::mem_fun(this, &TestView::OnMouseUp)); mouse_drag.connect(sigc::mem_fun(this, &TestView::OnMouseDrag)); mouse_click.connect(sigc::mem_fun(this, &TestView::OnMouseClick)); mouse_double_click.connect(sigc::mem_fun(this, &TestView::OnMouseDoubleClick)); mouse_move.connect(sigc::mem_fun(this, &TestView::OnMouseMove)); mouse_enter.connect(sigc::mem_fun(this, &TestView::OnMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &TestView::OnMouseLeave)); key_nav_focus_change.connect(sigc::mem_fun(this, &TestView::OnKeyNavFocusChange)); begin_key_focus.connect(sigc::mem_fun(this, &TestView::OnBeginKeyFocus)); end_key_focus.connect(sigc::mem_fun(this, &TestView::OnEndKeyFocus)); object_destroyed.connect(sigc::mem_fun(this, &TestView::OnObjectDestroyed)); } TestView::~TestView() { } void TestView::ResetEvents() { registered_mouse_down_ = false; registered_mouse_up_ = false; registered_mouse_drag_ = false; registered_mouse_enter_ = false; registered_mouse_leave_ = false; registered_mouse_click_ = false; registered_mouse_double_click_ = false; registered_mouse_move_ = false; registered_mouse_enter_ = false; registered_mouse_leave_ = false; registered_object_destroyed_ = false; } void TestView::ResetKeyFocusEvents() { registered_begin_keynav_focus_ = false; registered_end_keynav_focus_ = false; } void TestView::QueueDraw() { ++calls_to_queue_draw_; nux::View::QueueDraw(); } nux::Color TestView::GetColor() const { return current_color_; } void TestView::Draw(nux::GraphicsEngine& graphics_engine, bool /* force_draw */) { nux::Geometry geo = GetGeometry(); graphics_engine.QRP_Color(geo.x, geo.y, geo.width, geo.height, current_color_); if (has_focus_) graphics_engine.QRP_Color(geo.x, geo.y, 20, 20, with_key_focus_color_); } void TestView::OnMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_down_ = true; current_color_ = mouse_down_color_; mouse_mouse_down_ = true; QueueDraw(); } void TestView::OnMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_up_ = true; if (mouse_in_) current_color_ = mouse_in_color_; else current_color_ = normal_color_; mouse_mouse_down_ = false; mouse_mouse_drag_ = false; QueueDraw(); } void TestView::OnMouseDrag(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_drag_ = true; current_color_ = mouse_drag_color_; mouse_mouse_drag_ = true; QueueDraw(); } void TestView::OnMouseClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_click_ = true; QueueDraw(); } void TestView::OnMouseDoubleClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_double_click_ = true; current_color_ = mouse_down_color_; mouse_mouse_down_ = true; QueueDraw(); } void TestView::OnMouseMove(int /* x */, int /* y */, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_move_ = true; QueueDraw(); } void TestView::OnMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_enter_ = true; mouse_in_ = true; current_color_ = mouse_in_color_; QueueDraw(); } void TestView::OnMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { registered_mouse_leave_ = true; mouse_in_ = false; current_color_ = normal_color_; QueueDraw(); } void TestView::OnKeyNavFocusChange(nux::Area* /* area */, bool has_focus, nux::KeyNavDirection direction) { has_focus_ = HasKeyFocus(); has_focus_ = has_focus; key_nav_direction_ = direction; QueueDraw(); } void TestView::OnBeginKeyFocus() { registered_begin_keynav_focus_ = true; } void TestView::OnEndKeyFocus() { registered_end_keynav_focus_ = true; } void TestView::OnObjectDestroyed(nux::Object* /* object */) { registered_object_destroyed_ = true; } } nux-4.0.6+14.04.20140409/Nux/ProgramFramework/ProgramTemplate.cpp0000644000015301777760000001341112321344237024603 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include "Nux.h" #include "VLayout.h" #include "HLayout.h" #include "WindowThread.h" #include "TextEntry.h" #include "ProgramTemplate.h" namespace { unsigned int MAX_MESSAGE_LEN = 1024; std::string ReadMessageOnFd(int fd) { char buf[MAX_MESSAGE_LEN + 1]; ssize_t bytes = read(fd, reinterpret_cast (buf), MAX_MESSAGE_LEN); if (bytes == -1) throw std::runtime_error(std::string("read: ") + strerror(errno)); buf[bytes] = '\0'; return std::string(buf); } bool CheckForMessageOnFd(int fd, const std::string &msg) { struct pollfd pfd; pfd.events = POLLIN; pfd.revents = 0; pfd.fd = fd; if (poll(&pfd, 1, -1) == -1) throw std::runtime_error(std::string("poll: ") + strerror(errno)); if (ReadMessageOnFd(fd) == msg) return true; else return false; } void WaitForMessageOnFd(int fd, const std::string &msg) { while (!CheckForMessageOnFd(fd, msg)); } void SendMessageToFd(int fd, const std::string &msg) { if (msg.size() > MAX_MESSAGE_LEN) { std::stringstream ss; ss << "Only messages up to " << MAX_MESSAGE_LEN << " chars are supported."; throw std::runtime_error(ss.str ()); } if (write(fd, reinterpret_cast (const_cast(msg.c_str())), msg.size()) == -1) throw std::runtime_error(std::string("write: ") + strerror(errno)); } } ProgramTemplate::ProgramTemplate(const char* program_name, int window_width, int window_height, int program_life_span) { ready_to_go_ = false; window_width_ = window_width; window_height_ = window_height; if (window_width_ < 100) window_width_ = 100; if (window_height_ < 100) window_height_ = 100; timeout_signal_ = NULL; window_thread_ = NULL; program_name_ = program_name; program_life_span_ = program_life_span; if (program_life_span_ > 0 && program_life_span_ < 1000) { // Minimum life span is 1 second. program_life_span_ = 1000; } if (pipe2(test_pipe_, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); if (pipe2(program_pipe_, O_CLOEXEC) == -1) throw std::runtime_error(strerror(errno)); } ProgramTemplate::~ProgramTemplate() { if (window_thread_) delete window_thread_; } void ProgramTemplate::Startup() { nux::NuxInitialize(0); window_thread_ = nux::CreateGUIThread(program_name_.c_str(), window_width_, window_height_, NULL, ProgramTemplate::ThreadInitializer, this); window_thread_->window_configuration.connect(sigc::mem_fun(this, &ProgramTemplate::WaitForConfigureEvent)); } void ProgramTemplate::UserInterfaceSetup() { // nux::VLayout *MainVLayout = new nux::VLayout(NUX_TRACKER_LOCATION); // nux::TextEntry *text_entry_0 = new nux::TextEntry(TEXT("0123456789abcdefghij"), NUX_TRACKER_LOCATION); // MainVLayout->AddView(text_entry_0, 0, nux::eCenter, nux::eFull); // MainVLayout->SetVerticalInternalMargin(10); // MainVLayout->SetContentDistribution(nux::eStackCenter); // nux::GetWindowThread()->SetLayout(MainVLayout); // nux::ColorLayer background(nux::Color(0xFF4D4D4D)); // window_thread_->SetWindowBackgroundPaintLayer(&background); } void ProgramTemplate::Run() { if (window_thread_ == NULL) return; if (program_life_span_ > 0) { timeout_signal_ = new nux::TimeOutSignal(); timeout_signal_->tick.connect(sigc::mem_fun(this, &ProgramTemplate::ProgramExitCall)); window_thread_->GetTimerHandler().AddOneShotTimer(program_life_span_, timeout_signal_, NULL, NULL); } window_thread_->Run(NULL); } void ProgramTemplate::SendMessageToProgram(const std::string &msg) { SendMessageToFd(program_pipe_[1], msg); } void ProgramTemplate::WaitForMessageFromProgram(const std::string &msg) { WaitForMessageOnFd(test_pipe_[0], msg); } void ProgramTemplate::SendMessageToTest(const std::string &msg) { SendMessageToFd(test_pipe_[1], msg); } void ProgramTemplate::MessageReceivedFromTest() { HandleProgramMessage(ReadMessageOnFd(program_pipe_[0])); } void ProgramTemplate::ThreadInitializer(nux::NThread *, void *data) { using namespace std::placeholders; /* Monitor the test-to-app fd for messages */ ProgramTemplate *pt = reinterpret_cast(data); pt->window_thread_->WatchFdForEvents(pt->program_pipe_[0], std::bind(&ProgramTemplate::MessageReceivedFromTest, pt)); } void ProgramTemplate::HandleProgramMessage(const std::string &msg) { } bool ProgramTemplate::ReadyToGo() { return window_thread_; } nux::WindowThread* ProgramTemplate::GetWindowThread() { return window_thread_; } void ProgramTemplate::ProgramExitCall(void * /* data */) { if (window_thread_) window_thread_->ExitMainLoop(); } void ProgramTemplate::WaitForConfigureEvent(int /* x */, int /* y */, int /* width */, int /* height */) { ready_to_go_ = true; } // int main(int argc, char **argv) // { // ProgramTemplate test("Text Entry", 300, 300, 3000); // test.Startup(); // test.UserInterfaceSetup(); // test.Run(); // return 0; // } nux-4.0.6+14.04.20140409/Nux/ProgramFramework/TestView.h0000644000015301777760000000565712321344237022734 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #ifndef TEST_VIEW_H #define TEST_VIEW_H #include "Nux/TextureArea.h" namespace nux { class TestView: public nux::View { NUX_DECLARE_OBJECT_TYPE(TestView, View); public: TestView(NUX_FILE_LINE_PROTO); ~TestView(); nux::Color GetColor() const; bool AcceptKeyNavFocus() {return can_focus_;} void ResetEvents(); void ResetKeyFocusEvents(); void QueueDraw(); bool can_focus_; bool has_focus_; bool registered_mouse_down_; bool registered_mouse_up_; bool registered_mouse_drag_; bool registered_mouse_click_; bool registered_mouse_double_click_; bool registered_mouse_move_; bool registered_mouse_enter_; bool registered_mouse_leave_; bool registered_object_destroyed_; bool registered_begin_keynav_focus_; bool registered_end_keynav_focus_; unsigned int calls_to_queue_draw_; nux::KeyNavDirection key_nav_direction_; //!< The key nav direction received when the view obtained the focus. protected: nux::Color current_color_; nux::Color normal_color_; nux::Color mouse_down_color_; nux::Color mouse_drag_color_; nux::Color mouse_in_color_; nux::Color with_key_focus_color_; nux::Color without_key_focus_color_; bool mouse_in_; bool mouse_mouse_drag_; bool mouse_mouse_down_; void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnMouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseDoubleClick(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void OnMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags); void OnKeyNavFocusChange(nux::Area* area, bool has_focus, nux::KeyNavDirection direction); void OnBeginKeyFocus(); void OnEndKeyFocus(); void OnObjectDestroyed(Object* object); void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw); }; } #endif // TEST_VIEW_H nux-4.0.6+14.04.20140409/Nux/GeisAdapter.h0000644000015301777760000000633412321344237020056 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #ifndef GEISADAPTER_H #define GEISADAPTER_H #include "Features.h" #ifdef NUX_GESTURES_SUPPORT #include #include #include #include #include #include "NuxGraphics/GestureEvent.h" namespace nux { /*! This class translates events from geis into native nux::GestureEvents */ class GeisAdapter : public sigc::trackable { public: GeisAdapter(); ~GeisAdapter(); #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) void CreateGSource(GMainContext *context); #endif /* Returns whether initialization is complete. See also: signal init_complete() */ bool IsInitComplete() const {return is_init_complete_;} /* Initialization has finished. Subscriptions can now be filtered and activated. */ sigc::signal init_complete; //! Emitted when a new GestureEvent is ready to be processed sigc::signal event_ready; Geis GetGeisInstance() const {return geis_;} void ProcessGeisEvents(); //! Processes the next pending Geis event, which may yield a GestureEvent /*! Returns true if GestureEvent was filled and false otherwise. */ bool ProcessNextEvent(GestureEvent *event); private: class Device { public: int id; bool direct_touch; }; void ProcessEventDeviceAvailable(GeisEvent event); void ProcessEventDeviceUnavailable(GeisEvent event); void ProcessEventClassAvailable(GeisEvent event); void FillNuxEvent(GestureEvent &nux_event, GeisEvent event, EventType nux_event_type); void FillNuxEventGestureAttributes(GestureEvent &nux_event, GeisFrame frame); void FillNuxEventTouches(GestureEvent &nux_event, GeisTouchSet touch_set); void SplitUpdateIntoBeginAndEnd(GestureEvent &nux_event); Geis geis_; GeisGestureClass class_drag_; GeisGestureClass class_pinch_; GeisGestureClass class_rotate_; GeisGestureClass class_tap_; GeisGestureClass class_touch_; bool is_init_complete_; /* maps a device id to its corresponding device */ std::map devices_; /* Sometimes a single GeisEvent can yield two GestureEvents. When that happens, that second GestureEvent will be temporarily held here until it's consumed. */ std::unique_ptr pending_next_event_; friend class GeisAdapterTest; }; } // namespace nux #endif // NUX_GESTURES_SUPPORT #endif // GEISADAPTER_H nux-4.0.6+14.04.20140409/Nux/MenuPage.cpp0000644000015301777760000010305612321344237017721 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "MenuPage.h" #include "WindowCompositor.h" #include "ActionItem.h" #include "VLayout.h" #include "StaticText.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(MenuItem); NUX_IMPLEMENT_OBJECT_TYPE(MenuSeparator); NUX_IMPLEMENT_OBJECT_TYPE(MenuPage); static const int MENU_ICONE_WIDTH = 18; static const int MENU_ICON_HEIGHT = 18; static const int MENU_ITEM_MIN_WIDTH = 90; static const int MENU_ITEM_MIN_HEIGHT = 20; static const int MENU_ITEM_BORDER_TO_ICON_MARGIN = 5; static const int MENU_ITEM_ICON_TO_TEXT_MARGIN = 5; static const int MENU_ITEM_TEXT_TO_BORDER_MARGIN = 5; // Algorithm: // To initiate the menu, the mouse has to hit one of the menu bar item(they hold the name of the menu that are displayed). // When that happens, the menu attached to the MenuBarItem gets the focus and becomes visible. Before the mouse is released, // the flag m_NextMouseUpMeanStop is set to FALSE, meaning that the following mouse up will not be processed by the menu, even if the released happened // outside of any of the menu forming the menu cascade. This way, the menu will remain open. There are exceptions to this however. // After the firs mouse down on the MenuBarItem and before the mouse up event, if the mouse over the the opened menu, // then m_NextMouseUpMeanStop is set to TRUE. If the mouse is released over an active menu item, the menu cascade will close itself. // If the mouse is released outside any of the menu forming the menu cascade, the menu will close itself. // // MenuItem::MenuItem(const char *label, int UserValue, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { _child_menu = 0; _action_item = new ActionItem(label, UserValue, NUX_TRACKER_LOCATION); _pango_static_text = new StaticText(label, NUX_TRACKER_LOCATION); _pango_static_text->SetTextColor(Color(0.0f, 0.0f, 0.0f, 1.0f)); } MenuItem::~MenuItem() { _pango_static_text->Dispose(); if (_action_item) _action_item->UnReference(); if (_child_menu) _child_menu->UnReference(); } void MenuItem::SetChildMenu(MenuPage *menu) { nuxAssert(menu); NUX_RETURN_IF_NULL(menu); if (_child_menu) _child_menu->UnReference(); _child_menu = menu; _child_menu->Reference(); } MenuPage *MenuItem::GetChildMenu() const { return _child_menu; } void MenuItem::SetActionItem(ActionItem *action) { nuxAssertMsg(action != 0, "[MenuItem::SetActionItem] Parameter is Null."); if (action == 0) return; _pango_static_text->Dispose(); if (_action_item) _action_item->UnReference(); _action_item = action; _action_item->Reference(); _pango_static_text = new StaticText(_action_item->GetLabel(), NUX_TRACKER_LOCATION); } ActionItem *MenuItem::GetActionItem() const { return _action_item; } int MenuItem::GetTextWidth() { if (_pango_static_text) { int w, h; _pango_static_text->GetTextLayoutSize(w, h); return w; } return 0; } int MenuItem::GetTextHeight() { if (_pango_static_text) { int w, h; _pango_static_text->GetTextLayoutSize(w, h); return h; } return 0; } //ActionItem* MenuItem::GetActionItem() //{ // return &_action_item; //} void MenuItem::Draw(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void MenuItem::DrawAsMenuItem(GraphicsEngine &graphics_engine, const Color & /* textcolor */, bool is_highlighted, bool /* isFirstItem */, bool /* isLastItem */, bool /* draw_icone */) { Geometry geo = GetGeometry(); Geometry icon_geo(0, 0, 20, 20); Geometry text_geo = geo; text_geo.OffsetPosition(24, 0); text_geo.OffsetSize(2 * 24, 0); icon_geo.SetX(geo.x + 2); icon_geo.SetY(geo.y + 0); const char *label = _action_item->GetLabel(); if (is_highlighted) { /* if (isFirstItem && isLastItem) GetPainter().PaintShape(graphics_engine, geo, COLOR_FOREGROUND_SECONDARY, eSHAPE_CORNER_ROUND4); else if (isFirstItem) GetPainter().PaintShapeCorner(graphics_engine, geo, COLOR_FOREGROUND_SECONDARY, eSHAPE_CORNER_ROUND4, eCornerTopLeft | eCornerTopRight); else if (isLastItem) GetPainter().PaintShapeCorner(graphics_engine, geo, COLOR_FOREGROUND_SECONDARY, eSHAPE_CORNER_ROUND4, eCornerBottomLeft | eCornerBottomRight); else GetPainter().Paint2DQuadColor(graphics_engine, geo, COLOR_FOREGROUND_SECONDARY); */ GetPainter().Paint2DQuadColor(graphics_engine, geo, Color(0x44000000) /*COLOR_FOREGROUND_SECONDARY*/); _pango_static_text->SetTextColor(Color(1.0f, 1.0f, 1.0f, 1.0f)); } else { _pango_static_text->SetTextColor(Color(0.0f, 0.0f, 0.0f, 1.0f)); //GetPainter().Paint2DQuadColor(graphics_engine, geo, Color(0xFF868686)); } //if(m_Icon) { //GetPainter().Draw2DTextureAligned(graphics_engine, &_action_item->GetIcon(), icon_geo, TextureAlignmentStyle(eTACenter, eTACenter)); } if (label) { //GetPainter().PaintTextLineStatic(graphics_engine, GetFont(), text_geo, std::string(label), textcolor, eAlignTextLeft); _pango_static_text->SetGeometry(text_geo); _pango_static_text->ProcessDraw(graphics_engine, true); } } MenuSeparator::MenuSeparator(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { } MenuSeparator::~MenuSeparator() { } void MenuSeparator::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); int y0 = base.y + base.GetHeight() / 2; GetPainter().Draw2DLine(graphics_engine, base.x, y0, base.x + base.GetWidth(), y0, Color(0xFF222222)); GetPainter().Draw2DLine(graphics_engine, base.x, y0 + 1, base.x + base.GetWidth(), y0 + 1, Color(0xFFAAAAAA)); } MenuPage::MenuPage(const char *title, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) { m_Parent = 0; m_item_width = MENU_ITEM_MIN_WIDTH; m_item_height = MENU_ITEM_MIN_HEIGHT; m_show_item_icon = true; m_MenuWindow = 0; m_Name = title; m_IsTopOfMenuChain = false; _font_name = g_strdup("Ubuntu 12"); on_closure_continue_with_event_ = false; // Set Original State // Set Signals mouse_move.connect(sigc::mem_fun(this, &MenuPage::EmitMouseMove)); mouse_drag.connect(sigc::mem_fun(this, &MenuPage::EmitMouseDrag)); mouse_down.connect(sigc::mem_fun(this, &MenuPage::EmitMouseDown)); mouse_up.connect(sigc::mem_fun(this, &MenuPage::EmitMouseUp)); mouse_leave.connect(sigc::mem_fun(this, &MenuPage::RecvMouseLeave)); mouse_down_outside_pointer_grab_area.connect(sigc::mem_fun(this, &MenuPage::Terminate)); // Set Geometry SetGeometry(Geometry(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)); // Set layout m_numItem = 0; m_HighlightedItem = -1; m_IsActive = false; m_NextMouseUpMeanStop = false; m_SubMenuAction = 0; _vlayout = new VLayout(NUX_TRACKER_LOCATION); // No Need to set a composition layout. // The MenuPage is floating above everything else. SetLayout(_vlayout); SetTextColor(color::Black); } MenuPage::~MenuPage() { // std::vector ::iterator it; // // for (it = m_MenuItemVector.begin(); it != m_MenuItemVector.end(); it++) // { // (*it)->UnReference(); // } m_MenuItemVector.clear(); m_MenuSeparatorVector.clear(); RemoveLayout(); } //void MenuPage::SetName(const char* name) //{ // m_Name = name; //} // const char *MenuPage::GetName() const { return m_Name.c_str(); } bool MenuPage::CanClose() const { return m_Action_Triggered; } Area* MenuPage::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) { bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); if (mouse_inside == false) return NULL; if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) return NULL; return this; } void MenuPage::Draw(GraphicsEngine &graphics_engine, bool force_draw) { if (m_IsActive) { Geometry base = GetGeometry(); Geometry shadow; shadow = base; shadow.OffsetPosition(4, 4); //GetPainter().PaintShape(graphics_engine, shadow, Color(0xFF000000), eSHAPE_CORNER_ROUND4_SHADOW); graphics_engine.PushClippingRectangle(base); graphics_engine.GetRenderStates().SetBlend(GL_TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GetPainter().Paint2DQuadColor(graphics_engine, base, Color(0xCCFFFFFF)); graphics_engine.GetRenderStates().SetBlend(GL_FALSE); Geometry text_area; text_area.SetX(base.x); text_area.SetY(base.y); text_area.SetWidth(base.GetWidth()); text_area.SetHeight(PRACTICAL_WIDGET_HEIGHT); int i; std::vector::iterator it; int numItem = (int) m_MenuItemVector.size(); for (it = m_MenuItemVector.begin(), i = 0; it != m_MenuItemVector.end(); it++, i++) { bool is_highlighted = (m_HighlightedItem == i); (*it)->DrawAsMenuItem(graphics_engine, Color(0xFFFFFFFF) /*GetTextColor()*/, is_highlighted, i == 0, i == (numItem - 1), true); } std::vector::iterator separator_iterator; for (separator_iterator = m_MenuSeparatorVector.begin(); separator_iterator != m_MenuSeparatorVector.end(); separator_iterator++) { (*separator_iterator)->Draw(graphics_engine, force_draw); } graphics_engine.PopClippingRectangle(); } } void MenuPage::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void MenuPage::SetFontName(char *font_name) { std::vector::iterator it; for (it = m_MenuItemVector.begin(); it != m_MenuItemVector.end(); ++it) { (*it)->GetStaticText()->SetFontName(font_name); } g_free(_font_name); _font_name = g_strdup(font_name); } ActionItem *MenuPage::AddAction(const char *label, int UserValue) { // pMenuItem if added to the layout do not sink the Reference. MenuItem *pMenuItem(new MenuItem(label, UserValue, NUX_TRACKER_LOCATION)); pMenuItem->GetStaticText()->SetFontName(_font_name); m_MenuItemVector.push_back(pMenuItem); pMenuItem->SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); int new_item_width = pMenuItem->GetTextWidth(); //GetFont()->GetStringWidth(pMenuItem->GetActionItem()->GetLabel()); if (new_item_width < m_item_width) { std::vector::iterator it; for (it = m_MenuItemVector.begin(); it != m_MenuItemVector.end(); it++) { if (ShowItemIcon()) { pMenuItem->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN + MENU_ICONE_WIDTH + MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } else { pMenuItem->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } } } else { std::vector::iterator it; for (it = m_MenuItemVector.begin(); it != m_MenuItemVector.end(); it++) { if (ShowItemIcon()) { (*it)->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN + MENU_ICONE_WIDTH + MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } else { (*it)->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } (*it)->SetBaseSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } m_item_width = new_item_width; // SetBaseWidth(MENU_ITEM_ICON_TO_TEXT_MARGIN // + m_item_width // + MENU_ITEM_TEXT_TO_BORDER_MARGIN); } if (pMenuItem->GetChildMenu() != 0) { pMenuItem->GetChildMenu()->SetParentMenu(this); } m_numItem = (int) m_MenuItemVector.size(); _vlayout->AddView(pMenuItem, 0, eLeft, eFix); ComputeContentSize(); return pMenuItem->GetActionItem(); } //void MenuPage::AddActionItem(ActionItem* actionItem) //{ // nuxAssertMsg(actionItem != 0, "[MenuPage::AddActionItem] Parameter is Null."); // if (actionItem == 0) // return; // // MenuItem* pMenuItem = new MenuItem(actionItem->GetLabel(), actionItem->GetUserValue(), NUX_TRACKER_LOCATION); // pMenuItem->SinkReference(); // pMenuItem->SetActionItem(actionItem); // // m_MenuItemVector.push_back(pMenuItem); // pMenuItem->SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); // // int new_item_width = GetFont()->GetStringWidth(actionItem->GetLabel()); // if (new_item_width < m_item_width) // { // if (ShowItemIcon()) // { // pMenuItem->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN // + MENU_ICONE_WIDTH // + MENU_ITEM_ICON_TO_TEXT_MARGIN // + m_item_width // + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); // } // else // { // pMenuItem->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN // + m_item_width // + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); // } // } // else // { // if (ShowItemIcon()) // { // pMenuItem->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN // + MENU_ICONE_WIDTH // + MENU_ITEM_ICON_TO_TEXT_MARGIN // + new_item_width // + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); // } // else // { // pMenuItem->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN // + new_item_width // + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); // } // // std::vector::iterator it; // for (it = m_MenuItemVector.begin(); it != m_MenuItemVector.end(); it++) // { // (*it)->setSize(MENU_ITEM_ICON_TO_TEXT_MARGIN // + new_item_width // + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); // } // // m_item_width = new_item_width; // SetWidth(MENU_ITEM_ICON_TO_TEXT_MARGIN // + m_item_width // + MENU_ITEM_TEXT_TO_BORDER_MARGIN); // } // // if (pMenuItem->GetChildMenu() != 0) // { // pMenuItem->GetChildMenu()->SetParentMenu(this); // } // // m_numItem = (int)m_MenuItemVector.size(); // _vlayout->AddView(pMenuItem, 0, eLeft, eFix); // ComputeContentSize(); //} MenuPage *MenuPage::AddMenu(const char *label) { // pMenuItem if added to the layout do not sink the Reference. MenuItem *pMenuItem(new MenuItem(label, 0, NUX_TRACKER_LOCATION)); pMenuItem->SetChildMenu(new MenuPage(label)); //pMenuItem->SetActionItem(new ActionItem()); //pMenuItem->GetActionItem()->SetLabel(label); m_MenuItemVector.push_back(pMenuItem); pMenuItem->SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); int new_item_width = pMenuItem->GetTextWidth(); //GetFont()->GetStringWidth(label); if (new_item_width < m_item_width) { if (ShowItemIcon()) { pMenuItem->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN + MENU_ICONE_WIDTH + MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } else { pMenuItem->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } } else { if (ShowItemIcon()) { pMenuItem->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN + MENU_ICONE_WIDTH + MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } else { pMenuItem->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } std::vector< MenuItem * >::iterator it; for (it = m_MenuItemVector.begin(); it != m_MenuItemVector.end(); it++) { (*it)->SetBaseSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } m_item_width = new_item_width; SetBaseWidth(MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN); } if (pMenuItem->GetChildMenu() != 0) { pMenuItem->GetChildMenu()->SetParentMenu(this); } m_numItem = (int) m_MenuItemVector.size(); _vlayout->AddView(pMenuItem, 0, eLeft, eFix); ComputeContentSize(); return pMenuItem->GetChildMenu(); } ActionItem *MenuPage::AddSubMenu(const char * /* label */, MenuPage *menu) { menu->m_IsTopOfMenuChain = false; // pMenuItem if added to the layout do not sink the Reference. MenuItem *pMenuItem(new MenuItem(menu->GetName(), 0, NUX_TRACKER_LOCATION)); pMenuItem->SetChildMenu(menu); m_MenuItemVector.push_back(pMenuItem); pMenuItem->SetMinimumSize(DEFAULT_WIDGET_WIDTH, PRACTICAL_WIDGET_HEIGHT); int new_item_width = pMenuItem->GetTextWidth(); //GetFont()->GetStringWidth(label); if (new_item_width < m_item_width) { if (ShowItemIcon()) { pMenuItem->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN + MENU_ICONE_WIDTH + MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } else { pMenuItem->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } } else { if (ShowItemIcon()) { pMenuItem->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN + MENU_ICONE_WIDTH + MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } else { pMenuItem->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } std::vector< MenuItem * >::iterator it; for (it = m_MenuItemVector.begin(); it != m_MenuItemVector.end(); it++) { (*it)->SetBaseSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + new_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, m_item_height); } m_item_width = new_item_width; SetBaseWidth(MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN); } if (pMenuItem->GetChildMenu() != 0) { pMenuItem->GetChildMenu()->SetParentMenu(this); } m_numItem = (int) m_MenuItemVector.size(); _vlayout->AddView(pMenuItem, 0, eLeft, eFix); ComputeContentSize(); return pMenuItem->GetActionItem(); } void MenuPage::AddSeparator() { // pMenuSeparator if added to the layout do not sink the Reference. MenuSeparator *pMenuSeparator(new MenuSeparator(NUX_TRACKER_LOCATION)); m_MenuSeparatorVector.push_back(pMenuSeparator); if (ShowItemIcon()) { pMenuSeparator->SetMinMaxSize(MENU_ITEM_BORDER_TO_ICON_MARGIN + MENU_ICONE_WIDTH + MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, 4); } else { pMenuSeparator->SetMinMaxSize(MENU_ITEM_ICON_TO_TEXT_MARGIN + m_item_width + MENU_ITEM_TEXT_TO_BORDER_MARGIN, 4); } _vlayout->AddView(pMenuSeparator, 0, eLeft, eFix); ComputeContentSize(); } void MenuPage::RemoveItem(ActionItem * /* item */) { } void MenuPage::RemoveAllItem() { m_MenuSeparatorVector.clear(); m_MenuItemVector.clear(); m_numItem = 0; _vlayout->Clear(); ComputeContentSize(); //FIXME - Hack to fix a bug with the menu height not being reset after removing items Geometry base = GetGeometry(); base.height = 0; View::SetGeometry(base); } void MenuPage::EmitMouseMove(int /* x */, int y, int /* dx */, int /* dy */, unsigned long /* button_flags */, unsigned long /* key_flags */) { if (IsMouseInside()) { m_NextMouseUpMeanStop = true; // Find on which item the mouse is std::vector< MenuItem * >::iterator item_iterator; unsigned int i = 0; m_HighlightedItem = -1; for (item_iterator = m_MenuItemVector.begin(), i = 0; item_iterator != m_MenuItemVector.end(); item_iterator++, i++) { int MenuY = GetBaseY(); int py = (*item_iterator)->GetBaseY() - MenuY; int height = (*item_iterator)->GetBaseHeight(); if ((y >= py) && (y < py + height)) { m_HighlightedItem = i; QueueDraw(); break; } } } else { if (m_HighlightedItem != -1) { m_HighlightedItem = -1; QueueDraw(); } } if (m_HighlightedItem >= 0) { MenuItem *selected_action = m_MenuItemVector[m_HighlightedItem]; if ((selected_action->GetChildMenu() != 0) && selected_action->GetActionItem()->isEnabled()) { // This MenuItem has a sub-MenuPage. Start it. Geometry geo = selected_action->GetGeometry(); selected_action->GetChildMenu()->m_MenuWindow = selected_action->GetChildMenu()->GetParentMenu()->m_MenuWindow; selected_action->GetChildMenu()->StartMenu(geo.x + geo.GetWidth() - 5, geo.y, 0, 0); // The current SubMenu is not the same as the new one... if (m_SubMenuAction != selected_action) { // If m_SubMenuAction is not null then stop the sub menu StopActionSubMenu(); // Set the Action that holds the SubMenu. m_SubMenuAction = selected_action; } } else { StopActionSubMenu(); } } } void MenuPage::EmitMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags) { m_NextMouseUpMeanStop = true; EmitMouseMove(x, y, 0, 0, button_flags, key_flags); } void MenuPage::EmitMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags) { if (m_NextMouseUpMeanStop == false) { m_NextMouseUpMeanStop = true; return; } m_Action_Triggered = false; bool hit_inside_a_menu = false; if (m_SubMenuAction) { m_Action_Triggered = m_SubMenuAction->GetChildMenu()->TestMouseUp(x, y, button_flags, key_flags, hit_inside_a_menu); } if (m_Action_Triggered == false) { if (IsMouseInside()) { if (m_SubMenuAction) { m_Action_Triggered = false; } else if (m_HighlightedItem != -1) { if (m_MenuItemVector[m_HighlightedItem]->GetActionItem()->isEnabled() == false) { // Do nothing. We don't want to close the menu when we release the mouse over an action that is not Enabled. m_Action_Triggered = false; } else { m_Action_Triggered = true; // Fire the Action Here ExecuteActionItem(m_MenuItemVector[m_HighlightedItem]); NotifyActionTriggeredToParent(this, m_MenuItemVector[m_HighlightedItem]); } } } else { // Bellow the Mouse, there was no MenuPage when the MouseUp happened. if (hit_inside_a_menu == false) { // Terminate the MenuPage cascade NotifyTerminateMenuCascade(); } } } } bool MenuPage::TestMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, bool &hit_inside_a_menu) { m_Action_Triggered = false; if (m_SubMenuAction) { m_Action_Triggered = m_SubMenuAction->GetChildMenu()->TestMouseUp(x, y, button_flags, key_flags, hit_inside_a_menu); } if (m_Action_Triggered == false) { if (IsMouseInside()) { hit_inside_a_menu = true; if (m_SubMenuAction) { m_Action_Triggered = false; // Do nothing. We don't want to close the menu when we are above an action that has a submenu. } else if (m_HighlightedItem != -1) { if (m_MenuItemVector[m_HighlightedItem]->GetActionItem()->isEnabled() == false) { // Do nothing. We don't want to close the menu when we release the mouse over an action that is not Enabled. m_Action_Triggered = false; } else { m_Action_Triggered = true; // Fire the Action Here ExecuteActionItem(m_MenuItemVector[m_HighlightedItem]); NotifyActionTriggeredToParent(this, m_MenuItemVector[m_HighlightedItem]); // But Do not emit the Stop //sigPopupStop.emit(); } } } } if (m_Action_Triggered) return true; return false; } bool MenuPage::TestMouseDown() { bool b = false; if (m_SubMenuAction) { b = m_SubMenuAction->GetChildMenu()->TestMouseDown(); } if (b) { return true; } else { return IsMouseInside(); } } void MenuPage::EmitMouseDrag(int x, int y, int /* dx */, int /* dy */, unsigned long button_flags, unsigned long key_flags) { if (IsMouseInside()) EmitMouseMove(x, y, 0, 0, button_flags, key_flags); } void MenuPage::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { // Cancel selected item when the mouse is out. if (m_HighlightedItem != -1) { MenuItem *item = m_MenuItemVector[m_HighlightedItem]; if (item->GetChildMenu()) { if (!item->GetChildMenu()->IsActive()) { m_HighlightedItem = -1; } } else { m_HighlightedItem = -1; } } QueueDraw(); } void MenuPage::StartMenu(int MenuXPosition, int MenuYPosition, int /* x*/, int /* y */, bool /* OverrideCurrentMenuChain */) { Geometry base = GetGeometry(); base.SetX(MenuXPosition); base.SetY(MenuYPosition); int WindowWidth = GetWindowThread()->GetGraphicsEngine().GetWindowWidth(); int WindowHeight = GetWindowThread()->GetGraphicsEngine().GetWindowHeight(); // Correct the position of the MenuPage if is going out of the screen // The first page of a menu chain has less opportunities to be adjusted than its child pages. // The first page of a menu chain has(GetParentMenu() == 0) return true. int MenuLeft = base.x + base.GetWidth() + 5; if (MenuLeft > WindowWidth) { base.OffsetPosition(WindowWidth - MenuLeft, 0); } int MenuRight = base.x; if ((MenuRight < 0) && (GetParentMenu() != 0)) { base.OffsetPosition(-MenuRight, 0); } int MenuBottom = base.y + base.GetHeight() + 5; if ((MenuBottom > WindowHeight) && (GetParentMenu() != 0)) { base.OffsetPosition(0, WindowHeight - MenuBottom); } int MenuTop = base.y - 5; if ((MenuTop < 0) && (GetParentMenu() != 0)) { base.OffsetPosition(0, -MenuTop); } SetGeometry(base); SetActive(true); // Add the menu to the stack manager popup list. if (GetParentMenu() == 0) { // This is the head of the menu chain m_MenuWindow = GetWindowThread()->GetWindowCompositor().GetProcessingTopView(); } GetWindowThread()->GetWindowCompositor().AddMenu(this, m_MenuWindow/*, OverrideCurrentMenuChain*/); m_NextMouseUpMeanStop = false; StopActionSubMenu(); } void MenuPage::StopMenu(int /* x */, int /* y */) { SetActive(false); // The Stack Manager will remove all popup that are not visible anymore m_NextMouseUpMeanStop = false; m_HighlightedItem = -1; StopActionSubMenu(); // The MenuPage does not need to be redrawn, but in embedded mode, this triggers a dirty Area on // the BaseWindow and it informs the system to update this egion of the screen // (where the menu is about to disappear). QueueDraw(); /*Area *top_area = GetWindowThread()->GetWindowCompositor().GetProcessingTopView(); if (top_area) { if (top_area->IsView()) { NUX_STATIC_CAST(View*, top_area)->QueueDraw(); } if (top_area->IsLayout()) { NUX_STATIC_CAST(Layout*, top_area)->QueueDraw(); } }*/ } // Never call this function directly void MenuPage::Terminate(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { } void MenuPage::StopActionSubMenu() { if (m_SubMenuAction) { if (m_SubMenuAction->GetChildMenu()) { m_SubMenuAction->GetChildMenu()->StopMenu(0, 0); } } m_SubMenuAction = 0; } void MenuPage::ExecuteActionItem(MenuItem *menuItem) { menuItem->GetActionItem()->Trigger(); } void MenuPage::NotifyActionTriggeredToParent(MenuPage *menu, MenuItem *menuItem) { if (m_Parent) { m_Parent->NotifyActionTriggeredToParent(menu, menuItem); } else { sigActionTriggered.emit(menu, menuItem->GetActionItem()); } StopMenu(); } void MenuPage::NotifyTerminateMenuCascade() { if (m_Parent) { m_Parent->NotifyTerminateMenuCascade(); } else { sigTerminateMenuCascade.emit(); } // if (IsActive()) // { // StopMenu(); // } } void MenuPage::NotifyMouseDownOutsideMenuCascade(int x, int y) { if (m_Parent) { m_Parent->NotifyMouseDownOutsideMenuCascade(x, y); } else { // This is the top MenuPage in a menu chain. // If this MenuPage has been registered with a MenuBar, then the MenuBar will intercept this signal // and terminate the menu chain. sigMouseDownOutsideMenuCascade.emit(this, x, y); // It is also possible that this MenuPage is not associated to a MenuBar(called directly for a contextual menu) if (m_IsTopOfMenuChain == false) { // This MenuPage is not attached to a MenuBar if (IsActive()) { //StopMenu(); } } } } void MenuPage::SetParentMenu(MenuPage *parent) { m_Parent = parent; } MenuPage *MenuPage::GetParentMenu() { return m_Parent; } long MenuPage::ComputeContentSize() { return View::ComputeContentSize(); } void MenuPage::SetGeometry(const Geometry &geo) { // The MenuPage widget cannot be resized by the client. The menu widget controls its own size. Geometry base = GetGeometry(); // We are only interested in the position X/Y. The popup figures out its width and height by itself. base.SetX(geo.x); base.SetY(geo.y); base.SetWidth(geo.GetWidth()); base.SetHeight(m_numItem * PRACTICAL_WIDGET_HEIGHT); SetBaseXY(geo.x, geo.y); ComputeContentPosition(0, 0); } ActionItem *MenuPage::GetActionItem(int index) const { nuxAssert(index >= 0); if (index >= (int) m_MenuItemVector.size()) return 0; return m_MenuItemVector[index]->GetActionItem(); } int MenuPage::GetActionItemIndex(ActionItem *action) const { if (action == 0) return -1; for (int i = 0; i < (int) m_MenuItemVector.size(); i++) { if (action == m_MenuItemVector[i]->GetActionItem()) { return i; } } return -1; } Geometry MenuPage::GetAbsoluteGeometry() const { return GetGeometry(); } Geometry MenuPage::GetRootGeometry() const { return GetGeometry(); } void MenuPage::SetOnClosureContinueEventCycle(bool on_closure_continue_with_event) { on_closure_continue_with_event_ = on_closure_continue_with_event; } bool MenuPage::OnClosureContinueEventCycle() const { return on_closure_continue_with_event_; } } nux-4.0.6+14.04.20140409/Nux/HexRegExpValidator.cpp0000644000015301777760000000550312321344237021723 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "HexRegExpValidator.h" namespace nux { HexRegExpValidator::HexRegExpValidator(int Minimum, int Maximum) : m_Minimum(Minimum) , m_Maximum(Maximum) { _regexp_str = "^(0[xX])*[0-9a-fA-F]+$"; InitRegExp(); if (m_Minimum > m_Maximum) { int temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } HexRegExpValidator::HexRegExpValidator(const HexRegExpValidator ©) { m_Minimum = copy.m_Minimum; m_Maximum = copy.m_Maximum; _regexp_str = copy._regexp_str; InitRegExp(); } HexRegExpValidator &HexRegExpValidator::operator= (const HexRegExpValidator &rhs) { if (&rhs != this) { m_Minimum = rhs.m_Minimum; m_Maximum = rhs.m_Maximum; _regexp_str = rhs._regexp_str; InitRegExp(); } return *this; } HexRegExpValidator::~HexRegExpValidator() { } Validator *HexRegExpValidator::Clone() const { return new HexRegExpValidator(*this); } void HexRegExpValidator::SetMinimum(int value) { m_Minimum = value; if (m_Minimum > m_Maximum) { int temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } int HexRegExpValidator::GetMinimum() const { return m_Minimum; } void HexRegExpValidator::SetMaximum(int value) { m_Maximum = value; if (m_Minimum > m_Maximum) { int temp = m_Minimum; m_Minimum = m_Maximum; m_Maximum = temp; } } int HexRegExpValidator::GetMaximum() const { return m_Maximum; } int HexRegExpValidator::GetClampedValue(int i) const { if (i < m_Minimum) return m_Minimum; if (i > m_Maximum) return m_Maximum; return i; } void HexRegExpValidator::Alternative(const char * /* str */) { } std::string HexRegExpValidator::ToString(int i) { return std::to_string((long long)i); } int HexRegExpValidator::ToInteger(const char *str) { if (Validate(str) == Acceptable) return HexCharToInteger(str); else return 0; } } nux-4.0.6+14.04.20140409/Nux/HLayout.h0000644000015301777760000000355312321344237017253 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef HLAYOUT_H #define HLAYOUT_H #include "LinearLayout.h" namespace nux { class HLayout: public LinearLayout { NUX_DECLARE_OBJECT_TYPE(HLayout, LinearLayout); public: HLayout(NUX_FILE_LINE_PROTO); HLayout(std::string name, NUX_FILE_LINE_PROTO); ~HLayout(); virtual long ComputeContentSize(); virtual void ComputeContentPosition(float offsetX, float offsetY); virtual void HLayoutManagement(int width, int height); virtual unsigned int GetMaxStretchFactor(); virtual void GetCompositeList(std::list *ViewList); //! Compute the how elements are spread inside the layout /*! @param remaining_width Size that remains after subtracting elements width, inner and outer margins from the content width. @param offset_space The space at the left of all elements. @param element_margin The margin between elements. */ void ComputeStacking(int remaining_width, int &offset_space, int &element_margin); protected: virtual Area* KeyNavIteration(KeyNavDirection direction); }; } #endif // HLAYOUT_H nux-4.0.6+14.04.20140409/Nux/HSplitter.h0000644000015301777760000000602212321344237017576 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef HSPLITTER_H #define HSPLITTER_H namespace nux { class Layout; class HSplitter: public View { NUX_DECLARE_OBJECT_TYPE(HSplitter, View); public: HSplitter(NUX_FILE_LINE_PROTO); ~HSplitter(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); void AddWidget(Area *ic, float stretchfactor); void ResetSplitConfig(); void clearContent(); void OnSplitterMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags, int header_pos); void OnSplitterMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, int header_pos); void OnSplitterMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags, int header_pos); virtual void OverlayDrawing(GraphicsEngine &graphics_engine); //! Return true if this object can break the layout. /* Return true if this object can break the layout, meaning, the layout can be done on the composition layout only without recomputing the whole window layout. Inherited from Area */ virtual bool CanBreakLayout() { return true; } virtual Area* FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type); protected: virtual long ComputeContentSize(); virtual void DoneRedraw(); void ResizeSplitter(int header_pos); //void ContinuousSplitterAdjustment(); void setResizeOnSplitterRelease(bool b) { m_ResizeOnSplitterRelease = b; } bool getResizeOnSplitterRelease() { return m_ResizeOnSplitterRelease; } virtual bool AcceptKeyNavFocus(); virtual Area* KeyNavIteration(KeyNavDirection direction); private: typedef BasicView MySplitter; std::vector m_InterfaceObject; std::vector m_SplitterObject; std::vector m_SplitConfig; Point m_point; bool new_addition; bool m_ResizeOnSplitterRelease; int m_current_width; int m_current_height; int m_current_x; int m_current_y; bool m_initial_config; // splitter bar differential position; int mvt_dx, mvt_dy; int m_focus_splitter_index; }; } #endif // HSPLITTER_H nux-4.0.6+14.04.20140409/Nux/GridHLayout.cpp0000644000015301777760000005211612321344237020413 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "View.h" #include "GridHLayout.h" #include "HLayout.h" #include "VLayout.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(GridHLayout); GridHLayout::GridHLayout(NUX_FILE_LINE_DECL) : Layout(NUX_FILE_LINE_PARAM) { #if DEBUG_LAYOUT m_h_in_margin = 10; left_padding_ = 10; right_padding_ = 10; m_v_in_margin = 10; top_padding_ = 10; bottom_padding_ = 10; #endif m_h_in_margin = 10; m_v_in_margin = 10; filling_order_ = FILL_HORIZONTAL; _children_size = Size(64, 64); _force_children_size = true; _partial_visibility = true; _num_row = 1; _num_column = 1; _dynamic_column = true; match_content_size_ = true; // Start packing the elements from the top. Is the layout has more space than the elements can use, // leave that space at the bottom of the GridHLayout. m_ContentStacking = MAJOR_POSITION_LEFT; SetMinimumSize(32, 32); } GridHLayout::~GridHLayout() { } void GridHLayout::SetSpaceBetweenChildren(int horizontal_space, int vertical_space) { m_h_in_margin = horizontal_space; m_v_in_margin = vertical_space; } int GridHLayout::GetChildPos(Area *child) { int position = 0; std::list::const_iterator it; for (it = GetChildren().begin(); it != GetChildren().end(); it++) { if ((*it) == child) break; ++position; } return position; } Area* GridHLayout::GetChildAtPosition(int pos) { int position = 0; std::list::const_iterator it; for (it = GetChildren().begin(); it != GetChildren().end(); it++) { if (position == pos) return (*it); ++position; } return NULL; } void GridHLayout::EnablePartialVisibility(bool partial_visibility) { _partial_visibility = partial_visibility; } void GridHLayout::SetChildrenSize(int width, int height) { _children_size = Size(width, height); } Size GridHLayout::GetChildrenSize() const { return _children_size; } void GridHLayout::ForceChildrenSize(bool force) { _force_children_size = force; } int GridHLayout::GetNumColumn() const { return _num_column; } int GridHLayout::GetNumRow() const { return _num_row; } void GridHLayout::MatchContentSize(bool match_content) { match_content_size_ = match_content; } bool GridHLayout::IsMatchingContentSize() const { return match_content_size_; } void GridHLayout::GetCompositeList(std::list *ViewList) { std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsView()) { View *ic = static_cast(*it); ViewList->push_back(ic); } else if ((*it)->IsLayout()) { Layout *layout = static_cast(*it); layout->GetCompositeList(ViewList); } } } long GridHLayout::ComputeLayoutRowOrder() { std::list elements; if (GetScaleFactor() == 0) { ApplyMinWidth(); } if (_layout_element_list.size() == 0) { return eCompliantHeight | eCompliantWidth; } int num_elements = 0; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible()) { (*it)->SetLayoutDone(false); elements.push_back(*it); num_elements++; } (*it)->SetLayoutDone(false); } int original_height = GetBaseHeight(); // The grid layout goes through the child elements and assign them a size and position. Children are filled in the grid like this: // 0 1 2 3 4 5 // 6 7 8 9 10 11 // 12 13 .. .. .. .. // This is a left to right fill going down. An option can be added the fill the grid from top to bottom and going toward the right. nux::Geometry base = GetGeometry(); it = elements.begin(); int num_row = 0; int num_column = 0; if (num_elements > 0) ++num_row; if (_dynamic_column) { int X = base.x + left_padding_; int Y = base.y + top_padding_; bool first_element_of_row = true; for (int i = 0; i < num_elements; i++) { if (num_row == 1) num_column++; if (first_element_of_row) { first_element_of_row = false; } if (_force_children_size) { (*it)->SetMinimumSize(_children_size.width, _children_size.height); } (*it)->SetGeometry(nux::Geometry(X, Y, _children_size.width, _children_size.height)); (*it)->ComputeContentSize(); X += _children_size.width + m_h_in_margin; it++; if ((!_partial_visibility) && (X + _children_size.width > base.x + base.width)) { X = base.x + left_padding_; Y += _children_size.height + m_v_in_margin; first_element_of_row = true; if (i < num_elements - 1) ++num_row; } else if (X >= base.x + base.width) { X = base.x + left_padding_; Y += _children_size.height + m_v_in_margin; first_element_of_row = true; if (i < num_elements - 1) ++num_row; } } } _num_row = num_row; _num_column = num_column; if ((GetScaleFactor() == 0) || match_content_size_) { int h = num_row * _children_size.height + (top_padding_ + bottom_padding_) + (num_row - 1) * m_v_in_margin; SetMinimumHeight(h); SetBaseHeight(h); } long size_compliance = 0L; { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: GridHLayout Width compliant = " << m_fittingWidth << std::endl; #endif size_compliance |= eCompliantWidth; } // The layout has been resized to tightly pack its content if (GetBaseHeight() > original_height) { #if DEBUG_LAYOUT_COMPUTATION // The layout has been resized larger in height to tightly pack its content. // Or you can say that the layout refuse to be smaller than total HEIGHT of its elements. std::cout << "ComputeContentSize: GridHLayout Height block at " << GetBaseHeight() << std::endl; #endif size_compliance |= eLargerHeight; // need scrollbar } else if (GetBaseHeight() < original_height) { #if DEBUG_LAYOUT_COMPUTATION // The layout is smaller. std::cout << "ComputeContentSize: GridHLayout Height is smaller = " << GetBaseHeight() << std::endl; #endif size_compliance |= eSmallerHeight; } else { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: GridHLayout Height compliant = " << GetBaseHeight() << std::endl; #endif size_compliance |= eCompliantHeight; } // if (GetScaleFactor() == 0) // { // return size_compliance | eForceComply; // } //SetDirty(false); return size_compliance; } long GridHLayout::ComputeLayoutColumnOrder() { std::list elements; if (GetScaleFactor() == 0) { ApplyMinHeight(); } if (_layout_element_list.size() == 0) { return eCompliantHeight | eCompliantWidth; } int num_elements = 0; std::list::iterator it; for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++) { if ((*it)->IsVisible()) { (*it)->SetLayoutDone(false); elements.push_back(*it); num_elements++; } (*it)->SetLayoutDone(false); } int original_width = GetBaseWidth(); nux::Geometry base = GetGeometry(); it = elements.begin(); int num_row = 0; int num_column = 0; if (num_elements > 0) ++num_column; if (_dynamic_column) { int X = base.x + left_padding_; int Y = base.y + top_padding_; bool first_element_of_column = true; for (int i = 0; i < num_elements; i++) { if (num_column == 1) num_row++; if (first_element_of_column) { first_element_of_column = false; } if (_force_children_size) { (*it)->SetMinimumSize(_children_size.width, _children_size.height); } (*it)->SetGeometry(nux::Geometry(X, Y, _children_size.width, _children_size.height)); (*it)->ComputeContentSize(); Y += _children_size.height + m_v_in_margin; it++; if ((!_partial_visibility) && (Y + _children_size.height > base.y + base.height - top_padding_)) { X += _children_size.width + m_h_in_margin; Y = base.y + top_padding_; first_element_of_column = true; if (i < num_elements - 1) ++num_column; } else if (Y >= base.y + base.height) { X += _children_size.width + m_h_in_margin; Y = base.y + top_padding_; first_element_of_column = true; if (i < num_elements - 1) ++num_column; } } } _num_row = num_row; _num_column = num_column; if ((GetScaleFactor() == 0) || match_content_size_) { int w = num_column * _children_size.width + (left_padding_ + right_padding_) + (num_column - 1) * m_h_in_margin; SetMinimumWidth(w); SetBaseWidth(w); } long size_compliance = 0L; if (GetBaseWidth() > original_width) { #if DEBUG_LAYOUT_COMPUTATION // The layout has been resized larger in WIDTH to tightly pack its content. // Or you can say that the layout refuse to be smaller than total WIDTH of its elements. std::cout << "ComputeContentSize: VLayout Width block at " << GetWidth() << std::endl; #endif size_compliance |= eLargerWidth; // need scrollbar } else if (GetBaseWidth() < original_width) { #if DEBUG_LAYOUT_COMPUTATION // The layout is smaller. std::cout << "ComputeContentSize: VLayout Width smaller = " << GetWidth() << std::endl; #endif size_compliance |= eSmallerWidth; } else { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: VLayout Width compliant = " << GetWidth() << std::endl; #endif size_compliance |= eCompliantWidth; } { #if DEBUG_LAYOUT_COMPUTATION // The layout and its content resized together without trouble. std::cout << "ComputeContentSize: VLayout Height compliant = " << m_fittingHeight << std::endl; #endif size_compliance |= eCompliantHeight; } return size_compliance; } long GridHLayout::ComputeContentSize() { if (filling_order_ == FILL_HORIZONTAL) { return ComputeLayoutRowOrder(); } else { return ComputeLayoutColumnOrder(); } } void GridHLayout::ProcessDraw(GraphicsEngine &graphics_engine, bool force_draw) { if (_layout_element_list.size() == 0) return; std::list elements; std::list::iterator it = _layout_element_list.begin(); graphics_engine.PushModelViewMatrix(Get2DMatrix()); Geometry base = GetGeometry(); Geometry absolute_geometry = GetAbsoluteGeometry(); Geometry parent_geometry = absolute_geometry; Geometry visibility_geometry = absolute_geometry; if (GetToplevel()) { parent_geometry = GetToplevel()->GetAbsoluteGeometry(); } visibility_geometry = parent_geometry.Intersect(absolute_geometry); graphics_engine.PushClippingRectangle(base); it = _layout_element_list.begin(); bool first = false; bool last = false; int JJ = 0; int II = 0; if (filling_order_ == FILL_HORIZONTAL) { JJ = _num_row; II = _num_column; } else { JJ = _num_column; II = _num_row; } for (int j = 0; j < JJ; j++) { for (int i = 0; i < II; i++) { if (it == _layout_element_list.end()) break; if ((*it)->IsVisible() == false) { ++it; continue; } // Test if the element is inside the Grid before rendering. if (visibility_geometry.IsIntersecting((*it)->GetAbsoluteGeometry())) { if (first == false) { first = true; // First invisible child. } int x = 0; int y = 0; if (filling_order_ == FILL_HORIZONTAL) { x = base.x + left_padding_ + i * (_children_size.width + m_h_in_margin); y = base.y + top_padding_ + j * (_children_size.height + m_v_in_margin); } else { x = base.x + left_padding_ + j * (_children_size.width + m_h_in_margin); y = base.y + top_padding_ + i * (_children_size.height + m_v_in_margin); } graphics_engine.PushClippingRectangle(Geometry(x, y, _children_size.width, _children_size.height)); if ((*it)->IsView()) { View *ic = static_cast(*it); ic->ProcessDraw(graphics_engine, force_draw); } else if ((*it)->IsLayout()) { Layout *layout = static_cast(*it); layout->ProcessDraw(graphics_engine, force_draw); } graphics_engine.PopClippingRectangle(); } else { if (first) { // First invisible child. Exit! last = true; } } if (first && last) { // Early exit break; } it++; } if (first && last) break; } graphics_engine.PopClippingRectangle(); graphics_engine.PopModelViewMatrix(); draw_cmd_queued_ = false; } Area* GridHLayout::KeyNavIterationRowOrder(KeyNavDirection direction) { if (_layout_element_list.size() == 0) return NULL; if (IsVisible() == false) return NULL; if (next_object_to_key_focus_area_) { std::list::iterator it; std::list::iterator it_next; it = std::find(_layout_element_list.begin(), _layout_element_list.end(), next_object_to_key_focus_area_); it_next = it; ++it_next; if (it == _layout_element_list.end()) { // Should never happen nuxAssert(0); return NULL; } int position = GetChildPos(*it); // note that(*it) == next_object_to_key_focus_area_ int nun_column = GetNumColumn(); int nun_row = GetNumRow(); if ((direction == KEY_NAV_LEFT) && (it == _layout_element_list.begin())) { // first item return NULL; } if ((direction == KEY_NAV_LEFT) && position % nun_column == 0) { return NULL; } if ((direction == KEY_NAV_RIGHT) && (it_next == _layout_element_list.end())) { // last item return NULL; } if ((direction == KEY_NAV_RIGHT) && position % nun_column == nun_column - 1) { // last item return NULL; } if ((direction == KEY_NAV_UP) && ((position / nun_column) == 0)) { // top edge return NULL; } if ((direction == KEY_NAV_DOWN) && ((position / nun_column) == (nun_row - 1))) { // bottom edge return NULL; } ////// if (direction == KEY_NAV_LEFT) { --it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { int pos = GetChildPos(*it); if (it == _layout_element_list.begin() || ((pos % nun_column) == 0)) break; --it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_RIGHT) { ++it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { int pos = GetChildPos(*it); if ((it == _layout_element_list.end()) || (pos == (pos / nun_column) * nun_column + (nun_column -1))) break; ++it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_UP) { for (int i = 0; i < nun_column; ++i) { --it; } if (it != _layout_element_list.end()) return (*it)->KeyNavIteration(direction); } if (direction == KEY_NAV_DOWN) { for (int i = 0; i < nun_column; ++i) { ++it; } if (it != _layout_element_list.end()) return (*it)->KeyNavIteration(direction); } } else { Area* area = NULL; if (direction == KEY_NAV_UP) area = GetChildAtPosition(GetNumColumn() * (GetNumRow() - 1)); else area = _layout_element_list.front(); if (area) return area->KeyNavIteration(direction); } return NULL; } Area* GridHLayout::KeyNavIterationColumnOrder(KeyNavDirection direction) { if (_layout_element_list.size() == 0) return NULL; if (IsVisible() == false) return NULL; if (next_object_to_key_focus_area_) { std::list::iterator it; std::list::iterator it_next; it = std::find(_layout_element_list.begin(), _layout_element_list.end(), next_object_to_key_focus_area_); it_next = it; ++it_next; if (it == _layout_element_list.end()) { // Should never happen nuxAssert(0); return NULL; } int position = GetChildPos(*it); // note that(*it) == next_object_to_key_focus_area_ int nun_column = GetNumColumn(); int nun_row = GetNumRow(); if ((direction == KEY_NAV_UP) && (it == _layout_element_list.begin())) { // first item return NULL; } if ((direction == KEY_NAV_DOWN) && (it_next == _layout_element_list.end())) { // last item return NULL; } if ((direction == KEY_NAV_UP) && ((position % nun_row) == 0)) { // Left edge return NULL; } if ((direction == KEY_NAV_DOWN) && (position == (position / nun_row) * nun_row + (nun_row -1))) { // right edge return NULL; } if ((direction == KEY_NAV_LEFT) && ((position / nun_row) == 0)) { // top edge return NULL; } if ((direction == KEY_NAV_RIGHT) && ((position / nun_row) == nun_column)) { // bottom edge return NULL; } ////// if (direction == KEY_NAV_UP) { --it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { int pos = GetChildPos(*it); if (it == _layout_element_list.begin() || ((pos % nun_row) == 0)) break; --it; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_DOWN) { ++it; Area* key_nav_focus = (*it)->KeyNavIteration(direction); while (key_nav_focus == NULL) { ++it; int pos = GetChildPos(*it); if ((it == _layout_element_list.end()) || (pos == (pos / nun_row) * nun_row + (nun_row -1))) break; key_nav_focus = (*it)->KeyNavIteration(direction); } return key_nav_focus; } if (direction == KEY_NAV_LEFT) { for (int i = 0; i < nun_row; ++i) { --it; } return (*it)->KeyNavIteration(direction); } if (direction == KEY_NAV_RIGHT) { for (int i = 0; i < nun_row; ++i) { ++it; if (it == _layout_element_list.end()) return NULL; } return (*it)->KeyNavIteration(direction); } } else { std::list::iterator it; it = _layout_element_list.begin(); return (*it)->KeyNavIteration(direction); } return NULL; } Area* GridHLayout::KeyNavIteration(KeyNavDirection direction) { if (filling_order_ == FILL_HORIZONTAL) { return KeyNavIterationRowOrder(direction); } else { return KeyNavIterationColumnOrder(direction); } } void GridHLayout::SetFillingOrder(FillingOrder filling_order) { filling_order_ = filling_order; } GridHLayout::FillingOrder GridHLayout::GetFillingOrder() const { return filling_order_; } } nux-4.0.6+14.04.20140409/Nux/ToolButton.cpp0000644000015301777760000001021712321344237020325 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "Nux.h" #include "NuxGraphics/GLTextureResourceManager.h" #include "Layout.h" #include "HLayout.h" #include "VLayout.h" #include "ActionItem.h" #include "ToolButton.h" namespace nux { ToolButton::ToolButton(const char *BitmapFilename, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_ActionItem(0) { m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); if (BitmapFilename) m_Texture->Update(BitmapFilename); // Set Original State SetBaseString("ToolButton"); // Set Signals mouse_click.connect(sigc::mem_fun(this, &ToolButton::EmitClick)); mouse_double_click.connect(sigc::mem_fun(this, &ToolButton::RecvMouseDoubleClick)); mouse_down.connect(sigc::mem_fun(this, &ToolButton::RecvMouseDown)); mouse_up.connect(sigc::mem_fun(this, &ToolButton::RecvMouseUp)); mouse_enter.connect(sigc::mem_fun(this, &ToolButton::RecvMouseEnter)); mouse_leave.connect(sigc::mem_fun(this, &ToolButton::RecvMouseLeave)); SetMinimumSize(28, 28); SetGeometry(Geometry(0, 0, 24, 24)); } ToolButton::~ToolButton() { m_Texture->UnReference(); } void ToolButton::Draw(GraphicsEngine &graphics_engine, bool /* force_draw */) { Geometry base = GetGeometry(); if (IsMouseInside() && !IsMouseOwner()) { GetPainter().PaintBackground(graphics_engine, base); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BACKGROUND_SECONDARY), eSHAPE_CORNER_ROUND2); } else if (IsMouseOwner()) { GetPainter().PaintBackground(graphics_engine, base); GetPainter().PaintShape(graphics_engine, base, Color(0xFF2A2A2A), eSHAPE_CORNER_ROUND2); } else { GetPainter().PaintBackground(graphics_engine, base); GetPainter().PaintShape(graphics_engine, base, Color(COLOR_BACKGROUND_PRIMARY), eSHAPE_CORNER_ROUND2); } if (m_Texture) GetPainter().Draw2DTextureAligned(graphics_engine, m_Texture, base, TextureAlignmentStyle(eTACenter, eTACenter)); } void ToolButton::DrawContent(GraphicsEngine & /* graphics_engine */, bool /* force_draw */) { } void ToolButton::SetState(bool /* b */) { } void ToolButton::SetBitmap(const BaseTexture* Texture) { nuxAssert(Texture); NUX_RETURN_IF_NULL(Texture); if (m_Texture) m_Texture->UnReference(); m_Texture = Texture->Clone(); } void ToolButton::EmitClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { sigClick.emit(); if (m_ActionItem) m_ActionItem->Trigger(); } void ToolButton::RecvMouseDoubleClick(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void ToolButton::RecvMouseDown(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void ToolButton::RecvMouseUp(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void ToolButton::RecvMouseEnter(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void ToolButton::RecvMouseLeave(int /* x */, int /* y */, unsigned long /* button_flags */, unsigned long /* key_flags */) { QueueDraw(); } void ToolButton::SetAction(ActionItem *action) { m_ActionItem = action; } } nux-4.0.6+14.04.20140409/Nux/BasicView.cpp0000644000015301777760000000222212321344237020065 0ustar pbusernogroup00000000000000/* * Copyright 2012 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 3 along with this program. If not, see * * * Authored by: Jay Taoko * */ #include "Nux/Nux.h" #include "BasicView.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(BasicView); BasicView::BasicView(NUX_FILE_LINE_DECL) : nux::View(NUX_FILE_LINE_PARAM) { } BasicView::~BasicView() { } void BasicView::Draw(nux::GraphicsEngine& /* graphics_engine */, bool /* force_draw */) { // Draw nothing // For debug only: // graphics_engine.QRP_Color(GetBaseX(), GetBaseY(), GetBaseWidth(), GetBaseHeight(), nux::color::Pink); } } nux-4.0.6+14.04.20140409/Nux/ColorEditor.h0000644000015301777760000001373712321344237020120 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef COLOREDITOR_H #define COLOREDITOR_H #include "NuxGraphics/GpuDevice.h" #include "NuxGraphics/GLDeviceObjects.h" #include "NuxGraphics/GLSh_DrawFunction.h" #include "DoubleValidator.h" #include "TimerProc.h" namespace nux { class GLSh_ColorPicker; class HLayout; class VLayout; class EditTextBox; class CheckBox; class AbstractButton; class RadioButton; class RadioButtonGroup; class Button; class ColorEditor; class ColorPreview; class ColorDialogProxy { public: ColorDialogProxy(bool ModalWindow); ~ColorDialogProxy(); void RecvDialogOk(ColorEditor *coloreditor); void RecvDialogCancel(ColorEditor *coloreditor); void RecvDialogChange(ColorEditor *coloreditor); void Start(); bool IsActive(); void StopThreadMonitoring(); void SetColor(Color color); Color GetColor(); void SetPreviousColor(Color color); Color GetPreviousColor(); void SetColorModel(color::Model color_model); color::Model GetColorModel(); void SetColorChannel(color::Channel color_model); color::Channel GetColorChannel(); private: bool m_bDialogChange; bool m_bDialogRunning; unsigned int m_DialogThreadID; Color m_RGBColor; Color m_PreviousRGBColor; color::Model m_ColorModel; color::Channel color_channel_; bool m_ModalWindow; NThread *m_Thread; friend class ColorPreview; }; class ColorEditor : public View { public: ColorEditor(NUX_FILE_LINE_PROTO); ~ColorEditor(); void SetRed(double r); void SetGreen(double g); void SetBlue(double b); void SetHue(double h); void SetSaturation(double s); void SetValue(double v); void SetRGB(double r, double g, double b); void SetHSV(double h, double s, double v); void SetRGB(Color const& rgb); Color GetRGBColor() const; void SetColorModel(color::Model, color::Channel); color::Model GetColorModel() const; color::Channel GetColorChannel() const; void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void RecvPickerMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvPickerMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvPickerMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void RecvCheckColorModel(bool, color::Model, color::Channel); void RecvCheckColorModel0(AbstractButton *button, color::Model color_mode, color::Channel channel); sigc::signal< void, ColorEditor * > sigChange; protected: virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); virtual void PreLayoutManagement(); virtual bool AcceptKeyNavFocus(); private: //! Override of Area::SetMinimumHeight and made private. /*! Prevent changing the minimum height of the ColorEditor view. */ virtual void SetMinimumHeight(int h){}; //! Override of Area::SetMaximumHeight and made private. /*! Prevent changing the maximum height of the ColorEditor view. */ virtual void SetMaximumHeight(int h){}; //! Override of Area::SetMinimumWidth and made private. /*! Prevent changing the minimum width of the ColorEditor view. */ virtual void SetMinimumWidth(int w){}; //! Override of Area::SetMaximumWidth and made private. /*! Prevent changing the maximum width of the ColorEditor view. */ virtual void SetMaximumWidth(int w){}; void DrawBaseChannelMarker(GraphicsEngine &graphics_engine); void DrawRGB(GraphicsEngine &graphics_engine, bool force_draw); void DrawHSV(GraphicsEngine &graphics_engine, bool force_draw); color::Channel color_channel_; color::Model m_ColorModel; InputArea *picker_area_; InputArea *channel_area_; InputArea *selected_color_area_; HLayout *m_hlayout; VLayout *ctrllayout; GLSh_ColorPicker *m_RedShader; GLSh_ColorPicker *m_GreenShader; GLSh_ColorPicker *m_BlueShader; GLSh_ColorPicker *m_HueShader; GLSh_ColorPicker *m_SaturationShader; GLSh_ColorPicker *m_ValueShader; Point m_MarkerPosition; Point m_VertMarkerPosition; color::RedGreenBlue rgb_; color::HueSaturationValue hsv_; HLayout *redlayout; HLayout *greenlayout; HLayout *bluelayout; RadioButton *redcheck; EditTextBox *redtext; RadioButton *greencheck; EditTextBox *greentext; RadioButton *bluecheck; EditTextBox *bluetext; HLayout *huelayout; HLayout *saturationlayout; HLayout *valuelayout; RadioButton *huecheck; EditTextBox *hue_text_entry_; RadioButton *saturationcheck; EditTextBox *saturation_text_entry_; RadioButton *valuecheck; EditTextBox *value_text_entry_; RadioButtonGroup *radiogroup; DoubleValidator m_Validator; static Size picker_area_size; static int channel_area_width; }; } #endif // COLOREDITOR_H nux-4.0.6+14.04.20140409/Nux/AnimatedTextureArea.h0000644000015301777760000000341112321344237021553 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ANIMATEDTEXTUREAREA_H #define ANIMATEDTEXTUREAREA_H #include "NuxGraphics/GraphicsEngine.h" #include "TimerProc.h" namespace nux { class AnimatedTextureArea : public View { public: AnimatedTextureArea(NUX_FILE_LINE_PROTO); ~AnimatedTextureArea(); virtual void Draw(GraphicsEngine &graphics_engine, bool force_draw); virtual void DrawContent(GraphicsEngine &graphics_engine, bool force_draw); void SetTexture(TextureFrameAnimation *Texture); void RecvMouseDown(int x, int y, long button_flags, long key_flags); void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); sigc::signal sigMouseDown; sigc::signal sigMouseDrag; void StartAnimation(); void StopAnimation(); private: void TimerNextFrame(void *v); TimerFunctor *m_TimerFunctor; TimerHandle m_TimerHandler; TextureFrameAnimation *m_UserTexture; }; } #endif // ANIMATEDTEXTUREAREA_H nux-4.0.6+14.04.20140409/INSTALL0000644000015301777760000003660012321344237015773 0ustar pbusernogroup00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX `make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as `configure' are involved. Use GNU `make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. nux-4.0.6+14.04.20140409/NuxGraphics/0000755000015301777760000000000012321344711017165 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLAsmShader.cpp0000644000015301777760000002310312321344237022720 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GraphicsDisplay.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLAsmShader.h" #include "NuxCore/Logger.h" namespace nux { DECLARE_LOGGER(logger, "nux.graphics"); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLAsmShader); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLAsmVertexShader); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLAsmPixelShader); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLAsmShaderProgram); bool ExtractShaderString3(const std::string& ShaderToken, const std::string& ShaderSource, std::string& RetSource, std::string ShaderPreprocessorDefines); IOpenGLAsmShader::IOpenGLAsmShader(std::string const& shader_name, GLint shader_type, OpenGLResourceType ResourceType) : IOpenGLResource(ResourceType) , shader_name_(shader_name) , shader_type_(shader_type) , compiled_and_ready_(false) { #ifndef NUX_OPENGLES_20 CHECKGL(glGenProgramsARB(1, GetOpenGLIDAsInParam())); #endif } IOpenGLAsmShader::~IOpenGLAsmShader() { #ifndef NUX_OPENGLES_20 CHECKGL(glDeleteProgramsARB(1, GetOpenGLIDAsInParam())); #endif } void IOpenGLAsmShader::SetShaderCode(std::string const& shader_code) { compiled_and_ready_ = false; shader_code_ = shader_code; } bool IOpenGLAsmShader::IsValid() { return compiled_and_ready_; } bool IOpenGLAsmShader::Compile() { if (compiled_and_ready_) { return true; } #ifndef NUX_OPENGLES_20 if (shader_code_.empty()) { LOG_DEBUG(logger) << shader_name_ << " source code is empty."; } CHECKGL(glBindProgramARB(shader_type_, GetOpenGLID())); glProgramStringARB(shader_type_, GL_PROGRAM_FORMAT_ASCII_ARB, shader_code_.size(), shader_code_.c_str()); if (GL_INVALID_OPERATION == glGetError()) { // Find the error position GLint errPos; glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); // Print implementation-dependent program // errors and warnings string. LOG_ERROR(logger) << "Error in " << shader_name_ << " at position: " << errPos << "\n\t" << glGetString(GL_PROGRAM_ERROR_STRING_ARB); return false; } compiled_and_ready_ = true; #endif return compiled_and_ready_; } IOpenGLAsmVertexShader::IOpenGLAsmVertexShader() #ifndef NUX_OPENGLES_20 : IOpenGLAsmShader("VertexProgram", GL_VERTEX_PROGRAM_ARB, RT_GLSL_VERTEXSHADER) #else : IOpenGLAsmShader("VertexProgram", 0, RT_GLSL_VERTEXSHADER) #endif { } IOpenGLAsmPixelShader::IOpenGLAsmPixelShader() #ifndef NUX_OPENGLES_20 : IOpenGLAsmShader("PixelProgram", GL_FRAGMENT_PROGRAM_ARB, RT_GLSL_PIXELSHADER) #else : IOpenGLAsmShader("PixelProgram", 0, RT_GLSL_PIXELSHADER) #endif { } IOpenGLAsmShaderProgram::IOpenGLAsmShaderProgram(std::string ShaderProgramName) : IOpenGLResource(RT_GLSL_SHADERPROGRAM) , _ShaderProgramName(ShaderProgramName) { _OpenGLID = 0; m_AsmVertexProgram = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmVertexShader(); m_AsmFragmentProgram = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmPixelShader(); } IOpenGLAsmShaderProgram::~IOpenGLAsmShaderProgram() { _OpenGLID = 0; } void IOpenGLAsmShaderProgram::LoadIShaderFile(const char *ShaderFileName) { nuxAssertMsg(ShaderFileName, "[IOpenGLAsmShaderProgram::LoadIShaderFile] Invalid shader file name."); NUX_RETURN_IF_NULL(ShaderFileName); std::string SourceCode; LoadFileToString(SourceCode, ShaderFileName); LoadIShader(&SourceCode[0]); } void IOpenGLAsmShaderProgram::LoadIShader(const char* ShaderCode) { nuxAssertMsg(ShaderCode, "[IOpenGLAsmShaderProgram::LoadIShader] Invalid shader code."); NUX_RETURN_IF_NULL(ShaderCode); std::string VertexShaderSource; ExtractShaderString3("[Vertex Shader]", ShaderCode, VertexShaderSource, std::string("")); std::string PixelShaderSource; ExtractShaderString3("[Fragment Shader]", ShaderCode, PixelShaderSource, std::string("")); m_AsmVertexProgram->SetShaderCode(&VertexShaderSource[0]); m_AsmFragmentProgram->SetShaderCode(&PixelShaderSource[0]); m_AsmVertexProgram->Compile(); m_AsmFragmentProgram->Compile(); } void IOpenGLAsmShaderProgram::LoadVertexShader(const char* glslshader) { nuxAssertMsg(glslshader, "[IOpenGLAsmShaderProgram::LoadVertexShader] Invalid shader code."); NUX_RETURN_IF_NULL(glslshader); m_AsmVertexProgram->SetShaderCode(glslshader); m_AsmVertexProgram->Compile(); } void IOpenGLAsmShaderProgram::LoadPixelShader(const char *glslshader) { nuxAssertMsg(glslshader, "[IOpenGLAsmShaderProgram::LoadPixelShader] Invalid shader code."); NUX_RETURN_IF_NULL(glslshader); m_AsmFragmentProgram->SetShaderCode(glslshader); m_AsmFragmentProgram->Compile(); } void IOpenGLAsmShaderProgram::Link() { m_AsmVertexProgram->Compile(); m_AsmFragmentProgram->Compile(); } bool IOpenGLAsmShaderProgram::IsValid() { if (m_AsmVertexProgram->IsValid() && m_AsmFragmentProgram->IsValid()) return true; return false; } void IOpenGLAsmShaderProgram::Begin(void) { #ifndef NUX_OPENGLES_20 CHECKGL(glEnable(GL_VERTEX_PROGRAM_ARB)); CHECKGL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_AsmVertexProgram->GetOpenGLID())); CHECKGL(glEnable(GL_FRAGMENT_PROGRAM_ARB)); CHECKGL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_AsmFragmentProgram->GetOpenGLID())); #endif } void IOpenGLAsmShaderProgram::End(void) { #ifndef NUX_OPENGLES_20 CHECKGL(glDisable(GL_VERTEX_PROGRAM_ARB)); CHECKGL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0)); CHECKGL(glDisable(GL_FRAGMENT_PROGRAM_ARB)); CHECKGL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)); #endif } #ifndef NUX_OPENGLES_20 void IOpenGLAsmShaderProgram::SetVertexEnvParameter4dARB(unsigned int index, double x, double y, double z, double w) { CHECKGL(glProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetVertexEnvParameter4dvARB(unsigned int index, const double *params) { CHECKGL(glProgramEnvParameter4dvARB(GL_VERTEX_PROGRAM_ARB, index, params)); } void IOpenGLAsmShaderProgram::SetVertexEnvParameter4fARB(unsigned int index, float x, float y, float z, float w) { CHECKGL(glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetVertexEnvParameter4fvARB(unsigned int index, const float *params) { CHECKGL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index, params)); } void IOpenGLAsmShaderProgram::SetVertexLocalParameter4dARB(unsigned int index, double x, double y, double z, double w) { CHECKGL(glProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetVertexLocalParameter4dvARB(unsigned int index, const double *params) { CHECKGL(glProgramEnvParameter4dvARB(GL_VERTEX_PROGRAM_ARB, index, params)); } void IOpenGLAsmShaderProgram::SetVertexLocalParameter4fARB(unsigned int index, float x, float y, float z, float w) { CHECKGL(glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetVertexLocalParameter4fvARB(unsigned int index, const float *params) { CHECKGL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index, params)); } void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4dARB(unsigned int index, double x, double y, double z, double w) { CHECKGL(glProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4dvARB(unsigned int index, const double *params) { CHECKGL(glProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index, params)); } void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4fARB(unsigned int index, float x, float y, float z, float w) { CHECKGL(glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4fvARB(unsigned int index, const float *params) { CHECKGL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, params)); } void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4dARB(unsigned int index, double x, double y, double z, double w) { CHECKGL(glProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4dvARB(unsigned int index, const double *params) { CHECKGL(glProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index, params)); } void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4fARB(unsigned int index, float x, float y, float z, float w) { CHECKGL(glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w)); } void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4fvARB(unsigned int index, const float *params) { CHECKGL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, params)); } #endif } nux-4.0.6+14.04.20140409/NuxGraphics/GLRenderStates.h0000644000015301777760000013266012321344237022177 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLRENDERSTATES_H #define GLRENDERSTATES_H #include "NuxCore/NuxCore.h" #include "GpuDevice.h" namespace nux { enum { GFXRS_FRONT_POLYGONMODE, // GL_FILL GFXRS_BACK_POLYGONMODE, // GL_FILL GFXRS_CULLFACEENABLE, // GL_FALSE GFXRS_CULLFACE, // GL_BACK GFXRS_FRONTFACE, // GL_CCW GFXRS_SCISSORTESTENABLE, // GL_FALSE GFXRS_ZTESTENABLE, // GL_TRUE GFXRS_ZWRITEENABLE, // GL_TRUE GFXRS_ZFUNC, // GL_LESS GFXRS_ZNEAR, // 0.0f GFXRS_ZFAR, // 1.0f GFXRS_ALPHABLENDENABLE, // GL_FALSE GFXRS_BLENDOP, // GL_FUNC_ADD GFXRS_BLENDOPALPHA, // GL_FUNC_ADD GFXRS_SRCBLEND, // GL_ONE GFXRS_DESTBLEND, // GL_ZERO GFXRS_SRCBLENDALPHA, // GL_ONE GFXRS_DESTBLENDALPHA, // GL_ZERO GFXRS_ALPHATESTENABLE, // GL_FALSE GFXRS_ALPHATESTREF, // 0x0 GFXRS_ALPHATESTFUNC, // GL_ALWAYS GFXRS_STENCILENABLE, // GL_FALSE GFXRS_TWOSIDEDSTENCILENABLE, // GL_FALSE GFXRS_FRONT_STENCILWRITEMASK, // 0xFFFFFFFF GFXRS_BACK_STENCILWRITEMASK, // 0xFFFFFFFF GFXRS_FRONT_STENCILFUNC, // GL_ALWAYS GFXRS_FRONT_STENCILREF, // 0x0 GFXRS_FRONT_STENCILMASK, // 0xFF GFXRS_FRONT_STENCILFAIL, // GL_KEEP GFXRS_FRONT_STENCILZFAIL, // GL_KEEP GFXRS_FRONT_STENCILZPASS, // GL_KEEP GFXRS_BACK_STENCILFUNC, // GL_ALWAYS GFXRS_BACK_STENCILREF, // 0x0 GFXRS_BACK_STENCILMASK, // 0xFF GFXRS_BACK_STENCILFAIL, // GL_KEEP GFXRS_BACK_STENCILZFAIL, // GL_KEEP GFXRS_BACK_STENCILZPASS, // GL_KEEP GFXRS_LINESMOOTHENABLE, // GL_FALSE GFXRS_LINEWIDTH, // 1.0f GFXRS_LINEHINT, // GL_FASTEST GFXRS_COLORWRITEENABLE_R, // TRUE or FALSE GFXRS_COLORWRITEENABLE_G, // TRUE or FALSE GFXRS_COLORWRITEENABLE_B, // TRUE or FALSE GFXRS_COLORWRITEENABLE_A, // TRUE or FALSE GFXRS_MAX_RENDERSTATES, }; enum { GFXSS_ADDRESSU, GFXSS_ADDRESSV, GFXSS_ADDRESSW, GFXSS_MINFILTER, GFXSS_MAGFILTER, GFXSS_MIPMAPFILTER, GFXSS_MIPMAPLODBIAS, GFXSS_MAXANISOTROPY, GFXSS_SRGBWRITEENABLE, GFXSS_MAX_SAMPLERSTATES, }; typedef enum { CLEAR = 0, SRC, DST, SRC_OVER, DST_OVER, SRC_IN, DST_IN, SRC_OUT, DST_OUT, SRC_ATOP, DST_ATOP, XOR, PLUS } PorterDuffOperator; struct RenderStateMap { unsigned int Checked; unsigned int State; unsigned int iValue; float fValue; }; class GpuRenderStates { public: GpuRenderStates(GpuBrand board, GpuInfo* info); ~GpuRenderStates(); void ResetDefault(); void ResetStateChangeToDefault(); void CommitStateChangeToDefault(); void CheckStateChange(); void SubmitChangeStates(); //! Check that all render states ar conform to the default void CheckRenderStatesConformity(); // Render states #ifndef NUX_OPENGLES_20 inline void SetAlphaTest( bool EnableAlphaTest_, unsigned int AlphaTestFunc_ = GL_ALWAYS, BYTE AlphaTestRef_ = 0); #endif inline void SetBlend(bool AlphaBlendEnable_); inline void SetBlend(bool AlphaBlendEnable_, unsigned int SrcBlendFactor_ /*= GL_ONE*/, unsigned int DestBlendFactor_ /*= GL_ZERO*/); inline void GetBlend(unsigned int& AlphaBlendEnable_, unsigned int& SrcBlendFactor_, unsigned int& DestBlendFactor_); inline void SetSeparateBlend(bool _bEnable, unsigned int SrcBlendFactor_ /*= GL_ONE*/, unsigned int DestBlendFactor_ /*= GL_ZERO*/, unsigned int SrcFactorAlpha_ /*= GL_ONE*/, unsigned int DestFactorAlpha_ /*= GL_ZERO*/); inline void SetPremultipliedBlend(PorterDuffOperator op); inline void SetBlendOp( unsigned int BlendOp = GL_FUNC_ADD); inline void SetSeparateBlendOp( unsigned int BlendOpRGB_ = GL_FUNC_ADD, unsigned int BlendOpAlpha_ = GL_FUNC_ADD); inline void SetCullMode(bool EnableCullFace, unsigned int FrontFace_ = GL_CCW, unsigned int Cullface_ = GL_BACK); inline void SetDepthTest(bool EnableDepthTest, unsigned int WriteEnable_ = GL_TRUE, unsigned int DepthFunc_ = GL_LEQUAL); inline void SetDepthRange( float zNear = 0.0f, float zFar = 1.0f); inline void SetStencil(bool enable_stencil); inline void SetStencilFunc(unsigned int func, int ref, unsigned int mask); inline void SetStencilOp(unsigned int stencil_fail, unsigned int stencil_pass_depth_fail, unsigned int stencil_pass_depth_pass); #if 0 // If two sided stencil is not activated, the setting is also used for the back face. inline void SetStencilFrontFace( bool EnableStencil_, // GL_TRUE enable stencil test unsigned int Func_ = GL_ALWAYS, unsigned int FailOp_ = GL_KEEP, unsigned int ZFailOp_ = GL_KEEP, unsigned int ZPassOp_ = GL_KEEP, unsigned int Ref_ = 0, unsigned int Mask_ = 0xffffffff); // Set stencil test for the back face. inline void SetStencilBackFace( bool EnableTwoSideStencil_, // GL_TRUE enable Two Sided Stencil test unsigned int Func_ = GL_ALWAYS, unsigned int FailOp_ = GL_KEEP, unsigned int ZFailOp_ = GL_KEEP, unsigned int ZPassOp_ = GL_KEEP, unsigned int Ref_ = 0, unsigned int Mask_ = 0xffffffff); inline void SetFrontFaceStencilWriteMask( unsigned int WriteMask_ = 0xffffffff); inline void SetBackFaceStencilWriteMask( unsigned int WriteMask_ = 0xffffffff); #endif inline void EnableLineSmooth( bool EnableLineSmooth = TRUE, unsigned int LineWidth = 1, unsigned int HINT = GL_FASTEST); inline void SetColorMask( unsigned int bRed = TRUE, unsigned int bGreen = TRUE, unsigned int bBlue = TRUE, unsigned int bAlpha = TRUE); inline void GetColorMask( unsigned int& bRed, unsigned int& bGreen, unsigned int& bBlue, unsigned int& bAlpha); inline void SetDepthMask(unsigned int bDepth = TRUE); inline void EnableScissor(unsigned int bScissor = FALSE); #ifndef NUX_OPENGLES_20 inline void SetPolygonMode(unsigned int FrontMode = GL_FILL, unsigned int BackMode = GL_FILL); #else inline void SetPolygonMode(unsigned int FrontMode, unsigned int BackMode); #endif inline void SetPolygonOffset(unsigned int bEnable, float Factor = 0.0f, float Units = 0.0f); private: GpuBrand gpu_brand_; GpuInfo* gpu_info_; #ifndef NUX_OPENGLES_20 inline void HW__EnableAlphaTest(unsigned int b); inline void HW__SetAlphaTestFunc( unsigned int AlphaTestFunc_, BYTE AlphaTestRef_); #endif inline void HW__EnableAlphaBlend(unsigned int b); inline void HW__SetSeparateAlphaBlend_Enable(unsigned int b); inline void HW__SetSeparateAlphaBlendFactors( unsigned int SrcBlendFactor_, unsigned int DestBlendFactor_, unsigned int SrcFactorAlpha_, unsigned int DestFactorAlpha_); inline void HW__SetAlphaBlendOp(unsigned int BlendOpRGB_, unsigned int BlendOpAlpha_); inline void HW__EnableCulling(unsigned int b); inline void HW__SetFrontFace(unsigned int FrontFace_); inline void HW__SetCullFace(unsigned int CullFace_); inline void HW__SetEnableDepthTest(unsigned int b); inline void HW__SetDepthFunc(unsigned int Func); inline void HW__SetDepthRange(float zNear, float zFar); inline void HW__EnableStencil(unsigned int b); inline void HW__SetStencilOp(unsigned int FailOp_, unsigned int ZFailOp_, unsigned int ZPassOp_); inline void HW__SetStencilFunc(unsigned int func, int ref, unsigned int mask); #if 0 inline void HW__EnableTwoSidedStencil(unsigned int b); inline void HW__SetStencilFrontFaceWriteMask(unsigned int WriteMask_); inline void HW__SetStencilBackFaceWriteMask(unsigned int WriteMask_); inline void HW__SetFrontFaceStencilFunc(unsigned int Func_, unsigned int Ref_, unsigned int Mask_); inline void HW__SetBackFaceStencilFunc( unsigned int Func_, unsigned int Ref_, unsigned int Mask_); inline void HW__SetFrontFaceStencilOp( unsigned int FailOp_, unsigned int ZFailOp_, unsigned int ZPassOp_); inline void HW__SetBackFaceStencilOp( unsigned int FailOp_, unsigned int ZFailOp_, unsigned int ZPassOp_); #endif #ifndef NUX_OPENGLES_20 inline void HW__EnableLineSmooth(unsigned int EnableLineSmooth); #endif inline void HW__SetLineWidth(unsigned int width, unsigned int HINT); inline void HW__SetColorMask(unsigned int bRed, unsigned int bGreen, unsigned int bBlue, unsigned int bAlpha); inline void HW__SetDepthMask(unsigned int bDepth); inline void HW__EnableScissor(unsigned int bScissor); #ifndef NUX_OPENGLES_20 inline void HW__SetPolygonMode(unsigned int FrontMode, unsigned int BackMode); #endif private: RenderStateMap render_state_changes_[GFXRS_MAX_RENDERSTATES]; RenderStateMap sampler_state_changes_[4][GFXSS_MAX_SAMPLERSTATES]; }; #define SET_RS_VALUE(a, b) (a).iValue = (b) #define RS_VALUE(a) (a).iValue //#define SET_RS_VALUE_FLOAT(a, b) (a).fValue = (b) //#define RS_VALUE_FLOAT(a, b) (a).fValue #ifndef NUX_OPENGLES_20 inline void GpuRenderStates::SetAlphaTest( bool EnableAlphaTest_, unsigned int AlphaTestFunc_, BYTE AlphaTestRef_) { if (EnableAlphaTest_) { if (!RS_VALUE(render_state_changes_[GFXRS_ALPHATESTENABLE])) { HW__EnableAlphaTest(TRUE); } if ((RS_VALUE(render_state_changes_[GFXRS_ALPHATESTFUNC]) != AlphaTestFunc_) || (RS_VALUE(render_state_changes_[GFXRS_ALPHATESTREF]) != AlphaTestRef_)) { HW__SetAlphaTestFunc(AlphaTestFunc_, AlphaTestRef_); } } else { HW__EnableAlphaTest(GL_FALSE); HW__SetAlphaTestFunc(AlphaTestFunc_, AlphaTestRef_); } } #endif inline void GpuRenderStates::SetBlend(bool AlphaBlendEnable_) { if (AlphaBlendEnable_) { if (!RS_VALUE(render_state_changes_[GFXRS_ALPHABLENDENABLE])) { HW__EnableAlphaBlend(TRUE); } } else { if (RS_VALUE(render_state_changes_[GFXRS_ALPHABLENDENABLE])) { HW__EnableAlphaBlend(GL_FALSE); } } } inline void GpuRenderStates::SetBlend(bool AlphaBlendEnable_, unsigned int SrcBlendFactor_, unsigned int DestBlendFactor_) { SetBlend(AlphaBlendEnable_); if ((RS_VALUE(render_state_changes_[GFXRS_SRCBLEND]) != SrcBlendFactor_) || (RS_VALUE(render_state_changes_[GFXRS_DESTBLEND]) != DestBlendFactor_)) { HW__SetSeparateAlphaBlendFactors( SrcBlendFactor_, DestBlendFactor_, SrcBlendFactor_, DestBlendFactor_); } } inline void GpuRenderStates::GetBlend(unsigned int& AlphaBlendEnable_, unsigned int& SrcBlendFactor_, unsigned int& DestBlendFactor_) { AlphaBlendEnable_ = RS_VALUE(render_state_changes_[GFXRS_ALPHABLENDENABLE]); SrcBlendFactor_ = RS_VALUE(render_state_changes_[GFXRS_SRCBLEND]); DestBlendFactor_ = RS_VALUE(render_state_changes_[GFXRS_DESTBLEND]); } inline void GpuRenderStates::SetSeparateBlend(bool EnableSeparateAlphaBlend, unsigned int SrcBlendFactor_, unsigned int DestBlendFactor_, unsigned int SrcBlendFactorAlpha_, unsigned int DestBlendFactorAlpha_) { SetBlend(EnableSeparateAlphaBlend); // if (EnableSeparateAlphaBlend) // { // if (!RS_VALUE(render_state_changes_[GFXRS_ALPHABLENDENABLE])) // { // HW__EnableAlphaBlend(TRUE); // } if ((RS_VALUE(render_state_changes_[GFXRS_SRCBLEND]) != SrcBlendFactor_) || (RS_VALUE(render_state_changes_[GFXRS_DESTBLEND]) != DestBlendFactor_) || (RS_VALUE(render_state_changes_[GFXRS_SRCBLENDALPHA]) != SrcBlendFactorAlpha_) || (RS_VALUE(render_state_changes_[GFXRS_DESTBLENDALPHA]) != DestBlendFactorAlpha_)) { HW__SetSeparateAlphaBlendFactors( SrcBlendFactor_, DestBlendFactor_, SrcBlendFactorAlpha_, DestBlendFactorAlpha_); } // } // else // { // HW__EnableAlphaBlend(GL_FALSE); // HW__SetSeparateAlphaBlendFactors( // SrcBlendFactor_, // DestBlendFactor_, // SrcBlendFactorAlpha_, // DestBlendFactorAlpha_); // } } inline void GpuRenderStates::SetPremultipliedBlend(PorterDuffOperator op) { static const struct { const unsigned int src_blend; const unsigned int dst_blend; } factor[13] = { { GL_ZERO, GL_ZERO }, // CLEAR { GL_ONE, GL_ZERO }, // SRC { GL_ZERO, GL_ONE }, // DST { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, // SRC_OVER { GL_ONE_MINUS_DST_ALPHA, GL_ONE }, // DST_OVER { GL_DST_ALPHA, GL_ZERO }, // SRC_IN { GL_ZERO, GL_SRC_ALPHA }, // DST_IN { GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, // SRC_OUT { GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, // DST_OUT { GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, // SRC_ATOP { GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, // DST_ATOP { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, // XOR { GL_ONE, GL_ONE } // PLUS }; if ((RS_VALUE(render_state_changes_[GFXRS_SRCBLEND]) != factor[op].src_blend) || (RS_VALUE(render_state_changes_[GFXRS_DESTBLEND]) != factor[op].dst_blend)) { HW__SetSeparateAlphaBlendFactors (factor[op].src_blend, factor[op].dst_blend, factor[op].src_blend, factor[op].dst_blend); } } inline void GpuRenderStates::SetBlendOp(unsigned int BlendOp) { if ((RS_VALUE(render_state_changes_[GFXRS_BLENDOP]) != BlendOp)) { HW__SetAlphaBlendOp(BlendOp, BlendOp); } } inline void GpuRenderStates::SetSeparateBlendOp( unsigned int BlendOpRGB_, unsigned int BlendOpAlpha_) { if ((RS_VALUE(render_state_changes_[GFXRS_BLENDOP]) != BlendOpRGB_) || (RS_VALUE(render_state_changes_[GFXRS_BLENDOPALPHA]) != BlendOpAlpha_)) { HW__SetAlphaBlendOp(BlendOpRGB_, BlendOpAlpha_); } } inline void GpuRenderStates::SetCullMode(bool EnableCullFace, unsigned int FrontFace_, unsigned int Cullface_) { if (EnableCullFace) { if (!RS_VALUE(render_state_changes_[GFXRS_CULLFACEENABLE])) { HW__EnableCulling(TRUE); } if (RS_VALUE(render_state_changes_[GFXRS_FRONTFACE]) != FrontFace_) { HW__SetFrontFace(FrontFace_); } if (RS_VALUE(render_state_changes_[GFXRS_CULLFACE]) != Cullface_) { HW__SetCullFace(Cullface_); } } else { HW__EnableCulling(FALSE); HW__SetFrontFace(FrontFace_); HW__SetCullFace(Cullface_); } } inline void GpuRenderStates::SetDepthTest(bool EnableDepthTest, unsigned int WriteEnable_, unsigned int DepthFunc_) { if (EnableDepthTest) { if (!RS_VALUE(render_state_changes_[GFXRS_ZTESTENABLE])) { HW__SetEnableDepthTest(TRUE); } if (RS_VALUE(render_state_changes_[GFXRS_ZWRITEENABLE]) != WriteEnable_) { HW__SetDepthMask(WriteEnable_); } if (RS_VALUE(render_state_changes_[GFXRS_ZFUNC]) != DepthFunc_) { HW__SetDepthFunc(DepthFunc_); } } else { HW__SetEnableDepthTest(FALSE); HW__SetDepthMask(WriteEnable_); HW__SetDepthFunc(DepthFunc_); } } inline void GpuRenderStates::SetDepthRange(float zNear, float zFar) { if ((RS_VALUE(render_state_changes_[GFXRS_ZNEAR]) != static_cast (zNear)) || (RS_VALUE(render_state_changes_[GFXRS_ZFAR]) != static_cast (zFar))) { HW__SetDepthRange(zNear, zFar); } } void GpuRenderStates::SetStencil(bool enable_stencil) { if (enable_stencil) { if (!RS_VALUE(render_state_changes_[GFXRS_STENCILENABLE])) { HW__EnableStencil(TRUE); } } else { HW__EnableStencil(FALSE); } } void GpuRenderStates::SetStencilFunc(unsigned int func, int ref, unsigned int mask) { if ( (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFUNC]) != func) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILREF]) != (unsigned int)ref) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILMASK]) != mask) ) { HW__SetStencilFunc(func, ref, mask); } } void GpuRenderStates::SetStencilOp(unsigned int stencil_fail, unsigned int stencil_pass_depth_fail, unsigned int stencil_pass_depth_pass) { if ( (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFAIL]) != stencil_fail) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZFAIL]) != stencil_pass_depth_fail) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZPASS]) != stencil_pass_depth_pass) ) { HW__SetStencilOp(stencil_fail, stencil_pass_depth_fail, stencil_pass_depth_pass); } } #if 0 inline void GpuRenderStates::SetStencilFrontFace( bool EnableStencil_, // GL_TRUE enable stencil test unsigned int Func_, unsigned int FailOp_, unsigned int ZFailOp_, unsigned int ZPassOp_, unsigned int Ref_, unsigned int Mask_) { if (EnableStencil_) { if (!RS_VALUE(render_state_changes_[GFXRS_STENCILENABLE])) { HW__EnableStencil(TRUE); } if ( (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFUNC]) != Func_) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILREF]) != Ref_) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILMASK]) != Mask_) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFAIL]) != FailOp_) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZFAIL]) != ZFailOp_) || (RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZPASS]) != ZPassOp_) ) { HW__SetFrontFaceStencilFunc(Func_, Ref_, Mask_); HW__SetFrontFaceStencilOp(FailOp_, ZFailOp_, ZPassOp_); } } else { HW__EnableStencil(FALSE); HW__SetFrontFaceStencilFunc(Func_, Ref_, Mask_); HW__SetFrontFaceStencilOp(FailOp_, ZFailOp_, ZPassOp_); } } inline void GpuRenderStates::SetStencilBackFace( bool EnableTwoSideStencil_, // GL_TRUE enable Two Sided Stencil test unsigned int Func_, unsigned int FailOp_, unsigned int ZFailOp_, unsigned int ZPassOp_, unsigned int Ref_, unsigned int Mask_) { if (EnableTwoSideStencil_) { if (!RS_VALUE(render_state_changes_[GFXRS_STENCILENABLE])) { HW__EnableStencil(TRUE); } if (!RS_VALUE(render_state_changes_[GFXRS_TWOSIDEDSTENCILENABLE])) { HW__EnableTwoSidedStencil(TRUE); } if ( (RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILFUNC]) != Func_) || (RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILREF]) != Ref_) || (RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILMASK]) != Mask_) || (RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILFAIL]) != FailOp_) || (RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILZFAIL]) != ZFailOp_) || (RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILZPASS]) != ZPassOp_) ) { HW__SetBackFaceStencilFunc(Func_, Ref_, Mask_); HW__SetBackFaceStencilOp(FailOp_, ZFailOp_, ZPassOp_); } } else { HW__EnableTwoSidedStencil(FALSE); HW__SetBackFaceStencilFunc(Func_, Ref_, Mask_); HW__SetBackFaceStencilOp(FailOp_, ZFailOp_, ZPassOp_); } } inline void GpuRenderStates::SetFrontFaceStencilWriteMask( unsigned int WriteMask_) { HW__SetStencilFrontFaceWriteMask(WriteMask_); } inline void GpuRenderStates::SetBackFaceStencilWriteMask( unsigned int WriteMask_) { HW__SetStencilBackFaceWriteMask(WriteMask_); } #endif inline void GpuRenderStates::EnableLineSmooth( bool EnableLineSmooth, unsigned int LineWidth, unsigned int Hint) { if (EnableLineSmooth) { if (!RS_VALUE(render_state_changes_[GFXRS_LINESMOOTHENABLE])) { #ifndef NUX_OPENGLES_20 HW__EnableLineSmooth(GL_TRUE); #endif } if ((RS_VALUE(render_state_changes_[GFXRS_LINEWIDTH]) != LineWidth) || (RS_VALUE(render_state_changes_[GFXRS_LINEHINT]) != Hint)) { HW__SetLineWidth(LineWidth, Hint); } } else { #ifndef NUX_OPENGLES_20 HW__EnableLineSmooth(GL_FALSE); #endif HW__SetLineWidth(LineWidth, Hint); } } inline void GpuRenderStates::SetColorMask( unsigned int bRed, unsigned int bGreen, unsigned int bBlue, unsigned int bAlpha) { if ((RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_R]) != bRed) || (RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_G]) != bGreen) || (RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_B]) != bBlue) || (RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_A]) != bAlpha)) { HW__SetColorMask(bRed, bGreen, bBlue, bAlpha); } } inline void GpuRenderStates::GetColorMask( unsigned int& bRed, unsigned int& bGreen, unsigned int& bBlue, unsigned int& bAlpha) { bRed = RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_R]); bGreen = RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_G]); bBlue = RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_B]); bAlpha = RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_A]); } inline void GpuRenderStates::SetDepthMask(unsigned int bDepth) { if ((RS_VALUE(render_state_changes_[GFXRS_ZWRITEENABLE]) != bDepth)) { HW__SetDepthMask(bDepth); } } inline void GpuRenderStates::EnableScissor(unsigned int bScissor) { if ((RS_VALUE(render_state_changes_[GFXRS_SCISSORTESTENABLE]) != bScissor)) { HW__EnableScissor(bScissor); } } #ifndef NUX_OPENGLES_20 inline void GpuRenderStates::SetPolygonMode(unsigned int FrontMode, unsigned int BackMode) { if ((RS_VALUE(render_state_changes_[GFXRS_FRONT_POLYGONMODE]) != FrontMode) || (RS_VALUE(render_state_changes_[GFXRS_BACK_POLYGONMODE]) != BackMode)) { HW__SetPolygonMode(FrontMode, BackMode); } } #else inline void GpuRenderStates::SetPolygonMode(unsigned int /*FrontMode*/, unsigned int /*BackMode*/) { } #endif #ifndef NUX_OPENGLES_20 inline void GpuRenderStates::HW__EnableAlphaTest(unsigned int b) { if (b) { CHECKGL(glEnable(GL_ALPHA_TEST)); } else { CHECKGL(glDisable(GL_ALPHA_TEST)); } SET_RS_VALUE(render_state_changes_[GFXRS_ALPHATESTENABLE], b ? GL_TRUE : GL_FALSE); } inline void GpuRenderStates::HW__SetAlphaTestFunc(unsigned int AlphaTestFunc_, BYTE AlphaTestRef_) { nuxAssertMsg( (AlphaTestFunc_ == GL_NEVER) || (AlphaTestFunc_ == GL_LESS) || (AlphaTestFunc_ == GL_EQUAL) || (AlphaTestFunc_ == GL_LEQUAL) || (AlphaTestFunc_ == GL_GREATER) || (AlphaTestFunc_ == GL_NOTEQUAL) || (AlphaTestFunc_ == GL_GEQUAL) || (AlphaTestFunc_ == GL_ALWAYS), "Error(HW__SetAlphaTestFunc): Invalid Alpha Test Function RenderState"); CHECKGL(glAlphaFunc(AlphaTestFunc_, (float) AlphaTestRef_ * (1.0f / 255.0f))); SET_RS_VALUE(render_state_changes_[GFXRS_ALPHATESTFUNC], AlphaTestFunc_); SET_RS_VALUE(render_state_changes_[GFXRS_ALPHATESTREF], AlphaTestRef_); } #endif inline void GpuRenderStates::HW__EnableAlphaBlend(unsigned int b) { if (b) { CHECKGL(glEnable(GL_BLEND)); } else { CHECKGL(glDisable(GL_BLEND)); } SET_RS_VALUE(render_state_changes_[GFXRS_ALPHABLENDENABLE], b ? GL_TRUE : GL_FALSE); } inline void GpuRenderStates::HW__SetSeparateAlphaBlendFactors( unsigned int SrcBlendFactor_, unsigned int DestBlendFactor_, unsigned int SrcFactorAlpha_, unsigned int DestFactorAlpha_) { nuxAssertMsg((SrcBlendFactor_ == GL_ZERO) || (SrcBlendFactor_ == GL_ONE) || (SrcBlendFactor_ == GL_SRC_COLOR) || (SrcBlendFactor_ == GL_ONE_MINUS_SRC_COLOR) || (SrcBlendFactor_ == GL_DST_COLOR) || (SrcBlendFactor_ == GL_ONE_MINUS_DST_COLOR) || (SrcBlendFactor_ == GL_SRC_ALPHA) || (SrcBlendFactor_ == GL_ONE_MINUS_SRC_ALPHA) || (SrcBlendFactor_ == GL_DST_ALPHA) || (SrcBlendFactor_ == GL_ONE_MINUS_DST_ALPHA) || (SrcBlendFactor_ == GL_CONSTANT_COLOR) || (SrcBlendFactor_ == GL_ONE_MINUS_CONSTANT_COLOR) || (SrcBlendFactor_ == GL_CONSTANT_ALPHA) || (SrcBlendFactor_ == GL_ONE_MINUS_CONSTANT_ALPHA) || (SrcBlendFactor_ == GL_SRC_ALPHA_SATURATE), "Error(HW__SetSeparateAlphaBlendFactors): Invalid Blend RenderState"); nuxAssertMsg((DestBlendFactor_ == GL_ZERO) || (DestBlendFactor_ == GL_ONE) || (DestBlendFactor_ == GL_SRC_COLOR) || (DestBlendFactor_ == GL_ONE_MINUS_SRC_COLOR) || (DestBlendFactor_ == GL_DST_COLOR) || (DestBlendFactor_ == GL_ONE_MINUS_DST_COLOR) || (DestBlendFactor_ == GL_SRC_ALPHA) || (DestBlendFactor_ == GL_ONE_MINUS_SRC_ALPHA) || (DestBlendFactor_ == GL_DST_ALPHA) || (DestBlendFactor_ == GL_ONE_MINUS_DST_ALPHA) || (DestBlendFactor_ == GL_CONSTANT_COLOR) || (DestBlendFactor_ == GL_ONE_MINUS_CONSTANT_COLOR) || (DestBlendFactor_ == GL_CONSTANT_ALPHA) || (DestBlendFactor_ == GL_ONE_MINUS_CONSTANT_ALPHA), "Error(HW__SetSeparateAlphaBlendFactors): Invalid Blend RenderState"); nuxAssertMsg((SrcFactorAlpha_ == GL_ZERO) || (SrcFactorAlpha_ == GL_ONE) || (SrcFactorAlpha_ == GL_SRC_COLOR) || (SrcFactorAlpha_ == GL_ONE_MINUS_SRC_COLOR) || (SrcFactorAlpha_ == GL_DST_COLOR) || (SrcFactorAlpha_ == GL_ONE_MINUS_DST_COLOR) || (SrcFactorAlpha_ == GL_SRC_ALPHA) || (SrcFactorAlpha_ == GL_ONE_MINUS_SRC_ALPHA) || (SrcFactorAlpha_ == GL_DST_ALPHA) || (SrcFactorAlpha_ == GL_ONE_MINUS_DST_ALPHA) || (SrcFactorAlpha_ == GL_CONSTANT_COLOR) || (SrcFactorAlpha_ == GL_ONE_MINUS_CONSTANT_COLOR) || (SrcFactorAlpha_ == GL_CONSTANT_ALPHA) || (SrcFactorAlpha_ == GL_ONE_MINUS_CONSTANT_ALPHA) || (SrcFactorAlpha_ == GL_SRC_ALPHA_SATURATE), "Error(HW__SetSeparateAlphaBlendFactors): Invalid Blend RenderState"); nuxAssertMsg((DestFactorAlpha_ == GL_ZERO) || (DestFactorAlpha_ == GL_ONE) || (DestFactorAlpha_ == GL_SRC_COLOR) || (DestFactorAlpha_ == GL_ONE_MINUS_SRC_COLOR) || (DestFactorAlpha_ == GL_DST_COLOR) || (DestFactorAlpha_ == GL_ONE_MINUS_DST_COLOR) || (DestFactorAlpha_ == GL_SRC_ALPHA) || (DestFactorAlpha_ == GL_ONE_MINUS_SRC_ALPHA) || (DestFactorAlpha_ == GL_DST_ALPHA) || (DestFactorAlpha_ == GL_ONE_MINUS_DST_ALPHA) || (DestFactorAlpha_ == GL_CONSTANT_COLOR) || (DestFactorAlpha_ == GL_ONE_MINUS_CONSTANT_COLOR) || (DestFactorAlpha_ == GL_CONSTANT_ALPHA) || (DestFactorAlpha_ == GL_ONE_MINUS_CONSTANT_ALPHA), "Error(HW__SetSeparateAlphaBlendFactors): Invalid Blend RenderState"); CHECKGL(glBlendFuncSeparate( SrcBlendFactor_, DestBlendFactor_, SrcFactorAlpha_, DestFactorAlpha_)); SET_RS_VALUE(render_state_changes_[GFXRS_SRCBLEND], SrcBlendFactor_); SET_RS_VALUE(render_state_changes_[GFXRS_DESTBLEND], DestBlendFactor_); SET_RS_VALUE(render_state_changes_[GFXRS_SRCBLENDALPHA], SrcFactorAlpha_); SET_RS_VALUE(render_state_changes_[GFXRS_DESTBLENDALPHA], DestFactorAlpha_); } inline void GpuRenderStates::HW__SetAlphaBlendOp( unsigned int BlendOpRGB_, unsigned int BlendOpAlpha_) { #ifdef NUX_OPENGLES_20 nuxAssertMsg( (BlendOpRGB_ == GL_FUNC_ADD) || (BlendOpRGB_ == GL_FUNC_SUBTRACT) || (BlendOpRGB_ == GL_FUNC_REVERSE_SUBTRACT), "Error(HW__SetAlphaBlendOp): Invalid Blend Equation RenderState"); nuxAssertMsg( (BlendOpAlpha_ == GL_FUNC_ADD) || (BlendOpAlpha_ == GL_FUNC_SUBTRACT) || (BlendOpAlpha_ == GL_FUNC_REVERSE_SUBTRACT), "Error(HW__SetAlphaBlendOp): Invalid Blend Equation RenderState"); CHECKGL(glBlendEquationSeparate(BlendOpRGB_, BlendOpAlpha_)); #else nuxAssertMsg( (BlendOpRGB_ == GL_FUNC_ADD) || (BlendOpRGB_ == GL_FUNC_SUBTRACT) || (BlendOpRGB_ == GL_FUNC_REVERSE_SUBTRACT) || (BlendOpRGB_ == GL_MIN) || (BlendOpRGB_ == GL_MAX), "Error(HW__SetAlphaBlendOp): Invalid Blend Equation RenderState"); nuxAssertMsg( (BlendOpAlpha_ == GL_FUNC_ADD) || (BlendOpAlpha_ == GL_FUNC_SUBTRACT) || (BlendOpAlpha_ == GL_FUNC_REVERSE_SUBTRACT) || (BlendOpAlpha_ == GL_MIN) || (BlendOpAlpha_ == GL_MAX), "Error(HW__SetAlphaBlendOp): Invalid Blend Equation RenderState"); if (gpu_info_->SupportOpenGL20()) { CHECKGL(glBlendEquationSeparate(BlendOpRGB_, BlendOpAlpha_)); } else if (gpu_info_->Support_EXT_Blend_Equation_Separate()) { CHECKGL(glBlendEquationSeparateEXT(BlendOpRGB_, BlendOpAlpha_)); } else { CHECKGL(glBlendEquation(BlendOpRGB_)); } #endif SET_RS_VALUE(render_state_changes_[GFXRS_BLENDOP], BlendOpRGB_); SET_RS_VALUE(render_state_changes_[GFXRS_BLENDOPALPHA], BlendOpAlpha_); } inline void GpuRenderStates::HW__EnableCulling(unsigned int b) { if (b) { CHECKGL(glEnable(GL_CULL_FACE)); } else { CHECKGL(glDisable(GL_CULL_FACE)); } SET_RS_VALUE(render_state_changes_[GFXRS_CULLFACEENABLE], b ? GL_TRUE : GL_FALSE); } inline void GpuRenderStates::HW__SetFrontFace(unsigned int FrontFace_) { nuxAssertMsg( (FrontFace_ == GL_CW) || (FrontFace_ == GL_CCW), "Error(HW__SetFrontFace): Invalid Front Face RenderState"); CHECKGL(glFrontFace(FrontFace_)); SET_RS_VALUE(render_state_changes_[GFXRS_FRONTFACE], FrontFace_); } inline void GpuRenderStates::HW__SetCullFace(unsigned int CullFace_) { nuxAssertMsg( (CullFace_ == GL_FRONT) || (CullFace_ == GL_BACK) || (CullFace_ == GL_FRONT_AND_BACK), "Error(HW__SetCullFace): Invalid Cull Face RenderState"); CHECKGL(glCullFace(CullFace_)); SET_RS_VALUE(render_state_changes_[GFXRS_CULLFACE], CullFace_); } inline void GpuRenderStates::HW__SetEnableDepthTest(unsigned int b) { if (b) { CHECKGL(glEnable(GL_DEPTH_TEST)); } else { CHECKGL(glDisable(GL_DEPTH_TEST)); } SET_RS_VALUE(render_state_changes_[GFXRS_ZTESTENABLE], b ? GL_TRUE : GL_FALSE); } inline void GpuRenderStates::HW__SetDepthRange(float zNear, float zFar) { CHECKGL(glDepthRange(zNear, zFar)); SET_RS_VALUE(render_state_changes_[GFXRS_ZNEAR], static_cast (Clamp(zNear, 0.0f, 1.0f))); SET_RS_VALUE(render_state_changes_[GFXRS_ZFAR], static_cast (Clamp(zFar, 0.0f, 1.0f))); } inline void GpuRenderStates::HW__SetDepthFunc(unsigned int Func) { nuxAssertMsg( (Func == GL_NEVER) || (Func == GL_LESS) || (Func == GL_EQUAL) || (Func == GL_LEQUAL) || (Func == GL_GREATER) || (Func == GL_NOTEQUAL) || (Func == GL_GEQUAL) || (Func == GL_ALWAYS), "Error(HW__SetDepthFunc): Invalid Depth Func RenderState"); CHECKGL(glDepthFunc(Func)); SET_RS_VALUE(render_state_changes_[GFXRS_ZFUNC], Func); } inline void GpuRenderStates::HW__EnableStencil(unsigned int b) { if (b) { CHECKGL(glEnable(GL_STENCIL_TEST)); } else { CHECKGL(glDisable(GL_STENCIL_TEST)); } SET_RS_VALUE(render_state_changes_[GFXRS_STENCILENABLE], b ? GL_TRUE : GL_FALSE); } inline void GpuRenderStates::HW__SetStencilFunc(unsigned int func, int ref, unsigned int mask) { nuxAssertMsg( (func == GL_NEVER) || (func == GL_LESS) || (func == GL_EQUAL) || (func == GL_LEQUAL) || (func == GL_GREATER) || (func == GL_NOTEQUAL) || (func == GL_GEQUAL) || (func == GL_ALWAYS), "Error(HW__SetFrontFaceStencilFunc): Invalid Stencil Function RenderState"); CHECKGL(glStencilFunc(func, ref, mask)); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFUNC], func); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILREF], ref); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILMASK], mask); } inline void GpuRenderStates::HW__SetStencilOp(unsigned int stencil_fail, unsigned int stencil_pass_depth_fail, unsigned int stencil_pass_depth_pass) { nuxAssertMsg( (stencil_fail == GL_KEEP) || (stencil_fail == GL_ZERO) || (stencil_fail == GL_REPLACE) || (stencil_fail == GL_INCR) || (stencil_fail == GL_INCR_WRAP) || (stencil_fail == GL_DECR) || (stencil_fail == GL_DECR_WRAP) || (stencil_fail == GL_INVERT), "Error(HW__SetFrontFaceStencilOp): Invalid FailOp RenderState"); nuxAssertMsg( (stencil_pass_depth_fail == GL_KEEP) || (stencil_pass_depth_fail == GL_ZERO) || (stencil_pass_depth_fail == GL_REPLACE) || (stencil_pass_depth_fail == GL_INCR) || (stencil_pass_depth_fail == GL_INCR_WRAP) || (stencil_pass_depth_fail == GL_DECR) || (stencil_pass_depth_fail == GL_DECR_WRAP) || (stencil_pass_depth_fail == GL_INVERT), "Error(HW__SetFrontFaceStencilOp): Invalid ZFailOp RenderState"); nuxAssertMsg( (stencil_pass_depth_pass == GL_KEEP) || (stencil_pass_depth_pass == GL_ZERO) || (stencil_pass_depth_pass == GL_REPLACE) || (stencil_pass_depth_pass == GL_INCR) || (stencil_pass_depth_pass == GL_INCR_WRAP) || (stencil_pass_depth_pass == GL_DECR) || (stencil_pass_depth_pass == GL_DECR_WRAP) || (stencil_pass_depth_pass == GL_INVERT), "Error(HW__SetFrontFaceStencilOp): Invalid ZPassOp RenderState"); CHECKGL(glStencilOp(stencil_fail, stencil_pass_depth_fail, stencil_pass_depth_pass)); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFAIL], stencil_fail); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZFAIL], stencil_pass_depth_fail); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZPASS], stencil_pass_depth_pass); } #if 0 inline void GpuRenderStates::HW__EnableTwoSidedStencil(unsigned int b) { if (b) { if (gpu_brand_ == GPU_BRAND_AMD) { CHECKGL(glEnable(GL_STENCIL_TEST)); } else { CHECKGL(glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)); } } else { if (gpu_brand_ == GPU_BRAND_AMD) { CHECKGL(glDisable(GL_STENCIL_TEST)); } else { CHECKGL(glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)); } } SET_RS_VALUE(render_state_changes_[GFXRS_TWOSIDEDSTENCILENABLE], b ? GL_TRUE : GL_FALSE); } inline void GpuRenderStates::HW__SetStencilFrontFaceWriteMask(unsigned int WriteMask_) { CHECKGL(glActiveStencilFaceEXT(GL_FRONT)); CHECKGL(glStencilMask(WriteMask_)); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILWRITEMASK], WriteMask_); } inline void GpuRenderStates::HW__SetStencilBackFaceWriteMask(unsigned int WriteMask_) { CHECKGL(glActiveStencilFaceEXT(GL_BACK)); CHECKGL(glStencilMask(WriteMask_)); SET_RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILWRITEMASK], WriteMask_); } inline void GpuRenderStates::HW__SetFrontFaceStencilFunc(unsigned int Func_, unsigned int Ref_, unsigned int Mask_) { nuxAssertMsg( (Func_ == GL_NEVER) || (Func_ == GL_LESS) || (Func_ == GL_EQUAL) || (Func_ == GL_LEQUAL) || (Func_ == GL_GREATER) || (Func_ == GL_NOTEQUAL) || (Func_ == GL_GEQUAL) || (Func_ == GL_ALWAYS), "Error(HW__SetFrontFaceStencilFunc): Invalid Stencil Function RenderState"); CHECKGL(glActiveStencilFaceEXT(GL_FRONT)); CHECKGL(glStencilFunc(Func_, Ref_, Mask_)); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFUNC], Func_); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILREF], Ref_); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILMASK], Mask_); } inline void GpuRenderStates::HW__SetBackFaceStencilFunc( unsigned int Func_, unsigned int Ref_, unsigned int Mask_) { nuxAssertMsg( (Func_ == GL_NEVER) || (Func_ == GL_LESS) || (Func_ == GL_EQUAL) || (Func_ == GL_LEQUAL) || (Func_ == GL_GREATER) || (Func_ == GL_NOTEQUAL) || (Func_ == GL_GEQUAL) || (Func_ == GL_ALWAYS), "Error(HW__SetBackFaceStencilFunc): Invalid Stencil Function RenderState"); if (gpu_brand_ == GPU_BRAND_AMD) { CHECKGL(glStencilFuncSeparateATI(Func_/*Front function*/, Func_/*Back function*/, Ref_, Mask_)); // incorrect } else { CHECKGL(glActiveStencilFaceEXT(GL_BACK)); CHECKGL(glStencilFunc(Func_, Ref_, Mask_)); } SET_RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILFUNC], Func_); SET_RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILREF], Ref_); SET_RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILMASK], Mask_); } inline void GpuRenderStates::HW__SetFrontFaceStencilOp( unsigned int FailOp_, unsigned int ZFailOp_, unsigned int ZPassOp_) { nuxAssertMsg( (FailOp_ == GL_KEEP) || (FailOp_ == GL_ZERO) || (FailOp_ == GL_REPLACE) || (FailOp_ == GL_INCR) || (FailOp_ == GL_INCR_WRAP) || (FailOp_ == GL_DECR) || (FailOp_ == GL_DECR_WRAP) || (FailOp_ == GL_INVERT), "Error(HW__SetFrontFaceStencilOp): Invalid FailOp RenderState"); nuxAssertMsg( (ZFailOp_ == GL_KEEP) || (ZFailOp_ == GL_ZERO) || (ZFailOp_ == GL_REPLACE) || (ZFailOp_ == GL_INCR) || (ZFailOp_ == GL_INCR_WRAP) || (ZFailOp_ == GL_DECR) || (ZFailOp_ == GL_DECR_WRAP) || (ZFailOp_ == GL_INVERT), "Error(HW__SetFrontFaceStencilOp): Invalid ZFailOp RenderState"); nuxAssertMsg( (ZPassOp_ == GL_KEEP) || (ZPassOp_ == GL_ZERO) || (ZPassOp_ == GL_REPLACE) || (ZPassOp_ == GL_INCR) || (ZPassOp_ == GL_INCR_WRAP) || (ZPassOp_ == GL_DECR) || (ZPassOp_ == GL_DECR_WRAP) || (ZPassOp_ == GL_INVERT), "Error(HW__SetFrontFaceStencilOp): Invalid ZPassOp RenderState"); if (gpu_brand_ == GPU_BRAND_AMD) { CHECKGL(glStencilOpSeparateATI(GL_FRONT, FailOp_, ZFailOp_, ZPassOp_)); } else { CHECKGL(glActiveStencilFaceEXT(GL_FRONT)); CHECKGL(glStencilOp(FailOp_, ZFailOp_, ZPassOp_)); } SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILFAIL], FailOp_); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZFAIL], ZFailOp_); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_STENCILZPASS], ZPassOp_); } inline void GpuRenderStates::HW__SetBackFaceStencilOp( unsigned int FailOp_, unsigned int ZFailOp_, unsigned int ZPassOp_) { nuxAssertMsg( (FailOp_ == GL_KEEP) || (FailOp_ == GL_ZERO) || (FailOp_ == GL_REPLACE) || (FailOp_ == GL_INCR) || (FailOp_ == GL_INCR_WRAP) || (FailOp_ == GL_DECR) || (FailOp_ == GL_DECR_WRAP) || (FailOp_ == GL_INVERT), "Error(HW__SetBackFaceStencilOp): Invalid FailOp RenderState"); nuxAssertMsg( (ZFailOp_ == GL_KEEP) || (ZFailOp_ == GL_ZERO) || (ZFailOp_ == GL_REPLACE) || (ZFailOp_ == GL_INCR) || (ZFailOp_ == GL_INCR_WRAP) || (ZFailOp_ == GL_DECR) || (ZFailOp_ == GL_DECR_WRAP) || (ZFailOp_ == GL_INVERT), "Error(HW__SetBackFaceStencilOp): Invalid ZFailOp RenderState"); nuxAssertMsg( (ZPassOp_ == GL_KEEP) || (ZPassOp_ == GL_ZERO) || (ZPassOp_ == GL_REPLACE) || (ZPassOp_ == GL_INCR) || (ZPassOp_ == GL_INCR_WRAP) || (ZPassOp_ == GL_DECR) || (ZPassOp_ == GL_DECR_WRAP) || (ZPassOp_ == GL_INVERT), "Error(HW__SetBackFaceStencilOp): Invalid ZPassOp RenderState"); if (gpu_brand_ == GPU_BRAND_AMD) { CHECKGL(glStencilOpSeparateATI(GL_BACK, FailOp_, ZFailOp_, ZPassOp_)); } else { CHECKGL(glActiveStencilFaceEXT(GL_BACK)); CHECKGL(glStencilOp(FailOp_, ZFailOp_, ZPassOp_)); } SET_RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILFAIL], FailOp_); SET_RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILZFAIL], ZFailOp_); SET_RS_VALUE(render_state_changes_[GFXRS_BACK_STENCILZPASS], ZPassOp_); } #endif #ifndef NUX_OPENGLES_20 inline void GpuRenderStates::HW__EnableLineSmooth(unsigned int EnableLineSmooth) { if (EnableLineSmooth) { CHECKGL(glEnable(GL_LINE_SMOOTH)); } else { CHECKGL(glDisable(GL_LINE_SMOOTH)); } SET_RS_VALUE(render_state_changes_[GFXRS_LINESMOOTHENABLE], EnableLineSmooth ? GL_TRUE : GL_FALSE); } #endif inline void GpuRenderStates::HW__SetLineWidth(unsigned int width, unsigned int Hint) { nuxAssertMsg( (Hint == GL_NICEST) || (Hint == GL_FASTEST) || (Hint == GL_DONT_CARE), "Error(HW__SetLineWidth): Invalid Line Hint RenderState"); CHECKGL(glLineWidth(width)); SET_RS_VALUE(render_state_changes_[GFXRS_LINEWIDTH], width); #ifndef NUX_OPENGLES_20 CHECKGL(glHint(GL_LINE_SMOOTH_HINT, Hint)); SET_RS_VALUE(render_state_changes_[GFXRS_LINEHINT], Hint); #endif } inline void GpuRenderStates::HW__SetColorMask( unsigned int bRed, unsigned int bGreen, unsigned int bBlue, unsigned int bAlpha) { CHECKGL(glColorMask(bRed, bGreen, bBlue, bAlpha)); SET_RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_R], bRed); SET_RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_G], bGreen); SET_RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_B], bBlue); SET_RS_VALUE(render_state_changes_[GFXRS_COLORWRITEENABLE_A], bAlpha); } inline void GpuRenderStates::HW__SetDepthMask(unsigned int bDepth) { CHECKGL(glDepthMask(bDepth)); SET_RS_VALUE(render_state_changes_[GFXRS_ZWRITEENABLE], bDepth); } inline void GpuRenderStates::HW__EnableScissor(unsigned int bScissor) { if (bScissor) { CHECKGL(glEnable(GL_SCISSOR_TEST)); } else { CHECKGL(glDisable(GL_SCISSOR_TEST)); } SET_RS_VALUE(render_state_changes_[GFXRS_SCISSORTESTENABLE], bScissor ? GL_TRUE : GL_FALSE); } #ifndef NUX_OPENGLES_20 inline void GpuRenderStates::HW__SetPolygonMode(unsigned int FrontMode, unsigned int BackMode) { nuxAssertMsg( (FrontMode == GL_FILL) || (FrontMode == GL_LINE) || (FrontMode == GL_POINT), "Error(HW__SetPolygonMode): Invalid Point Hint RenderState"); nuxAssertMsg( (BackMode == GL_FILL) || (BackMode == GL_LINE) || (BackMode == GL_POINT), "Error(HW__SetPolygonMode): Invalid Point Hint RenderState"); CHECKGL(glPolygonMode(GL_FRONT, FrontMode)); CHECKGL(glPolygonMode(GL_BACK, BackMode)); SET_RS_VALUE(render_state_changes_[GFXRS_FRONT_POLYGONMODE], FrontMode); SET_RS_VALUE(render_state_changes_[GFXRS_BACK_POLYGONMODE], BackMode); } #endif #undef SET_RS_VALUE #undef RS_VALUE //#undef SET_RS_VALUE_FLOAT //#undef RS_VALUE_FLOAT } #endif // GLRENDERSTATES_H nux-4.0.6+14.04.20140409/NuxGraphics/GLShader.h0000644000015301777760000000174012321344237020774 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLSHADER_H #define GLSHADER_H #include "NuxCore/NuxCore.h" #include "NuxCore/Error.h" #include "NuxCore/OutputDevice.h" #include "GLResource.h" namespace nux { } #endif //GLSHADER_H nux-4.0.6+14.04.20140409/NuxGraphics/GestureEvent.cpp0000644000015301777760000000402212321344237022312 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #include "GestureEvent.h" #include "NuxCore/Logger.h" using namespace nux; DECLARE_LOGGER(logger, "nux.gestureevent"); GestureEvent::GestureEvent() { // that's how many fingers you have on your hand (duh). // Can't have gestures with more than that many touch points. touches_.reserve(5); } void GestureEvent::Accept() { GeisStatus status; status = geis_gesture_accept(geis_, geis_group_, gesture_id_); if (status != GEIS_STATUS_SUCCESS) { LOG_WARNING(logger) << "Failed to accept gesture with id " << gesture_id_; } } void GestureEvent::Reject() { GeisStatus status; status = geis_gesture_reject(geis_, geis_group_, gesture_id_); if (status != GEIS_STATUS_SUCCESS) { LOG_WARNING(logger) << "Failed to reject gesture with id " << gesture_id_; } } void GestureEvent::Reset() { Event::Reset(); gesture_id_ = -1; gesture_classes_ = 0; timestamp_ = -1; focus_.x = focus_.y = 0.0f; delta_.x = delta_.y = 0.0f; angle_ = 0.0f; angle_delta_ = 0.0f; angular_velocity_ = 0.0f; tap_duration_ = -1; velocity_.x = velocity_.y = 0.0f; radius_ = 0.0f; radius_delta_ = 0.0f; radial_velocity_ = 0.0f; is_construction_finished_ = false; touches_.clear(); geis_ = nullptr; geis_group_ = nullptr; } nux-4.0.6+14.04.20140409/NuxGraphics/GdkGraphics.h0000644000015301777760000000242212321344237021527 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUXIMAGE_GDKGRAPHICS_H #define NUXIMAGE_GDKGRAPHICS_H #include namespace nux { class NBitmapData; class GdkGraphics { public: GdkGraphics(); explicit GdkGraphics(const char* filename); // Takes ownership of the GdkPixbuf. explicit GdkGraphics(GdkPixbuf* pixbuf); ~GdkGraphics(); bool LoadImage(const char* filename); NBitmapData* GetBitmap() const; private: GdkPixbuf* pixbuf_; }; } #endif // NUXIMAGE_GDKGRAPHICS_H nux-4.0.6+14.04.20140409/NuxGraphics/Glew/0000755000015301777760000000000012321344711020063 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxGraphics/GLTextureStates.h0000644000015301777760000001435412321344237022417 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLTEXTURESTATES_H #define GLTEXTURESTATES_H #include "NuxCore/NuxCore.h" namespace nux { enum { GFXTS_ADDRESSU, // GL_REPEAT GFXTS_ADDRESSV, // GL_REPEAT GFXTS_ADDRESSW, // GL_REPEAT GFXTS_MINFILTER, // GL_NEAREST GFXTS_MAGFILTER, // GL_NEAREST GFXTS_MIPFILTER, // GL_NEAREST GFXTS_MIP_BASE_LEVEL, // 0 GFXTS_MIP_MAX_LEVEL, // 1000 GFXTS_MIN_LOD, // -1000 GFXTS_MAX_LOD, // +1000 GFXTS_BORDERCOLOR, // 0x00000000 GFXTS_MAX_TEXTURESTATES, }; struct TextureStateMap { bool Checked; unsigned int State; unsigned int Dirty; unsigned int iValue; float fValue; TextureStateMap() { Dirty = true; } }; class GpuDevice; class GLTextureStates { public: GLTextureStates(GLuint Type = GL_TEXTURE_2D); ~GLTextureStates(); void ResetDefault(); void ResetStateChangeToDefault(); void SetRenderStates(); void SetType(GLuint Type); void SetFiltering( unsigned int MIN = GL_NEAREST, unsigned int MAG = GL_NEAREST/*, unsigned int MIP = GL_NEAREST*/); void SetWrap( unsigned int U = GL_REPEAT, unsigned int V = GL_REPEAT, unsigned int W = GL_REPEAT); void SetLOD( float MinLod = -1000.0f, float MaxLod = +1000.0f); void SetMipLevel( unsigned int MinMip = 0, unsigned int MaxMip = 1000); void SetBorderColor( float R, float G, float B, float A); private: void HW_SetFiltering(); void HW_SetWrap(); void HW_SetLOD(); void HW_SetMipLevel(); void HW_SetBorderColor(); GLuint m_Type; TextureStateMap m_TextureStateChanges[GFXTS_MAX_TEXTURESTATES]; friend class GpuDevice; }; // #define SET_TS_VALUE(a, b) (a).iValue = (b); (a).Dirty = true; // #define TS_VALUE(a, b) (a).iValue // // #define SET_TS_VALUE_FLOAT(a, b) (a).fValue = (b); (a).Dirty = true; // #define TS_VALUE_FLOAT(a, b) (a).fValue // // // inline void GLTextureStates::SetFiltering( // unsigned int MIN, // unsigned int MAG // /*,unsigned int MIP*/) // { // nuxAssertMsg( // (MIN == GL_LINEAR) || // (MIN == GL_NEAREST) || // (MIN == GL_NEAREST_MIPMAP_NEAREST) || // (MIN == GL_LINEAR_MIPMAP_NEAREST) || // (MIN == GL_NEAREST_MIPMAP_LINEAR) || // (MIN == GL_LINEAR_MIPMAP_LINEAR), // "Error[GLTextureStates::SetFiltering]: Invalid Min. Filter State"); // // nuxAssertMsg( // (MAG == GL_LINEAR) || // (MAG == GL_NEAREST), // "Error[GLTextureStates::SetFiltering]: Invalid Mag. Filter State"); // // // nuxAssertMsg( // // (MIP == GL_LINEAR) || // // (MIP == GL_NEAREST), // // "Error[GLTextureStates::SetFiltering]: Invalid Mipmap Filter State"); // // SET_TS_VALUE(m_TextureStateChanges[GFXTS_MINFILTER], MIN); // SET_TS_VALUE(m_TextureStateChanges[GFXTS_MAGFILTER], MAG); // //SET_TS_VALUE(m_TextureStateChanges[GFXTS_MIPFILTER], MIP); // } // // inline void GLTextureStates::SetWrap( // unsigned int U, // unsigned int V, // unsigned int W) // { // nuxAssertMsg( // (U == GL_CLAMP) || // (U == GL_CLAMP_TO_EDGE) || // (U == GL_REPEAT), // "Error[GLTextureStates::SetWrap]: Invalid U Wrap State"); // nuxAssertMsg( // (V == GL_CLAMP) || // (V == GL_CLAMP_TO_EDGE) || // (V == GL_REPEAT), // "Error[GLTextureStates::SetWrap]: Invalid V Wrap State"); // nuxAssertMsg( // (W == GL_CLAMP) || // (W == GL_CLAMP_TO_EDGE) || // (W == GL_REPEAT), // "Error[GLTextureStates::SetWrap]: Invalid W Wrap State"); // // SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSU], U); // SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSV], V); // SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSW], W); // // // } // // inline void GLTextureStates::SetLOD(float MinLod, // float MaxLod) // { // SET_TS_VALUE_FLOAT(m_TextureStateChanges[GFXTS_MIN_LOD], MinLod); // SET_TS_VALUE_FLOAT(m_TextureStateChanges[GFXTS_MAX_LOD], MaxLod); // } // // inline void GLTextureStates::SetMipLevel( // unsigned int MinMip, // unsigned int MaxMip) // { // SET_TS_VALUE(m_TextureStateChanges[GFXTS_MIP_BASE_LEVEL], MinMip); // SET_TS_VALUE(m_TextureStateChanges[GFXTS_MIP_MAX_LEVEL], MaxMip); // } // // inline void GLTextureStates::SetBorderColor( // float R, // float G, // float B, // float A) // { // unsigned int r, g, b, a; // r = 255 * Clamp(R, 0.0f, 1.0f); // g = 255 * Clamp(G, 0.0f, 1.0f); // b = 255 * Clamp(B, 0.0f, 1.0f); // a = 255 * Clamp(A, 0.0f, 1.0f); // unsigned int color = (unsigned int) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)); // // SET_TS_VALUE(m_TextureStateChanges[GFXTS_BORDERCOLOR], color); // } // // #undef SET_TS_VALUE // #undef TS_VALUE // // #undef SET_TS_VALUE_FLOAT // #undef TS_VALUE_FLOAT } #endif // GLTEXTURESTATES_H nux-4.0.6+14.04.20140409/NuxGraphics/GdiImageLoader.cpp0000644000015301777760000001062612321344237022476 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "GdiImageLoader.h" namespace nux { NBitmapData* GdiLoadImageFile(const TCHAR* filename) { ULONG_PTR token; Gdiplus::GdiplusStartupInput input; Gdiplus::GdiplusStartup(&token, &input, NULL); Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(TCHAR_TO_UNICHAR(filename)); if (bitmap == 0 || (bitmap->GetType() == Gdiplus::ImageTypeUnknown) || (bitmap->GetWidth() == 0) || (bitmap->GetHeight() == 0)) { Gdiplus::GdiplusShutdown(token); return 0; } Gdiplus::BitmapData* bitmap_data = new Gdiplus::BitmapData; if (bitmap_data == 0) { delete bitmap; Gdiplus::GdiplusShutdown(token); return 0; } Gdiplus::PixelFormat pixel_format = bitmap->GetPixelFormat(); int channels = 4; BitmapFormat bitmap_format = BITFMT_UNKNOWN; if (pixel_format == PixelFormat24bppRGB) { bitmap_format = BITFMT_B8G8R8; channels = 3; } else if ((pixel_format == PixelFormat32bppARGB) || (pixel_format == PixelFormat32bppPARGB) || (pixel_format == PixelFormat32bppRGB)) { if (pixel_format == PixelFormat32bppARGB) pixel_format = PixelFormat32bppPARGB; // request conversion to pre-multiplied RGBA bitmap_format = BITFMT_B8G8R8A8; channels = 4; } else if ((pixel_format == PixelFormat16bppARGB1555) || (pixel_format == PixelFormat16bppGrayScale) || (pixel_format == PixelFormat16bppRGB555) || (pixel_format == PixelFormat16bppRGB565)) { pixel_format = PixelFormat24bppRGB; // request conversion to RGB bitmap_format = BITFMT_B8G8R8; channels = 3; } else if ((pixel_format == PixelFormat1bppIndexed) || (pixel_format == PixelFormat4bppIndexed) || (pixel_format == PixelFormat8bppIndexed)) { pixel_format = PixelFormat32bppARGB; // request conversion to RGBA bitmap_format = BITFMT_B8G8R8A8; channels = 4; } else if (pixel_format == PixelFormat48bppRGB) { pixel_format = PixelFormat24bppRGB; // request conversion to RGBA bitmap_format = BITFMT_B8G8R8; channels = 3; } else if ((pixel_format == PixelFormat64bppARGB) || (pixel_format == PixelFormat64bppPARGB)) { pixel_format = PixelFormat32bppARGB; // request conversion to RGBA bitmap_format = BITFMT_B8G8R8A8; channels = 4; } Gdiplus::Rect rect(0, 0, bitmap->GetWidth(), bitmap->GetHeight()); Gdiplus::Status status = bitmap->LockBits(&rect, Gdiplus::ImageLockModeRead, pixel_format, bitmap_data); if (status != Gdiplus::Ok) { delete bitmap_data; delete bitmap; Gdiplus::GdiplusShutdown(token); return 0; } unsigned int width = bitmap->GetWidth(); unsigned int height = bitmap->GetHeight(); NTextureData *Texture = NULL; Texture = new NTextureData(bitmap_format, width, height, 1); if (Texture == 0) { bitmap->UnlockBits(bitmap_data); delete bitmap_data; delete bitmap; Gdiplus::GdiplusShutdown(token); return 0; } ImageSurface &image_surface = Texture->GetSurface(0); unsigned char* dest = image_surface.GetPtrRawData(); int dest_pitch = image_surface.GetPitch(); unsigned char* dst = dest; unsigned char *src = (unsigned char*) bitmap_data->Scan0; unsigned int src_pitch = bitmap_data->Stride; for (unsigned int i = 0; i < height; i++) { Memcpy(dst, src + i*src_pitch, width*channels); dst += dest_pitch; } bitmap->UnlockBits(bitmap_data); delete bitmap_data; delete bitmap; Gdiplus::GdiplusShutdown(token); return Texture; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLIndexBuffer.cpp0000644000015301777760000000755612321344237023270 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLIndexBuffer.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLIndexBuffer); IOpenGLIndexBuffer::IOpenGLIndexBuffer(unsigned int Length, VBO_USAGE Usage, INDEX_FORMAT Format, NUX_FILE_LINE_DECL) : IOpenGLResource(RTINDEXBUFFER, NUX_FILE_LINE_PARAM) , _Length(Length) , _Format(Format) , _Usage(Usage) , _MemMap(0) , _OffsetToLock(0) , _SizeToLock(0) { CHECKGL(glGenBuffersARB(1, &_OpenGLID)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _OpenGLID)); CHECKGL(glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _Length, NULL, Usage)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); GRunTimeStats.Register(this); } IOpenGLIndexBuffer::~IOpenGLIndexBuffer() { CHECKGL(glDeleteBuffersARB(1, &_OpenGLID)); _OpenGLID = 0; GRunTimeStats.UnRegister(this); } int IOpenGLIndexBuffer::Lock( unsigned int OffsetToLock, unsigned int SizeToLock, void **ppbData) { nuxAssert(SizeToLock <= _Length); nuxAssert(OffsetToLock + SizeToLock <= _Length); if (SizeToLock == 0) { if (OffsetToLock == 0) { // lock the entire buffer SizeToLock = _Length; } else return OGL_INVALID_CALL; } // If _MemMap, _OffsetToLock and _SizeToLock are not equal to zero, then we have already mapped the buffer // Unlock it before locking again. nuxAssert(_MemMap == 0); nuxAssert(_OffsetToLock == 0); nuxAssert(_SizeToLock == 0); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _OpenGLID)); // Map the Entire buffer into system memory #ifndef NUX_OPENGLES_20 _MemMap = (BYTE *) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); // todo: use Format instead of GL_WRITE_ONLY_ARB CHECKGL_MSG(glMapBufferARB); *ppbData = (void *) (_MemMap + OffsetToLock); #else _MemMap = new BYTE[SizeToLock]; *ppbData = _MemMap; #endif _OffsetToLock = OffsetToLock; _SizeToLock = SizeToLock; CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); return OGL_OK; } int IOpenGLIndexBuffer::Unlock() { nuxAssert(_MemMap != 0); nuxAssert(_SizeToLock != 0); // No need to bind CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _OpenGLID)); #ifndef NUX_OPENGLES_20 CHECKGL(glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB)); #else CHECKGL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER_ARB, _OffsetToLock, _SizeToLock, _MemMap)); delete [] _MemMap; #endif CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); _MemMap = 0; _OffsetToLock = 0; _SizeToLock = 0; return OGL_OK; } int IOpenGLIndexBuffer::GetStride() { if (_Format == INDEX_FORMAT_USHORT) { return 2; } else if (_Format == INDEX_FORMAT_UINT) { return 4; } else return 0; } void IOpenGLIndexBuffer::BindIndexBuffer() { CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _OpenGLID)); } unsigned int IOpenGLIndexBuffer::GetSize() { return _Length; } } nux-4.0.6+14.04.20140409/NuxGraphics/GdiImageLoader.h0000644000015301777760000000212112321344237022132 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GDIIMAGELOADER_H #define GDIIMAGELOADER_H #ifdef NUX_OS_WINDOWS #include // Needed for GDI+ #include #include #include "ImageSurface.h" #endif namespace nux { NBitmapData* GdiLoadImageFile(const TCHAR* filename); } #endif // GDIIMAGELOADER_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVertexDeclaration.cpp0000644000015301777760000001035212321344237024476 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GLDeviceObjects.h" #include "IOpenGLVertexDeclaration.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLVertexDeclaration); IOpenGLVertexDeclaration::IOpenGLVertexDeclaration(const VERTEXELEMENT* pVertexElements) : IOpenGLResource(RTVERTEXDECLARATION) { for (int i = 0; i < 8; i++) { _stride[i] = 0; vertex_buffer_array.push_back(ObjectPtr(NULL)); } int index = 0; _declarations_array.clear(); while (pVertexElements[index].Stream != 0xFF) { VERTEXELEMENT VtxElement = pVertexElements[index]; _declarations_array.push_back(VtxElement); _stride[VtxElement.Stream] += GetVertexElementSize(VtxElement); ++index; } // Add in the invalid vertex element stream at the end. //VERTEXELEMENT *pVtxElement = new VERTEXELEMENT; //pVtxElement->Stream = 0xFF; // invalid stream _declarations_array.push_back(DECL_END); }; IOpenGLVertexDeclaration::~IOpenGLVertexDeclaration() { // IOpenGLVertexDeclaration is an abstraction. Is does not have an opengl id. _OpenGLID = 0; } // int IOpenGLVertexDeclaration::GetDeclaration( // VERTEXELEMENT& pDecl, // unsigned int *pNumElements) // { // *pNumElements = (unsigned int) _declarations_array.size(); // pDecl = _declarations_array[0]; // // return 1; // } VERTEXELEMENT IOpenGLVertexDeclaration::GetUsage(ATTRIB_USAGE_DECL /* usage */) { VERTEXELEMENT vtxelt; return vtxelt; // vtxelt.Stream = 0xFF; // invalid stream; // // for (unsigned int i = 0; _declarations_array.size(); i++) // { // if (_declarations_array[i].Usage == usage) // { // vtxelt = _declarations_array[i]; // return vtxelt; // } // } // // return vtxelt; } // This is a simple check to comply with the documentation of DrawPrimitiveUP in DirectX bool IOpenGLVertexDeclaration::IsUsingMoreThanStreamZero() { for (unsigned int i = 0; i < _declarations_array.size(); i++) { if (_declarations_array[i].Stream != 0) { return true; } } return false; } int IOpenGLVertexDeclaration::GetStride(int vertex_input_number) { NUX_RETURN_VALUE_IF_FALSE(vertex_input_number >= 0, 0); NUX_RETURN_VALUE_IF_FALSE(vertex_input_number < 8, 0); return _stride[vertex_input_number]; } void IOpenGLVertexDeclaration::SetVertexBuffer(int input_index, ObjectPtr vertex_buffer) { NUX_RETURN_IF_FALSE(input_index >= 0); NUX_RETURN_IF_FALSE(input_index < 8); vertex_buffer_array[input_index] = vertex_buffer; } ObjectPtr IOpenGLVertexDeclaration::GetVertexBuffer(int input_index) { NUX_RETURN_VALUE_IF_FALSE(input_index >= 0, ObjectPtr(NULL)); NUX_RETURN_VALUE_IF_FALSE(input_index < 8, ObjectPtr(NULL)); return vertex_buffer_array[input_index]; } void IOpenGLVertexDeclaration::SetVertexShaderAttributeLocation(int input_index, int shader_attribute_location) { NUX_RETURN_IF_FALSE(input_index >= 0); NUX_RETURN_IF_FALSE(input_index < 8); shader_attribute_location_array[input_index] = shader_attribute_location; } int IOpenGLVertexDeclaration::GetVertexShaderAttributeLocation(int input_index) { NUX_RETURN_VALUE_IF_FALSE(input_index >= 0, -1); NUX_RETURN_VALUE_IF_FALSE(input_index < 8, -1); return shader_attribute_location_array[input_index]; } } nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipeTextureBlend.cpp0000644000015301777760000006721212321344237024765 0ustar pbusernogroup00000000000000/* * Copyright 2010-2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * Robert Carr */ #include "NuxCore/NuxCore.h" #include "ImageSurface.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GraphicsEngine.h" #include "RenderingPipeTextureBlendShaderSource.h" namespace nux { std::string GraphicsEngine::GetBlendModeBlendFunc(LayerBlendMode layer_blend_mode) { switch (layer_blend_mode) { case LAYER_BLEND_MODE_NORMAL: return BlendNormalShader; case LAYER_BLEND_MODE_DARKEN: return BlendDarkenShader; case LAYER_BLEND_MODE_MULTIPLY: return BlendMultiplyShader; case LAYER_BLEND_MODE_COLOR_BURN: return BlendColorBurnShader; case LAYER_BLEND_MODE_LINEAR_BURN: return BlendLinearBurnShader; case LAYER_BLEND_MODE_LIGHTEN: return BlendLightenShader; case LAYER_BLEND_MODE_SCREEN: return BlendScreenShader; case LAYER_BLEND_MODE_COLOR_DODGE: return BlendColorDodgeShader; case LAYER_BLEND_MODE_LINEAR_DODGE: return BlendLinearDodgeShader; case LAYER_BLEND_MODE_OVERLAY: return BlendOverlayShader; case LAYER_BLEND_MODE_SOFT_LIGHT: return BlendSoftLightShader; case LAYER_BLEND_MODE_HARD_LIGHT: return BlendHardLightShader; case LAYER_BLEND_MODE_VIVID_LIGHT: return BlendVividLightShader; case LAYER_BLEND_MODE_LINEAR_LIGHT: return BlendLinearLightShader; case LAYER_BLEND_MODE_PIN_LIGHT: return BlendPinLightShader; case LAYER_BLEND_MODE_HARD_MIX: return BlendHardMixShader; case LAYER_BLEND_MODE_DIFFERENCE: return BlendDifferenceShader; case LAYER_BLEND_MODE_EXCLUSION: return BlendExclusionShader; case LAYER_BLEND_MODE_SUBTRACT: return BlendSubstractShader; case LAYER_BLEND_MODE_AVERAGE: return BlendAverageShader; case LAYER_BLEND_MODE_ADD: return BlendAddShader; case LAYER_BLEND_MODE_NEGATION: return BlendNegationShader; case LAYER_BLEND_MODE_REFLECT: return BlendReflectShader; case LAYER_BLEND_MODE_GLOW: return BlendGlowShader; case LAYER_BLEND_MODE_PHOENIX: return BlendPhoenixShader; case LAYER_BLEND_MODE_LAST: return BlendNormalShader; default: return BlendNormalShader; } } std::string GraphicsEngine::GetBlendModeString(LayerBlendMode layer_blend_mode) { switch (layer_blend_mode) { case LAYER_BLEND_MODE_NORMAL: return std::string("BlendNormal"); case LAYER_BLEND_MODE_DARKEN: return std::string("BlendDarken"); case LAYER_BLEND_MODE_MULTIPLY: return std::string("BlendMultiply"); case LAYER_BLEND_MODE_COLOR_BURN: return std::string("BlendColorBurn"); case LAYER_BLEND_MODE_LINEAR_BURN: return std::string("BlendLinearBurn"); case LAYER_BLEND_MODE_LIGHTEN: return std::string("BlendLighten"); case LAYER_BLEND_MODE_SCREEN: return std::string("BlendScreen"); case LAYER_BLEND_MODE_COLOR_DODGE: return std::string("BlendColorDodge"); case LAYER_BLEND_MODE_LINEAR_DODGE: return std::string("BlendLinearDodge"); case LAYER_BLEND_MODE_OVERLAY: return std::string("BlendOverlay"); case LAYER_BLEND_MODE_SOFT_LIGHT: return std::string("BlendSoftLight"); case LAYER_BLEND_MODE_HARD_LIGHT: return std::string("BlendHardLight"); case LAYER_BLEND_MODE_VIVID_LIGHT: return std::string("BlendVividLight"); case LAYER_BLEND_MODE_LINEAR_LIGHT: return std::string("BlendLinearLight"); case LAYER_BLEND_MODE_PIN_LIGHT: return std::string("BlendPinLight"); case LAYER_BLEND_MODE_HARD_MIX: return std::string("BlendHardMix"); case LAYER_BLEND_MODE_DIFFERENCE: return std::string("BlendDifference"); case LAYER_BLEND_MODE_EXCLUSION: return std::string("BlendExclusion"); case LAYER_BLEND_MODE_SUBTRACT: return std::string("BlendSubstract"); case LAYER_BLEND_MODE_AVERAGE: return std::string("BlendAverage"); case LAYER_BLEND_MODE_ADD: return std::string("BlendAdd"); case LAYER_BLEND_MODE_NEGATION: return std::string("BlendNegation"); case LAYER_BLEND_MODE_REFLECT: return std::string("BlendReflect"); case LAYER_BLEND_MODE_GLOW: return std::string("BlendGlow"); case LAYER_BLEND_MODE_PHOENIX: return std::string("BlendPhoenix"); case LAYER_BLEND_MODE_LAST: return std::string("BlendNormal"); default: return std::string("BlendNormal"); } } ObjectPtr GraphicsEngine::GetColorBlendOverTexProgram(LayerBlendMode layer_blend_mode) { if (blend_tex_color_prog_[layer_blend_mode].IsValid()) { return blend_tex_color_prog_[layer_blend_mode]; } ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const std::string vertex_code = NUX_VERTEX_SHADER_HEADER "uniform mat4 view_projection_matrix; \n\ attribute vec4 in_vertex; \n\ attribute vec4 in_bkg_tex_coord; \n\ varying vec4 bkg_tex_coord; \n\ void main() \n\ { \n\ gl_Position = view_projection_matrix * (in_vertex); \n\ bkg_tex_coord = in_bkg_tex_coord; \n\ }"; const std::string pixel_code = NUX_FRAGMENT_SHADER_HEADER "uniform vec4 bkg_color; \n\ uniform sampler2D bkg_texture; \n\ uniform vec4 frg_color; \n\ varying vec4 bkg_tex_coord; \n\ %s \n\ void main() \n\ { \n\ vec4 tex = texture2D(bkg_texture, bkg_tex_coord.st) * bkg_color; \n\ gl_FragColor.rgb = mix(tex.rgb,%s(tex.rgb, frg_color.rgb), frg_color.a); \n\ gl_FragColor.a = 1.0; \n\ }"; int safe_area = 10; int code_buffer_size = pixel_code.length(); code_buffer_size += GetBlendModeBlendFunc(layer_blend_mode).length(); code_buffer_size += GetBlendModeString(layer_blend_mode).length() + safe_area; char* shader_prog = new char[code_buffer_size]; std::memset(shader_prog, 0, code_buffer_size); sprintf(shader_prog, pixel_code.c_str(), GetBlendModeBlendFunc(layer_blend_mode).c_str(), GetBlendModeString(layer_blend_mode).c_str()); blend_tex_color_prog_[layer_blend_mode] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(vertex_code.c_str()); PS->SetShaderCode(shader_prog); delete [] shader_prog; blend_tex_color_prog_[layer_blend_mode]->ClearShaderObjects(); blend_tex_color_prog_[layer_blend_mode]->AddShaderObject(VS); blend_tex_color_prog_[layer_blend_mode]->AddShaderObject(PS); CHECKGL(glBindAttribLocation(blend_tex_color_prog_[layer_blend_mode]->GetOpenGLID(), 0, "in_vertex")); blend_tex_color_prog_[layer_blend_mode]->Link(); return blend_tex_color_prog_[layer_blend_mode]; } void GraphicsEngine::QRP_GLSL_ColorLayerOverTexture(int x, int y, int width, int height, ObjectPtr bkg_device_texture, TexCoordXForm& bkg_texxform, const Color& bkg_color, const Color& frg_color, LayerBlendMode layer_blend_mode) { if (!UsingGLSLCodePath()) return; ObjectPtr ShaderProg = GetColorBlendOverTexProgram(layer_blend_mode); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, bkg_device_texture, bkg_texxform); float fx = x, fy = y; float vtx_buffer[] = { fx, fy, 0.0f, 1.0f, bkg_texxform.u0, bkg_texxform.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, bkg_texxform.u0, bkg_texxform.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, bkg_texxform.u1, bkg_texxform.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, bkg_texxform.u1, bkg_texxform.v0, 0, 0, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int in_vertex_loc = ShaderProg->GetAttributeLocation("in_vertex"); int in_bkg_tex_coord_loc = ShaderProg->GetAttributeLocation("in_bkg_tex_coord"); int bkg_texture_loc = ShaderProg->GetUniformLocationARB("bkg_texture"); int bkg_color_loc = ShaderProg->GetUniformLocationARB("bkg_color"); int frg_color_loc = ShaderProg->GetUniformLocationARB("frg_color"); SetTexture(GL_TEXTURE0, bkg_device_texture); CHECKGL(glUniform1iARB(bkg_texture_loc, 0)); if (bkg_color_loc != -1) { CHECKGL(glUniform4fARB(bkg_color_loc, bkg_color.red, bkg_color.green, bkg_color.blue, bkg_color.alpha)); } if (frg_color_loc != -1) { CHECKGL(glUniform4fARB(frg_color_loc, frg_color.red, frg_color.green, frg_color.blue, frg_color.alpha)); } int view_projection_matrix_loc = ShaderProg->GetUniformLocationARB("view_projection_matrix"); Matrix4 mvp_matrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) view_projection_matrix_loc, 1, false, (GLfloat*) & (mvp_matrix.m)); if (in_vertex_loc != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_vertex_loc)); CHECKGL(glVertexAttribPointerARB((GLuint) in_vertex_loc, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer)); } if (in_bkg_tex_coord_loc != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_bkg_tex_coord_loc)); CHECKGL(glVertexAttribPointerARB((GLuint) in_bkg_tex_coord_loc, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); if (in_vertex_loc != -1) CHECKGL(glDisableVertexAttribArrayARB(in_vertex_loc)); if (in_bkg_tex_coord_loc != -1) CHECKGL(glDisableVertexAttribArrayARB(in_bkg_tex_coord_loc)); ShaderProg->End();; } ObjectPtr GraphicsEngine::GetTextureLayerOverColorProgram(LayerBlendMode layer_blend_mode) { if (blend_color_tex_prog_[layer_blend_mode].IsValid()) { return blend_color_tex_prog_[layer_blend_mode]; } ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); std::string vertex_code = NUX_VERTEX_SHADER_HEADER "uniform mat4 view_projection_matrix; \n\ attribute vec4 in_vertex; \n\ attribute vec4 in_frg_tex_coord; \n\ varying vec4 frg_tex_coord; \n\ void main() \n\ { \n\ gl_Position = view_projection_matrix * (in_vertex); \n\ frg_tex_coord = in_frg_tex_coord; \n\ }"; std::string pixel_code = NUX_FRAGMENT_SHADER_HEADER "uniform vec4 frg_color; \n\ uniform sampler2D frg_texture; \n\ uniform vec4 bkg_color; \n\ varying vec4 frg_tex_coord; \n\ %s \n\ void main() \n\ { \n\ vec3 tex = texture2D(frg_texture, frg_tex_coord.st).rgb * frg_color.rgb; \n\ gl_FragColor.rgb = %s(bkg_color.rgb * bkg_color.aaa, tex.rgb * frg_color.aaa); \n\ gl_FragColor.a = 1.0; \n\ }"; int safe_area = 10; int code_buffer_size = pixel_code.length(); code_buffer_size += GetBlendModeBlendFunc(layer_blend_mode).length(); code_buffer_size += GetBlendModeString(layer_blend_mode).length() + safe_area; char* shader_prog = new char[code_buffer_size]; std::memset(shader_prog, 0, code_buffer_size); sprintf(shader_prog, pixel_code.c_str(), GetBlendModeBlendFunc(layer_blend_mode).c_str(), GetBlendModeString(layer_blend_mode).c_str()); blend_color_tex_prog_[layer_blend_mode] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(vertex_code.c_str()); PS->SetShaderCode(shader_prog); delete [] shader_prog; blend_color_tex_prog_[layer_blend_mode]->ClearShaderObjects(); blend_color_tex_prog_[layer_blend_mode]->AddShaderObject(VS); blend_color_tex_prog_[layer_blend_mode]->AddShaderObject(PS); CHECKGL(glBindAttribLocation(blend_color_tex_prog_[layer_blend_mode]->GetOpenGLID(), 0, "in_vertex")); blend_color_tex_prog_[layer_blend_mode]->Link(); return blend_color_tex_prog_[layer_blend_mode]; } void GraphicsEngine::QRP_GLSL_TextureLayerOverColor(int x, int y, int width, int height, const Color& bkg_color, ObjectPtr frg_device_texture, TexCoordXForm& frg_texxform, const Color& frg_color, LayerBlendMode layer_blend_mode) { if (!UsingGLSLCodePath()) return; ObjectPtr ShaderProg = GetTextureLayerOverColorProgram(layer_blend_mode); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, frg_device_texture, frg_texxform); float fx = x, fy = y; float vtx_buffer[] = { fx, fy, 0.0f, 1.0f, frg_texxform.u0, frg_texxform.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, frg_texxform.u0, frg_texxform.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, frg_texxform.u1, frg_texxform.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, frg_texxform.u1, frg_texxform.v0, 0, 0, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int frg_texture_loc = ShaderProg->GetUniformLocationARB("frg_texture"); int frg_color_loc = ShaderProg->GetUniformLocationARB("frg_color"); int bkg_color_loc = ShaderProg->GetUniformLocationARB("bkg_color"); int in_vertex_loc = ShaderProg->GetAttributeLocation("in_vertex"); int in_frg_tex_coord_loc = ShaderProg->GetAttributeLocation("in_frg_tex_coord"); SetTexture(GL_TEXTURE0, frg_device_texture); CHECKGL(glUniform1iARB(frg_texture_loc, 0)); int view_projection_matrix_loc = ShaderProg->GetUniformLocationARB("view_projection_matrix"); Matrix4 mvp_matrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) view_projection_matrix_loc, 1, false, (GLfloat*) & (mvp_matrix.m)); if (in_vertex_loc != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_vertex_loc)); CHECKGL(glVertexAttribPointerARB((GLuint) in_vertex_loc, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer)); } if (in_frg_tex_coord_loc != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_frg_tex_coord_loc)); CHECKGL(glVertexAttribPointerARB((GLuint) in_frg_tex_coord_loc, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4)); } if (frg_color_loc != -1) { CHECKGL(glUniform4fARB(frg_color_loc, frg_color.red, frg_color.green, frg_color.blue, frg_color.alpha)); } if (bkg_color_loc != -1) { CHECKGL(glUniform4fARB(bkg_color_loc, bkg_color.red, bkg_color.green, bkg_color.blue, bkg_color.alpha)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); if (in_vertex_loc != -1) CHECKGL(glDisableVertexAttribArrayARB(in_vertex_loc)); if (in_frg_tex_coord_loc != -1) CHECKGL(glDisableVertexAttribArrayARB(in_frg_tex_coord_loc)); ShaderProg->End(); } ObjectPtr GraphicsEngine::GetColorLayerOverColorProgram(LayerBlendMode layer_blend_mode) { if (blend_color_color_prog_[layer_blend_mode].IsValid()) return blend_color_color_prog_[layer_blend_mode]; ObjectPtr vertexShader = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr pixelShader = _graphics_display.m_DeviceFactory->CreatePixelShader(); std::string vertex_code = NUX_VERTEX_SHADER_HEADER "uniform mat4 view_projection_matrix; \n\ attribute vec4 in_vertex; \n\ void main() \n\ { \n\ gl_Position = view_projection_matrix * in_vertex; \n\ }"; std::string pixel_code = NUX_FRAGMENT_SHADER_HEADER "uniform vec4 bkg_color; \n\ uniform vec4 frg_color; \n\ %s \n\ void main() \n\ { \n\ gl_FragColor.rgb = %s(bkg_color.rgb * bkg_color.aaa, frg_color.rgb * frg_color.aaa); \n\ gl_FragColor.a = 1.0; \n\ }"; int safe_area = 10; int code_buffer_size = pixel_code.length(); code_buffer_size += GetBlendModeBlendFunc(layer_blend_mode).length(); code_buffer_size += GetBlendModeString(layer_blend_mode).length() + safe_area; char* shader_prog = new char[code_buffer_size]; std::memset(shader_prog, 0, code_buffer_size); sprintf(shader_prog, pixel_code.c_str(), GetBlendModeBlendFunc(layer_blend_mode).c_str(), GetBlendModeString(layer_blend_mode).c_str()); blend_color_color_prog_[layer_blend_mode] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); vertexShader->SetShaderCode(vertex_code.c_str()); pixelShader->SetShaderCode(shader_prog); delete [] shader_prog; blend_color_color_prog_[layer_blend_mode]->ClearShaderObjects(); blend_color_color_prog_[layer_blend_mode]->AddShaderObject(vertexShader); blend_color_color_prog_[layer_blend_mode]->AddShaderObject(pixelShader); CHECKGL(glBindAttribLocation(blend_color_color_prog_[layer_blend_mode]->GetOpenGLID(), 0, "in_vertex")); blend_color_color_prog_[layer_blend_mode]->Link(); return blend_color_color_prog_[layer_blend_mode]; } void GraphicsEngine::QRP_GLSL_ColorLayerOverColor(int x, int y, int width, int height, const Color& bkg_color, const Color& frg_color, LayerBlendMode layer_blend_mode) { if (!UsingGLSLCodePath()) return; ObjectPtr shader_prog = GetColorLayerOverColorProgram(layer_blend_mode); float fx = x, fy = y; float vtx_buffer[] = { fx, fy, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); shader_prog->Begin(); int in_vertex_loc = shader_prog->GetAttributeLocation("in_vertex"); int bkg_color_loc = shader_prog->GetUniformLocationARB("bkg_color"); int frg_color_loc = shader_prog->GetUniformLocationARB("frg_color"); if (bkg_color_loc != -1) CHECKGL(glUniform4fARB(bkg_color_loc, bkg_color.red, bkg_color.green, bkg_color.blue, bkg_color.alpha)); if (frg_color_loc != -1) CHECKGL(glUniform4fARB(frg_color_loc, frg_color.red, frg_color.green, frg_color.blue, frg_color.alpha)); int view_projection_matrix_loc = shader_prog->GetUniformLocationARB("view_projection_matrix"); Matrix4 mvp_matrix = GetOpenGLModelViewProjectionMatrix(); shader_prog->SetUniformLocMatrix4fv((GLint) view_projection_matrix_loc, 1, false, (GLfloat*)&mvp_matrix.m); if (in_vertex_loc != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_vertex_loc)); CHECKGL(glVertexAttribPointerARB((GLuint)in_vertex_loc, 4, GL_FLOAT, GL_FALSE, 16, vtx_buffer)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); if (in_vertex_loc != -1) CHECKGL(glDisableVertexAttribArrayARB(in_vertex_loc)); shader_prog->End(); } ObjectPtr GraphicsEngine::GetTextureLayerOverTextureProgram(LayerBlendMode layer_blend_mode) { if (blend_tex_tex_prog_[layer_blend_mode].IsValid()) { return blend_tex_tex_prog_[layer_blend_mode]; } ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); std::string vertex_code = NUX_VERTEX_SHADER_HEADER "uniform mat4 view_projection_matrix; \n\ attribute vec4 in_vertex; \n\ attribute vec4 in_bkg_tex_coord; \n\ attribute vec4 in_frg_tex_coord; \n\ varying vec4 bkg_tex_coord; \n\ varying vec4 frg_tex_coord; \n\ void main() \n\ { \n\ bkg_tex_coord = in_bkg_tex_coord; \n\ frg_tex_coord = in_frg_tex_coord; \n\ gl_Position = view_projection_matrix * (in_vertex); \n\ }"; std::string pixel_code = NUX_FRAGMENT_SHADER_HEADER "varying vec4 bkg_tex_coord; \n\ varying vec4 frg_tex_coord; \n\ uniform vec4 bkg_color; \n\ uniform vec4 frg_color; \n\ uniform sampler2D bkg_texture; \n\ uniform sampler2D frg_texture; \n\ %s \n\ void main() \n\ { \n\ vec3 bkg_tex = texture2D(bkg_texture, bkg_tex_coord.st).rgb * bkg_color.rgb; \n\ vec3 frg_tex = texture2D(frg_texture, frg_tex_coord.st).rgb * frg_color.rgb; \n\ gl_FragColor.rgb = %s(bkg_tex.rgb * bkg_color.aaa, frg_tex.rgb * frg_color.aaa); \n\ gl_FragColor.a = 1.0; \n\ }"; int safe_area = 10; int code_buffer_size = pixel_code.length(); code_buffer_size += GetBlendModeBlendFunc(layer_blend_mode).length(); code_buffer_size += GetBlendModeString(layer_blend_mode).length() + safe_area; char* shader_prog = new char[code_buffer_size]; std::memset(shader_prog, 0, code_buffer_size); sprintf(shader_prog, pixel_code.c_str(), GetBlendModeBlendFunc(layer_blend_mode).c_str(), GetBlendModeString(layer_blend_mode).c_str()); blend_tex_tex_prog_[layer_blend_mode] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(vertex_code.c_str()); PS->SetShaderCode(shader_prog); delete [] shader_prog; blend_tex_tex_prog_[layer_blend_mode]->ClearShaderObjects(); blend_tex_tex_prog_[layer_blend_mode]->AddShaderObject(VS); blend_tex_tex_prog_[layer_blend_mode]->AddShaderObject(PS); CHECKGL(glBindAttribLocation(blend_tex_tex_prog_[layer_blend_mode]->GetOpenGLID(), 0, "in_vertex")); blend_tex_tex_prog_[layer_blend_mode]->Link(); return blend_tex_tex_prog_[layer_blend_mode]; } void GraphicsEngine::QRP_GLSL_TextureLayerOverTexture(int x, int y, int width, int height, ObjectPtr bkg_device_texture, TexCoordXForm& bkg_texxform, const Color& bkg_color, ObjectPtr frg_device_texture, TexCoordXForm& frg_texxform, const Color& frg_color, LayerBlendMode layer_blend_mode) { if (!UsingGLSLCodePath()) return; ObjectPtr ShaderProg = GetTextureLayerOverTextureProgram(layer_blend_mode); QRP_Compute_Texture_Coord(width, height, bkg_device_texture, bkg_texxform); QRP_Compute_Texture_Coord(width, height, frg_device_texture, frg_texxform); float fx = x, fy = y; float vtx_buffer[] = { fx, fy, 0.0f, 1.0f, bkg_texxform.u0, bkg_texxform.v0, 0.0f, 1.0f, frg_texxform.u0, frg_texxform.v0, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, bkg_texxform.u0, bkg_texxform.v1, 0.0f, 1.0f, frg_texxform.u0, frg_texxform.v1, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, bkg_texxform.u1, bkg_texxform.v1, 0.0f, 1.0f, frg_texxform.u1, frg_texxform.v1, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, bkg_texxform.u1, bkg_texxform.v0, 0.0f, 1.0f, frg_texxform.u1, frg_texxform.v0, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int bkg_texture_loc = ShaderProg->GetUniformLocationARB("bkg_texture"); int frg_texture_loc = ShaderProg->GetUniformLocationARB("frg_texture"); int in_vertex_loc = ShaderProg->GetAttributeLocation("in_vertex"); int in_bkg_tex_coord_loc = ShaderProg->GetAttributeLocation("in_bkg_tex_coord"); int in_frg_tex_coord_loc = ShaderProg->GetAttributeLocation("in_frg_tex_coord"); int TextureCoef0Location = ShaderProg->GetUniformLocationARB("bkg_color"); int TextureCoef1Location = ShaderProg->GetUniformLocationARB("frg_color"); SetTexture(GL_TEXTURE0, bkg_device_texture); SetTexture(GL_TEXTURE1, frg_device_texture); CHECKGL(glUniform1iARB(bkg_texture_loc, 0)); CHECKGL(glUniform1iARB(frg_texture_loc, 1)); CHECKGL(glUniform4fARB(TextureCoef0Location, bkg_color.red, bkg_color.green, bkg_color.blue, bkg_color.alpha )); CHECKGL(glUniform4fARB(TextureCoef1Location, frg_color.red, frg_color.green, frg_color.blue, frg_color.alpha )); int view_projection_matrix_loc = ShaderProg->GetUniformLocationARB("view_projection_matrix"); Matrix4 mvp_matrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) view_projection_matrix_loc, 1, false, (GLfloat*) & (mvp_matrix.m)); CHECKGL(glEnableVertexAttribArrayARB(in_vertex_loc)); CHECKGL(glVertexAttribPointerARB((GLuint) in_vertex_loc, 4, GL_FLOAT, GL_FALSE, 48, vtx_buffer)); if (in_bkg_tex_coord_loc != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_bkg_tex_coord_loc)); CHECKGL(glVertexAttribPointerARB((GLuint) in_bkg_tex_coord_loc, 4, GL_FLOAT, GL_FALSE, 48, vtx_buffer + 4)); } if (in_frg_tex_coord_loc != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_frg_tex_coord_loc)); CHECKGL(glVertexAttribPointerARB((GLuint) in_frg_tex_coord_loc, 4, GL_FLOAT, GL_FALSE, 48, vtx_buffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(in_vertex_loc)); if (in_bkg_tex_coord_loc != -1) CHECKGL(glDisableVertexAttribArrayARB(in_bkg_tex_coord_loc)); if (in_frg_tex_coord_loc != -1) CHECKGL(glDisableVertexAttribArrayARB(in_frg_tex_coord_loc)); ShaderProg->End(); } }nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLCgShader.cpp0000644000015301777760000001165312321344237022540 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLCgShader.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(ICgShader); NUX_IMPLEMENT_OBJECT_TYPE(ICgVertexShader); NUX_IMPLEMENT_OBJECT_TYPE(ICgPixelShader); ICgShader::ICgShader(NString ShaderName, OpenGLResourceType ResourceType) : IOpenGLResource(ResourceType) , _ShaderName(ShaderName) , _CgProgram(0) { } ICgShader::~ICgShader() { } const char *ICgShader::GetProgramString() { return cgGetProgramString( _CgProgram, CG_PROGRAM_SOURCE ); } const char *ICgShader::GetProgramBinary() { return cgGetProgramString( _CgProgram, CG_COMPILED_PROGRAM ); } CGparameter ICgShader::GetNamedParameter(const char *parameter) { return cgGetNamedParameter(_CgProgram, TCHAR_TO_ANSI(parameter)); } ICgVertexShader::ICgVertexShader(NString ShaderName) : _ready(0) , ICgShader(ShaderName, RT_GLSL_VERTEXSHADER) { } ICgVertexShader::~ICgVertexShader() { cgDestroyProgram(_CgProgram); _ready = 0; } void ICgVertexShader::CreateProgram(const ANSICHAR *ShaderCode, const ANSICHAR *EntryPoint) { CGprofile cg_vprofile = cgGLGetLatestProfile(CG_GL_VERTEX); nuxAssertMsg(ShaderCode != 0, "[ICgVertexShader::CreateProgram] Invalid shader code."); _ShaderCode = ANSI_TO_TCHAR(ShaderCode); _EntryPoint = ANSI_TO_TCHAR(EntryPoint); _CgProgram = cgCreateProgram(GetGpuDevice()->GetCgContext(), CG_SOURCE, ShaderCode, cg_vprofile, //CG_PROFILE_VP40 EntryPoint, 0); cgGLLoadProgram(_CgProgram); _ready = 0; } void ICgVertexShader::CreateProgramFromFileShaderCode(const char *Filename, const char *EntryPoint) { nuxAssertMsg(Filename != 0, "[ICgVertexShader::CreateProgramFromFileShaderCode] Invalid shader file."); if (Filename == 0) return; LoadFileToString(_ShaderCode, Filename); CreateProgram(TCHAR_TO_ANSI(&_ShaderCode[0]), TCHAR_TO_ANSI(EntryPoint)); _ready = 0; } bool ICgVertexShader::Compile() { return false; } void ICgVertexShader::BindProgram() { cgGLBindProgram(_CgProgram); } bool ICgVertexShader::IsValid() { return _ready; } ICgPixelShader::ICgPixelShader(NString ShaderName) : _ready(0) , ICgShader(ShaderName, RT_GLSL_PIXELSHADER) { } ICgPixelShader::~ICgPixelShader() { cgDestroyProgram(_CgProgram); _ready = 0; } void ICgPixelShader::CreateProgram(const ANSICHAR *ShaderCode, const ANSICHAR *EntryPoint) { CGprofile cg_fprofile = cgGLGetLatestProfile(CG_GL_FRAGMENT); nuxAssertMsg(ShaderCode != 0, "[ICgPixelShader::CreateProgram] Invalid shader code."); _ShaderCode = ANSI_TO_TCHAR(ShaderCode); _EntryPoint = ANSI_TO_TCHAR(EntryPoint); _CgProgram = cgCreateProgram(GetGpuDevice()->GetCgContext(), CG_SOURCE, ShaderCode, cg_fprofile, //CG_PROFILE_FP40, EntryPoint, 0); cgGLLoadProgram(_CgProgram); _ready = 0; } void ICgPixelShader::CreateProgramFromFileShaderCode(const char *Filename, const char *EntryPoint) { nuxAssertMsg(Filename != 0, "[ICgPixelShader::CreateProgramFromFileShaderCode] Invalid shader file."); if (Filename == 0) return; LoadFileToString(_ShaderCode, Filename); CreateProgram(TCHAR_TO_ANSI(&_ShaderCode[0]), TCHAR_TO_ANSI(EntryPoint)); _ready = 0; } bool ICgPixelShader::Compile() { return false; } void ICgPixelShader::BindProgram() { cgGLBindProgram(_CgProgram); } bool ICgPixelShader::IsValid() { return _ready; } void cgErrorCallback(void) { CGerror LastError = cgGetError(); if (LastError) { nuxDebugMsg("%s\n\n", cgGetErrorString(LastError)); nuxDebugMsg("%s\n", cgGetLastListing(GetGpuDevice()->GetCgContext())); nuxDebugMsg("Cg error, exiting...\n"); nuxAssertMsg(0, "[cgErrorCallback]: Cg Error."); } } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLAsmShader.h0000644000015301777760000001133712321344237022373 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLASMSHADER_H #define IOPENGLASMSHADER_H namespace nux { typedef enum { VTXATTRIB_INVALID = -1, VTXATTRIB_POSITION = 0, VTXATTRIB_WEIGHT = 1, VTXATTRIB_NORMAL = 2, VTXATTRIB_COLOR = 3, VTXATTRIB_COLOR_PRIMARY = 3, VTXATTRIB_COLOR_SECONDARY = 4, VTXATTRIB_FOGCOORD = 5, VTXATTRIB_TEXCOORD = 8, VTXATTRIB_TEXCOORD0 = 8, VTXATTRIB_TEXCOORD1 = 9, VTXATTRIB_TEXCOORD2 = 10, VTXATTRIB_TEXCOORD3 = 11, VTXATTRIB_TEXCOORD4 = 12, VTXATTRIB_TEXCOORD5 = 13, VTXATTRIB_TEXCOORD6 = 14, VTXATTRIB_TEXCOORD7 = 15, } VtxAttributeIndex; class IOpenGLResource; class IOpenGLAsmShader: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLAsmShader, IOpenGLResource); IOpenGLAsmShader(std::string const& shader_name, GLint shader_type, OpenGLResourceType ResourceType); virtual ~IOpenGLAsmShader(); public: void SetShaderCode(std::string const& shader_code); bool Compile(); bool IsValid(); protected: std::string shader_name_; std::string shader_code_; GLint shader_type_; bool compiled_and_ready_; }; class IOpenGLAsmVertexShader : public IOpenGLAsmShader { NUX_DECLARE_OBJECT_TYPE(IOpenGLAsmVertexShader, IOpenGLAsmShader); public: IOpenGLAsmVertexShader(); }; class IOpenGLAsmPixelShader : public IOpenGLAsmShader { NUX_DECLARE_OBJECT_TYPE(IOpenGLAsmPixelShader, IOpenGLAsmShader); public: IOpenGLAsmPixelShader(); }; class IOpenGLAsmShaderProgram : public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLAsmShaderProgram, IOpenGLResource); public: virtual ~IOpenGLAsmShaderProgram(); void LoadVertexShader(const char *glslshader); void LoadPixelShader(const char *glslshader); void LoadIShaderFile(const char *ShaderFileName); void LoadIShader(const char *ShaderCode); void Link(); bool IsValid(); void Begin(); void End(); void SetVertexEnvParameter4dARB (unsigned int index, double x, double y, double z, double w); void SetVertexEnvParameter4dvARB (unsigned int index, const double *params); void SetVertexEnvParameter4fARB (unsigned int index, float x, float y, float z, float w); void SetVertexEnvParameter4fvARB (unsigned int index, const float *params); void SetVertexLocalParameter4dARB (unsigned int index, double x, double y, double z, double w); void SetVertexLocalParameter4dvARB (unsigned int index, const double *params); void SetVertexLocalParameter4fARB (unsigned int index, float x, float y, float z, float w); void SetVertexLocalParameter4fvARB (unsigned int index, const float *params); void SetFragmentEnvParameter4dARB (unsigned int index, double x, double y, double z, double w); void SetFragmentEnvParameter4dvARB (unsigned int index, const double *params); void SetFragmentEnvParameter4fARB (unsigned int index, float x, float y, float z, float w); void SetFragmentEnvParameter4fvARB (unsigned int index, const float *params); void SetFragmentLocalParameter4dARB (unsigned int index, double x, double y, double z, double w); void SetFragmentLocalParameter4dvARB (unsigned int index, const double *params); void SetFragmentLocalParameter4fARB (unsigned int index, float x, float y, float z, float w); void SetFragmentLocalParameter4fvARB (unsigned int index, const float *params); private: IOpenGLAsmShaderProgram(std::string ShaderProgramName = std::string("AsmShaderProgram")); std::vector > ShaderObjectList; std::string _ShaderProgramName; ObjectPtr m_AsmVertexProgram; ObjectPtr m_AsmFragmentProgram; friend class GpuDevice; }; } #endif // IOPENGLASMSHADER_H nux-4.0.6+14.04.20140409/NuxGraphics/Makefile.am0000644000015301777760000001317212321344237021230 0ustar pbusernogroup00000000000000CLEANFILES = DISTCLEANFILES = EXTRA_DIST = $(srcdir)/GraphicsDisplayWin.cpp \ $(srcdir)/GraphicsDisplayWin.h lib_LTLIBRARIES = \ libnux-graphics-@NUX_API_VERSION@.la libnux_graphics_@NUX_API_VERSION@_la_CPPFLAGS= \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DPKGDATADIR=\""$(pkgdatadir)/@NUX_API_VERSION@"\" \ -DG_LOG_DOMAIN=\"NuxGraphics\" \ $(GCC_FLAGS) \ $(NUX_GRAPHICS_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(GEIS_CFLAGS) \ $(COVERAGE_CFLAGS) libnux_graphics_@NUX_API_VERSION@_la_LIBADD = \ $(top_builddir)/NuxCore/libnux-core-@NUX_API_VERSION@.la \ $(NUX_GRAPHICS_LIBS) \ $(GEIS_LIBS) libnux_graphics_@NUX_API_VERSION@_la_LDFLAGS = \ $(NUX_LT_LDFLAGS) \ $(COVERAGE_LDFLAGS) source_h = \ $(srcdir)/BitmapFormats.h \ $(srcdir)/CairoGraphics.h \ $(srcdir)/Events.h \ $(srcdir)/FontTexture.h \ $(srcdir)/FontRenderer.h \ $(srcdir)/GdkGraphics.h \ $(srcdir)/Gfx_Interface.h \ $(srcdir)/GLDeviceFrameBufferObject.h \ $(srcdir)/GLDeviceObjects.h \ $(srcdir)/GLError.h \ $(srcdir)/GlobalGraphicsInitializer.h \ $(srcdir)/GLPBuffer.h \ $(srcdir)/GLRenderStates.h \ $(srcdir)/GLResource.h \ $(srcdir)/GLResourceManager.h \ $(srcdir)/GLShader.h \ $(srcdir)/GLShaderParameter.h \ $(srcdir)/GLSh_ColorPicker.h \ $(srcdir)/GLSh_DrawFunction.h \ $(srcdir)/GLSh_Fill.h \ $(srcdir)/GLTemplatePrimitiveBuffer.h \ $(srcdir)/GLTextureResourceManager.h \ $(srcdir)/GLTextureStates.h \ $(srcdir)/GLThread.h \ $(srcdir)/GLTimer.h \ $(srcdir)/GLVertexResourceManager.h \ $(srcdir)/GLWindowManager.h \ $(srcdir)/GpuDevice.h \ $(srcdir)/GraphicsDisplay.h \ $(srcdir)/GraphicsEngine.h \ $(srcdir)/MeshData.h \ $(srcdir)/MeshFileLoader-OBJ.h \ $(srcdir)/ImageSurface.h \ $(srcdir)/IOpenGLAnimatedTexture.h \ $(srcdir)/IOpenGLBaseTexture.h \ $(srcdir)/IOpenGLCubeTexture.h \ $(srcdir)/IOpenGLFrameBufferObject.h \ $(srcdir)/IOpenGLGLSLShader.h \ $(srcdir)/IOpenGLIndexBuffer.h \ $(srcdir)/IOpenGLPixelBufferOject.h \ $(srcdir)/IOpenGLQuery.h \ $(srcdir)/IOpenGLRectangleTexture.h \ $(srcdir)/IOpenGLResource.h \ $(srcdir)/IOpenGLSurface.h \ $(srcdir)/IOpenGLTexture2D.h \ $(srcdir)/IOpenGLVertexBuffer.h \ $(srcdir)/IOpenGLVertexDeclaration.h \ $(srcdir)/IOpenGLVolume.h \ $(srcdir)/IOpenGLVolumeTexture.h \ $(srcdir)/NuxGraphics.h \ $(srcdir)/NuxGraphicsObject.h \ $(srcdir)/NuxGraphicsResources.h \ $(srcdir)/OpenGLDefinitions.h \ $(srcdir)/OpenGLMapping.h \ $(srcdir)/RenderingPipe.h \ $(srcdir)/RenderingPipeGLSL.h \ $(srcdir)/RenderingPipeTextureBlendShaderSource.h \ $(srcdir)/RunTimeStats.h if USE_X11 source_h += \ $(srcdir)/GraphicsDisplayX11.h \ $(srcdir)/VirtualKeyCodesX11.h \ $(srcdir)/XInputWindow.h endif if !NUX_OPENGLES_20 source_h += \ $(srcdir)/IOpenGLAsmShader.h \ $(srcdir)/RenderingPipeAsm.h endif if HAVE_GEIS source_h += \ $(srcdir)/GestureEvent.h endif source_cpp = \ $(srcdir)/BitmapFormats.cpp \ $(srcdir)/CairoGraphics.cpp \ $(srcdir)/Events.cpp \ $(srcdir)/FontRenderer.cpp \ $(srcdir)/FontTexture.cpp \ $(srcdir)/GdkGraphics.cpp \ $(srcdir)/GLDeviceFrameBufferObject.cpp \ $(srcdir)/GLDeviceObjects.cpp \ $(srcdir)/GLError.cpp \ $(srcdir)/GlobalGraphicsInitializer.cpp \ $(srcdir)/GLPBuffer.cpp \ $(srcdir)/GLRenderStates.cpp \ $(srcdir)/GLResource.cpp \ $(srcdir)/GLResourceManager.cpp \ $(srcdir)/GLShader.cpp \ $(srcdir)/GLShaderParameter.cpp \ $(srcdir)/GLSh_ColorPicker.cpp \ $(srcdir)/GLSh_DrawFunction.cpp \ $(srcdir)/GLSh_Fill.cpp \ $(srcdir)/GLTemplatePrimitiveBuffer.cpp \ $(srcdir)/GLTextureResourceManager.cpp \ $(srcdir)/GLTextureStates.cpp \ $(srcdir)/GLTimer.cpp \ $(srcdir)/GLVertexResourceManager.cpp \ $(srcdir)/GLWindowManager.cpp \ $(srcdir)/GpuDevice.cpp \ $(srcdir)/GpuDeviceShader.cpp \ $(srcdir)/GpuDeviceTexture.cpp \ $(srcdir)/GpuDeviceVertex.cpp \ $(srcdir)/GraphicsEngine.cpp \ $(srcdir)/MeshData.cpp \ $(srcdir)/MeshFileLoader-OBJ.cpp \ $(srcdir)/ImageSurface.cpp \ $(srcdir)/IOpenGLAnimatedTexture.cpp \ $(srcdir)/IOpenGLBaseTexture.cpp \ $(srcdir)/IOpenGLCubeTexture.cpp \ $(srcdir)/IOpenGLFrameBufferObject.cpp \ $(srcdir)/IOpenGLGLSLShader.cpp \ $(srcdir)/IOpenGLIndexBuffer.cpp \ $(srcdir)/IOpenGLPixelBufferOject.cpp \ $(srcdir)/IOpenGLQuery.cpp \ $(srcdir)/IOpenGLRectangleTexture.cpp \ $(srcdir)/IOpenGLSurface.cpp \ $(srcdir)/IOpenGLTexture2D.cpp \ $(srcdir)/IOpenGLVertexBuffer.cpp \ $(srcdir)/IOpenGLVertexDeclaration.cpp \ $(srcdir)/IOpenGLVolume.cpp \ $(srcdir)/IOpenGLVolumeTexture.cpp \ $(srcdir)/NuxGraphics.cpp \ $(srcdir)/NuxGraphicsObject.cpp \ $(srcdir)/NuxGraphicsResources.cpp \ $(srcdir)/RenderingPipe.cpp \ $(srcdir)/RenderingPipeGLSL.cpp \ $(srcdir)/RenderingPipeTextureBlend.cpp \ $(srcdir)/GLRenderingAPI.cpp \ $(srcdir)/RunTimeStats.cpp if USE_X11 source_cpp += \ $(srcdir)/GraphicsDisplayX11.cpp \ $(srcdir)/XInputWindow.cpp endif if !NUX_OPENGLES_20 source_cpp += \ $(srcdir)/IOpenGLAsmShader.cpp \ $(srcdir)/RenderingPipeAsm.cpp endif if HAVE_GEIS source_cpp += \ $(srcdir)/GestureEvent.cpp endif libnux_graphics_@NUX_API_VERSION@_la_SOURCES = \ $(source_cpp) \ $(source_h) nux_graphicsdir = $(includedir)/Nux-@NUX_API_VERSION@/NuxGraphics nux_graphics_HEADERS = \ $(source_h) nux-graphics-@NUX_API_VERSION@.pc: nux-graphics.pc $(AM_V_GEN) cp -f nux-graphics.pc nux-graphics-@NUX_API_VERSION@.pc pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = nux-graphics-@NUX_API_VERSION@.pc CLEANFILES += nux-graphics-@NUX_API_VERSION@.pc DISTCLEANFILES += nux-graphics.pc EXTRA_DIST += nux-graphics.pc.in nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLFrameBufferObject.h0000644000015301777760000000745012321344237024040 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLFRAMEBUFFEROBJECT_H #define IOPENGLFRAMEBUFFEROBJECT_H namespace nux { class IOpenGLResource; class IOpenGLFrameBufferObject: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLFrameBufferObject, IOpenGLResource); public: virtual ~IOpenGLFrameBufferObject(); void SetupFrameBufferObject(); int FormatFrameBufferObject(int Width, int Height, BitmapFormat PixelFormat); int SetRenderTarget(int color_attachment_index, ObjectPtr pRenderTargetSurface); int SetTextureAttachment(int color_attachment_index, ObjectPtr texture, int surface_level); int SetDepthSurface(ObjectPtr pDepthSurface); int SetDepthTextureAttachment(ObjectPtr depth_texture, int mip_level); ObjectPtr GetRenderTarget(int color_attachment_index); ObjectPtr GetDepthRenderTarget(); ObjectPtr TextureAttachment(int color_attachment_index); ObjectPtr DepthTextureAttachment(); int Clear(DWORD Flags, FLOAT red, FLOAT green, FLOAT blue, FLOAT alpha, FLOAT Z, DWORD Stencil); int Activate(bool WithClippingStack = false); //### Restore the original opengl back buffer as defined when creating the opengl context(color + depth + stencil). int Deactivate(); bool IsActive() { return _IsActive; } // For 2D screen operations std::vector _ClippingRegionStack; void PushClippingRegion(Rect const& rect); void PopClippingRegion(); void EmptyClippingRegion(); void ApplyClippingRegion(); //! Bypass the clipping rectangle stack and set a different clipping rectangle region. /*! You may restore the clipping rectangle stack with ApplyClippingRectangle. */ void SetClippingRectangle(const Rect &rect); void SetOpenGLClippingRectangle(int x, int y, int width, int height); Rect GetClippingRegion(); int GetNumberOfClippingRegions() const; int GetWidth() const { return attachment_width_; } int GetHeight() const { return attachment_height_; } private: struct Attachment { ObjectPtr texture; int level; }; IOpenGLFrameBufferObject(NUX_FILE_LINE_PROTO); int attachment_width_; int attachment_height_; BitmapFormat _PixelFormat; bool _IsActive; Rect _clipping_rect; ObjectPtr depth_surface_attachment_; ObjectPtr stencil_surface_attachment_; ObjectPtr depth_texture_attachment_; std::vector< ObjectPtr > surface_attachment_array_; std::vector< ObjectPtr > texture_attachment_array_; GLFramebufferObject _Fbo; // The framebuffer object used for rendering to the texture GLRenderbuffer _Rbo; bool platform_support_for_depth_texture_; friend class GpuDevice; }; } #endif // IOPENGLFRAMEBUFFEROBJECT_H nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipeGLSL.cpp0000644000015301777760000046420712321344237023126 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "ImageSurface.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "RenderingPipe.h" #include "GraphicsEngine.h" namespace nux { void GraphicsEngine::InitSlColorShader() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 VertexColor; \n\ varying vec4 vColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * AVertex; \n\ vColor = VertexColor; \n\ }"; VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 vColor; \n\ void main() \n\ { \n\ gl_FragColor = vColor; \n\ }"; PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); m_SlColor = _graphics_display.m_DeviceFactory->CreateShaderProgram(); m_SlColor->ClearShaderObjects(); m_SlColor->AddShaderObject(VS); m_SlColor->AddShaderObject(PS); m_SlColor->Link(); } void GraphicsEngine::InitSlTextureShader() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 VertexColor; \n\ uniform mat4 ViewProjectionMatrix; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyVertexColor = VertexColor; \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ void main() \n\ { \n\ vec4 v = SampleTexture(TextureObject0, varyTexCoord0); \n\ gl_FragColor = v*varyVertexColor; \n\ }"; // Textured 2D Primitive Shader m_SlTextureModColor = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString), "#define SAMPLERTEX2D"); m_SlTextureModColor->ClearShaderObjects(); m_SlTextureModColor->AddShaderObject(VS); m_SlTextureModColor->AddShaderObject(PS); CHECKGL(glBindAttribLocation(m_SlTextureModColor->GetOpenGLID(), 0, "AVertex")); m_SlTextureModColor->Link(); } void GraphicsEngine::InitSlColorModTexMaskAlpha() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 VertexColor; \n\ uniform mat4 ViewProjectionMatrix; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyVertexColor = VertexColor; \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ void main() \n\ { \n\ float alpha = SampleTexture(TextureObject0, varyTexCoord0).w; \n\ gl_FragColor = vec4(varyVertexColor.xyz, alpha*varyVertexColor.a); \n\ }"; m_SlColorModTexMaskAlpha = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString), "#define SAMPLERTEX2D"); m_SlColorModTexMaskAlpha->ClearShaderObjects(); m_SlColorModTexMaskAlpha->AddShaderObject(VS); m_SlColorModTexMaskAlpha->AddShaderObject(PS); CHECKGL(glBindAttribLocation(m_SlColorModTexMaskAlpha->GetOpenGLID(), 0, "AVertex")); CHECKGL(glBindAttribLocation(m_SlColorModTexMaskAlpha->GetOpenGLID(), 1, "MyTextureCoord0")); CHECKGL(glBindAttribLocation(m_SlColorModTexMaskAlpha->GetOpenGLID(), 2, "VectexColor")); m_SlColorModTexMaskAlpha->Link(); } void GraphicsEngine::InitSl2TextureAdd() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); // For some strange reason, make sure that the attribute holding the vertex position has a name that comes first in alphabetic order before all // other attributes. Otherwise you get a bug on NVidia! Why is that??? //////////////////////////////////////////////////////////////////////////////////////////////////// const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 MyTextureCoord1; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyTexCoord1 = MyTextureCoord1; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ uniform vec4 color0; \n\ uniform vec4 color1; \n\ #ifdef SAMPLERTEX2D \n\ uniform sampler2D TextureObject0; \n\ uniform sampler2D TextureObject1; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ #elif defined SAMPLERTEX2DRECT \n\ uniform sampler2DRect TextureObject0; \n\ uniform sampler2DRect TextureObject1; \n\ vec4 SampleTexture(sampler2DRect TexObject, vec4 TexCoord) \n\ { \n\ return texture2DRect(TexObject, TexCoord.st); \n\ } \n\ #endif \n\ void main() \n\ { \n\ vec4 b0 = color0*SampleTexture(TextureObject0, varyTexCoord0); \n\ vec4 b1 = color1*SampleTexture(TextureObject1, varyTexCoord1); \n\ gl_FragColor = b0 + b1; \n\ }"; m_Sl2TextureAdd = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString), "#define SAMPLERTEX2D"); m_Sl2TextureAdd->ClearShaderObjects(); m_Sl2TextureAdd->AddShaderObject(VS); m_Sl2TextureAdd->AddShaderObject(PS); CHECKGL(glBindAttribLocation(m_Sl2TextureAdd->GetOpenGLID(), 0, "AVertex")); m_Sl2TextureAdd->Link(); } void GraphicsEngine::InitSl2TextureDepRead() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); // For some strange reason, make sure that the attribute holding the vertex position has a name that comes first in alphabetic order before all // other attributes. Otherwise you get a bug on NVidia! Why is that??? //////////////////////////////////////////////////////////////////////////////////////////////////// const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 MyTextureCoord1; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyTexCoord1 = MyTextureCoord1; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ uniform vec4 color0; \n\ uniform vec4 color1; \n\ uniform sampler2D TextureObject0; \n\ uniform sampler2D TextureObject1; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ void main() \n\ { \n\ vec4 noise = SampleTexture(TextureObject0, varyTexCoord0); \n\ vec4 noise_bx2 = color0 * (2.0 * noise - vec4(1.0, 1.0, 1.0, 1.0)); \n\ vec4 b1 = color1 * SampleTexture(TextureObject1, varyTexCoord1 + noise_bx2); \n\ gl_FragColor = b1; \n\ }"; m_Sl2TextureDepRead = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); m_Sl2TextureDepRead->ClearShaderObjects(); m_Sl2TextureDepRead->AddShaderObject(VS); m_Sl2TextureDepRead->AddShaderObject(PS); CHECKGL(glBindAttribLocation(m_Sl2TextureDepRead->GetOpenGLID(), 0, "AVertex")); m_Sl2TextureDepRead->Link(); } void GraphicsEngine::InitSl2TextureMod() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); // For some strange reason, make sure that the attribute holding the vertex position has a name that comes first in alphabetic order before all // other attributes. Otherwise you get a bug on NVidia! Why is that??? //////////////////////////////////////////////////////////////////////////////////////////////////// const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 MyTextureCoord1; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyTexCoord1 = MyTextureCoord1; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ uniform vec4 color0; \n\ uniform vec4 color1; \n\ #ifdef SAMPLERTEX2D \n\ uniform sampler2D TextureObject0; \n\ uniform sampler2D TextureObject1; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ #elif defined SAMPLERTEX2DRECT \n\ uniform sampler2DRect TextureObject0; \n\ uniform sampler2DRect TextureObject1; \n\ vec4 SampleTexture(sampler2DRect TexObject, vec4 TexCoord) \n\ { \n\ return texture2DRect(TexObject, TexCoord.st); \n\ } \n\ #endif \n\ void main() \n\ { \n\ vec4 b0 = color0*SampleTexture(TextureObject0, varyTexCoord0); \n\ vec4 b1 = color1*SampleTexture(TextureObject1, varyTexCoord1); \n\ gl_FragColor = b0 * b1; \n\ }"; m_Sl2TextureMod = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString), "#define SAMPLERTEX2D"); m_Sl2TextureMod->ClearShaderObjects(); m_Sl2TextureMod->AddShaderObject(VS); m_Sl2TextureMod->AddShaderObject(PS); CHECKGL(glBindAttribLocation(m_Sl2TextureMod->GetOpenGLID(), 0, "AVertex")); m_Sl2TextureMod->Link(); } void GraphicsEngine::InitSl4TextureAdd() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); // For some strange reason, make sure that the attribute holding the vertex position has a name that comes first in alphabetic order before all // other attributes. Otherwise you get a bug on NVidia! Why is that??? //////////////////////////////////////////////////////////////////////////////////////////////////// const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 MyTextureCoord1; \n\ attribute vec4 MyTextureCoord2; \n\ attribute vec4 MyTextureCoord3; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ varying vec4 varyTexCoord2; \n\ varying vec4 varyTexCoord3; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyTexCoord1 = MyTextureCoord1; \n\ varyTexCoord2 = MyTextureCoord2; \n\ varyTexCoord3 = MyTextureCoord3; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyTexCoord1; \n\ varying vec4 varyTexCoord2; \n\ varying vec4 varyTexCoord3; \n\ uniform vec4 color0; \n\ uniform vec4 color1; \n\ uniform vec4 color2; \n\ uniform vec4 color3; \n\ uniform sampler2D TextureObject0; \n\ uniform sampler2D TextureObject1; \n\ uniform sampler2D TextureObject2; \n\ uniform sampler2D TextureObject3; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ void main() \n\ { \n\ vec4 b0 = color0*SampleTexture(TextureObject0, varyTexCoord0); \n\ vec4 b1 = color1*SampleTexture(TextureObject1, varyTexCoord1); \n\ vec4 b2 = color2*SampleTexture(TextureObject2, varyTexCoord2); \n\ vec4 b3 = color3*SampleTexture(TextureObject3, varyTexCoord3); \n\ gl_FragColor = b0+b1+b2+b3; \n\ }"; // Textured 2D Primitive Shader m_Sl4TextureAdd = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); m_Sl4TextureAdd->ClearShaderObjects(); m_Sl4TextureAdd->AddShaderObject(VS); m_Sl4TextureAdd->AddShaderObject(PS); CHECKGL(glBindAttribLocation(m_Sl4TextureAdd->GetOpenGLID(), 0, "AVertex")); m_Sl4TextureAdd->Link(); } void GraphicsEngine::InitSLPower() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ varying vec4 varyTexCoord0; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ uniform sampler2D TextureObject0; \n\ uniform vec2 TextureSize0; \n\ uniform vec4 exponent; \n\ uniform vec4 color0; \n\ vec4 SampleTexture(sampler2D TexObject, vec2 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ void main(void) \n\ { \n\ vec4 TexColor = SampleTexture(TextureObject0, varyTexCoord0.st); \n\ vec4 result = pow(TexColor, exponent); \n\ gl_FragColor = color0*result; \n\ }"; _component_exponentiation_prog = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); _component_exponentiation_prog->ClearShaderObjects(); _component_exponentiation_prog->AddShaderObject(VS); _component_exponentiation_prog->AddShaderObject(PS); CHECKGL(glBindAttribLocation(_component_exponentiation_prog->GetOpenGLID(), 0, "AVertex")); _component_exponentiation_prog->Link(); } void GraphicsEngine::InitSLAlphaReplicate() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ varying vec4 varyTexCoord0; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ uniform sampler2D TextureObject0; \n\ uniform vec4 color0; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ void main() \n\ { \n\ vec4 v = SampleTexture(TextureObject0, varyTexCoord0); \n\ gl_FragColor = vec4(v.a, v.a, v.a, v.a) * color0; \n\ }"; _alpha_replicate_prog = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); _alpha_replicate_prog->ClearShaderObjects(); _alpha_replicate_prog->AddShaderObject(VS); _alpha_replicate_prog->AddShaderObject(PS); CHECKGL(glBindAttribLocation(_alpha_replicate_prog->GetOpenGLID(), 0, "AVertex")); _alpha_replicate_prog->Link(); } void GraphicsEngine::InitSLHorizontalHQGaussFilter(int sigma) { int k = Clamp(sigma, NUX_MIN_GAUSSIAN_SIGMA, NUX_MAX_GAUSSIAN_SIGMA); if (_horizontal_hq_gauss_filter_prog[k-1].IsValid()) { // Shader program already compiled return; } ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 VertexColor; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyVertexColor = VertexColor; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ uniform vec2 TextureSize0; \n\ vec4 SampleTexture(sampler2D TexObject, vec2 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ #define NUM_SAMPLES %d \n\ uniform float W[NUM_SAMPLES]; \n\ void main() \n\ { \n\ vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); \n\ vec2 delta = vec2(1.0 / TextureSize0.x, 0.0); \n\ vec2 texCoord = vec2(varyTexCoord0.s, varyTexCoord0.t); \n\ texCoord.x -= float((NUM_SAMPLES - 1) / 2) / TextureSize0.x; \n\ texCoord.y += 0.0 / TextureSize0.y; \n\ for (int i = 0; i < NUM_SAMPLES; i++) \n\ { \n\ sum += SampleTexture(TextureObject0, texCoord) * W[i]; \n\ texCoord += delta; \n\ } \n\ gl_FragColor = vec4(sum.x, sum.y, sum.z, 1.0); \n\ }"; int l = strlen(PSString); char* shader_prog = new char[l+10]; sprintf(shader_prog, PSString, 6 * k + 1); _horizontal_hq_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(shader_prog, "#define SAMPLERTEX2D"); delete [] shader_prog; _horizontal_hq_gauss_filter_prog[k-1]->ClearShaderObjects(); _horizontal_hq_gauss_filter_prog[k-1]->AddShaderObject(VS); _horizontal_hq_gauss_filter_prog[k-1]->AddShaderObject(PS); CHECKGL(glBindAttribLocation(_horizontal_hq_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "AVertex")); _horizontal_hq_gauss_filter_prog[k-1]->Link(); } void GraphicsEngine::InitSLVerticalHQGaussFilter(int sigma) { int k = Clamp(sigma, NUX_MIN_GAUSSIAN_SIGMA, NUX_MAX_GAUSSIAN_SIGMA); if (_vertical_hq_gauss_filter_prog[k-1].IsValid()) { // Shader program already compiled return; } ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 VertexColor; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyVertexColor = VertexColor; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ uniform vec2 TextureSize0; \n\ vec4 SampleTexture(sampler2D TexObject, vec2 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ #define NUM_SAMPLES %d \n\ uniform float W [NUM_SAMPLES]; \n\ void main() \n\ { \n\ vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); \n\ vec2 delta = vec2(0.0, 1.0 / TextureSize0.y); \n\ vec2 texCoord = vec2(varyTexCoord0.s, varyTexCoord0.t); \n\ texCoord.x += 0.0 / TextureSize0.x; \n\ texCoord.y -= float((NUM_SAMPLES - 1) / 2) / TextureSize0.y; \n\ for (int i = 0; i < NUM_SAMPLES; ++i) \n\ { \n\ sum += SampleTexture(TextureObject0, texCoord) * W[i]; \n\ texCoord += delta; \n\ } \n\ gl_FragColor = vec4(sum.x, sum.y, sum.z, 1.0); \n\ }"; int l = strlen(PSString); char* shader_prog = new char[l+10]; sprintf(shader_prog, PSString, 6 * k + 1); _vertical_hq_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(shader_prog, "#define SAMPLERTEX2D"); delete [] shader_prog; _vertical_hq_gauss_filter_prog[k-1]->ClearShaderObjects(); _vertical_hq_gauss_filter_prog[k-1]->AddShaderObject(VS); _vertical_hq_gauss_filter_prog[k-1]->AddShaderObject(PS); CHECKGL(glBindAttribLocation(_vertical_hq_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "AVertex")); _vertical_hq_gauss_filter_prog[k-1]->Link(); } void GraphicsEngine::InitSLHorizontalLSGaussFilter(int k) { if (_horizontal_ls_gauss_filter_prog[k-1].IsValid()) { // Shader program already compiled return; } ObjectPtr vs = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr ps = _graphics_display.m_DeviceFactory->CreatePixelShader(); std::string vs_string = NUX_VERTEX_SHADER_HEADER "uniform mat4 view_projection_matrix; \n\ attribute vec4 vertex; \n\ attribute vec4 tex_coord; \n\ varying vec4 v_tex_coord; \n\ void main() \n\ { \n\ v_tex_coord = tex_coord; \n\ gl_Position = view_projection_matrix * vertex; \n\ }"; std::string ps_string = NUX_FRAGMENT_SHADER_HEADER "varying vec4 v_tex_coord; \n\ uniform sampler2D tex_object; \n\ #define NUM_SAMPLES %d \n\ uniform vec2 taps[NUM_SAMPLES]; \n\ void main() \n\ { \n\ vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb * taps[0][1]; \n\ for (int i = 1; i < NUM_SAMPLES; i++) \n\ { \n\ vec2 tap = taps[i]; \n\ vec2 offset = vec2(tap[0], 0.0); \n\ float weight = tap[1]; \n\ acc += texture2D(tex_object, v_tex_coord.st + offset).rgb * weight; \n\ acc += texture2D(tex_object, v_tex_coord.st - offset).rgb * weight; \n\ } \n\ gl_FragColor = vec4(acc, 1.0); \n\ }"; int l = ps_string.length(); char* shader_prog = new char[l+10]; sprintf(shader_prog, ps_string.c_str(), k); _horizontal_ls_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); vs->SetShaderCode(vs_string.c_str()); ps->SetShaderCode(shader_prog); delete[] shader_prog; _horizontal_ls_gauss_filter_prog[k-1]->ClearShaderObjects(); _horizontal_ls_gauss_filter_prog[k-1]->AddShaderObject(vs); _horizontal_ls_gauss_filter_prog[k-1]->AddShaderObject(ps); CHECKGL(glBindAttribLocation(_horizontal_ls_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "vertex")); _horizontal_ls_gauss_filter_prog[k-1]->Link(); } void GraphicsEngine::InitSLVerticalLSGaussFilter(int k) { if (_vertical_ls_gauss_filter_prog[k-1].IsValid()) { // Shader program already compiled return; } ObjectPtr vs = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr ps = _graphics_display.m_DeviceFactory->CreatePixelShader(); std::string vs_string = NUX_VERTEX_SHADER_HEADER "uniform mat4 view_projection_matrix; \n\ attribute vec4 vertex; \n\ attribute vec4 tex_coord; \n\ varying vec4 v_tex_coord; \n\ void main() \n\ { \n\ v_tex_coord = tex_coord; \n\ gl_Position = view_projection_matrix * vertex; \n\ }"; std::string ps_string = NUX_FRAGMENT_SHADER_HEADER "varying vec4 v_tex_coord; \n\ uniform sampler2D tex_object; \n\ #define NUM_SAMPLES %d \n\ uniform vec2 taps[NUM_SAMPLES]; \n\ void main() \n\ { \n\ vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb * taps[0][1]; \n\ for (int i = 1; i < NUM_SAMPLES; i++) \n\ { \n\ vec2 tap = taps[i]; \n\ vec2 offset = vec2(0.0, tap[0]); \n\ float weight = tap[1]; \n\ acc += texture2D(tex_object, v_tex_coord.st + offset).rgb * weight; \n\ acc += texture2D(tex_object, v_tex_coord.st - offset).rgb * weight; \n\ } \n\ gl_FragColor = vec4(acc, 1.0); \n\ }"; int l = ps_string.length(); char* shader_prog = new char[l+10]; sprintf(shader_prog, ps_string.c_str(), k); _vertical_ls_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); vs->SetShaderCode(vs_string.c_str()); ps->SetShaderCode(shader_prog); delete[] shader_prog; _vertical_ls_gauss_filter_prog[k-1]->ClearShaderObjects(); _vertical_ls_gauss_filter_prog[k-1]->AddShaderObject(vs); _vertical_ls_gauss_filter_prog[k-1]->AddShaderObject(ps); CHECKGL(glBindAttribLocation(_vertical_ls_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "vertex")); _vertical_ls_gauss_filter_prog[k-1]->Link(); } void GraphicsEngine::InitSLColorMatrixFilter() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ varying vec4 varyTexCoord0; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ uniform sampler2D TextureObject0; \n\ uniform vec4 color0; \n\ vec4 SampleTexture(sampler2D TexObject, vec2 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ // Color Matrix \n\ uniform float CM0[5]; \n\ uniform float CM1[5]; \n\ uniform float CM2[5]; \n\ uniform float CM3[5]; \n\ void main(void) \n\ { \n\ vec4 tex0 = SampleTexture(TextureObject0, varyTexCoord0.st); \n\ float r = CM0[0]* tex0.r + CM0[1]* tex0.g + CM0[2]* tex0.b + CM0[3]* tex0.a + CM0[4]; \n\ float g = CM1[0]* tex0.r + CM1[1]* tex0.g + CM1[2]* tex0.b + CM1[3]* tex0.a + CM1[4]; \n\ float b = CM2[0]* tex0.r + CM2[1]* tex0.g + CM2[2]* tex0.b + CM2[3]* tex0.a + CM2[4]; \n\ float a = CM3[0]* tex0.r + CM3[1]* tex0.g + CM3[2]* tex0.b + CM3[3]* tex0.a + CM3[4]; \n\ gl_FragColor = color0 * vec4(r, g, b, tex0.a); \n\ }"; _color_matrix_filter_prog = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString), "#define SAMPLERTEX2D"); _color_matrix_filter_prog->ClearShaderObjects(); _color_matrix_filter_prog->AddShaderObject(VS); _color_matrix_filter_prog->AddShaderObject(PS); CHECKGL(glBindAttribLocation(_color_matrix_filter_prog->GetOpenGLID(), 0, "AVertex")); _color_matrix_filter_prog->Link(); } void GraphicsEngine::QRP_GLSL_Color(int x, int y, int width, int height, const Color &color) { QRP_GLSL_Color(x, y, width, height, color, color, color, color); } void GraphicsEngine::QRP_GLSL_Color(int x, int y, int width, int height, const Color &c0, const Color &c1, const Color &c2, const Color &c3) { if (!m_SlColor.IsValid()) InitSlColorShader(); m_quad_tex_stats++; float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, c0.red, c0.green, c0.blue, c0.alpha, fx, fy + height, 0.0f, 1.0f, c1.red, c1.green, c1.blue, c1.alpha, fx + width, fy + height, 0.0f, 1.0f, c2.red, c2.green, c2.blue, c2.alpha, fx + width, fy, 0.0f, 1.0f, c3.red, c3.green, c3.blue, c3.alpha, }; ObjectPtr ShaderProg = m_SlColor; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_1Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm &texxform0, const Color &color0) { if (!m_SlTextureModColor.IsValid()) InitSlTextureShader(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, DeviceTexture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, }; ObjectPtr ShaderProg; if (DeviceTexture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { ShaderProg = m_SlTextureModColor; } // if (DeviceTexture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType) || // DeviceTexture->Type().IsDerivedFromType(IOpenGLAnimatedTexture::StaticObjectType)) // { // ShaderProg = m_TexturedRectProg; // } CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); SetTexture(GL_TEXTURE0, DeviceTexture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); } // Render the texture alpha into RGB and modulated by a color. void GraphicsEngine::QRP_GLSL_ColorModTexAlpha(int x, int y, int width, int height, ObjectPtr< IOpenGLBaseTexture> DeviceTexture, TexCoordXForm &texxform, const Color &color) { if (!m_SlColorModTexMaskAlpha.IsValid()) InitSlColorModTexMaskAlpha(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, DeviceTexture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 0, color.red, color.green, color.blue, color.alpha, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 0, color.red, color.green, color.blue, color.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 0, color.red, color.green, color.blue, color.alpha, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 0, color.red, color.green, color.blue, color.alpha, }; ObjectPtr ShaderProg; // if (DeviceTexture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { ShaderProg = m_SlColorModTexMaskAlpha; } if (DeviceTexture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType) || DeviceTexture->Type().IsDerivedFromType(IOpenGLAnimatedTexture::StaticObjectType)) { ShaderProg = m_SlColorModTexRectMaskAlpha; } CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); SetTexture(GL_TEXTURE0, DeviceTexture); if (TextureObjectLocation != -1) { CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); } int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); if (VertexLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); } if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArray(TextureCoord0Location)); CHECKGL(glVertexAttribPointer((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); if (VertexLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) { CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); } if (VertexColorLocation != -1) { CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); } ShaderProg->End(); } // Blend 2 textures together void GraphicsEngine::QRP_GLSL_2Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr DeviceTexture1, TexCoordXForm &texxform1, const Color &color1) { if (!m_Sl2TextureAdd.IsValid()) InitSl2TextureAdd(); ObjectPtr ShaderProg; ShaderProg = m_Sl2TextureAdd; QRP_Compute_Texture_Coord(width, height, DeviceTexture0, texxform0); QRP_Compute_Texture_Coord(width, height, DeviceTexture1, texxform1); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0.0f, 1.0f, texxform1.u0, texxform1.v0, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0.0f, 1.0f, texxform1.u0, texxform1.v1, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0.0f, 1.0f, texxform1.u1, texxform1.v1, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0.0f, 1.0f, texxform1.u1, texxform1.v0, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation0 = ShaderProg->GetUniformLocationARB("TextureObject0"); int TextureObjectLocation1 = ShaderProg->GetUniformLocationARB("TextureObject1"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int TextureCoord1Location = ShaderProg->GetAttributeLocation("MyTextureCoord1"); int TextureCoef0Location = ShaderProg->GetUniformLocationARB("color0"); int TextureCoef1Location = ShaderProg->GetUniformLocationARB("color1"); SetTexture(GL_TEXTURE0, DeviceTexture0); SetTexture(GL_TEXTURE1, DeviceTexture1); CHECKGL(glUniform1iARB(TextureObjectLocation0, 0)); CHECKGL(glUniform1iARB(TextureObjectLocation1, 1)); CHECKGL(glUniform4fARB(TextureCoef0Location, color0.red, color0.green, color0.blue, color0.alpha )); CHECKGL(glUniform4fARB(TextureCoef1Location, color1.red, color1.green, color1.blue, color1.alpha )); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_DisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm &texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm &texxform1, const Color& c1) { if (!m_Sl2TextureDepRead.IsValid()) InitSl2TextureDepRead(); ObjectPtr ShaderProg = m_Sl2TextureDepRead; QRP_Compute_Texture_Coord(width, height, distorsion_texture, texxform0); QRP_Compute_Texture_Coord(width, height, src_device_texture, texxform1); float fx = x, fy = y; float VtxBuffer [] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0.0f, 1.0f, texxform1.u0, texxform1.v0, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0.0f, 1.0f, texxform1.u0, texxform1.v1, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0.0f, 1.0f, texxform1.u1, texxform1.v1, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0.0f, 1.0f, texxform1.u1, texxform1.v0, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation0 = ShaderProg->GetUniformLocationARB("TextureObject0"); int TextureObjectLocation1 = ShaderProg->GetUniformLocationARB("TextureObject1"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int TextureCoord1Location = ShaderProg->GetAttributeLocation("MyTextureCoord1"); int TextureCoef0Location = ShaderProg->GetUniformLocationARB("color0"); int TextureCoef1Location = ShaderProg->GetUniformLocationARB("color1"); SetTexture(GL_TEXTURE0, distorsion_texture); SetTexture(GL_TEXTURE1, src_device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation0, 0)); CHECKGL(glUniform1iARB(TextureObjectLocation1, 1)); CHECKGL(glUniform4fARB(TextureCoef0Location, c0.red, c0.green, c0.blue, c0.alpha )); CHECKGL(glUniform4fARB(TextureCoef1Location, c1.red, c1.green, c1.blue, c1.alpha )); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_2TexMod(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr DeviceTexture1, TexCoordXForm &texxform1, const Color &color1) { if (!m_Sl2TextureMod.IsValid()) InitSl2TextureMod(); ObjectPtr ShaderProg; { ShaderProg = m_Sl2TextureMod; } QRP_Compute_Texture_Coord(width, height, DeviceTexture0, texxform0); QRP_Compute_Texture_Coord(width, height, DeviceTexture1, texxform1); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0.0f, 1.0f, texxform1.u0, texxform1.v0, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0.0f, 1.0f, texxform1.u0, texxform1.v1, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0.0f, 1.0f, texxform1.u1, texxform1.v1, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0.0f, 1.0f, texxform1.u1, texxform1.v0, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation0 = ShaderProg->GetUniformLocationARB("TextureObject0"); int TextureObjectLocation1 = ShaderProg->GetUniformLocationARB("TextureObject1"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int TextureCoord1Location = ShaderProg->GetAttributeLocation("MyTextureCoord1"); int TextureCoef0Location = ShaderProg->GetUniformLocationARB("color0"); int TextureCoef1Location = ShaderProg->GetUniformLocationARB("color1"); SetTexture(GL_TEXTURE0, DeviceTexture0); SetTexture(GL_TEXTURE1, DeviceTexture1); CHECKGL(glUniform1iARB(TextureObjectLocation0, 0)); CHECKGL(glUniform1iARB(TextureObjectLocation1, 1)); CHECKGL(glUniform4fARB(TextureCoef0Location, color0.red, color0.green, color0.blue, color0.alpha )); CHECKGL(glUniform4fARB(TextureCoef1Location, color1.red, color1.green, color1.blue, color1.alpha )); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_4Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr DeviceTexture1, TexCoordXForm &texxform1, const Color &color1, ObjectPtr DeviceTexture2, TexCoordXForm &texxform2, const Color &color2, ObjectPtr DeviceTexture3, TexCoordXForm &texxform3, const Color &color3) { if (!m_Sl4TextureAdd.IsValid()) InitSl4TextureAdd(); QRP_Compute_Texture_Coord(width, height, DeviceTexture0, texxform0); QRP_Compute_Texture_Coord(width, height, DeviceTexture1, texxform1); QRP_Compute_Texture_Coord(width, height, DeviceTexture2, texxform2); QRP_Compute_Texture_Coord(width, height, DeviceTexture3, texxform3); ObjectPtr ShaderProg; ShaderProg = m_Sl4TextureAdd; float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 1.0f, texxform1.u0, texxform1.v0, 0, 1.0f, texxform2.u0, texxform2.v0, 0, 1.0f, texxform3.u0, texxform3.v0, 0, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 1.0f, texxform1.u0, texxform1.v1, 0, 1.0f, texxform2.u0, texxform2.v1, 0, 1.0f, texxform3.u0, texxform3.v1, 0, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 1.0f, texxform1.u1, texxform1.v1, 0, 1.0f, texxform2.u1, texxform2.v1, 0, 1.0f, texxform3.u1, texxform3.v1, 0, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 1.0f, texxform1.u1, texxform1.v0, 0, 1.0f, texxform2.u1, texxform2.v0, 0, 1.0f, texxform3.u1, texxform3.v0, 0, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation0 = ShaderProg->GetUniformLocationARB("TextureObject0"); int TextureObjectLocation1 = ShaderProg->GetUniformLocationARB("TextureObject1"); int TextureObjectLocation2 = ShaderProg->GetUniformLocationARB("TextureObject2"); int TextureObjectLocation3 = ShaderProg->GetUniformLocationARB("TextureObject3"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int TextureCoord1Location = ShaderProg->GetAttributeLocation("MyTextureCoord1"); int TextureCoord2Location = ShaderProg->GetAttributeLocation("MyTextureCoord2"); int TextureCoord3Location = ShaderProg->GetAttributeLocation("MyTextureCoord3"); int TextureCoef0Location = ShaderProg->GetUniformLocationARB("color0"); int TextureCoef1Location = ShaderProg->GetUniformLocationARB("color1"); int TextureCoef2Location = ShaderProg->GetUniformLocationARB("color2"); int TextureCoef3Location = ShaderProg->GetUniformLocationARB("color3"); SetTexture(GL_TEXTURE0, DeviceTexture0); SetTexture(GL_TEXTURE1, DeviceTexture1); SetTexture(GL_TEXTURE2, DeviceTexture2); SetTexture(GL_TEXTURE3, DeviceTexture3); CHECKGL(glUniform1iARB(TextureObjectLocation0, 0)); CHECKGL(glUniform1iARB(TextureObjectLocation1, 1)); CHECKGL(glUniform1iARB(TextureObjectLocation2, 2)); CHECKGL(glUniform1iARB(TextureObjectLocation3, 3)); CHECKGL(glUniform4fARB(TextureCoef0Location, color0.red, color0.green, color0.blue, color0.alpha )); CHECKGL(glUniform4fARB(TextureCoef1Location, color1.red, color1.green, color1.blue, color1.alpha )); CHECKGL(glUniform4fARB(TextureCoef2Location, color2.red, color2.green, color2.blue, color2.alpha )); CHECKGL(glUniform4fARB(TextureCoef3Location, color3.red, color3.green, color3.blue, color3.alpha )); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 8)); } if (TextureCoord2Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord2Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord2Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 12)); } if (TextureCoord3Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord3Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord3Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 16)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); if (TextureCoord2Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord2Location)); if (TextureCoord3Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord3Location)); ShaderProg->End(); } /////////////////////////////////////////// void GraphicsEngine::QRP_GLSL_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0) { QRP_GLSL_Triangle(x0, y0, x1, y1, x2, y2, c0, c0, c0); } void GraphicsEngine::QRP_GLSL_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2) { if (!m_SlColor.IsValid()) InitSlColorShader(); float VtxBuffer[] = { static_cast(x0), static_cast(y0), 0.0f, 1.0f, c0.red, c0.green, c0.blue, c0.alpha, static_cast(x1), static_cast(y1), 0.0f, 1.0f, c1.red, c1.green, c1.blue, c1.alpha, static_cast(x2), static_cast(y2), 0.0f, 1.0f, c2.red, c2.green, c2.blue, c2.alpha, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); m_SlColor->Begin(); int VertexLocation = m_SlColor->GetAttributeLocation("AVertex"); int VertexColorLocation = m_SlColor->GetAttributeLocation("VertexColor"); int VPMatrixLocation = m_SlColor->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); m_SlColor->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); CHECKGL(glDrawArrays(GL_TRIANGLES, 0, 3)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); m_SlColor->End(); m_triangle_stats++; } ////////////////////// // DRAW LINES // ////////////////////// void GraphicsEngine::QRP_GLSL_Line(int x0, int y0, int x1, int y1, Color c0) { QRP_GLSL_Line(x0, y0, x1, y1, c0, c0); } void GraphicsEngine::QRP_GLSL_Line(int x0, int y0, int x1, int y1, Color c0, Color c1) { if (!m_SlColor.IsValid()) InitSlColorShader(); float VtxBuffer[] = { static_cast(x0), static_cast(y0), 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c0.red, c0.green, c0.blue, c0.alpha, static_cast(x1), static_cast(y1), 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c1.red, c1.green, c1.blue, c1.alpha, }; ObjectPtr ShaderProg = m_SlColor; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_LINES, 0, 2)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); m_line_stats++; } void GraphicsEngine::QRP_GLSL_QuadWireframe(int x0, int y0, int width, int height, Color c0, Color c1, Color c2, Color c3) { if (!m_SlColor.IsValid()) InitSlColorShader(); float fx0 = x0, fy0 = y0; float VtxBuffer[] = { fx0, fy0, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c0.red, c0.green, c0.blue, c0.alpha, fx0, fy0 + height - 1, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c1.red, c1.green, c1.blue, c1.alpha, fx0 + width - 1, fy0 + height - 1, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c2.red, c2.green, c2.blue, c2.alpha, fx0 + width - 1, fy0, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c3.red, c3.green, c3.blue, c3.alpha, fx0, fy0, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, c0.red, c0.green, c0.blue, c0.alpha, }; ObjectPtr ShaderProg = m_SlColor; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_LINE_STRIP, 0, 5)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); m_line_stats++; } void GraphicsEngine::QRP_GLSL_Power(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color &c0, Vector4 exponent) { if (!_component_exponentiation_prog.IsValid()) InitSLPower(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr ShaderProg; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } ShaderProg = _component_exponentiation_prog; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int Color0Location = ShaderProg->GetUniformLocationARB("color0"); int ExponentLocation = ShaderProg->GetUniformLocationARB("exponent"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); CHECKGL(glUniform4fARB(ExponentLocation, exponent.x, exponent.y, exponent.z, exponent.w )); CHECKGL(glUniform4fARB(Color0Location, c0.red, c0.green, c0.blue, c0.alpha)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_AlphaReplicate(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color &c0) { if (!_alpha_replicate_prog.IsValid()) InitSLAlphaReplicate(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr ShaderProg; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } ShaderProg = _alpha_replicate_prog; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int Color0Location = ShaderProg->GetUniformLocationARB("color0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); CHECKGL(glUniform4fARB(Color0Location, c0.red, c0.green, c0.blue, c0.alpha)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); ShaderProg->End(); } void GraphicsEngine::InitSLHorizontalGaussFilter() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ varying vec4 varyTexCoord0; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ uniform sampler2D TextureObject0; \n\ uniform vec2 TextureSize0; \n\ vec4 SampleTexture(sampler2D TexObject, vec2 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ #define NUM_SAMPLES 7 \n\ uniform float W[NUM_SAMPLES]; \n\ void main() \n\ { \n\ vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); \n\ vec2 delta = vec2(1.0 / TextureSize0.x, 0.0); \n\ vec2 texCoord = vec2(varyTexCoord0.s, varyTexCoord0.t); \n\ texCoord.x -= float((NUM_SAMPLES - 1) / 2) / TextureSize0.x; \n\ texCoord.y += 0.0 / TextureSize0.y; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[0]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[1]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[2]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[3]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[4]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[5]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[6]; \n\ texCoord += delta; \n\ gl_FragColor = vec4(sum.x, sum.y, sum.z, sum.w); \n\ }"; _horizontal_gauss_filter_prog = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); _horizontal_gauss_filter_prog->ClearShaderObjects(); _horizontal_gauss_filter_prog->AddShaderObject(VS); _horizontal_gauss_filter_prog->AddShaderObject(PS); CHECKGL(glBindAttribLocation(_horizontal_gauss_filter_prog->GetOpenGLID(), 0, "AVertex")); _horizontal_gauss_filter_prog->Link(); } void GraphicsEngine::QRP_GLSL_HorizontalGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma) { if (!_horizontal_gauss_filter_prog.IsValid()) InitSLHorizontalGaussFilter(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr ShaderProg; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } ShaderProg = _horizontal_gauss_filter_prog; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int WeightsLocation = ShaderProg->GetUniformLocationARB("W"); int TextureSizeLocation = ShaderProg->GetUniformLocationARB("TextureSize0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); sigma = Clamp (sigma, 0.1f, 9.0f); // Set the Gaussian weights { float *W; GaussianWeights(&W, sigma, 7); CHECKGL(glUniform1fv(WeightsLocation, 7, W)); delete[] W; } CHECKGL(glUniform2fARB(TextureSizeLocation, width, height)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); ShaderProg->End(); } void GraphicsEngine::InitSLVerticalGaussFilter() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ varying vec4 varyTexCoord0; \n\ void main() \n\ { \n\ varyTexCoord0 = MyTextureCoord0; \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ uniform sampler2D TextureObject0; \n\ uniform vec2 TextureSize0; \n\ vec4 SampleTexture(sampler2D TexObject, vec2 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ #define NUM_SAMPLES 7 \n\ uniform float W [NUM_SAMPLES]; \n\ void main() \n\ { \n\ vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); \n\ vec2 delta = vec2(0.0, 1.0 / TextureSize0.y); \n\ vec2 texCoord = vec2(varyTexCoord0.s, varyTexCoord0.t); \n\ texCoord.x += 0.0 / TextureSize0.x; \n\ texCoord.y -= float((NUM_SAMPLES - 1) / 2) / TextureSize0.y; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[0]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[1]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[2]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[3]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[4]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[5]; \n\ texCoord += delta; \n\ sum += SampleTexture(TextureObject0, texCoord) * W[6]; \n\ texCoord += delta; \n\ gl_FragColor = vec4(sum.x, sum.y, sum.z, sum.w); \n\ }"; _vertical_gauss_filter_prog = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); _vertical_gauss_filter_prog->ClearShaderObjects(); _vertical_gauss_filter_prog->AddShaderObject(VS); _vertical_gauss_filter_prog->AddShaderObject(PS); CHECKGL(glBindAttribLocation(_vertical_gauss_filter_prog->GetOpenGLID(), 0, "AVertex")); _vertical_gauss_filter_prog->Link(); } void GraphicsEngine::QRP_GLSL_VerticalGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma) { if (!_vertical_gauss_filter_prog.IsValid()) InitSLVerticalGaussFilter(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr ShaderProg; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } ShaderProg = _vertical_gauss_filter_prog; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int WeightsLocation = ShaderProg->GetUniformLocationARB("W"); int TextureSizeLocation = ShaderProg->GetUniformLocationARB("TextureSize0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); sigma = Clamp (sigma, 0.1f, 9.0f); // Set the Gaussian weights { float *W; GaussianWeights(&W, sigma, 7); CHECKGL(glUniform1fv(WeightsLocation, 7, W)); delete[] W; } CHECKGL(glUniform2fARB(TextureSizeLocation, width, height)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_HorizontalHQGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma) { int k = Clamp(sigma, NUX_MIN_GAUSSIAN_SIGMA, NUX_MAX_GAUSSIAN_SIGMA); if (_horizontal_hq_gauss_filter_prog[k-1].IsValid() == false) { InitSLHorizontalHQGaussFilter(k); } m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr ShaderProg; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } ShaderProg = _horizontal_hq_gauss_filter_prog[k-1]; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int WeightsLocation = ShaderProg->GetUniformLocationARB("W"); int TextureSizeLocation = ShaderProg->GetUniformLocationARB("TextureSize0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); sigma = Clamp (sigma, 0.1f, NUX_MAX_GAUSSIAN_SIGMA); // Set the Gaussian weights { float *W; GaussianWeights(&W, sigma, 6*k+1); CHECKGL(glUniform1fv(WeightsLocation, 6*k+1, W)); delete[] W; } CHECKGL(glUniform2fARB(TextureSizeLocation, width, height)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_VerticalHQGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma) { int k = Clamp(sigma, NUX_MIN_GAUSSIAN_SIGMA, NUX_MAX_GAUSSIAN_SIGMA); if (_vertical_hq_gauss_filter_prog[k-1].IsValid() == false) { InitSLVerticalHQGaussFilter(k); } m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr ShaderProg; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } ShaderProg = _vertical_hq_gauss_filter_prog[k-1]; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int WeightsLocation = ShaderProg->GetUniformLocationARB("W"); int TextureSizeLocation = ShaderProg->GetUniformLocationARB("TextureSize0"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); sigma = Clamp (sigma, 0.1f, NUX_MAX_GAUSSIAN_SIGMA); // Set the Gaussian weights { float *W; GaussianWeights(&W, sigma, 6*k+1); CHECKGL(glUniform1fv(WeightsLocation, 6*k+1, W)); delete[] W; } CHECKGL(glUniform2fARB(TextureSizeLocation, width, height)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); ShaderProg->End(); } void GraphicsEngine::QRP_GLSL_HorizontalLSGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma) { std::vector weights(0); std::vector offsets(0); int num_samples = LinearSampleGaussianWeights(weights, offsets, sigma); if (_horizontal_ls_gauss_filter_prog[num_samples-1].IsValid() == false) { InitSLHorizontalLSGaussFilter(num_samples); } m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float vtx_buffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr shader_prog; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } shader_prog = _horizontal_ls_gauss_filter_prog[num_samples-1]; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); shader_prog->Begin(); int tex_object_location = shader_prog->GetUniformLocationARB("tex_object"); int taps_location = shader_prog->GetUniformLocationARB("taps"); int vertex_location = shader_prog->GetAttributeLocation("vertex"); int tex_coord_location = shader_prog->GetAttributeLocation("tex_coord"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(tex_object_location, 0)); std::vector taps; for (int i = 0; i < num_samples; ++i) { taps.push_back(offsets[i] /= width); taps.push_back(weights[i]); } CHECKGL(glUniform2fv(taps_location, taps.size(), &taps[0])); int VPMatrixLocation = shader_prog->GetUniformLocationARB("view_projection_matrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); shader_prog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(vertex_location)); CHECKGL(glVertexAttribPointerARB((GLuint) vertex_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer)); if (tex_coord_location != -1) { CHECKGL(glEnableVertexAttribArrayARB(tex_coord_location)); CHECKGL(glVertexAttribPointerARB((GLuint) tex_coord_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(vertex_location)); if (tex_coord_location != -1) CHECKGL(glDisableVertexAttribArrayARB(tex_coord_location)); shader_prog->End(); } void GraphicsEngine::QRP_GLSL_VerticalLSGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma) { std::vector weights(0); std::vector offsets(0); int num_samples = LinearSampleGaussianWeights(weights, offsets, sigma); if (_vertical_ls_gauss_filter_prog[num_samples-1].IsValid() == false) { InitSLVerticalLSGaussFilter(num_samples); } m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float vtx_buffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr shader_prog; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } shader_prog = _vertical_ls_gauss_filter_prog[num_samples-1]; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); shader_prog->Begin(); int tex_object_location = shader_prog->GetUniformLocationARB("tex_object"); int taps_location = shader_prog->GetUniformLocationARB("taps"); int vertex_location = shader_prog->GetAttributeLocation("vertex"); int tex_coord_location = shader_prog->GetAttributeLocation("tex_coord"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(tex_object_location, 0)); std::vector taps; for (int i = 0; i < num_samples; ++i) { taps.push_back(offsets[i] /= height); taps.push_back(weights[i]); } CHECKGL(glUniform2fv(taps_location, taps.size(), &taps[0])); int VPMatrixLocation = shader_prog->GetUniformLocationARB("view_projection_matrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); shader_prog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(vertex_location)); CHECKGL(glVertexAttribPointerARB((GLuint) vertex_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer)); if (tex_coord_location != -1) { CHECKGL(glEnableVertexAttribArrayARB(tex_coord_location)); CHECKGL(glVertexAttribPointerARB((GLuint) tex_coord_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(vertex_location)); if (tex_coord_location != -1) CHECKGL(glDisableVertexAttribArrayARB(tex_coord_location)); shader_prog->End(); } void GraphicsEngine::QRP_GLSL_ColorMatrix(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform0, const Color &c0, Matrix4 color_matrix, Vector4 offset) { if (!_color_matrix_filter_prog.IsValid()) InitSLColorMatrixFilter(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, }; ObjectPtr ShaderProg; if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { return; } ShaderProg = _color_matrix_filter_prog; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int Color0Location = ShaderProg->GetUniformLocationARB("color0"); int MatrixRow0Location = ShaderProg->GetUniformLocationARB("CM0"); int MatrixRow1Location = ShaderProg->GetUniformLocationARB("CM1"); int MatrixRow2Location = ShaderProg->GetUniformLocationARB("CM2"); int MatrixRow3Location = ShaderProg->GetUniformLocationARB("CM3"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); CHECKGL(glUniform4fARB(Color0Location, c0.red, c0.green, c0.blue, c0.alpha)); float v[5]; v[0] = color_matrix.m[0][0]; v[1] = color_matrix.m[0][1]; v[2] = color_matrix.m[0][2]; v[3] = color_matrix.m[0][3]; v[4] = offset.x; CHECKGL(glUniform1fvARB(MatrixRow0Location, 5, v)); v[0] = color_matrix.m[1][0]; v[1] = color_matrix.m[1][1]; v[2] = color_matrix.m[1][2]; v[3] = color_matrix.m[1][3]; v[4] = offset.y; CHECKGL(glUniform1fvARB(MatrixRow1Location, 5, v)); v[0] = color_matrix.m[2][0]; v[1] = color_matrix.m[2][1]; v[2] = color_matrix.m[2][2]; v[3] = color_matrix.m[2][3]; v[4] = offset.z; CHECKGL(glUniform1fvARB(MatrixRow2Location, 5, v)); v[0] = color_matrix.m[3][0]; v[1] = color_matrix.m[3][1]; v[2] = color_matrix.m[3][2]; v[3] = color_matrix.m[3][3]; v[4] = offset.w; CHECKGL(glUniform1fvARB(MatrixRow3Location, 5, v)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); ShaderProg->End(); } ObjectPtr GraphicsEngine::QRP_GLSL_GetBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, float sigma, int num_pass) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); num_pass = Clamp (num_pass, 1, 50); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(x, y, quad_width, quad_height, device_texture, texxform, color::White); TexCoordXForm texxform1; for (int i = 0; i < num_pass; i++) { SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); if (_offscreen_color_rt0.IsValid()) QRP_GLSL_HorizontalGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt0, texxform1, c0, sigma); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); if (_offscreen_color_rt1.IsValid()) QRP_GLSL_VerticalGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt1, texxform1, c0, sigma); } _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt0; } ObjectPtr GraphicsEngine::QRP_GLSL_GetLSBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, float sigma, int num_pass) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); num_pass = Clamp (num_pass, 1, 50); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(x, y, quad_width, quad_height, device_texture, texxform, color::White); TexCoordXForm texxform1; for (int i = 0; i < num_pass; i++) { SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_HorizontalLSGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt0, texxform1, c0, sigma); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_VerticalLSGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt1, texxform1, c0, sigma); } _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt0; } ObjectPtr GraphicsEngine::QRP_GLSL_GetPower( ObjectPtr device_texture, TexCoordXForm &texxform, const Color &c0, const Vector4 &exponent) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(0, 0, quad_width, quad_height, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_Power(0, 0, quad_width, quad_height, _offscreen_color_rt0, texxform, c0, exponent); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt1; } ObjectPtr GraphicsEngine::QRP_GLSL_GetAlphaTexture( ObjectPtr device_texture, TexCoordXForm &texxform, const Color & c0) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(0, 0, quad_width, quad_height, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_AlphaReplicate(0, 0, quad_width, quad_height, _offscreen_color_rt0, texxform, c0); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt1; } ObjectPtr GraphicsEngine::QRP_GLSL_GetColorMatrixTexture( ObjectPtr device_texture, TexCoordXForm &texxform, const Color & c0, Matrix4 color_matrix, Vector4 offset) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(0, 0, quad_width, quad_height, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_ColorMatrix(0, 0, quad_width, quad_height, _offscreen_color_rt0, texxform, c0, color_matrix, offset); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt1; } ObjectPtr GraphicsEngine::QRP_GLSL_GetLQBlur( int /* x */, int /* y */, int /* buffer_width */, int /* buffer_height */, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& /* c0 */) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); texxform.mag_filter = TEXFILTER_LINEAR; texxform.min_filter = TEXFILTER_LINEAR; SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width/2, quad_height/2); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(0, 0, quad_width / 2, quad_height / 2, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width/4, quad_height/4); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(0, 0, quad_width / 4, quad_height / 4, _offscreen_color_rt0, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt2, _offscreen_depth_rt2, quad_width/8, quad_height/8); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(0, 0, quad_width / 8, quad_height / 8, _offscreen_color_rt1, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt3, _offscreen_depth_rt3, quad_width, quad_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); TexCoordXForm texxform0; TexCoordXForm texxform1; TexCoordXForm texxform2; TexCoordXForm texxform3; texxform0.flip_v_coord = true; texxform2.flip_v_coord = true; QRP_GLSL_4Tex(0, 0, quad_width, quad_height, device_texture, texxform0, Color(0.25, 0.25, 0.25, 0.25), _offscreen_color_rt0, texxform1, Color(0.25, 0.25, 0.25, 0.25), _offscreen_color_rt1, texxform2, Color(0.25, 0.25, 0.25, 0.25), _offscreen_color_rt2, texxform3, Color(0.25, 0.25, 0.25, 0.25)); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt3; } ObjectPtr GraphicsEngine::QRP_GLSL_GetHQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, float sigma, int num_pass) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); num_pass = Clamp (num_pass, 1, 50); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(x, y, quad_width, quad_height, device_texture, texxform, color::White); TexCoordXForm texxform1; for (int i = 0; i < num_pass; i++) { SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_HorizontalHQGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt0, texxform1, c0, sigma); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_VerticalHQGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt1, texxform1, c0, sigma); } _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt0; } void GraphicsEngine::QRP_GLSL_GetHQBlurFx( int x, int y, int buffer_width, int buffer_height, FxStructure *fx_structure, TexCoordXForm &texxform, const Color& c0, float sigma, int num_pass) { int quad_width = fx_structure->src_texture->GetWidth(); int quad_height = fx_structure->src_texture->GetHeight(); num_pass = Clamp (num_pass, 1, 50); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); fx_structure->src_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->src_texture->SetFiltering(GL_NEAREST, GL_NEAREST); fx_structure->dst_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->dst_texture->SetFiltering(GL_NEAREST, GL_NEAREST); fx_structure->temp_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->temp_texture->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(x, y, quad_width, quad_height, fx_structure->src_texture, texxform, color::White); TexCoordXForm texxform1; for (int i = 0; i < num_pass; i++) { SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_HorizontalGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma); SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_VerticalGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma); } _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } } void GraphicsEngine::QRP_GLSL_GetLSBlurFx( int x, int y, int buffer_width, int buffer_height, FxStructure *fx_structure, TexCoordXForm &texxform, const Color& c0, float sigma, int num_pass) { int quad_width = fx_structure->src_texture->GetWidth(); int quad_height = fx_structure->src_texture->GetHeight(); num_pass = Clamp (num_pass, 1, 50); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); fx_structure->src_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->src_texture->SetFiltering(GL_NEAREST, GL_NEAREST); fx_structure->dst_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->dst_texture->SetFiltering(GL_NEAREST, GL_NEAREST); fx_structure->temp_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->temp_texture->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_1Tex(x, y, quad_width, quad_height, fx_structure->src_texture, texxform, color::White); TexCoordXForm texxform1; for (int i = 0; i < num_pass; i++) { SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_HorizontalLSGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma); SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_VerticalLSGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma); } _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } } ObjectPtr GraphicsEngine::QRP_GLSL_GetDisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm &texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm &texxform1, const Color& c1) { ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, width, height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_DisturbedTexture(x, y, width, height, distorsion_texture, texxform0, c0, src_device_texture, texxform1, c1); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt0; } void GraphicsEngine::QRP_GLSL_GetDisturbedTextureFx( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm &texxform0, const Color& c0, FxStructure *fx_structure, TexCoordXForm &texxform1, const Color& c1) { ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, width, height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_GLSL_DisturbedTexture(x, y, width, height, distorsion_texture, texxform0, c0, fx_structure->src_texture, texxform1, c1); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } } void GraphicsEngine::InitSlPixelateShader() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 VertexColor; \n\ uniform mat4 ViewProjectionMatrix; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyVertexColor = VertexColor; \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform vec4 pixel_size; \n\ uniform vec4 pixel_size_inv; \n\ uniform sampler2D TextureObject0; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ void main() \n\ { \n\ vec4 tex_coord = floor(varyTexCoord0 * pixel_size_inv) * pixel_size; \n\ vec4 v = SampleTexture(TextureObject0, tex_coord); \n\ gl_FragColor = v*varyVertexColor; \n\ }"; // Textured 2D Primitive Shader m_SLPixelate = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString), "#define SAMPLERTEX2D"); m_SLPixelate->ClearShaderObjects(); m_SLPixelate->AddShaderObject(VS); m_SLPixelate->AddShaderObject(PS); CHECKGL(glBindAttribLocation(m_SLPixelate->GetOpenGLID(), 0, "AVertex")); m_SLPixelate->Link(); } void GraphicsEngine::QRP_GLSL_Pixelate(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm &texxform0, const Color &color0, int pixel_size) { if (!m_SLPixelate.IsValid()) InitSlPixelateShader(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, DeviceTexture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, }; float tex_width = DeviceTexture->GetWidth(); float tex_height = DeviceTexture->GetHeight(); ObjectPtr ShaderProg; ShaderProg = m_SLPixelate; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int PixelSizeLocation = ShaderProg->GetUniformLocationARB("pixel_size"); int PixelSizeInvLocation = ShaderProg->GetUniformLocationARB("pixel_size_inv"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); SetTexture(GL_TEXTURE0, DeviceTexture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); ShaderProg->SetUniform4f((GLint) PixelSizeLocation, (float)pixel_size / (float)tex_width, (float)pixel_size / (float)tex_height, 1.0f, 1.0f); ShaderProg->SetUniform4f((GLint) PixelSizeInvLocation, (float)tex_width / (float)pixel_size, (float)tex_height / (float)pixel_size, 1.0f, 1.0f); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); } ObjectPtr GraphicsEngine::QRP_GLSL_GetPixelBlocks( ObjectPtr device_texture, TexCoordXForm &texxform0, const Color& /* c0 */, int pixel_size) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); QRP_GLSL_Pixelate(0, 0, quad_width, quad_height, device_texture, texxform0, color::White, pixel_size); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } return _offscreen_color_rt0; } void GraphicsEngine::QRP_GLSL_GetCopyTexture( int width, int height, ObjectPtr& dst_device_texture, ObjectPtr& src_device_texture, TexCoordXForm &texxform0, const Color& c0) { if (src_device_texture.IsValid() == false) { return; } ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } if ((dst_device_texture.IsValid() == false) || (dst_device_texture->GetWidth() != width) || (dst_device_texture->GetHeight() != height) || (dst_device_texture->GetPixelFormat() != src_device_texture->GetPixelFormat())) { dst_device_texture = _graphics_display.GetGpuDevice()->CreateTexture(width, height, 1, src_device_texture->GetPixelFormat()); } CHECKGL(glClearColor(0, 0, 0, 0)); SetFrameBufferHelper(_offscreen_fbo, dst_device_texture, _offscreen_depth_rt0, width, height); CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); QRP_GLSL_1Tex(0, 0, width, height, src_device_texture, texxform0, c0); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); SetOrthographicProjectionMatrix(previous_width, previous_height); } } void GraphicsEngine::InitSlTexturePremultiplyShader() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); std::string VSString; std::string PSString; VSString = NUX_VERTEX_SHADER_HEADER "attribute vec4 i_vertex; \n\ attribute vec4 i_texture_coord0; \n\ attribute vec4 i_vertex_color; \n\ uniform mat4 ViewProjectionMatrix; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * (i_vertex); \n\ varyTexCoord0 = i_texture_coord0; \n\ varyVertexColor = i_vertex_color; \n\ }"; PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ void main() \n\ { \n\ vec4 tex = texture2D(TextureObject0, varyTexCoord0.st); \n\ gl_FragColor = vec4(tex.r * tex.a, tex.g * tex.a, tex.b * tex.a, tex.a) * varyVertexColor; \n\ }"; // Textured 2D Primitive Shader m_SlTexturePremultiplyModColor = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(VSString.c_str()); PS->SetShaderCode(PSString.c_str()); m_SlTexturePremultiplyModColor->ClearShaderObjects(); m_SlTexturePremultiplyModColor->AddShaderObject(VS); m_SlTexturePremultiplyModColor->AddShaderObject(PS); //CHECKGL(glBindAttribLocation(m_SlTexturePremultiplyModColor->GetOpenGLID(), 0, "i_vertex")); m_SlTexturePremultiplyModColor->Link(); } void GraphicsEngine::QRP_GLSL_1TexPremultiply(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm &texxform0, const Color &color0) { if (DeviceTexture.IsNull() || (!DeviceTexture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType))) { return; } if (!m_SlTexturePremultiplyModColor.IsValid()) InitSlTexturePremultiplyShader(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, DeviceTexture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, }; ObjectPtr ShaderProg = m_SlTexturePremultiplyModColor; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int VertexLocation = ShaderProg->GetAttributeLocation("i_vertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("i_texture_coord0"); int VertexColorLocation = ShaderProg->GetAttributeLocation("i_vertex_color"); SetTexture(GL_TEXTURE0, DeviceTexture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); } void GraphicsEngine::InitSLDesaturation() { ObjectPtr VS = _graphics_display.m_DeviceFactory->CreateVertexShader(); ObjectPtr PS = _graphics_display.m_DeviceFactory->CreatePixelShader(); const char* VSString = NUX_VERTEX_SHADER_HEADER "attribute vec4 AVertex; \n\ attribute vec4 MyTextureCoord0; \n\ attribute vec4 VertexColor; \n\ uniform mat4 ViewProjectionMatrix; \n\ varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * (AVertex); \n\ varyTexCoord0 = MyTextureCoord0; \n\ varyVertexColor = VertexColor; \n\ }"; const char* PSString = NUX_FRAGMENT_SHADER_HEADER "varying vec4 varyTexCoord0; \n\ varying vec4 varyVertexColor; \n\ uniform sampler2D TextureObject0; \n\ uniform float desat_factor; \n\ uniform vec3 luma; \n\ void main() \n\ { \n\ vec4 texel = texture2D(TextureObject0, varyTexCoord0.st); \n\ vec4 desat_texel = vec4 (luma.r * texel.r + luma.g * texel.g + luma.b * texel.b); \n\ vec4 final = (vec4 (1.0, 1.0, 1.0, 1.0) - desat_factor) * desat_texel + desat_factor * texel; \n\ final.a = texel.a; \n\ gl_FragColor = final * varyVertexColor; \n\ }"; // Textured 2D Primitive Shader desaturation_prog_ = _graphics_display.m_DeviceFactory->CreateShaderProgram(); VS->SetShaderCode(TCHAR_TO_ANSI(VSString)); PS->SetShaderCode(TCHAR_TO_ANSI(PSString)); desaturation_prog_->ClearShaderObjects(); desaturation_prog_->AddShaderObject(VS); desaturation_prog_->AddShaderObject(PS); CHECKGL(glBindAttribLocation(desaturation_prog_->GetOpenGLID(), 0, "AVertex")); desaturation_prog_->Link(); } void GraphicsEngine::QRP_GLSL_TexDesaturate(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform0, const Color& color0, float desaturation_factor) { if (!desaturation_prog_.IsValid()) InitSLDesaturation(); m_quad_tex_stats++; QRP_Compute_Texture_Coord(width, height, DeviceTexture, texxform0); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, color0.red, color0.green, color0.blue, color0.alpha, }; ObjectPtr ShaderProg; if (DeviceTexture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { ShaderProg = desaturation_prog_; } CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); int TextureObjectLocation = ShaderProg->GetUniformLocationARB("TextureObject0"); int luma_location = ShaderProg->GetUniformLocationARB("luma"); int desat_factor_location = ShaderProg->GetUniformLocationARB("desat_factor"); int VertexLocation = ShaderProg->GetAttributeLocation("AVertex"); int TextureCoord0Location = ShaderProg->GetAttributeLocation("MyTextureCoord0"); int VertexColorLocation = ShaderProg->GetAttributeLocation("VertexColor"); SetTexture(GL_TEXTURE0, DeviceTexture); CHECKGL(glUniform1iARB(TextureObjectLocation, 0)); float luma[3] = {color::LumaRed, color::LumaGreen, color::LumaBlue}; CHECKGL(glUniform3fv(luma_location, 3, luma)); CHECKGL(glUniform1f(desat_factor_location, desaturation_factor)); int VPMatrixLocation = ShaderProg->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); ShaderProg->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); } } nux-4.0.6+14.04.20140409/NuxGraphics/GLThread.h0000644000015301777760000000153212321344237020774 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLTHREAD_H #define GLTHREAD_H #endif // GLTHREAD_H nux-4.0.6+14.04.20140409/NuxGraphics/GLShaderParameter.cpp0000644000015301777760000000271412321344237023172 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "GLShader.h" #include "GLDeviceObjects.h" #include "GLShaderParameter.h" namespace nux { GLShaderParameter::GLShaderParameter(GLProgramObject *Shader, const char *ParamName, eShaderParameterType ParamType, bool IsOptional, bool IsStatic) : m_ShaderParameterType(ParamType) , m_Name(ParamName) , m_bIsOptional(IsOptional) , m_bIsStatic(IsStatic) , m_ShaderProgram(Shader) , m_ShaderProgram2(0) , m_NextParameter(0) { m_Index = -1; } } nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipeTextureBlendShaderSource.h0000644000015301777760000005171112321344237026737 0ustar pbusernogroup00000000000000/* * Copyright 2010-2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * Robert Carr */ #ifndef RENDERING_PIPE_TEXTURE_BLEND_SHADER_SOURCE_H #define RENDERING_PIPE_TEXTURE_BLEND_SHADER_SOURCE_H namespace nux { static const std::string BlendNormalShader = " \n\ vec3 BlendNormal(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return L; \n\ }"; static const std::string BlendLightenShader = " \n\ vec3 BlendLighten(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ // This mode is commutative \n\ vec3 V = max(L, B); \n\ return V; \n\ }"; static const std::string BlendDarkenShader = " \n\ vec3 BlendDarken(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ vec3 V = min(L, B); \n\ return V; \n\ }"; static const std::string BlendMultiplyShader = " \n\ vec3 BlendMultiply(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return(B * L); \n\ }"; static const std::string BlendAverageShader = " \n\ vec3 BlendAverage(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ // This mode is commutative \n\ return((B + L) / 2.0); \n\ }"; // *** Additive Modes *** static const std::string BlendAddShader = " \n\ vec3 BlendAdd(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return min(B + L, vec3(1.0)); \n\ }"; static const std::string BlendSubstractShader = " \n\ vec3 BlendSubstract(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return max(B + L - vec3(1.0), vec3(0.0)); \n\ }"; // *** Difference Modes *** static const std::string BlendDifferenceShader = " \n\ vec3 BlendDifference(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return abs(B - L); \n\ }"; static const std::string BlendNegationShader = " \n\ vec3 BlendNegation(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return(vec3(1.0) - abs(vec3(1.0) - B - L)); \n\ }"; static const std::string BlendExclusionShader = " \n\ vec3 BlendExclusion(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return(B + L - 2.0 * B * L); \n\ }"; static const std::string BlendScreenShader = " \n\ vec3 BlendScreen(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return(1.0 - (1.0 - B) * (1.0 - L)); \n\ }"; static const std::string BlendOverlayShader = " \n\ float _BlendOverlay(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L < 0.5) \n\ return(2.0 * B * L); \n\ else \n\ return(1.0 - 2.0 * (1.0 - B) * (1.0 - L)); \n\ } \n\ vec3 BlendOverlay(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendOverlay(B.r,L.r), _BlendOverlay(B.g ,L.g), _BlendOverlay(B.b,L.b)); \n\ }"; static const std::string BlendSoftLightShader = " \n\ float _BlendSoftLight(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L < 0.5) \n\ return(2.0 * B * L + B * B * (1.0 - 2.0 * L)); \n\ else \n\ return sqrt(B) * (2.0 * L - 1.0) + 2.0 * B * (1.0 - L); \n\ } \n\ vec3 BlendSoftLight(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendSoftLight(B.r, L.r), _BlendSoftLight(B.g, L.g), _BlendSoftLight(B.b, L.b)); \n\ }"; static const std::string BlendHardLightShader = " \n\ float _BlendHardLight(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L < 0.5) \n\ return(2.0 * B * L); \n\ else \n\ return(1.0 - 2.0 * (1.0 - B) * (1.0 - L)); \n\ } \n\ vec3 BlendHardLight(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendHardLight(B.r, L.r), _BlendHardLight(B.g, L.g), _BlendHardLight(B.b, L.b)); \n\ }"; static const std::string BlendColorDodgeShader = " \n\ float _BlendColorDodge(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L == 1.0) \n\ return 1.0; \n\ else \n\ return min(B / (1.0 - L), 1.0); \n\ } \n\ vec3 BlendColorDodge(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendColorDodge(B.r, L.r), _BlendColorDodge(B.g, L.g), _BlendColorDodge(B.b, L.b)); \n\ }"; static const std::string BlendLinearDodgeShader = " \n\ float _BlendLinearDodge(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ return min(B + L, 1.0); \n\ } \n\ vec3 BlendLinearDodge(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendLinearDodge(B.r, L.r), _BlendLinearDodge(B.g, L.g), _BlendLinearDodge(B.b, L.b)); \n\ }"; static const std::string BlendColorBurnShader = " \n\ float _BlendColorBurn(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L == 0.0) \n\ return 0.0; \n\ else \n\ return max(1.0 - ((1.0 - B) / L), 0.0); \n\ } \n\ vec3 BlendColorBurn(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendColorBurn(B.r, L.r), _BlendColorBurn(B.g, L.g), _BlendColorBurn(B.b, L.b)); \n\ }"; static const std::string BlendLinearBurnShader = " \n\ float _BlendLinearBurn(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ return max(B + L - 1.0, 0.0); \n\ } \n\ vec3 BlendLinearBurn(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendLinearBurn(B.r, L.r), _BlendLinearBurn(B.g, L.g), _BlendLinearBurn(B.b, L.b)); \n\ }"; static const std::string BlendLinearLightShader = BlendLinearBurnShader + BlendLinearDodgeShader + "float _BlendLinearLight(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L < 0.5) \n\ return _BlendLinearBurn(B, (2.0 * L)); \n\ else \n\ return _BlendLinearDodge(B, (2.0 * (L - 0.5))); \n\ } \n\ vec3 BlendLinearLight(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendLinearLight(B.r, L.r), _BlendLinearLight(B.g, L.g), _BlendLinearLight(B.b, L.b)); \n\ }"; static const std::string BlendVividLightShader = BlendColorBurnShader + BlendColorDodgeShader + "float _BlendVividLight(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L < 0.5) \n\ return _BlendColorBurn(B, (2.0 * L)); \n\ else \n\ return _BlendColorDodge(B, (2.0 * (L - 0.5))); \n\ } \n\ vec3 BlendVividLight(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendVividLight(B.r, L.r), _BlendVividLight(B.g, L.g), _BlendVividLight(B.b, L.b)); \n\ }"; static const std::string BlendPinLightShader = " \n\ float _BlendPinLight(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L < 0.5) \n\ return min(B, (2.0 * L)); \n\ else \n\ return max(B, (2.0 * (L - 0.5))); \n\ } \n\ vec3 BlendPinLight(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendPinLight(B.r, L.r), _BlendPinLight(B.g, L.g), _BlendPinLight(B.b, L.b)); \n\ }"; static const std::string BlendHardMixShader = BlendVividLightShader + "float _BlendHardMix(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (_BlendVividLight(B, L) < 0.5) \n\ return 0.0; \n\ else \n\ return 1.0; \n\ } \n\ vec3 BlendHardMix(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendHardMix(B.r, L.r), _BlendHardMix(B.g, L.g), _BlendHardMix(B.b, L.b)); \n\ }"; static const std::string BlendReflectShader = " \n\ float _BlendReflect(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L == 1.0) \n\ return 1.0; \n\ else \n\ return min(B * B / (1.0 - L), 1.0); \n\ } \n\ vec3 BlendReflect(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendReflect(B.r, L.r), _BlendReflect(B.g, L.g), _BlendReflect(B.b, L.b)); \n\ }"; static const std::string BlendGlowShader = " \n\ float _BlendGlow(float B /*background layer*/, float L /*foreground layer*/) \n\ { \n\ if (L == 1.0) \n\ return 1.0; \n\ else \n\ return min(L * L / (1.0 - B), 1.0); \n\ } \n\ vec3 BlendGlow(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return vec3(_BlendGlow(B.r, L.r), _BlendGlow(B.g, L.g), _BlendGlow(B.b, L.b)); \n\ }"; static const std::string BlendPhoenixShader = " \n\ vec3 BlendPhoenix(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return min(B, L) - max(B, L) + vec3(1.0); \n\ }"; static const std::string BlendOpacityShader = " \n\ vec3 BlendOpacity(vec3 B /*background layer*/, vec3 L /*foreground layer*/) \n\ { \n\ return O * L + (1 - O) * B; \n\ }"; } #endif nux-4.0.6+14.04.20140409/NuxGraphics/GLResourceManager.h0000644000015301777760000002426512321344237022657 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLRESOURCEMANAGER_H #define GLRESOURCEMANAGER_H namespace nux { // class BaseTexture; // class Texture2D; // class TextureRectangle; // class TextureCube; // class TextureVolume; // class TextureFrameAnimation; // // class NVertexBuffer; // class NIndexBuffer; // // class CachedTexture2D; // class CachedTextureRectangle; // class CachedTextureCube; // class CachedTextureVolume; // class CachedTextureFrameAnimation; // ResourceData CachedResourceData // | | // BaseTexture CachedBaseTexture // | | // Texture2D CachedTexture2D // // // NResourceFactory // | // NGLResourceFactory // | // TGLResourceFactory // // // NResourceSet // | // TResourceCache // | // NResourceCache: TResourceCache // // //! Base class for all types of resources. class ResourceData: public Object { NUX_DECLARE_OBJECT_TYPE(ResourceData, Object); public: ResourceData(NUX_FILE_LINE_PROTO); virtual ~ResourceData(); int GetResourceIndex() const; private: int m_ResourceIndex; }; class CachedResourceData; class NResourceSet { public: NResourceSet(); virtual ~NResourceSet() {}; protected: CachedResourceData *FirstResource; // Flush virtual void Flush() {} // FreeResource - Called when a potentially cached resource has been freed. virtual void FreeResource(ResourceData * /* Resource */) {} // FlushResource - Removes a resource from the set. virtual void FlushResource(CachedResourceData * /* Resource */) {} friend class CachedResourceData; }; enum EResourceUpdateHint { RUH_Static, // The resource is updated once, at creation time. RUH_CacheableDynamic, // The resource is updated occasionally, but not every frame. RUH_Dynamic // The resource changes every frame. }; class CachedResourceData: public Object { NUX_DECLARE_OBJECT_TYPE(CachedResourceData, Object); public: CachedResourceData(NResourceSet *InSet); virtual ~CachedResourceData(); //! Returns the size in bytes of the resource. /*! Returns the size in bytes of the resource. @return Size of the resource in bytes. */ virtual unsigned int GetSize() const { return Size; } //! Returns the size of the max LOD of the resource. /*! Returns the size of the max LOD of the resource. For a texture, this is the size of mipmap 0. Texture resource overwrite this function. @return Size of the resource in bytes. */ virtual unsigned int GetMaxLodSize() const { return Size; } /*! Updates the resource. */ virtual bool UpdateResource(ResourceData *Resource) = 0; protected: NResourceSet *Set; bool _cached; unsigned int NumRefs; NObjectType *ResourceType; unsigned int Size; EResourceUpdateHint UpdateHint; CachedResourceData *PrevResource; CachedResourceData *NextResource; template friend class TResourceCache; friend class NResourceCache; }; //! Device independent resource factory. class NResourceFactory { public: NResourceFactory(NObjectType *Type) : m_ResourceType(Type) {} virtual ~NResourceFactory() {} // Returns the resource type for this factory const NObjectType &Type() const { return *m_ResourceType; } /*! Returns true if the given ResourceData is created by this factory. @param Resource - the resource in question. */ bool BuildsThisResource(ResourceData *Resource) { return Resource->Type().IsObjectType(Type()); } virtual CachedResourceData *BuildResource(NResourceSet * /* ResourceManager */, ResourceData * /* Resource */) { return NULL; } private: //! Type associated with this factory class. NObjectType *m_ResourceType; }; template class TGLResourceFactory : public NResourceFactory { public: /*! Constructor. @param type - resource class type to associate w/ this factory. */ TGLResourceFactory(NObjectType *Type) : NResourceFactory(Type) {} virtual ~TGLResourceFactory(void) {} //! Create a new resource. /*! Create a new resource for the given ResourceData. @param ResourceManager The resource manager. @param Resource Resource to build and cache. @return The built resource. */ virtual CachedResourceData *BuildResource(NResourceSet *ResourceManager, ResourceData *Resource) { return new U(ResourceManager, (T *)Resource); } }; //! Device independent resource updater. class NResourceUpdater { public: NResourceUpdater(NObjectType *Type) : m_ResourceType(Type) {} //! Returns the resource type for this factory. const NObjectType &Type() const { return *m_ResourceType; } /*! Returns true if the given ResourceData can be updated by this factory. @param Resource The resource in question. */ bool UpdatesThisResource(ResourceData *Resource) { return Resource->Type().IsObjectType(Type()); } virtual bool UpdateResource(ObjectPtr< CachedResourceData > DeviceResource, ResourceData *Resource) const { return DeviceResource->UpdateResource(Resource); } private: //! Type associated with this factory class. NObjectType *m_ResourceType; }; template class TResourceCache: public NResourceSet { public: std::map< IdType, ObjectPtr< ResourceType > > ResourceMap; // Resource factory instances for each ResourceData/CachedResourceData pair. std::vector ResourceFactories; // Resource updater instances for each ResourceData type. std::vector ResourceUpdaters; TResourceCache() : NResourceSet() {} void Flush() { // See the language FAQ 35.18 at http://www.parashift.com/c++-faq-lite/templates.html for why the "typename". typename std::map< IdType, ObjectPtr< ResourceType > >::iterator It; for (It = ResourceMap.begin(); It != ResourceMap.end(); It++) { // ObjectPtr< ResourceType > CachedResource = (*It).second; // CachedResource->_cached = 0; // CachedResource.Release(); (*It).second->_cached = 0; (*It).second.Release(); } // Erases all elements from the map. ResourceMap.clear(); } void AddCachedResource(const IdType &Id, ObjectPtr< ResourceType > Resource) { typedef std::map< IdType, ObjectPtr< ResourceType > > MapType; ResourceMap.insert(typename MapType::value_type(Id, Resource)); Resource->_cached = 1; } ObjectPtr FindCachedResourceById(const IdType &Id) { typedef std::map< IdType, ObjectPtr< ResourceType > > MapType; typename MapType::iterator it = ResourceMap.find(Id); if (it != ResourceMap.end()) return(*it).second; return ObjectPtr (0); } /*! Remove a cached resource from the cache. The cached resource may still have references to it. The resource internal flag "_cached" is set to false. */ void FlushResourceId(const IdType &Id) { ObjectPtr CachedResource(0); typedef std::map > MapType; typename MapType::iterator it = ResourceMap.find(Id); if (it != ResourceMap.end()) CachedResource = (*it).second; if (CachedResource.IsValid()) { ResourceMap.erase(it); CachedResource->_cached = false; } } virtual void FlushResource(CachedResourceData *Resource) { typedef std::map< IdType, ObjectPtr< ResourceType > > MapType; typename MapType::iterator it; for (it = ResourceMap.begin(); it != ResourceMap.end(); it++) { ObjectPtr< ResourceType > CachedResource = (*it).second; if (CachedResource == Resource) { ResourceMap.erase(it); CachedResource->_cached = 0; // Make sure that if the following line deletes the resource, it doesn't try to remove itself from the TDynamicMap we're iterating over. return; } } } // Register CachedResourceData with the corresponding ResourceData virtual void InitializeResourceFactories() = 0; std::vector& GetResourceFactories(void) { return(ResourceFactories); } std::vector& GetResourceUpdaters(void) { return(ResourceUpdaters); } }; class NResourceCache: public TResourceCache { public: NResourceCache() : TResourceCache() {} ObjectPtr< CachedResourceData > GetCachedResource(ResourceData *Source); bool IsCachedResource(ResourceData *Source); virtual void InitializeResourceFactories(); // virtual void FreeResource(ResourceData *Resource) // { // FlushResourceId(Resource->GetResourceIndex()); // } }; //////////////////////////////////////////////////////////////////////////////////////////////////// } #endif // GLRESOURCEMANAGER_H nux-4.0.6+14.04.20140409/NuxGraphics/GpuDevice.h0000755000015301777760000004172612321344237021231 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLDEVICEFACTORY_H #define GLDEVICEFACTORY_H #include "GLResource.h" #include "GLDeviceFrameBufferObject.h" #include "GLDeviceObjects.h" #include "GLTextureStates.h" #include "GLTemplatePrimitiveBuffer.h" namespace nux { class GpuRenderStates; //! Brand of GPUs. typedef enum { GPU_VENDOR_UNKNOWN = 0, GPU_BRAND_AMD, GPU_BRAND_NVIDIA, GPU_BRAND_INTEL, } GpuBrand; template class ObjectPtr; struct STREAMSOURCE { WORD Stream; ObjectPtr VertexBuffer; unsigned short StreamOffset; unsigned short StreamStride; STREAMSOURCE() { Stream = 0; //VertexBuffer = 0; StreamOffset = 0; StreamStride = 0; } void ResetStreamSource() { Stream = 0; StreamOffset = 0; VertexBuffer = ObjectPtr (0); StreamStride = 0; } }; // GPU Graphics information. class GpuInfo { public: GpuInfo(); bool SupportOpenGL11() const {return _support_opengl_version_11;} bool SupportOpenGL12() const {return _support_opengl_version_12;} bool SupportOpenGL13() const {return _support_opengl_version_13;} bool SupportOpenGL14() const {return _support_opengl_version_14;} bool SupportOpenGL15() const {return _support_opengl_version_15;} bool SupportOpenGL20() const {return _support_opengl_version_20;} bool SupportOpenGL21() const {return _support_opengl_version_21;} bool SupportOpenGL30() const {return _support_opengl_version_30;} bool SupportOpenGL31() const {return _support_opengl_version_31;} bool SupportOpenGL32() const {return _support_opengl_version_32;} bool SupportOpenGL33() const {return _support_opengl_version_33;} bool SupportOpenGL40() const {return _support_opengl_version_40;} bool SupportOpenGL41() const {return _support_opengl_version_41;} bool Support_EXT_Swap_Control() const {return _support_ext_swap_control;} bool Support_ARB_Texture_Rectangle() const {return _support_arb_texture_rectangle;} bool Support_ARB_Vertex_Program() const {return _support_arb_vertex_program;} bool Support_ARB_Fragment_Program() const {return _support_arb_fragment_program;} bool Support_ARB_Shader_Objects() const {return _support_arb_shader_objects;} bool Support_ARB_Vertex_Shader() const {return _support_arb_vertex_shader;} bool Support_ARB_Fragment_Shader() const {return _support_arb_fragment_shader;} bool Support_ARB_Vertex_Buffer_Object() const {return _support_arb_vertex_buffer_object;} bool Support_ARB_Texture_Non_Power_Of_Two() const {return _support_arb_texture_non_power_of_two;} bool Support_EXT_Framebuffer_Object() const {return _support_ext_framebuffer_object;} bool Support_EXT_Draw_Range_Elements() const {return _support_ext_draw_range_elements;} bool Support_EXT_Stencil_Two_Side() const {return _support_ext_stencil_two_side;} bool Support_EXT_Texture_Rectangle() const {return _support_ext_texture_rectangle;} bool Support_NV_Texture_Rectangle() const {return _support_nv_texture_rectangle;} bool Support_ARB_Pixel_Buffer_Object() const {return _support_arb_pixel_buffer_object;} bool Support_EXT_Blend_Equation_Separate() const {return _support_ext_blend_equation_separate;} bool Support_Depth_Buffer() const {return _support_depth_buffer;} #ifndef NUX_OPENGLES_20 bool Support_EXT_Texture_sRGB() const {return _support_ext_texture_srgb;} bool Support_EXT_Texture_Decode() const {return _support_ext_texture_srgb_decode;} bool Support_EXT_Framebuffer_sRGB() const {return _support_ext_framebuffer_srgb;} bool Support_ARB_Framebuffer_sRGB() const {return _support_arb_framebuffer_srgb;} #endif int GetMaxFboAttachment() const {return _opengl_max_fb_attachment;} int GetMaxTextureSize() const {return _opengl_max_texture_size;} private: void Setup(); bool _support_opengl_version_11; bool _support_opengl_version_12; bool _support_opengl_version_13; bool _support_opengl_version_14; bool _support_opengl_version_15; bool _support_opengl_version_20; bool _support_opengl_version_21; bool _support_opengl_version_30; bool _support_opengl_version_31; bool _support_opengl_version_32; bool _support_opengl_version_33; bool _support_opengl_version_40; bool _support_opengl_version_41; int _opengl_max_texture_size; int _opengl_max_texture_units; int _opengl_max_texture_coords; int _opengl_max_texture_image_units; int _opengl_max_fb_attachment; int _opengl_max_vertex_attributes; bool _support_ext_swap_control; bool _support_arb_vertex_program; bool _support_arb_fragment_program; bool _support_arb_shader_objects; bool _support_arb_vertex_shader; bool _support_arb_fragment_shader; bool _support_arb_vertex_buffer_object; bool _support_arb_texture_non_power_of_two; bool _support_ext_framebuffer_object; bool _support_ext_draw_range_elements; bool _support_ext_stencil_two_side; bool _support_ext_texture_rectangle; bool _support_arb_texture_rectangle; //!< Promoted from GL_EXT_TEXTURE_RECTANGLE to ARB. bool _support_nv_texture_rectangle; bool _support_arb_pixel_buffer_object; bool _support_ext_blend_equation_separate; bool _support_depth_buffer; #ifndef NUX_OPENGLES_20 bool _support_ext_texture_srgb; bool _support_ext_texture_srgb_decode; bool _support_ext_framebuffer_srgb; bool _support_arb_framebuffer_srgb; #endif friend class GpuDevice; }; //! The interface to the GPU. /*! This is the object that serves as the interface between the program and the GPU device. The GpuDevice creates the opengl primitives used for rendering. */ class GpuDevice { private: static STREAMSOURCE _StreamSource[MAX_NUM_STREAM]; public: ObjectPtr CreateTexture( int Width, int Height, int Levels, BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO); ObjectPtr CreateTexture2DFromID(int id, int Width, int Height, int Levels, BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO); ObjectPtr CreateRectangleTexture( int Width , int Height , int Levels , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO); ObjectPtr CreateCubeTexture( int EdgeLength , int Levels , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO); ObjectPtr CreateVolumeTexture( int Width , int Height , int Depth , int Levels , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO); ObjectPtr CreateAnimatedTexture( int Width , int Height , int Depth , BitmapFormat PixelFormat); ObjectPtr CreateVertexBuffer( int Length , VBO_USAGE Usage); ObjectPtr CreateIndexBuffer( int Length , VBO_USAGE Usage // Dynamic or WriteOnly , INDEX_FORMAT Format); ObjectPtr CreatePixelBufferObject(int Size, VBO_USAGE Usage); ObjectPtr CreateQuery( QUERY_TYPE Type); ObjectPtr CreateVertexDeclaration( const VERTEXELEMENT *pVertexElements); //! Create an return an ObjectPtr that encapsulates OpenGL framebuffer object. /*! Create an return an ObjectPtr that encapsulates OpenGL framebuffer object. This function has side effects. It will change the framebuffer object that is set in the GPU. */ ObjectPtr CreateFrameBufferObject(); ObjectPtr CreateShaderProgram(); ObjectPtr CreateVertexShader(); ObjectPtr CreatePixelShader(); #ifndef NUX_OPENGLES_20 ObjectPtr CreateAsmShaderProgram(); ObjectPtr CreateAsmVertexShader(); ObjectPtr CreateAsmPixelShader(); #endif #if (NUX_ENABLE_CG_SHADERS) ObjectPtr CreateCGVertexShader(); ObjectPtr CreateCGPixelShader(); #endif // This is for the fixed pipeline // When using shaders see how a shader sampler parameter links to a texture with a call to setTexture. int SetTexture(unsigned int TextureUnit, IOpenGLBaseTexture *texture); int DrawIndexedPrimitive( ObjectPtr IndexBuffer, ObjectPtr VertexDeclaration, PRIMITIVE_TYPE PrimitiveType, int PrimitiveCount ); // Draw Primitive without index buffer int DrawPrimitive( ObjectPtr VertexDeclaration, PRIMITIVE_TYPE pt_, unsigned vtx_start_, unsigned num_prims_); // Draw Primitive without index buffer, and use a user pointer for the source of the stream. int DrawPrimitiveUP( ObjectPtr VertexDeclaration, PRIMITIVE_TYPE PrimitiveType, unsigned int PrimitiveCount, const void *pVertexStreamZeroData, unsigned int VertexStreamZeroStride ); int SetStreamSource( unsigned int StreamNumber, ObjectPtr pStreamData, unsigned int OffsetInBytes, unsigned int Stride); //! Setup a NULL vertex buffer void InvalidateVertexBuffer(); //! Setup a NULL index buffer void InvalidateIndexBuffer(); //! Setup a NULL texture void InvalidateTextureUnit(int TextureUnitIndex); int AllocateUnpackPixelBufferIndex(int *index); int FreeUnpackPixelBufferIndex(const int index); int BindUnpackPixelBufferIndex(const int index); int BindPackPixelBufferIndex(const int index); void *LockUnpackPixelBufferIndex(const int index, const int Size); void *LockPackPixelBufferIndex(const int index, const int Size); void UnlockUnpackPixelBufferIndex(const int index); void UnlockPackPixelBufferIndex(const int index); // All these operations are done on the default frame buffer object: _FrameBufferObject. int FormatFrameBufferObject(unsigned int Width, unsigned int Height, BitmapFormat PixelFormat); int SetColorRenderTargetSurface(unsigned int ColorAttachmentIndex, ObjectPtr pRenderTargetSurface); int SetDepthRenderTargetSurface(ObjectPtr pDepthSurface); ObjectPtr GetColorRenderTargetSurface(unsigned int ColorAttachmentIndex); ObjectPtr GetDepthRenderTargetSurface(); // Activate and Deactivate the default framebuffer: _FrameBufferObject. void ActivateFrameBuffer(); //! Restore the backbuffer as the render target. void DeactivateFrameBuffer(); unsigned int GetPixelStoreAlignment() const; public: void SetCurrentFrameBufferObject(ObjectPtr fbo); ObjectPtr GetFrameBufferObject() const; ObjectPtr GetCurrentFrameBufferObject(); ObjectPtr ActiveFboTextureAttachment(int color_attachment_index); ObjectPtr ActiveFboDepthTextureAttachment(); int GetOpenGLMajorVersion() const; int GetOpenGLMinorVersion() const; private: // Default FrameBufferobject ObjectPtr _FrameBufferObject; ObjectPtr active_framebuffer_object_; struct PixelBufferObject { ObjectPtr PBO; bool IsReserved; }; public: #if (NUX_ENABLE_CG_SHADERS) CGcontext GetCgContext() { return m_Cgcontext; } CGcontext m_Cgcontext; #endif bool UsePixelBufferObjects() const; GpuBrand GetGPUBrand() const; GpuRenderStates& GetRenderStates(); const GpuInfo& GetGpuInfo() const; void ResetRenderStates(); void VerifyRenderStates(); //! Create a texture that the system supports. Rectangle texture or 2D texture. /*! @Width Texture width. @Height Texture height. @Levels Texture number of mipmaps. If 0, all the mipmaps levels are created @PixelFormat Texture format. @return A device texture. Depending on the system capabilities returns a ObjectPtr or ObjectPtr. */ ObjectPtr CreateSystemCapableDeviceTexture( int Width , int Height , int Levels , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO); //! Created a cached texture /*! @return A cached texture. Depending on the system capabilities, returns a Texture2D or TextureRectangle. */ BaseTexture* CreateSystemCapableTexture(NUX_FILE_LINE_PROTO); bool SUPPORT_GL_ARB_TEXTURE_NON_POWER_OF_TWO() const { return gpu_info_->Support_ARB_Texture_Non_Power_Of_Two(); } bool SUPPORT_GL_EXT_TEXTURE_RECTANGLE() const { return gpu_info_->Support_EXT_Texture_Rectangle(); } bool SUPPORT_GL_ARB_TEXTURE_RECTANGLE() const { return gpu_info_->Support_ARB_Texture_Rectangle(); } private: // int _glsl_version_major; //!< GLSL major version. int _glsl_version_minor; //!< GLSL major version. int opengl_major_; //!< OpenGL major version. int opengl_minor_; //!< OpenGL minor version. std::string _board_vendor_string; //!< GPU vendor sting. std::string _board_renderer_string; //!< GPU renderer sting. std::string _openGL_version_string; //!< OpenGL version string. GpuBrand gpu_brand_; //!< GPU brand. bool use_pixel_buffer_object_; unsigned int pixel_store_alignment_; std::vector _PixelBufferArray; bool OGL_EXT_SWAP_CONTROL; bool GL_ARB_VERTEX_PROGRAM; bool GL_ARB_FRAGMENT_PROGRAM; bool GL_ARB_SHADER_OBJECTS; bool GL_ARB_VERTEX_SHADER; bool GL_ARB_FRAGMENT_SHADER; bool GL_ARB_VERTEX_BUFFER_OBJECT; bool GL_ARB_TEXTURE_NON_POWER_OF_TWO; bool GL_EXT_FRAMEBUFFER_OBJECT; bool GL_EXT_DRAW_RANGE_ELEMENTS; bool GL_EXT_STENCIL_TWO_SIDE; bool GL_EXT_TEXTURE_RECTANGLE; bool GL_ARB_TEXTURE_RECTANGLE; //!< Promoted from GL_EXT_TEXTURE_RECTANGLE to ARB. bool GL_NV_TEXTURE_RECTANGLE; GpuRenderStates* gpu_render_states_; GpuInfo* gpu_info_; public: ObjectPtr backup_texture0_; #if defined(NUX_OS_WINDOWS) GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat, HDC device_context, HGLRC &opengl_rendering_context, int req_opengl_major = 1, // requested opengl major version. int req_opengl_minor = 0, // requested opengl minor version. bool opengl_es_20 = false); #elif defined(USE_X11) #ifdef NUX_OPENGLES_20 GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat, Display *display, Window window, bool has_new_glx_support, EGLConfig fb_config, EGLContext &opengl_rendering_context, int req_opengl_major = 2, int req_opengl_minor = 0, bool opengl_es_20 = true); #else GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat, Display *display, Window window, bool has_new_glx_support, GLXFBConfig fb_config, GLXContext &opengl_rendering_context, int req_opengl_major = 1, // requested opengl major version. int req_opengl_minor = 0, // requested opengl minor version. bool opengl_es_20 = false); #endif #elif defined(NO_X11) GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat, EGLDisplay display, EGLConfig fb_config, EGLContext &opengl_rendering_context, int req_opengl_major, int req_opengl_minor); #endif ~GpuDevice(); friend class IOpenGLSurface; friend class GraphicsEngine; }; } #endif // GLDEVICEFACTORY_H nux-4.0.6+14.04.20140409/NuxGraphics/GLResource.cpp0000644000015301777760000002137112321344237021712 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "IOpenGLVertexBuffer.h" namespace nux { const char *OGLDeviceErrorMessages[] = { "OGL_OK", "OGL_ERROR_UNKNOWN", "OGL_INVALID_SURFACE_LEVEL", "OGL_INVALID_CALL", "OGL_INVALID_LOCK", "OGL_INVALID_UNLOCK", "OGL_INVALID_TEXTURE", }; /* This table lists the most efficient combinations of internalformat(either generic or specific), format, and type: internalformat format type ------------------------------------------------------------------------------------ GL_ALPHA16 GL_ALPHA GL_UNSIGNED_SHORT GL_ALPHA8 or GL_ALPHA GL_ALPHA GL_UNSIGNED_BYTE GL_INTENSITY16 GL_INTENSITY GL_UNSIGNED_SHORT GL_INTENSITY8 GL_INTENSITY GL_UNSIGNED_BYTE GL_LUMINANCE16 GL_LUMINANCE GL_UNSIGNED_SHORT GL_LUMINANCE8 or GL_LUMINANCE GL_LUMINANCE GL_UNSIGNED_BYTE GL_LUMINANCE16_ALPHA16 GL_LUMINANCE_ALPHA GL_UNSIGNED_INT_16_16_REV GL_LUMINANCE8_ALPHA8 or GL_LUMINANCE_ALPHA GL_LUMINANCE_ALPHA GL_UNSIGNED_SHORT_8_8_REV GL_RGB8 GL_RGBA GL_UNSIGNED_INT_8_8_8_8 GL_RGBA8 or GL_RGBA8 GL_RGBA GL_UNSIGNED_INT_8_8_8_8 GL_ARGB_SCE GL_BGRA GL_UNSIGNED_INT_8_8_8_8_REV GL_RGB16F GL_RGBA GL_HALF_FLOAT_ARB GL_RGBA16F GL_RGBA GL_HALF_FLOAT_ARB GL_LUMINANCE_ALPHA16F_ARB GL_ALPHA_LUMINANCE_SCE GL_HALF_FLOAT_ARB GL_LUMINANCE32F_ARB GL_LUMINANCE GL_FLOAT GL_RGB32F_ARB GL_RGBA GL_FLOAT GL_RGBA32F_ARB GL_RGBA GL_FLOAT GL_DEPTH_COMPONENT24 or GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT GL_UNSIGNED_INT_24_8_SCE */ // //void AddVertexElement(std::vector& Elements, // WORD Stream, // WORD Offset, // //WORD Stride, // ATTRIB_DECL_TYPE Type, // ATTRIB_USAGE_DECL Usage, // BYTE UsageIndex) //{ // VERTEXELEMENT Element; // Element.Stream = Stream; // Element.Offset = Offset; // // We don't want to store ATTRIB_DECL_TYPE. We unpack it here so we don't have to do it every frame. // // Opengl commands such as cgGLSetParameterPointer needs to know how many components there are in // // a vertex attribute and what is the format of each component. // DecomposeTypeDeclaraction(Type, &Element.NumComponent, &Element.Type); // //Element.Stride = Stride; // Element.Usage = Usage; // Element.UsageIndex = UsageIndex; // Elements.AddItem(Element); //} void DecomposeTypeDeclaraction(ATTRIB_DECL_TYPE Type, int &NumComponent, ATTRIB_COMPONENT_TYPE &ComponentType) { switch(Type) { case ATTRIB_DECLTYPE_FLOAT1: { NumComponent = 1; ComponentType = ATTRIB_CT_FLOAT; break; } case ATTRIB_DECLTYPE_FLOAT2: { NumComponent = 2; ComponentType = ATTRIB_CT_FLOAT; break; } case ATTRIB_DECLTYPE_FLOAT3: { NumComponent = 3; ComponentType = ATTRIB_CT_FLOAT; break; } case ATTRIB_DECLTYPE_FLOAT4: { NumComponent = 4; ComponentType = ATTRIB_CT_FLOAT; break; } case ATTRIB_DECLTYPE_COLOR: { NumComponent = 4; ComponentType = ATTRIB_CT_UNSIGNED_BYTE; break; } case ATTRIB_DECLTYPE_UBYTE4: { NumComponent = 4; ComponentType = ATTRIB_CT_UNSIGNED_BYTE; break; } case ATTRIB_DECLTYPE_SHORT2: { NumComponent = 2; ComponentType = ATTRIB_CT_SHORT; break; } case ATTRIB_DECLTYPE_SHORT4: { NumComponent = 4; ComponentType = ATTRIB_CT_SHORT; break; } case ATTRIB_DECLTYPE_UBYTE4N: { NumComponent = 4; ComponentType = ATTRIB_CT_UNSIGNED_BYTE; break; } case ATTRIB_DECLTYPE_SHORT2N: { NumComponent = 2; ComponentType = ATTRIB_CT_SHORT; break; } case ATTRIB_DECLTYPE_SHORT4N: { NumComponent = 4; ComponentType = ATTRIB_CT_SHORT; break; } case ATTRIB_DECLTYPE_USHORT2N: { NumComponent = 2; ComponentType = ATTRIB_CT_UNSIGNED_SHORT; break; } case ATTRIB_DECLTYPE_USHORT4N: { NumComponent = 4; ComponentType = ATTRIB_CT_UNSIGNED_SHORT; break; } #ifndef NUX_OPENGLES_20 case ATTRIB_DECLTYPE_FLOAT16_2: { NumComponent = 2; ComponentType = ATTRIB_CT_HALF_FLOAT; break; } case ATTRIB_DECLTYPE_FLOAT16_4: { NumComponent = 4; ComponentType = ATTRIB_CT_HALF_FLOAT; break; } #endif case ATTRIB_DECLTYPE_UNUSED: default: { NumComponent = 0; ComponentType = ATTRIB_CT_UNKNOWN; nuxError("Unsupported Declaration Type. \n"); } } } UINT GetVertexElementSize(VERTEXELEMENT vtxelement) { ATTRIB_COMPONENT_TYPE type = vtxelement.Type; UINT NumComponent = vtxelement.NumComponent; switch(type) { case ATTRIB_CT_BYTE: case ATTRIB_CT_UNSIGNED_BYTE: return 1 * NumComponent; case ATTRIB_CT_SHORT: case ATTRIB_CT_UNSIGNED_SHORT: return 2 * NumComponent; case ATTRIB_CT_INT: case ATTRIB_CT_UNSIGNED_INT: case ATTRIB_CT_FLOAT: return 4 * NumComponent; #ifndef NUX_OPENGLES_20 case ATTRIB_CT_HALF_FLOAT: return 2 * NumComponent; case ATTRIB_CT_DOUBLE: return 8 * NumComponent; #endif case ATTRIB_CT_UNKNOWN: default: nuxAssert("Unknown Component Type"); return 0; } return 0; } void AddVertexElement(std::vector& Elements, WORD Stream, WORD Offset, //ubiU16 Stride, ATTRIB_DECL_TYPE Type, ATTRIB_USAGE_DECL /* Usage */, BYTE /* UsageIndex */) { VERTEXELEMENT Element; Element.Stream = Stream; Element.Offset = Offset; // We don't want to store ATTRIB_DECL_TYPE. We unpack it here so we don't have to do it every frame. // Opengl commands such as cgGLSetParameterPointer needs to know how many components there are in // a vertex attribute and what is the format of each component. DecomposeTypeDeclaraction(Type, Element.NumComponent, Element.Type); //Element.Stride = Stride; //Element.Usage = Usage; //Element.UsageIndex = UsageIndex; Elements.push_back(Element); } unsigned int GetGLElementCount(PRIMITIVE_TYPE InPrimitiveType, unsigned int InPrimitiveCount) { switch(InPrimitiveType) { case PRIMITIVE_TYPE_POINTLIST: return InPrimitiveCount; case PRIMITIVE_TYPE_LINELIST: return InPrimitiveCount * 2; case PRIMITIVE_TYPE_LINESTRIP: return InPrimitiveCount + 1; case PRIMITIVE_TYPE_TRIANGLELIST: return InPrimitiveCount * 3; case PRIMITIVE_TYPE_TRIANGLESTRIP: return InPrimitiveCount + 2; case PRIMITIVE_TYPE_TRIANGLEFAN: return InPrimitiveCount; #ifndef NUX_OPENGLES_20 case PRIMITIVE_TYPE_QUADLIST: return InPrimitiveCount * 4; case PRIMITIVE_TYPE_QUADSTRIP: return InPrimitiveCount * 2 + 2; #endif default: return 0; } nuxAssertMsg(0, "[GetGLElementCount] Invalid PRIMITIVE_TYPE"); return InPrimitiveCount; } } nux-4.0.6+14.04.20140409/NuxGraphics/GLRenderingAPI.cpp0000644000015301777760000000151612321344237022371 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GraphicsEngine.h" namespace nux { } nux-4.0.6+14.04.20140409/NuxGraphics/GLTextureStates.cpp0000644000015301777760000003026412321344237022750 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GLTextureStates.h" namespace nux { const struct TextureStateLookUpTable { TextureStateLookUpTable() { // setup render state map #define UL_MAP(state__, default_value__, checked__) \ default_texture_state[GFXTS_##state__].iValue = default_value__; \ default_texture_state[GFXTS_##state__].Checked = checked__; #define UL_MAP_FLOAT(state__, default_value__, checked__) \ default_texture_state[GFXTS_##state__].fValue = default_value__; \ default_texture_state[GFXTS_##state__].Checked = checked__; UL_MAP(ADDRESSU , GL_REPEAT , 1); UL_MAP(ADDRESSV , GL_REPEAT , 1); UL_MAP(ADDRESSW , GL_REPEAT , 1); UL_MAP(MINFILTER , GL_NEAREST , 1); UL_MAP(MAGFILTER , GL_NEAREST , 1); UL_MAP(MIPFILTER , GL_NEAREST , 1); UL_MAP(MIP_BASE_LEVEL , 0 , 1); UL_MAP(MIP_MAX_LEVEL , 1000 , 1); UL_MAP_FLOAT(MIN_LOD , -1000 , 1); UL_MAP_FLOAT(MAX_LOD , +1000 , 1); UL_MAP(BORDERCOLOR , 0x0 , 1); #undef UL_MAP #undef UL_MAP_FLOAT }; TextureStateMap default_texture_state[GFXTS_MAX_TEXTURESTATES]; } s_TextureStateLUT; GLTextureStates::GLTextureStates(GLuint Type) { SetType(Type); Memcpy(&m_TextureStateChanges, &s_TextureStateLUT.default_texture_state, sizeof(m_TextureStateChanges)); } GLTextureStates::~GLTextureStates() { } void GLTextureStates::SetType(GLuint Type) { #ifndef NUX_OPENGLES_20 nuxAssertMsg( (Type == GL_TEXTURE_1D) || (Type == GL_TEXTURE_2D) || (Type == GL_TEXTURE_RECTANGLE_ARB) || (Type == GL_TEXTURE_3D) || (Type == GL_TEXTURE_CUBE_MAP_ARB), "Error[GLTextureStates::GLTextureStates]: Invalid texture type."); #else nuxAssertMsg( (Type == GL_TEXTURE_2D), "Error[GLTextureStates::GLTextureStates]: Invalid texture type."); #endif m_Type = Type; } void GLTextureStates::ResetDefault() { } void GLTextureStates::ResetStateChangeToDefault() { } void GLTextureStates::SetRenderStates() { HW_SetFiltering(); HW_SetWrap(); HW_SetLOD(); HW_SetMipLevel(); } #define SET_TS_VALUE(a, b) if (a.iValue != b){(a).iValue = (b); (a).Dirty = true;} #define TS_VALUE(a, b) (a).iValue #define SET_TS_VALUE_FLOAT(a, b) if (a.fValue != b){(a).fValue = (b); (a).Dirty = true;} #define TS_VALUE_FLOAT(a, b) (a).fValue void GLTextureStates::HW_SetFiltering() { if (m_TextureStateChanges[GFXTS_MINFILTER].Dirty || m_TextureStateChanges[GFXTS_MAGFILTER].Dirty) { CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_MIN_FILTER, m_TextureStateChanges[GFXTS_MINFILTER].iValue )); CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_MAG_FILTER, m_TextureStateChanges[GFXTS_MAGFILTER].iValue)); m_TextureStateChanges[GFXTS_MINFILTER].Dirty = false; m_TextureStateChanges[GFXTS_MAGFILTER].Dirty = false; } } void GLTextureStates::HW_SetWrap() { if (m_TextureStateChanges[GFXTS_ADDRESSU].Dirty || m_TextureStateChanges[GFXTS_ADDRESSV].Dirty || m_TextureStateChanges[GFXTS_ADDRESSW].Dirty) { CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_WRAP_S, m_TextureStateChanges[GFXTS_ADDRESSU].iValue)); CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_WRAP_T, m_TextureStateChanges[GFXTS_ADDRESSV].iValue)); #ifndef NUX_OPENGLES_20 CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_WRAP_R, m_TextureStateChanges[GFXTS_ADDRESSW].iValue)); #endif m_TextureStateChanges[GFXTS_ADDRESSU].Dirty = false; m_TextureStateChanges[GFXTS_ADDRESSV].Dirty = false; m_TextureStateChanges[GFXTS_ADDRESSW].Dirty = false; } } void GLTextureStates::HW_SetLOD() { #ifndef NUX_OPENGLES_20 if (m_Type == GL_TEXTURE_RECTANGLE_ARB) { // No support for mip LOP on rectangle texture. // ATI seems to not generate and Error. // Nvidia generates an error m_TextureStateChanges[GFXTS_MIN_LOD].Dirty = false; m_TextureStateChanges[GFXTS_MAX_LOD].Dirty = false; return; } if (m_TextureStateChanges[GFXTS_MIN_LOD].Dirty || m_TextureStateChanges[GFXTS_MAX_LOD].Dirty) { CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_MIN_LOD, m_TextureStateChanges[GFXTS_MIN_LOD].fValue)); CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_MAX_LOD, m_TextureStateChanges[GFXTS_MAX_LOD].fValue)); m_TextureStateChanges[GFXTS_MIN_LOD].Dirty = false; m_TextureStateChanges[GFXTS_MAX_LOD].Dirty = false; } #endif } void GLTextureStates::HW_SetMipLevel() { #ifndef NUX_OPENGLES_20 if (m_TextureStateChanges[GFXTS_MIN_LOD].Dirty || m_TextureStateChanges[GFXTS_MAX_LOD].Dirty) { CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_MIN_LOD, m_TextureStateChanges[GFXTS_MIN_LOD].fValue)); CHECKGL(glTexParameteri(m_Type, GL_TEXTURE_MAX_LOD, m_TextureStateChanges[GFXTS_MAX_LOD].fValue)); m_TextureStateChanges[GFXTS_MIN_LOD].Dirty = false; m_TextureStateChanges[GFXTS_MAX_LOD].Dirty = false; } #endif } void GLTextureStates::HW_SetBorderColor() { } void GLTextureStates::SetFiltering( unsigned int MinFilter, unsigned int MagFilter /*,unsigned int MIP*/) { nuxAssertMsg( (MinFilter == GL_LINEAR) || (MinFilter == GL_NEAREST) || (MinFilter == GL_NEAREST_MIPMAP_NEAREST) || (MinFilter == GL_LINEAR_MIPMAP_NEAREST) || (MinFilter == GL_NEAREST_MIPMAP_LINEAR) || (MinFilter == GL_LINEAR_MIPMAP_LINEAR), "Error[GLTextureStates::SetFiltering]: Invalid MinFilter state"); nuxAssertMsg( (MagFilter == GL_LINEAR) || (MagFilter == GL_NEAREST), "Error[GLTextureStates::SetFiltering]: Invalid MagFilter state"); // nuxAssertMsg( // (MIP == GL_LINEAR) || // (MIP == GL_NEAREST), // "Error[GLTextureStates::SetFiltering]: Invalid Mipmap Filter State"); #ifndef NUX_OPENGLES_20 if (m_Type == GL_TEXTURE_RECTANGLE_ARB) { if ((MinFilter != GL_NEAREST) && (MinFilter != GL_LINEAR)) { nuxError("[GLTextureStates::SetFiltering] Incorrect MinFilter for rectangle texture."); SET_TS_VALUE(m_TextureStateChanges[GFXTS_MINFILTER], GL_LINEAR); } else { SET_TS_VALUE(m_TextureStateChanges[GFXTS_MINFILTER], MinFilter); } if ((MagFilter != GL_NEAREST) && (MagFilter != GL_LINEAR)) { nuxError("[GLTextureStates::SetFiltering] Incorrect MagFilter for rectangle texture."); SET_TS_VALUE(m_TextureStateChanges[GFXTS_MAGFILTER], GL_LINEAR); } else { SET_TS_VALUE(m_TextureStateChanges[GFXTS_MAGFILTER], MagFilter); } } else { SET_TS_VALUE(m_TextureStateChanges[GFXTS_MINFILTER], MinFilter); SET_TS_VALUE(m_TextureStateChanges[GFXTS_MAGFILTER], MagFilter); } #else SET_TS_VALUE(m_TextureStateChanges[GFXTS_MINFILTER], MinFilter); SET_TS_VALUE(m_TextureStateChanges[GFXTS_MAGFILTER], MagFilter); #endif //SET_TS_VALUE(m_TextureStateChanges[GFXTS_MIPFILTER], MIP); } void GLTextureStates::SetWrap( unsigned int U, unsigned int V, unsigned int W) { #ifndef NUX_OPENGLES_20 nuxAssertMsg( (U == GL_CLAMP) || (U == GL_CLAMP_TO_EDGE) || (U == GL_CLAMP_TO_BORDER) || (U == GL_MIRRORED_REPEAT) || (U == GL_MIRROR_CLAMP_EXT) || (U == GL_MIRROR_CLAMP_TO_EDGE_EXT) || (U == GL_MIRROR_CLAMP_TO_BORDER_EXT) || (U == GL_REPEAT), "Error[GLTextureStates::SetWrap]: Invalid U Wrap State"); nuxAssertMsg( (V == GL_CLAMP) || (V == GL_CLAMP_TO_EDGE) || (V == GL_CLAMP_TO_BORDER) || (V == GL_MIRRORED_REPEAT) || (V == GL_MIRROR_CLAMP_EXT) || (V == GL_MIRROR_CLAMP_TO_EDGE_EXT) || (V == GL_MIRROR_CLAMP_TO_BORDER_EXT) || (V == GL_REPEAT), "Error[GLTextureStates::SetWrap]: Invalid V Wrap State"); nuxAssertMsg( (W == GL_CLAMP) || (W == GL_CLAMP_TO_EDGE) || (W == GL_CLAMP_TO_BORDER) || (W == GL_MIRRORED_REPEAT) || (W == GL_MIRROR_CLAMP_EXT) || (W == GL_MIRROR_CLAMP_TO_EDGE_EXT) || (W == GL_MIRROR_CLAMP_TO_BORDER_EXT) || (W == GL_REPEAT), "Error[GLTextureStates::SetWrap]: Invalid W Wrap State"); if (m_Type == GL_TEXTURE_RECTANGLE_ARB) { if ((U != GL_CLAMP) && (U != GL_CLAMP_TO_BORDER) && (U != GL_CLAMP_TO_EDGE)) { nuxError("[GLTextureStates::SetFiltering] Incorrect warp for rectangle texture."); SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSU], GL_CLAMP_TO_EDGE); } else { SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSU], U); } if ((V != GL_CLAMP) && (V != GL_CLAMP_TO_BORDER) && (V != GL_CLAMP_TO_EDGE)) { nuxError("[GLTextureStates::SetFiltering] Incorrect warp for rectangle texture."); SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSV], GL_CLAMP_TO_EDGE); } else { SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSV], V); } if ((W != GL_CLAMP) && (W != GL_CLAMP_TO_BORDER) && (W != GL_CLAMP_TO_EDGE)) { nuxError("[GLTextureStates::SetFiltering] Incorrect warp for rectangle texture."); SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSW], GL_CLAMP_TO_EDGE); } else { SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSW], W); } } else { SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSU], U); SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSV], V); SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSW], W); } #else nuxAssertMsg( (U == GL_CLAMP) || (U == GL_CLAMP_TO_EDGE) || (U == GL_CLAMP_TO_BORDER) || (U == GL_MIRRORED_REPEAT) || (U == GL_REPEAT), "Error[GLTextureStates::SetWrap]: Invalid U Wrap State"); nuxAssertMsg( (V == GL_CLAMP) || (V == GL_CLAMP_TO_EDGE) || (V == GL_CLAMP_TO_BORDER) || (V == GL_MIRRORED_REPEAT) || (V == GL_REPEAT), "Error[GLTextureStates::SetWrap]: Invalid V Wrap State"); SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSU], U); SET_TS_VALUE(m_TextureStateChanges[GFXTS_ADDRESSV], V); #endif } void GLTextureStates::SetLOD(float MinLod, float MaxLod) { SET_TS_VALUE_FLOAT(m_TextureStateChanges[GFXTS_MIN_LOD], MinLod); SET_TS_VALUE_FLOAT(m_TextureStateChanges[GFXTS_MAX_LOD], MaxLod); } void GLTextureStates::SetMipLevel( unsigned int MinMip, unsigned int MaxMip) { SET_TS_VALUE(m_TextureStateChanges[GFXTS_MIP_BASE_LEVEL], MinMip); SET_TS_VALUE(m_TextureStateChanges[GFXTS_MIP_MAX_LEVEL], MaxMip); } void GLTextureStates::SetBorderColor( float R, float G, float B, float A) { unsigned int r, g, b, a; r = 255 * Clamp(R, 0.0f, 1.0f); g = 255 * Clamp(G, 0.0f, 1.0f); b = 255 * Clamp(B, 0.0f, 1.0f); a = 255 * Clamp(A, 0.0f, 1.0f); unsigned int color = (unsigned int) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)); SET_TS_VALUE(m_TextureStateChanges[GFXTS_BORDERCOLOR], color); } #undef SET_TS_VALUE #undef TS_VALUE #undef SET_TS_VALUE_FLOAT #undef TS_VALUE_FLOAT } nux-4.0.6+14.04.20140409/NuxGraphics/GLVertexResourceManager.h0000644000015301777760000001174512321344237024054 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLVERTEXRESOURCEMANAGER_H #define GLVERTEXRESOURCEMANAGER_H #include "GLResourceManager.h" #include "IOpenGLVertexBuffer.h" #include "IOpenGLIndexBuffer.h" #include "IOpenGLVertexDeclaration.h" #include "MeshData.h" namespace nux { class VertexBuffer: public ResourceData { NUX_DECLARE_OBJECT_TYPE(VertexBuffer, ResourceData); public: VertexBuffer(); virtual ~VertexBuffer(); VertexBuffer(int Size, int Stride); //! Allocate space for a "num_element", each of size "size". /*! @param num_element Number of elements. @param size Number of byte for every element. */ void Allocate(int num_index, int size); int GetSize() const; int GetStride() const; int GetNumElement() const; const void* GetPtrRawData() const; void* GetPtrRawData(); public: std::vector _Data; int _Stride; }; class IndexBuffer: public ResourceData { NUX_DECLARE_OBJECT_TYPE(IndexBuffer, ResourceData); // IndexBuffer is very similar to MeshBuffer except that vertex indices // are not inter-mixed with other vertex data. So the Stride here should be 2 bytes or 4 bytes. public: IndexBuffer(); virtual ~IndexBuffer(); IndexBuffer(int Size, int Stride); void Allocate(int Size, int Stride); int GetSize() const; int GetStride() const; int GetNumIndex() const; const void* GetPtrRawData() const; void* GetPtrRawData(); public: std::vector _Data; int _Stride; int _num_index; }; class VertexDeclaration: public ResourceData { NUX_DECLARE_OBJECT_TYPE(NVertexDeclaration, ResourceData); public: VertexDeclaration(); ~VertexDeclaration(); void AddVertexComponent(VERTEXELEMENT); std::vector _declaration; }; class CachedVertexBuffer: public CachedResourceData { NUX_DECLARE_OBJECT_TYPE(CachedVertexBuffer, CachedResourceData); public: CachedVertexBuffer(NResourceSet* ResourceManager, VertexBuffer* resource); ~CachedVertexBuffer(); ObjectPtr _vertex_buffer; bool UpdateResource(ResourceData* Resource); int GetElementSize() const; int GetBufferStride() const; private: void LoadVertexData(VertexBuffer* vertex_buffer); int _Size; int _Stride; }; class CachedIndexBuffer: public CachedResourceData { NUX_DECLARE_OBJECT_TYPE(CachedIndexBuffer, CachedResourceData); public: CachedIndexBuffer(NResourceSet* ResourceManager, IndexBuffer* resource); ~CachedIndexBuffer(); ObjectPtr _index_buffer; bool UpdateResource(ResourceData* Resource); int GetElementSize() const; int GetBufferStride() const; int GetNumIndex() const; private: void LoadIndexData(IndexBuffer* index_buffer); int _Size; int _Stride; int _num_index; }; class CachedVertexDeclaration: public CachedResourceData { NUX_DECLARE_OBJECT_TYPE(CachedVertexDeclaration, CachedResourceData); public: CachedVertexDeclaration(NResourceSet* ResourceManager, VertexDeclaration* Resource); ~CachedVertexDeclaration(); bool UpdateResource(ResourceData* Resource); ObjectPtr _declaration; }; class CachedMeshBuffer; class MeshBuffer: public ResourceData { NUX_DECLARE_OBJECT_TYPE(MeshBuffer, ResourceData); public: MeshBuffer(NUX_FILE_LINE_PROTO); virtual ~MeshBuffer(); bool Update(const MeshData* mesh_data); ObjectPtr GetCachedMeshBuffer(); public: VertexBuffer* _vertex_buffer; IndexBuffer* _index_buffer; VertexDeclaration* _vertex_declaration; NuxMeshPrimitiveType _mesh_primitive_type; }; class CachedMeshBuffer: public CachedResourceData { NUX_DECLARE_OBJECT_TYPE(CachedMeshBuffer, CachedResourceData); public: ObjectPtr _cached_vertex_buffer; ObjectPtr _cached_vertex_declaration; ObjectPtr _cached_index_buffer; NuxMeshPrimitiveType _mesh_primitive_type; CachedMeshBuffer(NResourceSet* ResourceManager, MeshBuffer* resource); ~CachedMeshBuffer(); bool UpdateResource(ResourceData* Resource); }; } #endif // GLVERTEXRESOURCEMANAGER_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLBaseTexture.h0000644000015301777760000001204612321344237022755 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLBASETEXTURE_H #define IOPENGLBASETEXTURE_H #include "GLResource.h" #include "IOpenGLResource.h" #include "GLShaderParameter.h" #include "GLTextureStates.h" namespace nux { class IOpenGLResource; class IOpenGLBaseTexture; int GetTextureSize(IOpenGLBaseTexture *pTexture); // todo: It should not be possible to create an object of type IOpenGLBaseTexture directly. class IOpenGLBaseTexture: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLBaseTexture, IOpenGLResource); public: IOpenGLBaseTexture(OpenGLResourceType ResourceType, unsigned int Width, unsigned int Height, unsigned int Depth, unsigned int NumMipLevel, BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO); virtual ~IOpenGLBaseTexture(); BitmapFormat GetPixelFormat() const { return _PixelFormat; } int GetNumMipLevel() const { return _NumMipLevel; } bool IsPowerOfTwo() const { return _IsPOT; } int GetWidth() const { if (_ResourceType == RTTEXTURE) return _Width; if (_ResourceType == RTTEXTURERECTANGLE) return _Width; if (_ResourceType == RTCUBETEXTURE) return _Width; return 0; } int GetHeight() const { if (_ResourceType == RTTEXTURE) return _Height; if (_ResourceType == RTTEXTURERECTANGLE) return _Height; if (_ResourceType == RTCUBETEXTURE) return _Width; return 0; } int GetDepth() const { if (_ResourceType == RTTEXTURE) return 1; if (_ResourceType == RTTEXTURERECTANGLE) return 1; if (_ResourceType == RTCUBETEXTURE) return 1; if (_ResourceType == RTVOLUMETEXTURE) return _Depth; if (_ResourceType == RTANIMATEDTEXTURE) return _Depth; return 0; } int GetFormatRowMemoryAlignment() const { return _RowMemoryAlignment; } //GLTextureStates& GetTextureStates() {return _TextureStates;} void SetRenderStates(); void SetFiltering(unsigned int MIN = GL_NEAREST, unsigned int MAG = GL_NEAREST/*, unsigned int MIP = GL_NEAREST*/); void SetWrap(unsigned int U = GL_REPEAT, unsigned int V = GL_REPEAT, unsigned int W = GL_REPEAT); void SetLOD(float MinLod = -1000.0f, float MaxLod = +1000.0f); void SetMipLevel(unsigned int MinMip = 0, unsigned int MaxMip = 1000); void SetBorderColor(float R, float G, float B, float A); int BindTexture(); int BindTextureToUnit(int TextureUnitIndex); virtual void GetSurfaceLevel(int Level, ObjectPtr& surface); virtual ObjectPtr GetSurfaceLevel(int Level); virtual int LockRect( int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect); virtual int UnlockRect(int Level); //! Return a pointer to a mipmap level data. /*! Return a pointer to a mipmap level data. The data is in the RGBA format.\n @param level The requested texture mipmap level data. @param width Returns the width in pixel of the image data. @param height Returns the height in pixel of the image data. @param stride Returns the row stride of the image data. @return A pointer to RGBA data. The caller must delete the data by calling delete []. */ virtual unsigned char* GetSurfaceData(int level, int &width, int &height, int &stride); void Save(const char* filename); protected: GLTextureStates _TextureStates; bool _IsPOT; // is power of two? int _NumMipLevel; BitmapFormat _PixelFormat; // These parameters are scalable across textures, cube textures and volume textures. // For texture and cube texture _Depth is equal to 1. // For cube texture, _Width = _Height int _Width; int _Height; int _Depth; int _RowMemoryAlignment; friend class IOpenGLSurface; friend class IOpenGLVolume; friend void GetTextureDesc( IOpenGLBaseTexture *pTexture, unsigned int Level, TEXTURE_DESC *pDesc ); friend int GetTextureSize(IOpenGLBaseTexture *pTexture); }; } #endif // IOPENGLBASETEXTURE_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLSurface.cpp0000644000015301777760000006170712321344237022455 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GraphicsDisplay.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLSurface.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLSurface); IOpenGLSurface::IOpenGLSurface(IOpenGLBaseTexture *DeviceBaseTexture , GLenum OpenGLID , GLenum TextureTarget , GLenum SurfaceTarget , int MipLevel , int Slice , NUX_FILE_LINE_DECL) : IOpenGLResource(RTSURFACE, NUX_FILE_LINE_PARAM) , _STextureTarget(TextureTarget) , _SSurfaceTarget(SurfaceTarget) , _SMipLevel(MipLevel) , _SSlice(Slice) , _BaseTexture(DeviceBaseTexture) , _AllocatedUnpackBuffer(0xFFFFFFFF) { // IOpenGLSurface surfaces are created inside a IOpenGLTexture2D, IOpenGLCubeTexture and IOpenGLVolumeTexture. // They reside within those classes. The reference counting starts once a call to GetSurfaceLevel, // GetCubeMapSurface or GetVolumeLevel is made to the container object. _RefCount = 0; _OpenGLID = OpenGLID; _LockedRect.pBits = 0; _LockedRect.Pitch = 0; _CompressedDataSize = 0; _Initialized = 0; } IOpenGLSurface::~IOpenGLSurface() { } BitmapFormat IOpenGLSurface::GetPixelFormat() const { if (_BaseTexture == 0) { nuxAssert(0); // should not happen return BITFMT_UNKNOWN; } return _BaseTexture->GetPixelFormat(); } int IOpenGLSurface::GetWidth() const { if (_BaseTexture == 0) { nuxAssert(0); // should not happen return 0; } return ImageSurface::GetLevelDim(_BaseTexture->_PixelFormat, _BaseTexture->_Width, _SMipLevel); } int IOpenGLSurface::GetHeight() const { if (_BaseTexture == 0) { nuxAssert(0); // should not happen return 0; } return ImageSurface::GetLevelDim(_BaseTexture->_PixelFormat, _BaseTexture->_Height, _SMipLevel); } int IOpenGLSurface::GetMipLevel() const { return _SMipLevel; } int IOpenGLSurface::GetSurfaceTarget() const { return _SSurfaceTarget; } int IOpenGLSurface::GetDesc(SURFACE_DESC *pDesc) { pDesc->Width = GetWidth(); pDesc->Height = GetHeight(); pDesc->PixelFormat = GetPixelFormat(); pDesc->Type = _ResourceType; return OGL_OK; } int IOpenGLSurface::RefCount() const { if (_BaseTexture) return _BaseTexture->RefCount(); nuxAssert(0); // Surface with no underlying texture. That should not happen. return 0; } int IOpenGLSurface::LockRect( SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect) { // If _LockedRect.pBits or _LockedRect.Pitch are not equal to zero, then we have already Locked the buffer // Unlock it before locking again. nuxAssert(_LockedRect.pBits == 0); nuxAssert(_LockedRect.Pitch == 0); nuxAssert(_CompressedDataSize == 0); if ((_LockedRect.pBits != 0) || (_LockedRect.Pitch != 0) || (_CompressedDataSize != 0)) { // already locked; return OGL_INVALID_LOCK; } _Rect.bottom = _Rect.left = _Rect.right = _Rect.top = 0; GLint unpack_alignment = GPixelFormats[_BaseTexture->_PixelFormat].RowMemoryAlignment; unsigned int halfUnpack = Log2(unpack_alignment); CHECKGL(glBindTexture(_STextureTarget, _BaseTexture->_OpenGLID)); unsigned int surface_size = 0; unsigned int BytePerPixel = 0; IOpenGLBaseTexture *texture = _BaseTexture; if (!((_BaseTexture->_ResourceType == RTTEXTURE) || (_BaseTexture->_ResourceType == RTTEXTURERECTANGLE) || (_BaseTexture->_ResourceType == RTCUBETEXTURE) || (_BaseTexture->_ResourceType == RTVOLUMETEXTURE) || (_BaseTexture->_ResourceType == RTANIMATEDTEXTURE))) { nuxAssertMsg(0, "Unknown resource type"); } int texwidth, texheight; texwidth = ImageSurface::GetLevelDim(texture->_PixelFormat, texture->_Width, _SMipLevel); texheight = ImageSurface::GetLevelDim(texture->_PixelFormat, texture->_Height, _SMipLevel); if ( texture->_PixelFormat == BITFMT_DXT1 || texture->_PixelFormat == BITFMT_DXT2 || texture->_PixelFormat == BITFMT_DXT3 || texture->_PixelFormat == BITFMT_DXT4 || texture->_PixelFormat == BITFMT_DXT5) { if (texture->_PixelFormat == BITFMT_DXT1) { // We can conceive a 4x4 DXT1 block as if each texel uses 4 bits. // Actually, for DXT, we have 2 16-bits colors(5:6:5), and each texel uses 2 bits to interpolate // between the 2 colors. // --------------------- // | COLOR0 | 16 bits // --------------------- // | COLOR1 | 16 bits // --------------------- // | xx | xx | xx | xx | xx = 2 bits // --------------------- // | xx | xx | xx | xx | // --------------------- // | xx | xx | xx | xx | // --------------------- // | xx | xx | xx | xx | // --------------------- // A line of n texel DXT1 data uses n/2 bytes(4 bits/texel). So the number of bytes used for a // texwidth texel, is texwidth/2 bytes. // Note that texwidth is divisible by 4(to to the upper rounding to 4), therefore, it is also divisible // by 2. // glCompressedTexImage2DARB, glCompressedTexImage3DARB, // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei. surface_size = ImageSurface::GetLevelSize(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); _CompressedDataSize = surface_size; _LockedRect.Pitch = ImageSurface::GetLevelPitch(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); if (_Initialized == false) { InitializeLevel(); } } else { // A line of n texel DXT3/5 data uses n bytes(1 byte/texel). So the number of bytes used for a // texwidth texels, is texwidth bytes. // glCompressedTexImage2DARB, glCompressedTexImage3DARB, // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei. surface_size = ImageSurface::GetLevelSize(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); _CompressedDataSize = surface_size; _LockedRect.Pitch = ImageSurface::GetLevelPitch(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); if (_Initialized == false) { InitializeLevel(); } } } else { _LockedRect.Pitch = ImageSurface::GetLevelPitch(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); surface_size = ImageSurface::GetLevelSize(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); if (_Initialized == false) { InitializeLevel(); } } _Rect.left = 0; _Rect.top = 0; _Rect.bottom = texheight; _Rect.right = texwidth; if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { GetGraphicsDisplay()->GetGpuDevice()->AllocateUnpackPixelBufferIndex(&_AllocatedUnpackBuffer); } if (pRect == 0) { if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { // Mapping the entire area of the surface _LockedRect.pBits = GetGraphicsDisplay()->GetGpuDevice()->LockUnpackPixelBufferIndex(_AllocatedUnpackBuffer, surface_size); pLockedRect->pBits = _LockedRect.pBits; pLockedRect->Pitch = _LockedRect.Pitch; } else { //[DEBUGGING - NO PBO] // Mapping the entire area of the surface _LockedRect.pBits = new BYTE[surface_size]; pLockedRect->pBits = _LockedRect.pBits; pLockedRect->Pitch = _LockedRect.Pitch; } } else { //[WARNING] // this section of code is suppose to handle rectangles that are not the size of the entire surface. // It works for uncompressed texture. However it hasn't been tested for compressed texture. // reserve and lock a surface size equal to(RectWidth * RectHeight * BytePerPixel) int RectWidth = pRect->right - pRect->left; int RectHeight = pRect->bottom - pRect->top; nuxAssert(RectWidth >= 0); nuxAssert(RectHeight >= 0); unsigned int RectSize = (((RectWidth * BytePerPixel + (unpack_alignment - 1)) >> (halfUnpack)) << (halfUnpack)) * RectHeight; if (RectSize == 0) { _LockedRect.pBits = NULL; _LockedRect.Pitch = 0; pLockedRect->pBits = NULL; pLockedRect->Pitch = 0; return OGL_INVALID_LOCK; } if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { _LockedRect.pBits = GetGraphicsDisplay()->GetGpuDevice()->LockUnpackPixelBufferIndex(_AllocatedUnpackBuffer, RectSize); pLockedRect->pBits = ((BYTE *) _LockedRect.pBits); pLockedRect->Pitch = (((RectWidth * BytePerPixel + (unpack_alignment - 1)) >> (halfUnpack)) << (halfUnpack)); } else { //[DEBUGGING - NO PBO] _LockedRect.pBits = new BYTE[RectSize]; pLockedRect->pBits = ((BYTE *) _LockedRect.pBits); pLockedRect->Pitch = (((RectWidth * BytePerPixel + (unpack_alignment - 1)) >> (halfUnpack)) << (halfUnpack)); } _Rect.left = pRect->left; _Rect.top = pRect->top; _Rect.bottom = pRect->bottom; _Rect.right = pRect->right; } return OGL_OK; } int IOpenGLSurface::UnlockRect() { if (_LockedRect.pBits == 0) { return OGL_INVALID_UNLOCK; } CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, _BaseTexture->GetFormatRowMemoryAlignment())); #ifndef NUX_OPENGLES_20 if (_STextureTarget == GL_TEXTURE_2D || _STextureTarget == GL_TEXTURE_RECTANGLE_ARB || _STextureTarget == GL_TEXTURE_CUBE_MAP || _STextureTarget == GL_TEXTURE_3D) #else if (_STextureTarget == GL_TEXTURE_2D) #endif { BYTE *DataPtr = 0; int w = _Rect.right - _Rect.left; int h = _Rect.bottom - _Rect.top; CHECKGL(glBindTexture(_STextureTarget, _BaseTexture->_OpenGLID)); #ifndef NUX_OPENGLES_20 if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { // Unmap the texture image buffer GetGraphicsDisplay()->GetGpuDevice()->BindUnpackPixelBufferIndex(_AllocatedUnpackBuffer); CHECKGL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); DataPtr = NUX_BUFFER_OFFSET(0); } else { CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); #endif DataPtr = (BYTE *) _LockedRect.pBits; #ifndef NUX_OPENGLES_20 } #endif IOpenGLTexture2D *texture = (IOpenGLTexture2D *) _BaseTexture; #ifndef NUX_OPENGLES_20 if ( /*texture->_PixelFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||*/ texture->_PixelFormat == BITFMT_DXT1 || texture->_PixelFormat == BITFMT_DXT2 || texture->_PixelFormat == BITFMT_DXT3 || texture->_PixelFormat == BITFMT_DXT4 || texture->_PixelFormat == BITFMT_DXT5) { nuxAssert(_CompressedDataSize != 0); int width = Max (1, texture->_Width >> _SMipLevel); int height = Max (1, texture->_Height >> _SMipLevel); int xoffset = _Rect.left; int yoffset = _Rect.top; if (_STextureTarget != GL_TEXTURE_3D) { glCompressedTexSubImage2DARB(_SSurfaceTarget, _SMipLevel, // level xoffset, yoffset, width, height, GPixelFormats[texture->_PixelFormat].PlatformFormat, _CompressedDataSize, // image Size DataPtr // data ); CHECKGL_MSG(glCompressedTexSubImage2DARB); } else { glCompressedTexSubImage3DARB(_SSurfaceTarget, _SMipLevel, // level xoffset, yoffset, 0, width, height, _SSlice, GPixelFormats[texture->_PixelFormat].PlatformFormat, _CompressedDataSize, // image Size DataPtr // data ); CHECKGL_MSG(glCompressedTexSubImage3DARB); } // We can use glCompressedTexImage2DARB if we are sure we always lock // the entire area of the surface. // glCompressedTexImage2DARB(_SSurfaceTarget, // _SMipLevel, // level // texture->_Format, // width, // height, // 0, // border // _CompressedDataSize, // image Size // _LockedRect.pBits // data // ); // CHECKGL_MSG(glCompressedTexImage2DARB); // { //[DEBUGGING - Red Texture] // // This is going to put some red in the texture. // // The texture is not compressed. // BYTE *color_array = new BYTE[width*height*4]; // for (int i = 0; i < width*height*4; i += 4) // { // color_array[i + 0] = 0xff; // color_array[i + 1] = _SMipLevel * 0x3F; // color_array[i + 2] = 0x0; // color_array[i + 3] = 0xFF; // } // glTexImage2D(GL_TEXTURE_2D, // _SMipLevel, // GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, color_array); // CHECKGL_MSG(glTexImage2D); // delete [] color_array; // } } else { //CHECKGL(glPixelStorei(GL_UNPACK_ROW_LENGTH, w)); if (_STextureTarget != GL_TEXTURE_3D) { #endif CHECKGL(glTexSubImage2D(_SSurfaceTarget, _SMipLevel, _Rect.left, _Rect.top, w, h, GPixelFormats[texture->_PixelFormat].Format, GPixelFormats[texture->_PixelFormat].type, DataPtr )); #ifndef NUX_OPENGLES_20 } else { CHECKGL(glTexSubImage3D(_SSurfaceTarget, _SMipLevel, _Rect.left, _Rect.top, _SSlice, // z offset w, h, 1, GPixelFormats[texture->_PixelFormat].Format, GPixelFormats[texture->_PixelFormat].type, DataPtr )); } //CHECKGL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); // CHECKGL(glTexImage2D(_SSurfaceTarget, // _SMipLevel, // GPixelFormats[texture->_PixelFormat].PlatformFormat, // w, // h, // 0, // //### todo: // // - find the correct format matching the internal format // // - find the correct type matching the internal format // GPixelFormats[texture->_PixelFormat].Format, // GPixelFormats[texture->_PixelFormat].type, // DataPtr // )); } #endif } else { nuxDebugMsg("[IOpenGLSurface::UnlockRect] Incorrect Texture Target."); } #ifndef NUX_OPENGLES_20 if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); GetGraphicsDisplay()->GetGpuDevice()->FreeUnpackPixelBufferIndex(_AllocatedUnpackBuffer); } else { #endif //[DEBUGGING - NO PBO] if (_LockedRect.pBits) { delete [] ((BYTE *) _LockedRect.pBits); } #ifndef NUX_OPENGLES_20 } #endif CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, GetGraphicsDisplay()->GetGpuDevice()->GetPixelStoreAlignment())); _LockedRect.pBits = 0; _LockedRect.Pitch = 0; _CompressedDataSize = 0; return OGL_OK; } int IOpenGLSurface::InitializeLevel() { // Because we use SubImage when unlocking surfaces, we must first get some dummy data in the surface before we can make a lock. int texwidth = ImageSurface::GetLevelWidth(_BaseTexture->_PixelFormat, _BaseTexture->_Width, _SMipLevel); int texheight = ImageSurface::GetLevelHeight(_BaseTexture->_PixelFormat, _BaseTexture->_Height, _SMipLevel); int MemAlignment = ImageSurface::GetMemAlignment(_BaseTexture->_PixelFormat); nuxAssert( texwidth > 0 ); // Should never happen nuxAssert( texheight > 0 ); // Should never happen CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, MemAlignment)); #ifndef NUX_OPENGLES_20 int size = ImageSurface::GetLevelSize(_BaseTexture->_PixelFormat, _BaseTexture->_Width, _BaseTexture->_Height, _SMipLevel); nuxAssert( size > 0 ); // Should never happen if ( _BaseTexture->_PixelFormat == BITFMT_DXT1 || _BaseTexture->_PixelFormat == BITFMT_DXT2 || _BaseTexture->_PixelFormat == BITFMT_DXT3 || _BaseTexture->_PixelFormat == BITFMT_DXT4 || _BaseTexture->_PixelFormat == BITFMT_DXT5) { if (_STextureTarget != GL_TEXTURE_3D) { glCompressedTexImage2DARB( _SSurfaceTarget, _SMipLevel, // level GPixelFormats[_BaseTexture->_PixelFormat].PlatformFormat, texwidth, texheight, 0, // border size, // image Size NULL // data ); CHECKGL_MSG(glCompressedTexImage2DARB); } else { // glCompressedTexImage3DARB( // _SSurfaceTarget, // _SMipLevel, // level // GPixelFormats[_BaseTexture->_PixelFormat].PlatformFormat, // texwidth, // texheight, // _SSlice, // 0, // border // size, // image Size // DummyBuffer // data // ); // CHECKGL_MSG(glCompressedTexImage3DARB); } } else { if (_STextureTarget != GL_TEXTURE_3D) { #endif glTexImage2D( _SSurfaceTarget, _SMipLevel, // level GPixelFormats[_BaseTexture->_PixelFormat].PlatformFormat, texwidth, texheight, 0, // border GPixelFormats[_BaseTexture->_PixelFormat].Format, GPixelFormats[_BaseTexture->_PixelFormat].type, NULL); CHECKGL_MSG(glTexImage2D); #ifndef NUX_OPENGLES_20 } else { // glTexImage3D( // _SSurfaceTarget, // _SMipLevel, // level // GPixelFormats[PixelFormat].PlatformFormat, // texwidth, // texheight, // _SSlice, // 0, // border // GPixelFormats[PixelFormat].Format, // GPixelFormats[PixelFormat].type, // DummyBuffer); // CHECKGL_MSG(glTexImage3D); } } #endif // { //[DEBUGGING - Red Texture] // // This is going to put some red in the texture. // // The texture is not compressed. // BYTE *color_array = new BYTE[texwidth*texheight*4]; // for (unsigned int i = 0; i < texwidth*texheight*4; i += 4) // { // color_array[i + 0] = 0xff; // color_array[i + 1] = _SMipLevel * 0x3F; // color_array[i + 2] = 0x0; // color_array[i + 3] = 0xFF; // } // glTexImage2D(GL_TEXTURE_2D, // _SMipLevel, // GL_RGBA8, texwidth, texheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, color_array); // CHECKGL_MSG(glTexImage2D); // delete [] color_array; // } CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, GetGraphicsDisplay()->GetGpuDevice()->GetPixelStoreAlignment())); _Initialized = true; return OGL_OK; } void IOpenGLSurface::CopyRenderTarget(int x, int y, int width, int height) { CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, _BaseTexture->GetFormatRowMemoryAlignment())); #ifndef NUX_OPENGLES_20 if (_STextureTarget == GL_TEXTURE_2D || _STextureTarget == GL_TEXTURE_RECTANGLE_ARB || _STextureTarget == GL_TEXTURE_CUBE_MAP || _STextureTarget == GL_TEXTURE_3D) #else if (_STextureTarget == GL_TEXTURE_2D) #endif { CHECKGL(glBindTexture(_STextureTarget, _BaseTexture->_OpenGLID)); #ifndef NUX_OPENGLES_20 if (_STextureTarget != GL_TEXTURE_3D) { CHECKGL(glCopyTexImage2D(_SSurfaceTarget, _SMipLevel, GPixelFormats [_BaseTexture->_PixelFormat].Format, x, y, width, height, 0)); } else { CHECKGL(glCopyTexSubImage3D(_SSurfaceTarget, _SMipLevel, 0, 0, 0, x, y, width, height)); } #else CHECKGL(glCopyTexImage2D(_SSurfaceTarget, _SMipLevel, GPixelFormats [_BaseTexture->_PixelFormat].Format, x, y, width, height, 0)); #endif } } unsigned char* IOpenGLSurface::GetSurfaceData(int &width, int &height, int &stride) { width = 0; height = 0; stride = 0; if (_BaseTexture->_OpenGLID == 0) { return NULL; } #ifndef NUX_OPENGLES_20 CHECKGL(glBindTexture(_STextureTarget, _BaseTexture->_OpenGLID)); // Despite a 1 byte pack alignment not being the most optimum, do it for simplicity. CHECKGL(glPixelStorei(GL_PACK_ALIGNMENT, 1)); // We want RGBA data int mip_level_size = GetWidth() * GetHeight() * 4; unsigned char* img = new unsigned char[mip_level_size]; // Internal OpenGL textures are in the RGBA format. // If the selected texture image does not contain four components, the following mappings are applied: // - Single-component textures are treated as RGBA buffers with red set to the single-component value, green set to 0, blue set to 0, and alpha set to 1. // - red set to component zero // - green set to 0 // - blue set to 0 // - alpha set to 1.0 // - Two-component textures are treated as RGBA buffers with: // - red set to component zero // - green set to 0 // - blue set to 0 // - alpha set to component one // // - Three-component textures are treated as RGBA buffers with: // - red set to component zero // - green set to component one // - blue set to component two // - alpha set to 1.0 CHECKGL(glGetTexImage(_STextureTarget, _SMipLevel, GL_RGBA, GL_UNSIGNED_BYTE, img)); width = GetWidth(); height = GetHeight(); stride = width * 4; return img; #else //FIXME: need to render to framebuffer and use glReadPixels return NULL; #endif } } nux-4.0.6+14.04.20140409/NuxGraphics/GLShader.cpp0000644000015301777760000000163312321344237021330 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "GLResource.h" #include "GLShader.h" #include "GLShaderParameter.h" namespace nux { } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLRectangleTexture.cpp0000644000015301777760000001115412321344237024341 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLDeviceObjects.h" #include "IOpenGLRectangleTexture.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLRectangleTexture); IOpenGLRectangleTexture::IOpenGLRectangleTexture( unsigned int Width , unsigned int Height , unsigned int Levels , BitmapFormat PixelFormat, bool Dummy, NUX_FILE_LINE_DECL) : IOpenGLBaseTexture(RTTEXTURERECTANGLE, Width, Height, 1, Levels, PixelFormat, NUX_FILE_LINE_PARAM) { #ifndef NUX_OPENGLES_20 if (Dummy == false) { CHECKGL(glGenTextures(1, &_OpenGLID)); CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _OpenGLID)); } //_SurfaceArray.Empty(Levels); for (unsigned int l = 0; l < Levels; l++) { IOpenGLSurface *surface = new IOpenGLSurface(this, _OpenGLID, GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_RECTANGLE_ARB, l, 0, NUX_FILE_LINE_PARAM); if (Dummy == false) surface->InitializeLevel(); _SurfaceArray.push_back(ObjectPtr (surface)); surface->UnReference(); } SetFiltering(GL_NEAREST, GL_NEAREST); SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); SetRenderStates(); GRunTimeStats.Register(this); #endif } IOpenGLRectangleTexture::~IOpenGLRectangleTexture() { for (int l = 0; l < _NumMipLevel; l++) { _SurfaceArray[l] = ObjectPtr (0);; } _SurfaceArray.clear(); CHECKGL(glDeleteTextures(1, &_OpenGLID)); _OpenGLID = 0; GRunTimeStats.UnRegister(this); } ObjectPtr IOpenGLRectangleTexture::GetSurfaceLevel(int Level) { if (Level < _NumMipLevel) { return _SurfaceArray[Level]; } else { nuxAssertMsg(0, "[IOpenGLRectangleTexture::GetSurfaceLevel] Invalid surface level"); } return ObjectPtr (0); } void IOpenGLRectangleTexture::GetSurfaceLevel(int Level, ObjectPtr& surface) { surface = GetSurfaceLevel(Level); } int IOpenGLRectangleTexture::LockRect( int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect) { nuxAssertMsg(pLockedRect, "[IOpenGLRectangleTexture::LockRect] Invalid parameter 'pLockedRect'."); nuxAssertMsg(Level >= 0, "[IOpenGLRectangleTexture::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLRectangleTexture::LockRect] Invalid mipmap level."); if (Level < _NumMipLevel) { ObjectPtr pSurfaceLevel = _SurfaceArray[Level]; return pSurfaceLevel->LockRect(pLockedRect, pRect); } else { pLockedRect->pBits = 0; pLockedRect->Pitch = 0; return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } int IOpenGLRectangleTexture::UnlockRect( int Level ) { nuxAssertMsg(Level >= 0, "[IOpenGLRectangleTexture::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLRectangleTexture::LockRect] Invalid mipmap level."); if (Level < _NumMipLevel) { ObjectPtr pSurfaceLevel = _SurfaceArray[Level]; return pSurfaceLevel->UnlockRect(); } else { return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } unsigned int IOpenGLRectangleTexture::EnableGammaCorrection(bool /* b */) { nuxAssert(_OpenGLID); return OGL_OK; } unsigned char* IOpenGLRectangleTexture::GetSurfaceData(int level, int &width, int &height, int &stride) { width = 0; height = 0; stride = 0; if (level < 0) { nuxAssertMsg(level >= 0, "[IOpenGLRectangleTexture::GetSurfaceData] Invalid mipmap level."); return NULL; } if (level >= _NumMipLevel) { nuxAssertMsg(level < _NumMipLevel, "[IOpenGLRectangleTexture::GetSurfaceData] Invalid mipmap level."); return NULL; } ObjectPtr pSurfaceLevel = _SurfaceArray[level]; return pSurfaceLevel->GetSurfaceData(width, height, stride); } } nux-4.0.6+14.04.20140409/NuxGraphics/GLPBuffer.h0000644000015301777760000001123312321344237021115 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef __PBUFFERS_H__ #define __PBUFFERS_H__ #ifndef NUX_OPENGLES_20 #if defined(WIN32) #include "GLResource.h" # pragma warning (disable : 4786) #elif defined(UNIX) # include # include #elif defined(__APPLE__) # include #endif #include #include // The pixel format for the pbuffer is controlled by the mode string passed // into the PBuffer constructor. This string can have the following attributes: // // r - r pixel format (for float buffer). // rg - rg pixel format (for float buffer). // rgb - rgb pixel format. 8 bit or 16/32 bit in float buffer mode // rgba - same as "rgb alpha" string // alpha - must have alpha channel // depth - must have a depth buffer // depth=n - must have n-bit depth buffer // stencil - must have a stencil buffer // double - must support double buffered rendering // samples=n - must support n-sample antialiasing (n can be 2 or 4) // float=n - must support n-bit per channel floating point // // texture2D // textureRECT // textureCUBE - must support binding pbuffer as texture to specified target // - binding the depth buffer is also supporting by specifying // '=depth' like so: texture2D=depth or textureRECT=depth // - the internal format of the texture will be rgba by default or // float if pbuffer is floating point // namespace nux { class PBuffer { public: // see above for documentation on strMode format // set managed to true if you want the class to cleanup OpenGL objects in destructor PBuffer (const char *strMode, bool managed = false); ~PBuffer(); bool Initialize (int iWidth, int iHeight, bool bShareContexts, bool bShareObjects); void Destroy(); void Activate (PBuffer *current = NULL); // to switch between pbuffers, pass active pbuffer as argument void Deactivate(); #if defined(WIN32) int Bind (int iBuffer); int Release (int iBuffer); void HandleModeSwitch(); #endif unsigned int GetSizeInBytes(); unsigned int CopyToBuffer (void *ptr, int w = -1, int h = -1); inline int GetNumComponents() { return m_iNComponents; } inline int GetBitsPerComponent() { return m_iBitsPerComponent; } inline int GetWidth() { return m_iWidth; } inline int GetHeight() { return m_iHeight; } inline bool IsSharedContext() { return m_bSharedContext; } #if defined(WIN32) inline bool IsTexture() { return m_bIsTexture; } #endif protected: #if defined(NUX_OS_WINDOWS) HDC m_hDC; ///< Handle to a device context. HGLRC m_hGLRC; ///< Handle to a GL context. HPBUFFERARB m_hPBuffer;///< Handle to a pbuffer. HGLRC m_hOldGLRC; HDC m_hOldDC; std::vector m_pfAttribList; std::vector m_pbAttribList; bool m_bIsTexture; #elif defined(NUX_OS_LINUX) Display *m_pDisplay; GLXPbuffer m_glxPbuffer; GLXContext m_glxContext; Display *m_pOldDisplay; GLXPbuffer m_glxOldDrawable; GLXContext m_glxOldContext; std::vector m_pfAttribList; std::vector m_pbAttribList; #elif defined(NUX_OS_MACOSX) AGLContext m_context; WindowPtr m_window; std::vector m_pfAttribList; #endif int m_iWidth; int m_iHeight; int m_iNComponents; int m_iBitsPerComponent; const char *m_strMode; bool m_bSharedContext; bool m_bShareObjects; private: std::string getStringValue (std::string token); int getIntegerValue (std::string token); #if defined(NUX_OS_WINDOWS) || defined(NUX_OS_LINUX) void parseModeString (const char *modeString, std::vector *pfAttribList, std::vector *pbAttribList); bool m_bIsActive; bool m_bManaged; #endif }; } #endif // NUX_OPENGLES_20 #endif // __PBUFFERS_H__ nux-4.0.6+14.04.20140409/NuxGraphics/CairoGraphics.cpp0000644000015301777760000004300512321344237022414 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxCore/Rect.h" #include "BitmapFormats.h" #include "CairoGraphics.h" namespace nux { CairoGraphics::CairoGraphics(cairo_format_t format, int width, int height) : m_surface_format(format) , _width(0) , _height(0) , _zoom(1.0f) , _opacity(1.0f) { nuxAssert(width >= 0); nuxAssert(height >= 0); _width = width; _height = height; if (_width <= 0) _width = 1; if (_height <= 0) _height = 1; _cairo_surface = cairo_image_surface_create(m_surface_format, _width, _height); _cr = cairo_create(_cairo_surface); if (cairo_status(_cr) == CAIRO_STATUS_NO_MEMORY) { // If memory cannot be allocated, a special cairo_t object will be returned // on which cairo_status() returns CAIRO_STATUS_NO_MEMORY. // You can use this object normally, but no drawing will be done. nuxAssertMsg(0, "[CairoGraphics::GetContext] Cairo context error."); } } CairoGraphics::~CairoGraphics() { if (_cr) { cairo_destroy(_cr); } cairo_surface_destroy(_cairo_surface); } cairo_t *CairoGraphics::GetContext() { cairo_t *cr = cairo_create(_cairo_surface); if (cairo_status(cr) == CAIRO_STATUS_NO_MEMORY) { // If memory cannot be allocated, a special cairo_t object will be returned // on which cairo_status() returns CAIRO_STATUS_NO_MEMORY. // You can use this object normally, but no drawing will be done. nuxAssertMsg(0, "[CairoGraphics::GetContext] Cairo context error."); } return cr; } cairo_t *CairoGraphics::GetInternalContext() { return _cr; } cairo_surface_t* CairoGraphics::GetSurface() { return _cairo_surface; } NBitmapData *CairoGraphics::GetBitmap() { if ((_width <= 0) || (_height <= 0)) { nuxDebugMsg("[CairoGraphics::GetBitmap] Invalid surface."); } NUX_RETURN_VALUE_IF_NULL(_width, 0); NUX_RETURN_VALUE_IF_NULL(_height, 0); cairo_surface_flush(_cairo_surface); BitmapFormat bitmap_format = BITFMT_UNKNOWN; if (m_surface_format == CAIRO_FORMAT_ARGB32) { // Each pixel is a 32-bit quantity, with alpha in the upper 8 bits, // then red, then green, then blue. The 32-bit quantities are stored native-endian. // Pre-multiplied alpha is used. (That is, 50% transparent red is 0x80800000, not 0x80ff0000.) bitmap_format = BITFMT_B8G8R8A8; } if (m_surface_format == CAIRO_FORMAT_RGB24) { // Each pixel is a 32-bit quantity, with the upper 8 bits unused. // Red, Green, and Blue are stored in the remaining 24 bits in that order. bitmap_format = BITFMT_B8G8R8A8; } if (m_surface_format == CAIRO_FORMAT_A8) { // Each pixel is a 8-bit quantity holding an alpha value. bitmap_format = BITFMT_A8; } if (m_surface_format == CAIRO_FORMAT_A1) bitmap_format = BITFMT_A8; NTextureData *bitmap_data = new NTextureData(bitmap_format, _width, _height, 1); unsigned char *ptr = cairo_image_surface_get_data(_cairo_surface); int stride = cairo_image_surface_get_stride(_cairo_surface); if (ptr == NULL || stride == 0) { // _cairo_surface is not a valid surface nuxError("[CairoGraphics::GetBitmap] Invalid surface"); return bitmap_data; // just returns because we will segfault otherwise } unsigned char* dest_u8 = bitmap_data->GetSurface(0).GetPtrRawData(); const int pitch = bitmap_data->GetSurface(0).GetPitch(); if (m_surface_format == CAIRO_FORMAT_A1) { std::vector temp(pitch); for (int j = 0; j < _height; ++j) { for (int i = 0; i < _width; ++i) { // Get the byte int a = ptr[j * stride + i/8]; // Get the position in the byte int b = (i - 8 * (i / 8)); // Shift the byte and get the last bit int c = (a >> b) & 0x1; // If the last bit is set, put 1, otherwise put 0 temp[i] = c ? 0xFF : 0x0; } Memcpy(dest_u8 + j * pitch, temp.data(), _width); } } else { for (int j = 0; j < _height; ++j) { Memcpy(dest_u8 + j * pitch, (const void *) (&ptr[j * stride]), _width * GPixelFormats[bitmap_format].NumComponents); } } return bitmap_data; } int CairoGraphics::GetWidth() const { return _width; } int CairoGraphics::GetHeight() const { return _height; } bool CairoGraphics::PushState() { nuxAssert(_cr); _opacity_stack.push(_opacity); cairo_save(_cr); return true; } bool CairoGraphics::PopState() { nuxAssert(_cr); if (_opacity_stack.empty()) { return false; } _opacity = _opacity_stack.top(); _opacity_stack.pop(); cairo_restore(_cr); return true; } bool CairoGraphics::ClearCanvas() { // Clear the surface. nuxAssert(_cr); cairo_operator_t op = cairo_get_operator(_cr); cairo_set_operator(_cr, CAIRO_OPERATOR_CLEAR); cairo_paint(_cr); cairo_set_operator(_cr, op); // Set the clip region to an infinitely large shape containing the target. cairo_reset_clip(_cr); _opacity = 1.0f; _opacity_stack = std::stack(); cairo_restore(_cr); cairo_save(_cr); return true; } bool CairoGraphics::ClearRect(double x, double y, double w, double h) { nuxAssert(_cr); cairo_rectangle(_cr, x, y, w, h); cairo_operator_t op = cairo_get_operator(_cr); cairo_set_operator(_cr, CAIRO_OPERATOR_CLEAR); cairo_fill(_cr); cairo_set_operator(_cr, op); return true; } bool CairoGraphics::DrawLine(double x0, double y0, double x1, double y1, double width, const Color &c) { nuxAssert(_cr); if (width < 0.0) { return false; } cairo_set_line_width(_cr, width); cairo_set_source_rgba(_cr, c.red, c.green, c.blue, _opacity); cairo_move_to(_cr, x0, y0); cairo_line_to(_cr, x1, y1); cairo_stroke(_cr); return true; } void CairoGraphics::TranslateCoordinates(double tx, double ty) { nuxAssert(_cr); cairo_translate(_cr, tx, ty); } bool CairoGraphics::DrawFilledRect(double x, double y, double w, double h, const Color &c) { nuxAssert(_cr); if (w <= 0.0 || h <= 0.0) { return false; } cairo_set_source_rgba(_cr, c.red, c.green, c.blue, _opacity); cairo_rectangle(_cr, x, y, w, h); cairo_fill(_cr); return true; } bool CairoGraphics::DrawCanvas(double x, double y, CairoGraphics *cg) { if (cg == 0) return false; cairo_surface_t *s = cg->GetSurface(); double src_zoom = cg->_zoom; double inv_zoom = 1.0 / src_zoom; cairo_save(_cr); IntersectRectClipRegion(x, y, cg->GetWidth(), cg->GetHeight()); cairo_scale(_cr, inv_zoom, inv_zoom); cairo_set_source_surface(_cr, s, x * src_zoom, y * src_zoom); cairo_pattern_set_extend(cairo_get_source(_cr), CAIRO_EXTEND_PAD); cairo_paint_with_alpha(_cr, _opacity); cairo_restore(_cr); return true; } static inline double _align(double val) { double fract = val - (int) val; if (fract != 0.5f) return(double) ((int) val + 0.5f); else return val; } bool CairoGraphics::DrawRoundedRectangle(cairo_t* cr, double aspect, double x, double y, double cornerRadius, double width, double height, bool align) { double radius = cornerRadius / aspect; if (align) { // top-left, right of the corner cairo_move_to(cr, _align(x + radius), _align(y)); // top-right, left of the corner cairo_line_to(cr, _align(x + width - radius), _align(y)); // top-right, below the corner cairo_arc(cr, _align(x + width - radius), _align(y + radius), radius, -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); // bottom-right, above the corner cairo_line_to(cr, _align(x + width), _align(y + height - radius)); // bottom-right, left of the corner cairo_arc(cr, _align(x + width - radius), _align(y + height - radius), radius, 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); // bottom-left, right of the corner cairo_line_to(cr, _align(x + radius), _align(y + height)); // bottom-left, above the corner cairo_arc(cr, _align(x + radius), _align(y + height - radius), radius, 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); // top-left, right of the corner cairo_arc(cr, _align(x + radius), _align(y + radius), radius, 180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); } else { // top-left, right of the corner cairo_move_to(cr, x + radius, y); // top-right, left of the corner cairo_line_to(cr, x + width - radius, y); // top-right, below the corner cairo_arc(cr, x + width - radius, y + radius, radius, -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); // bottom-right, above the corner cairo_line_to(cr, x + width, y + height - radius); // bottom-right, left of the corner cairo_arc(cr, x + width - radius, y + height - radius, radius, 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); // bottom-left, right of the corner cairo_line_to(cr, x + radius, y + height); // bottom-left, above the corner cairo_arc(cr, x + radius, y + height - radius, radius, 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); // top-left, right of the corner cairo_arc(cr, x + radius, y + radius, radius, 180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); } return true; } static inline void _blurinner(guchar* pixel, gint* zR, gint* zG, gint* zB, gint* zA, gint alpha, gint aprec, gint zprec) { gint R; gint G; gint B; guchar A; R = *pixel; G = *(pixel + 1); B = *(pixel + 2); A = *(pixel + 3); *zR += (alpha * ((R << zprec) - *zR)) >> aprec; *zG += (alpha * ((G << zprec) - *zG)) >> aprec; *zB += (alpha * ((B << zprec) - *zB)) >> aprec; *zA += (alpha * ((A << zprec) - *zA)) >> aprec; *pixel = *zR >> zprec; *(pixel + 1) = *zG >> zprec; *(pixel + 2) = *zB >> zprec; *(pixel + 3) = *zA >> zprec; } static inline void _blurrow(guchar* pixels, gint width, gint /* height */, // TODO: This seems very strange. Why is height not used as it is in _blurcol() ? gint channels, gint line, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* scanline; scanline = &(pixels[line * width * channels]); zR = *scanline << zprec; zG = *(scanline + 1) << zprec; zB = *(scanline + 2) << zprec; zA = *(scanline + 3) << zprec; for (index = 0; index < width; index ++) _blurinner(&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = width - 2; index >= 0; index--) _blurinner(&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } static inline void _blurcol(guchar* pixels, gint width, gint height, gint channels, gint x, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* ptr; ptr = pixels; ptr += x * channels; zR = *((guchar*) ptr ) << zprec; zG = *((guchar*) ptr + 1) << zprec; zB = *((guchar*) ptr + 2) << zprec; zA = *((guchar*) ptr + 3) << zprec; for (index = width; index < (height - 1) * width; index += width) _blurinner((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = (height - 2) * width; index >= 0; index -= width) _blurinner((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } // // pixels image-data // width image-width // height image-height // channels image-channels // // in-place blur of image 'img' with kernel of approximate radius 'radius' // // blurs with two sided exponential impulse response // // aprec = precision of alpha parameter in fixed-point format 0.aprec // // zprec = precision of state parameters zR,zG,zB and zA in fp format 8.zprec // void _expblur(guchar* pixels, gint width, gint height, gint channels, gint radius, gint aprec, gint zprec) { gint alpha; gint row = 0; gint col = 0; if (radius < 1) return; // calculate the alpha such that 90% of // the kernel is within the radius. // (Kernel extends to infinity) alpha = (gint) ((1 << aprec) * (1.0f - expf(-2.3f / (radius + 1.f)))); for (; row < height; row++) _blurrow(pixels, width, height, channels, row, alpha, aprec, zprec); for (; col < width; col++) _blurcol(pixels, width, height, channels, col, alpha, aprec, zprec); return; } // if called like BlurSurface(radius) or BlurSurface(radius, NULL) it will // try to blur the image-surface of the internal cairo-context bool CairoGraphics::BlurSurface(unsigned int radius, cairo_surface_t* surf) { cairo_surface_t* surface; guchar* pixels; guint width; guint height; cairo_format_t format; if (surf) surface = surf; else surface = cairo_get_target(_cr); // don't do anything if we're not dealing with an image-surface if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_IMAGE) return false; // before we mess with the surface execute any pending drawing cairo_surface_flush(surface); pixels = cairo_image_surface_get_data(surface); width = cairo_image_surface_get_width(surface); height = cairo_image_surface_get_height(surface); format = cairo_image_surface_get_format(surface); switch(format) { case CAIRO_FORMAT_ARGB32: _expblur(pixels, width, height, 4, radius, 16, 7); break; case CAIRO_FORMAT_RGB24: _expblur(pixels, width, height, 3, radius, 16, 7); break; case CAIRO_FORMAT_A8: _expblur(pixels, width, height, 1, radius, 16, 7); break; default : // do nothing break; } // inform cairo we altered the surfaces contents cairo_surface_mark_dirty(surface); return true; } bool CairoGraphics::IntersectRectClipRegion(double x, double y, double w, double h) { if (w <= 0.0 || h <= 0.0) { return false; } cairo_antialias_t pre = cairo_get_antialias(_cr); cairo_set_antialias(_cr, CAIRO_ANTIALIAS_NONE); cairo_rectangle(_cr, x, y, w, h); cairo_clip(_cr); cairo_set_antialias(_cr, pre); return true; } bool CairoGraphics::IntersectGeneralClipRegion(std::list ®ion) { bool do_clip = false; cairo_antialias_t pre = cairo_get_antialias(_cr); cairo_set_antialias(_cr, CAIRO_ANTIALIAS_NONE); std::list::iterator it; for (it = region.begin(); it != region.end(); ++it) { Rect rect = (*it); if (!rect.IsNull()) { cairo_rectangle(_cr, rect.x, rect.y, rect.width, rect.height); do_clip = true; } } if (do_clip) { cairo_clip(_cr); } cairo_set_antialias(_cr, pre); return true; } } nux-4.0.6+14.04.20140409/NuxGraphics/NuxGraphicsObject.cpp0000644000015301777760000000000012321344237023244 0ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxGraphics/GLWindowManager.cpp0000644000015301777760000001454112321344237022666 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "GLWindowManager.h" namespace nux { #if defined(NUX_OS_WINDOWS) const char *WINDOW_CLASS_NAME = "InalogicWindowClass"; HINSTANCE gInstance = 0; #endif DisplayAccessController *DisplayAccessController::m_pInstance = 0; DisplayAccessController::DisplayAccessController() { #if defined(NUX_OS_WINDOWS) // Register Windows Class // Get hInstance of current application. if (gInstance == 0) hInstance = GetModuleHandle(NULL); else hInstance = gInstance; WinClass.cbSize = sizeof(WNDCLASSEX); // CS_CLASSDC Specifies that one device context is shared between all windows created with this class. // CS_DBLCLKS This is needed if you want to be able to detect double mouse clicks made on the window. // CS_HREDRAW The window is redrawn if there is a change in the window's width or if the window is moved horizontally. // CS_NOCLOSE Disables the close option on the window menu. // CS_OWNDC A unique device context is created for each window created. This is the opposite to CS_CLASSDC. // CS_PARENTDC This sets the clipping rectangle of the child window to that of the parent window. This allows the child window to be able to draw on the parent window. // CS_VREDRAW The window is redrawn if there is a change in the window's height or if the window is moved vertically. WinClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; // Redraw On Size, And Own DC For Window. WinClass.lpfnWndProc = (WNDPROC) WndProcManager; // WndProc Handles Messages WinClass.cbClsExtra = 0; // No Extra Window Data WinClass.cbWndExtra = 0; // No Extra Window Data WinClass.hInstance = hInstance; // Set The Instance WinClass.hIcon = LoadIcon(hInstance, "IDI_INALOGIC"); //LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon WinClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Class cursor: Load The Arrow Pointer WinClass.hbrBackground = NULL; //(HBRUSH)GetStockObject(BLACK_BRUSH); // No Background Required For GL WinClass.lpszMenuName = NULL; // We Don't Want A Menu WinClass.lpszClassName = WINDOW_CLASS_NAME; //gClassName; // Set The Class Name WinClass.hIconSm = LoadIcon(hInstance, "IDI_INALOGIC"); if (!RegisterClassEx(&WinClass)) // Attempt To Register The Window Class { nuxCriticalMsg("[DisplayAccessController::~DisplayAccessController] Failed to register window class name: %s.", WINDOW_CLASS_NAME); } #endif } DisplayAccessController::~DisplayAccessController() { #if defined(NUX_OS_WINDOWS) if (!UnregisterClass(WINDOW_CLASS_NAME, hInstance)) // Are We Able To Unregister Class { nuxDebugMsg("[DisplayAccessController::~DisplayAccessController] Failed to unregister window class name: %s.", WINDOW_CLASS_NAME); hInstance = NULL; // Set hInstance To NULL } #endif } DisplayAccessController &DisplayAccessController::Instance() { if (m_pInstance == 0) { m_pInstance = new DisplayAccessController(); } return *m_pInstance; } GraphicsDisplay *DisplayAccessController::CreateGLWindow(const char *WindowTitle, unsigned int WindowWidth, unsigned int WindowHeight, WindowStyle Style, GraphicsDisplay *GLWindow, bool fullscreen_flag, bool create_rendering_data) { if (GetGraphicsDisplay()) { // A GlWindow already exist for this thread. nuxAssertMsg(0, "Only one GLWindow per thread is allowed"); return 0; } GraphicsDisplay *glwindow = new GraphicsDisplay(); glwindow->CreateOpenGLWindow(WindowTitle, WindowWidth, WindowHeight, Style, GLWindow, fullscreen_flag, create_rendering_data); return glwindow; } #if defined(NUX_OS_WINDOWS) GraphicsDisplay *DisplayAccessController::CreateFromForeignWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext) { if (GetGraphicsDisplay()) { // A GlWindow already exist for this thread. nuxAssertMsg(0, "Only one GLWindow per thread is allowed"); return 0; } GraphicsDisplay *glwindow = new GraphicsDisplay(); glwindow->CreateFromOpenGLWindow(WindowHandle, WindowDCHandle, OpenGLRenderingContext); return glwindow; } #elif defined(USE_X11) # ifdef NUX_OPENGLES_20 GraphicsDisplay *DisplayAccessController::CreateFromForeignWindow(Display *X11Display, Window X11Window, EGLContext OpenGLContext) # else GraphicsDisplay *DisplayAccessController::CreateFromForeignWindow(Display *X11Display, Window X11Window, GLXContext OpenGLContext) # endif { if (GetGraphicsDisplay()) { // A GlWindow already exist for this thread. nuxAssertMsg(0, "Only one GLWindow per thread is allowed"); return 0; } GraphicsDisplay *glwindow = new GraphicsDisplay(); glwindow->CreateFromOpenGLWindow(X11Display, X11Window, OpenGLContext); return glwindow; } #endif } // namespace nux #ifndef NUX_OPENGLES_20 GLEWContext *glewGetContext() { return nux::GetGraphicsDisplay()->GetGLEWContext(); } #endif #if defined(NUX_OS_WINDOWS) WGLEWContext *wglewGetContext() { return nux::GetGraphicsDisplay()->GetWGLEWContext(); } #elif defined(NUX_OS_LINUX) && !defined(NUX_OPENGLES_20) GLXEWContext *glxewGetContext() { return nux::GetGraphicsDisplay()->GetGLXEWContext(); } #endif nux-4.0.6+14.04.20140409/NuxGraphics/ImageSurface.cpp0000644000015301777760000012040412321344237022230 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxCore/Logger.h" #include "NuxCore/Math/MathFunctions.h" #include "BitmapFormats.h" #include "GdkGraphics.h" #if defined(NUX_OS_WINDOWS) #include "GdiImageLoader.h" #endif #include "ImageSurface.h" namespace nux { DECLARE_LOGGER(logger, "nux.image"); extern PixelFormatInfo GPixelFormats[]; NBitmapData *LoadGdkPixbuf(GdkPixbuf *pixbuf) { NUX_RETURN_VALUE_IF_NULL(pixbuf, nullptr); unsigned int width = gdk_pixbuf_get_width(pixbuf); unsigned int height = gdk_pixbuf_get_height(pixbuf); unsigned int row_bytes = gdk_pixbuf_get_rowstride(pixbuf); NTextureData *Texture = new NTextureData(BITFMT_R8G8B8A8, width, height, 1); guchar *img = gdk_pixbuf_get_pixels(pixbuf); auto& surface = Texture->GetSurface(0); for (unsigned int i = 0; i < width; ++i) { for (unsigned int j = 0; j < height; ++j) { guchar *pixels = img + ( j * row_bytes + i * 4); UINT value = (* (pixels + 3) << 24) | // a (* (pixels + 2) << 16) | // b (* (pixels + 1) << 8) | // g * (pixels + 0); // r surface.Write32b(i, j, value); } } return Texture; } NBitmapData *LoadImageFile(const TCHAR *filename) { if (!GFileManager.FileExist(filename)) { nuxAssertMsg(0, "[LoadImageFile] Can't find file: %s", filename); return 0; } NBitmapData *BitmapData = 0; #if defined(NUX_OS_WINDOWS) BitmapData = GdiLoadImageFile(filename); if (BitmapData) return BitmapData; #elif defined(NUX_OS_LINUX) GdkGraphics gdkgraphics; gdkgraphics.LoadImage(filename); BitmapData = gdkgraphics.GetBitmap(); if (BitmapData) return BitmapData; #endif // Unsupported format LOG_DEBUG(logger) << "Unknown file format: " << filename; return 0; } bool HasOpenEXRSupport() { #ifdef NUX_OPENEXR_SUPPORT return true; #else return false; #endif } void MakeCheckBoardImage(ImageSurface &Image, int width, int height, Color const& dark, Color const& light, int TileWidth, int TileHeight) { Image.Allocate(BITFMT_R8G8B8A8, width, height); if (TileWidth <= 0) TileWidth = 4; if (TileHeight <= 0) TileHeight = 4; for (int j = 0; j < height; ++j) { for (int i = 0; i < width; ++i) { /*every 8 bits, change color from black to white or vice versa */ bool even_column = ((i / TileWidth) % 2) == 0; bool even_row = ((j / TileHeight ) % 2) == 0; bool is_dark = even_column ^ even_row; Color const& c = is_dark ? dark : light; Image.Write(i, j, c.red * 255, c.green * 255, c.blue * 255, c.alpha * 255); } } Image.FlipVertical(); } NBitmapData::NBitmapData() : m_TotalMemorySize(0) { } NBitmapData::~NBitmapData() { } ImageSurface::ImageSurface() : width_(0) , height_(0) , format_(BITFMT_UNKNOWN) , m_Pitch(0) , bpe_(0) , Alignment_(4) { Allocate(format_, width_, height_); } ImageSurface::ImageSurface(BitmapFormat format, unsigned int width, unsigned int height) : width_(0) , height_(0) , format_(BITFMT_UNKNOWN) , m_Pitch(0) , bpe_(0) , Alignment_(4) { Allocate(format, width, height); } ImageSurface::ImageSurface(ImageSurface const& surface) { width_ = surface.width_; height_ = surface.height_; bpe_ = surface.bpe_; format_ = surface.format_; m_Pitch = surface.m_Pitch; Alignment_ = surface.Alignment_; RawData_ = surface.RawData_; } ImageSurface::ImageSurface(ImageSurface&& surface) : ImageSurface() { swap(*this, surface); } ImageSurface &ImageSurface::operator = (ImageSurface copy) { swap(*this, copy); return *this; } void swap(ImageSurface& lhs, ImageSurface& rhs) { using std::swap; swap(lhs.width_, rhs.width_); swap(lhs.height_, rhs.height_); swap(lhs.bpe_, rhs.bpe_); swap(lhs.format_, rhs.format_); swap(lhs.m_Pitch, rhs.m_Pitch); swap(lhs.Alignment_, rhs.Alignment_); swap(lhs.RawData_, rhs.RawData_); } int ImageSurface::GetPitch() const { return m_Pitch; } int ImageSurface::GetBlockHeight() const { unsigned int block = GPixelFormats[format_].BlockSizeY; unsigned int HeightInBlocks = Align(GetHeight(), block) / block; return HeightInBlocks; } BitmapFormat ImageSurface::GetFormat() const { return format_; } int ImageSurface::GetAlignment() const { return Alignment_; } void ImageSurface::Allocate(BitmapFormat format, int width, int height) { nuxAssert(format < BITFMT_END_GFX_FORMATS); nuxAssert(width >= 0); nuxAssert(height >= 0); if (width < 0) width = 0; if (height < 0) height = 0; if ((format_ == format) && (width_ == width) && (height_ == height)) { // no need to recreate Clear(); return; } if ((width == 0) || (height == 0)) { width_ = 0; height_ = 0; Alignment_ = 1; bpe_ = 0; format_ = BITFMT_UNKNOWN; m_Pitch = 0; RawData_.clear(); RawData_.shrink_to_fit(); return; } width_ = width; height_ = height; Alignment_ = GPixelFormats[format].RowMemoryAlignment; bpe_ = GPixelFormats[format].BlockBytes; format_ = format; // For DXT, width and height are rounded up to a multiple of 4 in order // to create 4x4 blocks of pixels; And in this context, byte alignment // is 1 ie. data is densely packed. unsigned int block = GPixelFormats[format].BlockSizeX; unsigned int shift = Log2(GPixelFormats[format].BlockSizeX); m_Pitch = Align((bpe_ * ((width_ + (block - 1)) >> shift)), Alignment_); block = GPixelFormats[format].BlockSizeY; shift = Log2(GPixelFormats[format].BlockSizeY); RawData_.resize(m_Pitch * Align((height + (block-1)) >> shift, block)); RawData_.shrink_to_fit(); Clear(); } // This computes the correct pitch of a line. For instance if the unpack // alignment is 4, the pitch must have a number of pixel multiple of 4. See // Avoiding 16 Common OpenGL Pitfalls // http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ // 7. Watch Your Pixel Store Alignment int ImageSurface::GetLevelPitch(BitmapFormat format, int width, int /* height */, int miplevel) { int levelwidth = ImageSurface::GetLevelDim(format, width, miplevel); int bpe = GPixelFormats[format].BlockBytes; int memalignment = GPixelFormats[format].RowMemoryAlignment; int block = GPixelFormats[format].BlockSizeX; int shift = Log2(GPixelFormats[format].BlockSizeX); int pitch = Align((bpe * ((levelwidth + (block - 1)) >> shift)), memalignment); return pitch; } int ImageSurface::GetLevelPitchNoMemAlignment(BitmapFormat format, int width, int /* height */, int miplevel) { int levelwidth = ImageSurface::GetLevelDim(format, width, miplevel); int bpe = GPixelFormats[format].BlockBytes; int block = GPixelFormats[format].BlockSizeX; int shift = Log2(GPixelFormats[format].BlockSizeX); int pitch = Align((bpe * ((levelwidth + (block - 1)) >> shift)), 1); return pitch; } int ImageSurface::GetLevelSize(BitmapFormat format, int width, int height, int miplevel) { int pitch = ImageSurface::GetLevelPitch(format, width, height, miplevel); int levelheight = ImageSurface::GetLevelDim(format, height, miplevel); int block = GPixelFormats[format].BlockSizeY; int HeightInBlocks = Align(levelheight, block) / block; int size = pitch * HeightInBlocks; return size; } int ImageSurface::GetLevelSize(BitmapFormat format, int width, int height, int depth, int miplevel) { int pitch = ImageSurface::GetLevelPitch(format, width, height, miplevel); int levelheight = ImageSurface::GetLevelDim(format, height, miplevel); int leveldepth = ImageSurface::GetLevelDim(format, depth, miplevel); int block = GPixelFormats[format].BlockSizeY; int HeightInBlocks = Align(levelheight, block) / block; int size = pitch * HeightInBlocks; return leveldepth * size; } int ImageSurface::GetLevelWidth(BitmapFormat /* format */, int width, int miplevel) { // return 1 if the mip level does not exist. return Max (1, width >> miplevel); } int ImageSurface::GetLevelHeight(BitmapFormat /* format */, int height, int miplevel) { // return 1 if the mip level does not exist. return Max (1, height >> miplevel); } int ImageSurface::GetLevelDim(BitmapFormat /* format */, int length, int miplevel) { // return 1 if the mip level does not exist. return Max (1, length >> miplevel); } int ImageSurface::GetNumMipLevel(BitmapFormat /* format */, int width, int height) { int NumTotalMipLevel = 1 + floorf(Log2(Max(width, height))); return NumTotalMipLevel; } int ImageSurface::GetMemAlignment(BitmapFormat format) { return GPixelFormats[format].RowMemoryAlignment; } int ImageSurface::GetLevelBlockWidth(BitmapFormat format, int width, int miplevel) { int block = GPixelFormats[format].BlockSizeX; int WidthInBlocks = Align(GetLevelDim(format, width, miplevel), block) / block; return WidthInBlocks; } int ImageSurface::GetLevelBlockHeight(BitmapFormat format, int height, int miplevel) { int block = GPixelFormats[format].BlockSizeY; int HeightInBlocks = Align(GetLevelDim(format, height, miplevel), block) / block; return HeightInBlocks; } bool ImageSurface::IsNull() const { if ((width_ == 0) || (height_ == 0) || (format_ == BITFMT_UNKNOWN)) return true; return false; } void ImageSurface::Write32b(int i, int j, unsigned int value) { nuxAssert(i < width_); nuxAssert(j < height_); nuxAssert(bpe_ >= 4); if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) return; RawData_[j *m_Pitch + i *bpe_ + 0] = (unsigned char) (value & 0xff); RawData_[j *m_Pitch + i *bpe_ + 1] = (unsigned char) ((value & 0xff00) >> 8); RawData_[j *m_Pitch + i *bpe_ + 2] = (unsigned char) ((value & 0xff0000) >> 16); RawData_[j *m_Pitch + i *bpe_ + 3] = (unsigned char) ((value & 0xff000000) >> 24); } void ImageSurface::Write24b(int i, int j, unsigned int value) { nuxAssert(i < width_); nuxAssert(j < height_); nuxAssert(bpe_ >= 3); if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) return; RawData_[j *m_Pitch + i *bpe_ + 0] = (unsigned char) (value & 0xff); RawData_[j *m_Pitch + i *bpe_ + 1] = (unsigned char) ((value & 0xff00) >> 8); RawData_[j *m_Pitch + i *bpe_ + 2] = (unsigned char) ((value & 0xff0000) >> 16); } void ImageSurface::Write16b(int i, int j, unsigned short value) { nuxAssert(i < width_); nuxAssert(j < height_); nuxAssert(bpe_ >= 2); if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) return; RawData_[j *m_Pitch + i *bpe_ + 0] = (unsigned char) (value & 0xff); RawData_[j *m_Pitch + i *bpe_ + 1] = (unsigned char) ((value & 0xff00) >> 8); } void ImageSurface::Write8b(int i, int j, unsigned char value) { nuxAssert(i < width_); nuxAssert(j < height_); nuxAssert(bpe_ >= 1); if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) return; RawData_[j *m_Pitch + i *bpe_ + 0] = (unsigned char) (value & 0xff); } void ImageSurface::Write(int i, int j, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { nuxAssert(i < width_); nuxAssert(j < height_); nuxAssert(bpe_ == 4); if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) return; if ((i < 0) || (i > width_)) return; if ((j < 0) || (j > height_)) return; if (bpe_ != 4) return; RawData_[j *m_Pitch + i *bpe_ + 0] = r; RawData_[j *m_Pitch + i *bpe_ + 1] = g; RawData_[j *m_Pitch + i *bpe_ + 2] = b; RawData_[j *m_Pitch + i *bpe_ + 3] = a; } unsigned int ImageSurface::Read(int i, int j) { nuxAssert(i < width_); nuxAssert(j < height_); nuxAssert(bpe_); if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) return 0x00000000; if (bpe_ == 4) { return ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 3] << 24) | ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 2] << 16) | ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 1] << 8) | ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 0] << 0); } if (bpe_ == 3) { return ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 2] << 16) | ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 1] << 8) | ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 0] << 0); } if (bpe_ == 2) { return ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 1] << 8) | ((unsigned int) RawData_[j * m_Pitch + i * bpe_ + 0] << 0); } if (bpe_ == 1) { return (unsigned int) RawData_[j * m_Pitch + i * bpe_ + 0]; } return 0x0000000; } void ImageSurface::Clear() { if (RawData_.empty()) return; if ((width_ == 0) || (height_ == 0)) return; auto size = GetSize(); memset(RawData_.data(), 0, size); } void ImageSurface::FlipHorizontal() { if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) return; int i, j, k; if (RawData_.empty()) return; if (width_ == 0 || height_ == 0) return; std::vector flip_data(m_Pitch*height_); for (j = 0; j < height_; j++) { for (i = 0; i < width_; i++) { for (k = 0; k < bpe_; k++) { flip_data[ (j*m_Pitch) + i *bpe_ + k] = RawData_[ (j*m_Pitch) + (width_-i-1) * bpe_ + k]; } } } RawData_.swap(flip_data); } void ImageSurface::FlipVertical() { if (RawData_.empty()) return; if (width_ == 0 || height_ == 0) return; if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) { FlipDXTVertical(); } else { std::vector flip_data(m_Pitch*height_); for (int j = 0; j < height_; j++) { for (int i = 0; i < width_; i++) { for (int k = 0; k < bpe_; k++) { flip_data[ (j*m_Pitch) + i *bpe_ + k] = RawData_[ (height_-j-1) *m_Pitch + i * bpe_ + k]; } } } RawData_.swap(flip_data); } } void ImageSurface::FlipDXTVertical() { //void(CDDSImage::*flipblocks)(DXTColBlock*, unsigned int); int xblocks = (width_ + 3) / 4; int yblocks = (height_ + 3) / 4; int blocksize; int linesize; switch(format_) { case BITFMT_DXT1: blocksize = 8; //flipblocks = &CDDSImage::flip_blocks_dxtc1; break; case BITFMT_DXT2: blocksize = 16; //flipblocks = &CDDSImage::flip_blocks_dxtc2; break; case BITFMT_DXT3: blocksize = 16; //flipblocks = &CDDSImage::flip_blocks_dxtc3; break; case BITFMT_DXT4: blocksize = 16; //flipblocks = &CDDSImage::flip_blocks_dxtc4; break; case BITFMT_DXT5: blocksize = 16; //flipblocks = &CDDSImage::flip_blocks_dxtc5; break; default: return; } linesize = xblocks * blocksize; DXTColBlock *top; DXTColBlock *bottom; for (int j = 0; j < (yblocks >> 1); j++) { top = reinterpret_cast(&(RawData_[j * linesize])); bottom = reinterpret_cast(&(RawData_[((yblocks - j) - 1) * linesize])); switch(format_) { case BITFMT_DXT1: FlipBlocksDXT1(top, xblocks); FlipBlocksDXT1(bottom, xblocks); break; case BITFMT_DXT2: FlipBlocksDXT3(top, xblocks); FlipBlocksDXT3(bottom, xblocks); break; case BITFMT_DXT3: FlipBlocksDXT3(top, xblocks); FlipBlocksDXT3(bottom, xblocks); break; case BITFMT_DXT4: FlipBlocksDXT5(top, xblocks); FlipBlocksDXT5(bottom, xblocks); break; case BITFMT_DXT5: FlipBlocksDXT5(top, xblocks); FlipBlocksDXT5(bottom, xblocks); break; default: nuxAssert("[ImageSurface::FlipDXTVertical] Invalid Switch option."); break; } SwapBlocks(bottom, top, linesize); } } void ImageSurface::SwapBlocks(void *byte1, void *byte2, int size) { std::vector tmp(size); memcpy(tmp.data(), byte1, size); memcpy(byte1, byte2, size); memcpy(byte2, tmp.data(), size); } void ImageSurface::FlipBlocksDXT1(DXTColBlock *line, int numBlocks) { DXTColBlock *curblock = line; for (int i = 0; i < numBlocks; i++) { SwapBlocks(&curblock->row[0], &curblock->row[3], sizeof(unsigned char)); SwapBlocks(&curblock->row[1], &curblock->row[2], sizeof(unsigned char)); curblock++; } } void ImageSurface::FlipBlocksDXT3(DXTColBlock *line, int numBlocks) { DXTColBlock *curblock = line; DXT3AlphaBlock *alphablock; for (int i = 0; i < numBlocks; i++) { alphablock = (DXT3AlphaBlock *) curblock; SwapBlocks(&alphablock->row[0], &alphablock->row[3], sizeof(unsigned short)); SwapBlocks(&alphablock->row[1], &alphablock->row[2], sizeof(unsigned short)); curblock++; SwapBlocks(&curblock->row[0], &curblock->row[3], sizeof(unsigned char)); SwapBlocks(&curblock->row[1], &curblock->row[2], sizeof(unsigned char)); curblock++; } } void ImageSurface::FlipBlocksDXT5(DXTColBlock *line, int numBlocks) { DXTColBlock *curblock = line; DXT5AlphaBlock *alphablock; for (int i = 0; i < numBlocks; i++) { alphablock = (DXT5AlphaBlock *) curblock; FlipDXT5Alpha(alphablock); curblock++; SwapBlocks(&curblock->row[0], &curblock->row[3], sizeof(unsigned char)); SwapBlocks(&curblock->row[1], &curblock->row[2], sizeof(unsigned char)); curblock++; } } void ImageSurface::FlipDXT5Alpha(DXT5AlphaBlock *block) { unsigned char gBits[4][4]; const unsigned long mask = 0x00000007; // bits = 00 00 01 11 unsigned long bits = 0; memcpy(&bits, &block->row[0], sizeof(unsigned char) * 3); gBits[0][0] = (unsigned char) (bits & mask); bits >>= 3; gBits[0][1] = (unsigned char) (bits & mask); bits >>= 3; gBits[0][2] = (unsigned char) (bits & mask); bits >>= 3; gBits[0][3] = (unsigned char) (bits & mask); bits >>= 3; gBits[1][0] = (unsigned char) (bits & mask); bits >>= 3; gBits[1][1] = (unsigned char) (bits & mask); bits >>= 3; gBits[1][2] = (unsigned char) (bits & mask); bits >>= 3; gBits[1][3] = (unsigned char) (bits & mask); bits = 0; memcpy(&bits, &block->row[3], sizeof(unsigned char) * 3); gBits[2][0] = (unsigned char) (bits & mask); bits >>= 3; gBits[2][1] = (unsigned char) (bits & mask); bits >>= 3; gBits[2][2] = (unsigned char) (bits & mask); bits >>= 3; gBits[2][3] = (unsigned char) (bits & mask); bits >>= 3; gBits[3][0] = (unsigned char) (bits & mask); bits >>= 3; gBits[3][1] = (unsigned char) (bits & mask); bits >>= 3; gBits[3][2] = (unsigned char) (bits & mask); bits >>= 3; gBits[3][3] = (unsigned char) (bits & mask); unsigned long *pBits = ((unsigned long *) & (block->row[0])); *pBits = *pBits | (gBits[3][0] << 0); *pBits = *pBits | (gBits[3][1] << 3); *pBits = *pBits | (gBits[3][2] << 6); *pBits = *pBits | (gBits[3][3] << 9); *pBits = *pBits | (gBits[2][0] << 12); *pBits = *pBits | (gBits[2][1] << 15); *pBits = *pBits | (gBits[2][2] << 18); *pBits = *pBits | (gBits[2][3] << 21); pBits = ((unsigned long *) & (block->row[3])); #ifdef __APPLE__ *pBits &= 0x000000ff; #else *pBits &= 0xff000000; #endif *pBits = *pBits | (gBits[1][0] << 0); *pBits = *pBits | (gBits[1][1] << 3); *pBits = *pBits | (gBits[1][2] << 6); *pBits = *pBits | (gBits[1][3] << 9); *pBits = *pBits | (gBits[0][0] << 12); *pBits = *pBits | (gBits[0][1] << 15); *pBits = *pBits | (gBits[0][2] << 18); *pBits = *pBits | (gBits[0][3] << 21); } const unsigned char *ImageSurface::GetPtrRawData() const { return RawData_.data(); } unsigned char *ImageSurface::GetPtrRawData() { return RawData_.data(); } int ImageSurface::GetSize() const { if ((format_ == BITFMT_DXT1) || (format_ == BITFMT_DXT2) || (format_ == BITFMT_DXT3) || (format_ == BITFMT_DXT4) || (format_ == BITFMT_DXT5)) { return m_Pitch * ((height_ + 3) >> 2); } else { return m_Pitch * height_; } } Color ImageSurface::AverageColor() { if (width_ == 0 || height_ == 0) return Color(0.f, 0.f, 0.f, 0.f); float r, g, b, a; r = g = b = a = 0; if (bpe_ == 8) { for (int j = 0; j < height_; j++) { for (int i = 0; i < width_; i++) { unsigned int v = Read(i, j); r += (v & 0x000000FF); g += (v & 0x0000FF00) >> 1; b += (v & 0x00FF0000) >> 2; a += (v & 0xFF000000) >> 3; } } } unsigned int num_pixels = width_ * height_; return Color(r / num_pixels, g / num_pixels, b / num_pixels, a / num_pixels); } /////////////////////////////////////////////////////////////////// NTextureData::NTextureData(BitmapFormat f, int width, int height, int NumMipmap) : m_NumMipmap(0) , m_MipSurfaceArray(1) { Allocate(f, width, height, NumMipmap); } void NTextureData::swap(NTextureData& other) { using std::swap; swap(this->m_NumMipmap, other.m_NumMipmap); swap(this->m_TotalMemorySize, other.m_TotalMemorySize); swap(this->m_MipSurfaceArray, other.m_MipSurfaceArray); } //! Copy constructor NTextureData::NTextureData(const NTextureData &object) { m_NumMipmap = object.m_NumMipmap; m_TotalMemorySize = object.m_TotalMemorySize; m_MipSurfaceArray = object.m_MipSurfaceArray; } //! Move constructor NTextureData::NTextureData(NTextureData&& other) : NTextureData() { swap(other); } //! Assignment constructor NTextureData &NTextureData::operator = (NTextureData copy) { swap(copy); return *this; } void NTextureData::Allocate(BitmapFormat format, int width, int height, int NumMipmapRequested) { nuxAssertMsg(width >= 0, "[NTextureData::Allocate] Error: Negative texture width."); nuxAssertMsg(height >= 0, "[NTextureData::Allocate] Error: Negative texture height."); nuxAssert(NumMipmapRequested >= 0); int NumTotalMipLevel = 1 + (int) Floor(Log2(Max(width, height))); m_NumMipmap = NumMipmapRequested; if (NumMipmapRequested == 0) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; if (NumMipmapRequested > NumTotalMipLevel) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; m_TotalMemorySize = 0; m_MipSurfaceArray.resize(m_NumMipmap); m_MipSurfaceArray.shrink_to_fit(); for (int i = 0; i < m_NumMipmap; ++i) { int w = width >> i; int h = height >> i; m_MipSurfaceArray[i] = ImageSurface(format, w, h); m_TotalMemorySize += m_MipSurfaceArray[i].GetSize(); } } void NTextureData::AllocateCheckBoardTexture(int width, int height, int NumMipmap, Color color0, Color color1, int TileWidth, int TileHeight) { Allocate(BITFMT_R8G8B8A8, width, height, NumMipmap); for (int i = 0; i < m_NumMipmap; ++i) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), i); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), i); MakeCheckBoardImage(m_MipSurfaceArray[i], w, h, color0, color1, TileWidth, TileHeight); } } void NTextureData::AllocateColorTexture(int width, int height, int NumMipmap, Color color0) { Allocate(BITFMT_R8G8B8A8, width, height, NumMipmap); for (int i = 0; i < m_NumMipmap; ++i) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), i); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), i); MakeCheckBoardImage(m_MipSurfaceArray[i], w, h, color0, color0); } } int NTextureData::GetNumMipmap() const { return m_NumMipmap; } bool NTextureData::SetSurface(int MipLevel, const ImageSurface &targetsurface) { nuxAssert(MipLevel >= 0); nuxAssert(MipLevel < m_NumMipmap); ImageSurface &surface = GetSurface(MipLevel); if (surface.GetFormat() != targetsurface.GetFormat()) return false; if (surface.GetWidth() != targetsurface.GetWidth()) return false; if (surface.GetHeight() != targetsurface.GetHeight()) return false; surface = targetsurface; return true; } /////////////////////////////////////////////////////////////////// NCubemapData::NCubemapData(BitmapFormat format, int width, int height, int NumMipmap) : m_NumMipmap(0) { Allocate(format, width, height, NumMipmap); } NCubemapData::~NCubemapData() { ClearData(); } void NCubemapData::ClearData() { int n = (int) m_MipSurfaceArray[0].size(); for (int i = 0; i < n; i++) { delete m_MipSurfaceArray[0][i]; delete m_MipSurfaceArray[1][i]; delete m_MipSurfaceArray[2][i]; delete m_MipSurfaceArray[3][i]; delete m_MipSurfaceArray[4][i]; delete m_MipSurfaceArray[5][i]; } m_MipSurfaceArray[0].clear(); m_MipSurfaceArray[1].clear(); m_MipSurfaceArray[2].clear(); m_MipSurfaceArray[3].clear(); m_MipSurfaceArray[4].clear(); m_MipSurfaceArray[5].clear(); } //! Copy constructor NCubemapData::NCubemapData(const NCubemapData &object) { for (int face = 0; face < 6; face++) for (int i = 0; i < object.GetNumMipmap(); i++) m_MipSurfaceArray[face].push_back(new ImageSurface(object.GetSurface(face, i))); } //! Assignment constructor NCubemapData &NCubemapData::operator = (const NCubemapData ©) { ClearData(); m_NumMipmap = copy.m_NumMipmap; m_TotalMemorySize = copy.m_TotalMemorySize; for (int face = 0; face < 6; face++) for (int i = 0; i < copy.GetNumMipmap(); i++) m_MipSurfaceArray[face].push_back(new ImageSurface(copy.GetSurface(face, i))); return *this; } void NCubemapData::Allocate(BitmapFormat format, int width, int height, int NumMipmapRequested) { nuxAssertMsg(width >= 0, "[NCubemapData::Allocate] Error: Negative texture width."); nuxAssertMsg(height >= 0, "[NCubemapData::Allocate] Error: Negative texture height."); nuxAssert(NumMipmapRequested >= 0); ClearData(); int NumTotalMipLevel = 1 + (int) Floor(Log2(Max(width, height))); m_NumMipmap = NumMipmapRequested; if (NumMipmapRequested == 0) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; if (NumMipmapRequested > NumTotalMipLevel) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; m_TotalMemorySize = 0; for (int face = 0; face < 6; face++) { for (int i = 0; i < m_NumMipmap; i++) { int w = width >> i; int h = height >> i; m_MipSurfaceArray[face].push_back(new ImageSurface(format, w, h)); m_TotalMemorySize += m_MipSurfaceArray[face][i]->GetSize(); } } } void NCubemapData::AllocateCheckBoardTexture(int width, int height, int NumMipmap, Color color0, Color color1, int TileWidth, int TileHeight) { Allocate(BITFMT_R8G8B8A8, width, height, NumMipmap); for (int face = 0; face < 6; face++) { for (int i = 0; i < m_NumMipmap; i++) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), i); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), i); MakeCheckBoardImage(*m_MipSurfaceArray[face][i], w, h, color0, color1, TileWidth, TileHeight); } } } void NCubemapData::AllocateColorTexture(int width, int height, int NumMipmap, Color color0) { Allocate(BITFMT_R8G8B8A8, width, height, NumMipmap); for (int face = 0; face < 6; face++) { for (int i = 0; i < m_NumMipmap; i++) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), i); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), i); MakeCheckBoardImage(*m_MipSurfaceArray[face][i], w, h, color0, color0); } } } int NCubemapData::GetNumMipmap() const { return m_MipSurfaceArray[0].size(); } bool NCubemapData::SetSurface(int face, int MipLevel, const ImageSurface &targetsurface) { nuxAssert(face >= 0); nuxAssert(face < 6); nuxAssert(MipLevel >= 0); nuxAssert(MipLevel < m_NumMipmap); ImageSurface &surface = GetSurface(face, MipLevel); if (surface.GetFormat() != targetsurface.GetFormat()) return false; if (surface.GetWidth() != targetsurface.GetWidth()) return false; if (surface.GetHeight() != targetsurface.GetHeight()) return false; surface = targetsurface; return true; } /////////////////////////////////////////////////////////////////// NVolumeData::NVolumeData(BitmapFormat format, int width, int height, int depth, int NumMipmap) : m_NumMipmap(0) , m_Depth(0) , m_MipSurfaceArray(0) { Allocate(format, width, height, depth, NumMipmap); } NVolumeData::~NVolumeData() { ClearData(); } void NVolumeData::ClearData() { for (int mip = 0; mip < GetNumMipmap(); mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(GetFormat(), GetDepth(), mip); s++) { delete m_MipSurfaceArray[mip][s]; } m_MipSurfaceArray[mip].clear(); } delete [] m_MipSurfaceArray; } //! Copy constructor NVolumeData::NVolumeData(const NVolumeData &object) { for (int mip = 0; mip < object.GetNumMipmap(); mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(object.GetFormat(), object.GetDepth(), mip); s++) { m_MipSurfaceArray[mip].push_back(new ImageSurface(object.GetSurface(s, mip))); } } } //! Assignment constructor NVolumeData &NVolumeData::operator = (const NVolumeData ©) { ClearData(); m_Depth = copy.m_Depth; m_NumMipmap = copy.m_NumMipmap; m_TotalMemorySize = copy.m_TotalMemorySize; m_MipSurfaceArray = new std::vector[m_NumMipmap]; for (int mip = 0; mip < copy.GetNumMipmap(); mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(copy.GetFormat(), copy.GetDepth(), mip); s++) { m_MipSurfaceArray[mip].push_back(new ImageSurface(copy.GetSurface(s, mip))); } } return *this; } void NVolumeData::Allocate(BitmapFormat format, int width, int height, int depth, int NumMipmapRequested) { nuxAssertMsg(depth >= 0, "[NVolumeData::Allocate] Error: Negative number of slice."); nuxAssertMsg(width >= 0, "[NVolumeData::Allocate] Error: Negative texture width."); nuxAssertMsg(height >= 0, "[NVolumeData::Allocate] Error: Negative texture height."); nuxAssert(NumMipmapRequested >= 0); ClearData(); int NumTotalMipLevel = 1 + (int) Floor(Log2(Max(width, height))); m_NumMipmap = NumMipmapRequested; if (NumMipmapRequested == 0) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; if (NumMipmapRequested > NumTotalMipLevel) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; m_Depth = depth; m_MipSurfaceArray = new std::vector[m_NumMipmap]; m_TotalMemorySize = 0; for (int mip = 0; mip < m_NumMipmap; mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(format, depth, mip); s++) { int w = ImageSurface::GetLevelDim(format, width, mip); int h = ImageSurface::GetLevelDim(format, height, mip); m_MipSurfaceArray[mip].push_back(new ImageSurface(format, w, h)); m_TotalMemorySize += m_MipSurfaceArray[mip][s]->GetSize(); } } } void NVolumeData::AllocateCheckBoardTexture(int width, int height, int slice, int NumMipmap, Color color0, Color color1, int TileWidth, int TileHeight) { Allocate(BITFMT_R8G8B8A8, width, height, slice, NumMipmap); for (int mip = 0; mip < m_NumMipmap; mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetDepth(), mip); s++) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), mip); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), mip); MakeCheckBoardImage(* (m_MipSurfaceArray[mip][s]), w, h, color0, color1, TileWidth, TileHeight); } } } void NVolumeData::AllocateColorTexture(int width, int height, int slice, int NumMipmap, Color color0) { Allocate(BITFMT_R8G8B8A8, width, height, slice, NumMipmap); for (int mip = 0; mip < m_NumMipmap; mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetDepth(), mip); s++) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), mip); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), mip); MakeCheckBoardImage(* (m_MipSurfaceArray[mip][s]), w, h, color0, color0); } } } int NVolumeData::GetNumMipmap() const { return m_NumMipmap; } bool NVolumeData::SetSurface(int Slice, int MipLevel, const ImageSurface &targetsurface) { nuxAssert(Slice >= 0); nuxAssert(Slice < m_Depth); nuxAssert(MipLevel >= 0); nuxAssert(MipLevel < m_NumMipmap); ImageSurface &surface = GetSurface(Slice, MipLevel); if (surface.GetFormat() != targetsurface.GetFormat()) return false; if (surface.GetWidth() != targetsurface.GetWidth()) return false; if (surface.GetHeight() != targetsurface.GetHeight()) return false; surface = targetsurface; return true; } /////////////////////////////////////////////////////////////////// NAnimatedTextureData::NAnimatedTextureData(BitmapFormat format, int width, int height, int depth) : m_NumMipmap(0) , m_Depth(0) , m_MipSurfaceArray(0) { Allocate(format, width, height, depth, 1); } NAnimatedTextureData::~NAnimatedTextureData() { ClearData(); } void NAnimatedTextureData::ClearData() { for (int mip = 0; mip < GetNumMipmap(); mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(GetFormat(), GetDepth(), mip); s++) { delete m_MipSurfaceArray[mip][s]; } m_MipSurfaceArray[mip].clear(); } m_FrameTimeArray.clear(); delete [] m_MipSurfaceArray; } //! Copy constructor NAnimatedTextureData::NAnimatedTextureData(const NAnimatedTextureData &object) { for (int mip = 0; mip < object.GetNumMipmap(); mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(object.GetFormat(), object.GetDepth(), mip); s++) { m_MipSurfaceArray[mip].push_back(new ImageSurface(object.GetSurface(mip, s))); } } for (int frame = 0; frame < object.GetDepth(); frame++) { m_FrameTimeArray.push_back(object.GetFrameTime(frame)); } } //! Assignment constructor NAnimatedTextureData &NAnimatedTextureData::operator = (const NAnimatedTextureData ©) { ClearData(); m_Depth = copy.GetDepth(); m_NumMipmap = copy.m_NumMipmap; m_TotalMemorySize = copy.m_TotalMemorySize; m_MipSurfaceArray = new std::vector[m_NumMipmap]; for (int mip = 0; mip < copy.GetNumMipmap(); mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(copy.GetFormat(), copy.GetDepth(), mip); s++) { m_MipSurfaceArray[mip].push_back(new ImageSurface(copy.GetSurface(s))); } } for (int frame = 0; frame < copy.GetDepth(); frame++) { m_FrameTimeArray.push_back(copy.GetFrameTime(frame)); } return *this; } void NAnimatedTextureData::Allocate(BitmapFormat format, int width, int height, int depth, int NumMipmapRequested) { nuxAssertMsg(depth >= 0, "[NAnimatedTextureData::Allocate] Error: Negative number of slice."); nuxAssertMsg(width >= 0, "[NAnimatedTextureData::Allocate] Error: Negative texture width."); nuxAssertMsg(height >= 0, "[NAnimatedTextureData::Allocate] Error: Negative texture height."); nuxAssert(NumMipmapRequested >= 0); ClearData(); int NumTotalMipLevel = 1 + (int) Floor(Log2(Max(width, height))); m_NumMipmap = NumMipmapRequested; if (NumMipmapRequested == 0) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; if (NumMipmapRequested > NumTotalMipLevel) m_NumMipmap = NumTotalMipLevel ? NumTotalMipLevel : 1; m_Depth = depth; m_MipSurfaceArray = new std::vector[m_NumMipmap]; m_TotalMemorySize = 0; for (int mip = 0; mip < m_NumMipmap; mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(format, depth, mip); s++) { int w = ImageSurface::GetLevelDim(format, width, mip); int h = ImageSurface::GetLevelDim(format, height, mip); m_MipSurfaceArray[mip].push_back(new ImageSurface(format, w, h)); m_TotalMemorySize += m_MipSurfaceArray[mip][s]->GetSize(); } } } void NAnimatedTextureData::AllocateCheckBoardTexture(int width, int height, int slice, int NumMipmap, Color color0, Color color1, int TileWidth, int TileHeight) { Allocate(BITFMT_R8G8B8A8, width, height, slice, NumMipmap); for (int mip = 0; mip < m_NumMipmap; mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetDepth(), mip); s++) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), mip); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), mip); MakeCheckBoardImage(* (m_MipSurfaceArray[mip][s]), w, h, color0, color1, TileWidth, TileHeight); } } } void NAnimatedTextureData::AllocateColorTexture(int width, int height, int slice, int NumMipmap, Color color0) { Allocate(BITFMT_R8G8B8A8, width, height, slice, NumMipmap); for (int mip = 0; mip < m_NumMipmap; mip++) { for (int s = 0; s < ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetDepth(), mip); s++) { int w = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetWidth(), mip); int h = ImageSurface::GetLevelDim(BITFMT_R8G8B8A8, GetHeight(), mip); MakeCheckBoardImage(* (m_MipSurfaceArray[mip][s]), w, h, color0, color0); } } } int NAnimatedTextureData::GetNumMipmap() const { return m_NumMipmap; } bool NAnimatedTextureData::SetSurface(int Slice, int MipLevel, const ImageSurface &targetsurface) { nuxAssert(Slice >= 0); nuxAssert(Slice < m_Depth); nuxAssert(MipLevel >= 0); nuxAssert(MipLevel < m_NumMipmap); ImageSurface &surface = GetSurface(Slice, MipLevel); if (surface.GetFormat() != targetsurface.GetFormat()) return false; if (surface.GetWidth() != targetsurface.GetWidth()) return false; if (surface.GetHeight() != targetsurface.GetHeight()) return false; surface = targetsurface; return true; } } nux-4.0.6+14.04.20140409/NuxGraphics/GlobalGraphicsInitializer.cpp0000644000015301777760000000470212321344237024764 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "RunTimeStats.h" #include "NuxGraphicsResources.h" #include "FontTexture.h" #include "GlobalGraphicsInitializer.h" namespace nux { static NuxGraphicsGlobalSingletonInitializer *GNuxGraphicsGlobalInitializer = 0; static void SystemStart() { static unsigned char StaticBuffer[sizeof(NuxGraphicsGlobalSingletonInitializer) ]; // Placement new in our reserved buffer. GNuxGraphicsGlobalInitializer = new(StaticBuffer) NuxGraphicsGlobalSingletonInitializer(); //GLogDevice.AddOutputDevice( &NUX_GLOBAL_OBJECT_INSTANCE(NOutputLogFile)); //GLogDevice.AddOutputDevice( &NUX_GLOBAL_OBJECT_INSTANCE(NOutputVisualDebugConsole)); } static void SystemShutdown() { // Manually destroy initializer if (GNuxGraphicsGlobalInitializer) GNuxGraphicsGlobalInitializer->~NuxGraphicsGlobalSingletonInitializer(); GNuxGraphicsGlobalInitializer = 0; } bool NuxGraphicsGlobalSingletonInitializer::m_NuxGraphicsGlobalObjectsReady = false; NuxGraphicsGlobalSingletonInitializer::NuxGraphicsGlobalSingletonInitializer() { m_NuxGraphicsGlobalObjectsReady = true; } NuxGraphicsGlobalSingletonInitializer::~NuxGraphicsGlobalSingletonInitializer() { m_NuxGraphicsGlobalObjectsReady = false; } bool NuxGraphicsGlobalSingletonInitializer::Ready() { return m_NuxGraphicsGlobalObjectsReady; } int NuxGraphicsGlobalInitializer::m_Count = 0; NuxGraphicsGlobalInitializer::NuxGraphicsGlobalInitializer() { if (m_Count++ == 0) { SystemStart(); } } NuxGraphicsGlobalInitializer::~NuxGraphicsGlobalInitializer() { if (--m_Count == 0) { SystemShutdown(); } } } nux-4.0.6+14.04.20140409/NuxGraphics/GLWindowManager.h0000644000015301777760000000647712321344237022344 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef DISPLAYACCESSCONTROLLER_H #define DISPLAYACCESSCONTROLLER_H #include "NuxCore/NuxCore.h" #if defined(NUX_OS_WINDOWS) #include "GraphicsDisplay.h" #elif defined(NUX_OS_LINUX) #include "GraphicsDisplay.h" #endif namespace nux { class GraphicsDisplay; class GpuDevice; class GraphicsEngine; extern const char *WINDOW_CLASS_NAME; class DisplayAccessController { public: //! Create a graphics window capable of doing OpenGL rendering. /*! @param WindowTitle The title name of the window. @param WindowWidth Window width. @param WindowHeight Window height. @param Style Window style. @param parent The parent window. @param fullscreen_flag True to create a full screen window. @param create_rendering_data If true, then in GraphicsEngine, the system creates the OpenGL shaders and the font textures for the rendering. */ GraphicsDisplay *CreateGLWindow(const char *WindowTitle, unsigned int WindowWidth, unsigned int WindowHeight, WindowStyle Style, GraphicsDisplay *parent, bool fullscreen_flag = false, bool create_rendering_data = true); #if defined(NUX_OS_WINDOWS) HINSTANCE GetInstance() { return hInstance; } #endif #if defined(NUX_OS_WINDOWS) //! Create a GraphicsDisplay from a foreign window and display. GraphicsDisplay *CreateFromForeignWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext); #elif defined(USE_X11) //! Create a GraphicsDisplay from a foreign window and display. # ifdef NUX_OPENGLES_20 GraphicsDisplay *CreateFromForeignWindow(Display *X11Display, Window X11Window, EGLContext OpenGLContext); # else GraphicsDisplay *CreateFromForeignWindow(Display *X11Display, Window X11Window, GLXContext OpenGLContext); # endif #elif defined(NO_X11) GraphicsDisplay *CreateFromForeignWindow(EGLDisplay *disp, EGLContext OpenGLContext); #endif static DisplayAccessController &Instance(); private: static DisplayAccessController *m_pInstance; DisplayAccessController(); DisplayAccessController(const DisplayAccessController &); // Does not make sense for a singleton. This is a self assignment. DisplayAccessController &operator= (const DisplayAccessController &); // Declare operator address-of as private DisplayAccessController *operator &(); ~DisplayAccessController(); #if defined(NUX_OS_WINDOWS) HINSTANCE hInstance; WNDCLASSEX WinClass; #endif }; #define gGLWindowManager nux::DisplayAccessController::Instance() } #endif // DISPLAYACCESSCONTROLLER_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLResource.h0000644000015301777760000000664012321344237022314 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLRESOURCE_H #define IOPENGLRESOURCE_H namespace nux { class GpuDevice; class IOpenGLBaseTexture; class IOpenGLTexture2D; class IOpenGLRectangleTexture; class IOpenGLCubeTexture; class IOpenGLSurface; class IOpenGLVolumeTexture; class IOpenGLVolume; class IOpenGLQuery; class IOpenGLShader; class IOpenGLVertexShader; class IOpenGLPixelShader; template class ObjectPtr; #define NUM_VERTEX_SHADER_INPUT_ATTRIBUTE 16 enum VertexAttributeType { VAT_UNDEFINED = 0, VAT_FLOAT = 1, VAT_FLOAT2, VAT_FLOAT3, VAT_FLOAT4, VAT_FLOAT_MAT2, VAT_FLOAT_MAT3, VAT_FLOAT_MAT4, }; enum ShaderType { SHADER_TYPE_GLSL = 0, SHADER_TYPE_CG, SHADER_TYPE_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ }; struct ShaderAttributeDefinition { int attribute_index; // 0 to 15 std::string attribute_name; int type; // 1, 2, 3 or 4 component, bool valid; // true is the attribute is used }; ////////////////////////////////////////////////////////////////////////// class IOpenGLResource: public Object { NUX_DECLARE_OBJECT_TYPE(IOpenGLResource, Object); public: IOpenGLResource(OpenGLResourceType ResourceType, NUX_FILE_LINE_PROTO) : Object(true, NUX_FILE_LINE_PARAM) , _OpenGLID(0) , _RefCount(0) , _ResourceType(ResourceType) { } virtual ~IOpenGLResource() { } virtual int RefCount() const { return GetReferenceCount(); } OpenGLResourceType GetResourceType() const { return _ResourceType; } GLuint GetOpenGLID() const { return _OpenGLID; } GLuint* GetOpenGLIDAsInParam() { return &_OpenGLID; } private: GLuint _OpenGLID; int _RefCount; OpenGLResourceType _ResourceType; friend class IOpenGLFrameBufferObject; friend class IOpenGLSurface; friend class IOpenGLBaseTexture; friend class IOpenGLCubeTexture; friend class IOpenGLVolumeTexture; friend class IOpenGLAnimatedTexture; friend class IOpenGLTexture2D; friend class IOpenGLRectangleTexture; friend class IOpenGLVolume; friend class IOpenGLQuery; friend class GpuDevice; friend class IOpenGLIndexBuffer; friend class IOpenGLVertexBuffer; friend class IOpenGLVertexDeclaration; friend class IOpenGLShader; friend class IOpenGLVertexShader; friend class IOpenGLPixelShader; friend class IOpenGLGeometryShader; friend class IOpenGLShaderProgram; friend class IOpenGLAsmShaderProgram; friend class IOpenGLPixelBufferObject; }; } #endif // IOPENGLRESOURCE_H nux-4.0.6+14.04.20140409/NuxGraphics/OpenGLDefinitions.h0000644000015301777760000000143712321344237022666 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipeAsm.h0000644000015301777760000000160512321344237022537 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RENDERINGPIPEASM_H #define RENDERINGPIPEASM_H namespace nux { } #endif // RENDERINGPIPEASM_H nux-4.0.6+14.04.20140409/NuxGraphics/NuxGraphicsObject.h0000644000015301777760000000000012321344237022711 0ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxGraphics/GLResourceManager.cpp0000644000015301777760000001407212321344237023205 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "IOpenGLResource.h" #include "GLResourceManager.h" #include "GraphicsEngine.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" namespace nux { extern PixelFormatInfo GPixelFormats[]; NUX_IMPLEMENT_OBJECT_TYPE(ResourceData); NUX_IMPLEMENT_OBJECT_TYPE(CachedResourceData); ResourceData::ResourceData(NUX_FILE_LINE_DECL) : Object(true, NUX_FILE_LINE_PARAM) , m_ResourceIndex(NUX_INVALID_INDEX) { #define GET_UNIQUE_RESOURCE_INDEX NUX_GLOBAL_OBJECT_INSTANCE(UniqueIndex) m_ResourceIndex = GET_UNIQUE_RESOURCE_INDEX.GetUniqueIndex(); #undef GET_UNIQUE_RESOURCE_INDEX } ResourceData::~ResourceData() { // If the windows thread is deleted before any texture type resource, the // graphics display will not exist. GraphicsDisplay* display = GetGraphicsDisplay(); if (display) display->GetGraphicsEngine()->FlushCachedResourceData(this); } int ResourceData::GetResourceIndex() const { return m_ResourceIndex; } NResourceSet::NResourceSet() : FirstResource( NULL ) { if ( 1 ) { } } CachedResourceData::CachedResourceData(NResourceSet *ResourceManager) : Set(ResourceManager) , _cached(0) , NumRefs(0) , ResourceType(NULL) , Size(0) , UpdateHint(RUH_Static) { PrevResource = NULL; NextResource = Set->FirstResource; Set->FirstResource = this; if (NextResource) { NextResource->PrevResource = this; } } CachedResourceData::~CachedResourceData() { if (PrevResource) { PrevResource->NextResource = NextResource; } else { Set->FirstResource = NextResource; } if (NextResource) { NextResource->PrevResource = PrevResource; } if (_cached) { Set->FlushResource(this); _cached = false; } } void NResourceCache::InitializeResourceFactories() { // Define the factory pair ResourceData - CachedResourceData #define NUX_DEFINE_RESOURCE_FACTORY_PAIR(SourceTypeName, ResourceTypeName) \ static TGLResourceFactory Factory##SourceTypeName(&SourceTypeName::StaticObjectType); \ GetResourceFactories().push_back(&Factory##SourceTypeName); NUX_DEFINE_RESOURCE_FACTORY_PAIR(Texture2D, CachedTexture2D); NUX_DEFINE_RESOURCE_FACTORY_PAIR(TextureRectangle, CachedTextureRectangle); NUX_DEFINE_RESOURCE_FACTORY_PAIR(TextureCube, CachedTextureCube); NUX_DEFINE_RESOURCE_FACTORY_PAIR(TextureVolume, CachedTextureVolume); NUX_DEFINE_RESOURCE_FACTORY_PAIR(TextureFrameAnimation, CachedTextureFrameAnimation); NUX_DEFINE_RESOURCE_FACTORY_PAIR(VertexBuffer, CachedVertexBuffer); NUX_DEFINE_RESOURCE_FACTORY_PAIR(IndexBuffer, CachedIndexBuffer); NUX_DEFINE_RESOURCE_FACTORY_PAIR(VertexDeclaration, CachedVertexDeclaration); NUX_DEFINE_RESOURCE_FACTORY_PAIR(MeshBuffer, CachedMeshBuffer); #undef NUX_DEFINE_RESOURCE_FACTORY_PAIR // Define the factory updater for and ResourceData #define NUX_DEFINE_RESOURCE_UPDATER(SourceTypeName) \ static NResourceUpdater Updater##SourceTypeName(&SourceTypeName::StaticObjectType); \ GetResourceUpdaters().push_back(&Updater##SourceTypeName); NUX_DEFINE_RESOURCE_UPDATER(Texture2D); NUX_DEFINE_RESOURCE_UPDATER(TextureRectangle); NUX_DEFINE_RESOURCE_UPDATER(TextureCube); NUX_DEFINE_RESOURCE_UPDATER(TextureVolume); NUX_DEFINE_RESOURCE_UPDATER(TextureFrameAnimation); NUX_DEFINE_RESOURCE_UPDATER(VertexBuffer); NUX_DEFINE_RESOURCE_UPDATER(IndexBuffer); NUX_DEFINE_RESOURCE_UPDATER(VertexDeclaration); NUX_DEFINE_RESOURCE_UPDATER(MeshBuffer); #undef NUX_DEFINE_RESOURCE_UPDATER } ObjectPtr NResourceCache::GetCachedResource(ResourceData *Source) { NUX_RETURN_VALUE_IF_NULL(Source, ObjectPtr(0)); // check to see if it already exists ObjectPtr CachedResource = TResourceCache::FindCachedResourceById(Source->GetResourceIndex()); if (CachedResource.IsNull()) { // iterate over the list of factory types for (unsigned int i = 0; i < GetResourceFactories().size(); ++i) { NResourceFactory *ResourceFactory = GetResourceFactories() [i]; // check if the factory is valid for the source resource type if (ResourceFactory->BuildsThisResource(Source)) { // cache the device resource CachedResourceData* ptr = ResourceFactory->BuildResource(this, Source); CachedResource = ObjectPtr (ptr); ptr->UnReference(); break; } } // make sure the result is valid if (CachedResource.IsNull()) { nuxError("Cannot cache resource type %s", Source->Type().name ); } else { // Get resource type CachedResource->ResourceType = & (Source->Type()); // add it to the pool of cached resources AddCachedResource(Source->GetResourceIndex(), CachedResource); } } return CachedResource; } bool NResourceCache::IsCachedResource(ResourceData *Source) { ObjectPtr CachedResource = TResourceCache< int, CachedResourceData >::FindCachedResourceById(Source->GetResourceIndex()); return(CachedResource.IsValid()); } } nux-4.0.6+14.04.20140409/NuxGraphics/GraphicsEngine.h0000644000015301777760000013630212321344237022234 0ustar pbusernogroup00000000000000/* * Copyright 2010-2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef OPENGLENGINE_H #define OPENGLENGINE_H #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLRenderStates.h" #include "FontTexture.h" #include "RenderingPipe.h" #include "GLShader.h" #if defined(NUX_OS_WINDOWS) #include "GraphicsDisplay.h" #include "GLWindowManager.h" #elif defined(NUX_OS_LINUX) #include "GraphicsDisplay.h" #include "GLWindowManager.h" #endif #define NUX_MAX_GAUSSIAN_SIGMA 11 #define NUX_MIN_GAUSSIAN_SIGMA 1 #ifndef NUX_OPENGLES_20 #define NUX_VERTEX_SHADER_HEADER "#version 110 \n" #else #define NUX_VERTEX_SHADER_HEADER #endif #ifndef NUX_OPENGLES_20 #define NUX_FRAGMENT_SHADER_HEADER "#version 110 \n" #else #define NUX_FRAGMENT_SHADER_HEADER "precision mediump float; \n" #endif namespace nux { class FontTexture; class FontRenderer; class FilePath; class BaseTexture; class TextureRectangle; class ROPConfig { public: ROPConfig(); ~ROPConfig(); bool Blend; unsigned int SrcBlend; unsigned int DstBlend; static ROPConfig Default; }; class BlendOperator { public: BlendOperator(); ~BlendOperator(); void EnableBlending(bool enable); void SetPorterDuffOperator(PorterDuffOperator op); void SetCustomBlendOperator(unsigned int src_blend, unsigned int dst_blend); bool _enable; unsigned int _src_blend; unsigned int _dst_blend; }; typedef struct { int x; int y; int width; int height; } OpenGLContext; class FxStructure { public: FxStructure(); ~FxStructure(); ObjectPtr dst_texture; ObjectPtr src_texture; ObjectPtr temp_texture; }; typedef enum { LAYER_BLEND_MODE_NORMAL, // Darken Modes LAYER_BLEND_MODE_DARKEN, LAYER_BLEND_MODE_MULTIPLY, LAYER_BLEND_MODE_COLOR_BURN, LAYER_BLEND_MODE_LINEAR_BURN, // Lighten Modes LAYER_BLEND_MODE_LIGHTEN, LAYER_BLEND_MODE_SCREEN, LAYER_BLEND_MODE_COLOR_DODGE, LAYER_BLEND_MODE_LINEAR_DODGE, // Constrast Modes LAYER_BLEND_MODE_OVERLAY, LAYER_BLEND_MODE_SOFT_LIGHT, LAYER_BLEND_MODE_HARD_LIGHT, LAYER_BLEND_MODE_VIVID_LIGHT, LAYER_BLEND_MODE_LINEAR_LIGHT, LAYER_BLEND_MODE_PIN_LIGHT, LAYER_BLEND_MODE_HARD_MIX, // Inversion Modes LAYER_BLEND_MODE_DIFFERENCE, LAYER_BLEND_MODE_EXCLUSION, // Cancellation Modes LAYER_BLEND_MODE_SUBTRACT, // Others LAYER_BLEND_MODE_AVERAGE, LAYER_BLEND_MODE_ADD, LAYER_BLEND_MODE_NEGATION, LAYER_BLEND_MODE_REFLECT, LAYER_BLEND_MODE_GLOW, LAYER_BLEND_MODE_PHOENIX, //LAYER_BLEND_MODE_OPACITY, LAYER_BLEND_MODE_LAST } LayerBlendMode; //! Rendering engine class /*! This is the object that renders the graphics primitives. */ class GraphicsEngine { public: /*! @param GlWindow The graphics window for this rendering engine. @param create_rendering_data If true, then in GraphicsEngine, the system creates the OpenGL shaders and the font textures for the rendering. */ GraphicsEngine(GraphicsDisplay& GlWindow, bool create_rendering_data = true); ~GraphicsEngine(); void SetContext(int x, int y, int width, int height); void GetContextSize(int& w, int& h) const; int GetContextWidth() const; int GetContextHeight() const; int GetContextX() const; int GetContextY() const; void GetWindowSize(int& w, int& h) const; int GetWindowWidth() const; int GetWindowHeight() const; OpenGLContext m_CurrrentContext; // Load Textures BaseTexture* Load2DTextureFile(const char* filename); BaseTexture* Load2DRectangleTextureFile(const char* filename); BaseTexture* Load2DTextureFileGenerateAlpha(const char* filename, int red, int green, int blue); void SetTexture(int TextureUnit, BaseTexture* Texture); void SetTexture(int TextureUnit, ObjectPtr< IOpenGLBaseTexture > Texture); void EnableTextureMode(int TextureUnit, int TextureMode); void DisableTextureMode(int TextureUnit, int TextureMode); void DisableAllTextureMode(int TextureUnit); /////////////////// // DRAW TEXTURE // /////////////////// // Neutral //! Render a textured quad. /*! Shader Output = ve4(tex.r, tex.g, tex.b, tex.a) */ void QRP_1Tex(int x, int y, int width, int height, ObjectPtr Tex0, TexCoordXForm& texxform, const Color& color0); //! Render a textured quad. /*! Multiply the shader rgb output with the texture alpha. Shader Output = ve4(tex.r*tex.a, tex.g*tex.a, tex.b*tex.a, tex.a) */ void QRP_1TexPremultiply(int x, int y, int width, int height, ObjectPtr Tex0, TexCoordXForm& texxform, const Color& color0); void QRP_TexDesaturate(int x, int y, int width, int height, ObjectPtr Tex0, TexCoordXForm& texxform, const Color& color0, float desaturation_factor); void QRP_Pixelate(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform, const Color& c0, int pixel_size); void QRP_Color(int x, int y, int width, int height, const Color& c0); void QRP_Color(int x, int y, int width, int height, const Color& c0, const Color& c1, const Color& c2, const Color& c3); void QRP_ColorModTexAlpha(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform0, const Color& color); void QRP_2Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1); void QRP_2TexMod(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1); void QRP_4Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1, ObjectPtr DeviceTexture2, TexCoordXForm& texxform2, const Color& color2, ObjectPtr DeviceTexture3, TexCoordXForm& texxform3, const Color& color3); void QRP_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0); void QRP_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2); void QRP_Line(int x0, int y0, int x1, int y1, Color c0); void QRP_Line(int x0, int y0, int x1, int y1, Color c0, Color c1); void QRP_QuadWireframe(int x0, int y0, int width, int height, Color c0, Color c1, Color c2, Color c3); ObjectPtr QRP_GetBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); ObjectPtr QRP_GetAlphaTexture( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0); ObjectPtr QRP_GetColorMatrixTexture( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, Matrix4 color_matrix, Vector4 offset); ObjectPtr QRP_GetPower( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, const Vector4& exponent); ObjectPtr QRP_GetLQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0); ObjectPtr QRP_GetHQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); void QRP_DisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm& texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm& texxform1, const Color& c1); ObjectPtr QRP_GetPixelBlocks( ObjectPtr device_texture, TexCoordXForm& texxform0, const Color& c0, int pixel_size); void QRP_GetCopyTexture( int width, int height, ObjectPtr& dst_device_texture, ObjectPtr& src_device_texture, TexCoordXForm& texxform0, const Color& c0); #ifndef NUX_OPENGLES_20 // ASM void QRP_ASM_1Tex(int x, int y, int width, int height, ObjectPtr Tex0, TexCoordXForm& texxform, const Color& color0); void QRP_ASM_1TexPremultiply(int x, int y, int width, int height, ObjectPtr Tex0, TexCoordXForm& texxform, const Color& color0); void QRP_ASM_Pixelate(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform, const Color& c0, int pixel_size); void QRP_ASM_Color(int x, int y, int width, int height, const Color& c0); void QRP_ASM_Color(int x, int y, int width, int height, const Color& c0, const Color& c1, const Color& c2, const Color& c3); void QRP_ASM_ColorModTexAlpha(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform0, const Color& color); void QRP_ASM_2Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1); void QRP_ASM_2TexMod(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1); void QRP_ASM_4Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1, ObjectPtr DeviceTexture2, TexCoordXForm& texxform2, const Color& color2, ObjectPtr DeviceTexture3, TexCoordXForm& texxform3, const Color& color3); void QRP_ASM_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0); void QRP_ASM_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2); void QRP_ASM_Line(int x0, int y0, int x1, int y1, Color c0); void QRP_ASM_Line(int x0, int y0, int x1, int y1, Color c0, Color c1); void QRP_ASM_QuadWireframe(int x0, int y0, int width, int height, Color c0, Color c1, Color c2, Color c3); void QRP_ASM_Power (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, Vector4 exponent); void QRP_ASM_AlphaReplicate (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0); void QRP_ASM_HorizontalGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_ASM_VerticalGauss (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_ASM_ColorMatrix (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, Matrix4 color_matrix, Vector4 offset); //! Blur texture /*! @param device_texture The texture that is to be blurred. @param texxform Texture transformation of device_texture. @param x Position of the source texture in result buffer. @param y Position of the source texture in result buffer. @param buffer_width Width of result texture. @param buffer_height Height of result texture. @param sigma */ ObjectPtr QRP_ASM_GetBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& color, float sigma = 1.0f, int num_pass = 1); void QRP_ASM_GetBlurTextureFx( int x, int y, int buffer_width, int buffer_height, FxStructure* fx_structure, TexCoordXForm& texxform, const Color& color, float sigma = 1.0f, int num_pass = 1); //! Replicate the alpha channel in all components of the texture. /*! @param device_texture Source texture. @param texxform Texture transformation parameter. @param color Modulation color. @return Texture with all components set to the alpha value of the source. */ ObjectPtr QRP_ASM_GetAlphaTexture( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& color); //! Color matrix filter. /*! @param device_texture Source texture. @param texxform Texture transformation parameter. @param c Modulation color. @param color_matrix 4x4 section of the color matrix filter. @param offset Last column of the color matrix filter. @return Texture resulting from the processing of the source through a color matrix. */ ObjectPtr QRP_ASM_GetColorMatrixTexture( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c, Matrix4 color_matrix, Vector4 offset); //! Texture components raised to a power. /*! Each component of the texture is raised to a power provided in the exponent parameter. @param device_texture Source texture. @param texxform Texture transformation parameter. @param c Modulation color. @param exponent Power values for each component. @return A texture where the component of the source texture have been raised to a power. */ ObjectPtr QRP_ASM_GetPower( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, const Vector4& exponent); ObjectPtr QRP_ASM_GetLQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0); ObjectPtr QRP_ASM_GetHQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); void QRP_ASM_DisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm& texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm& texxform1, const Color& c1); //! Pixel blocks. /*! @param device_texture Source texture. @param texxform Texture transformation parameter. @param color Modulation color. @param pixel_size Size of pixel blocks. @return A texture pixelated version of the source texture. */ ObjectPtr QRP_ASM_GetPixelBlocks( ObjectPtr device_texture, TexCoordXForm& texxform0, const Color& color, int pixel_size); void QRP_ASM_GetCopyTexture( int width, int height, ObjectPtr& dst_device_texture, ObjectPtr& src_device_texture, TexCoordXForm& texxform0, const Color& c0); #endif // GLSL void QRP_GLSL_1Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform, const Color& c0); void QRP_GLSL_1TexPremultiply(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform, const Color& c0); void QRP_GLSL_TexDesaturate(int x, int y, int width, int height, ObjectPtr Tex0, TexCoordXForm& texxform, const Color& color0, float desaturation_factor); void QRP_GLSL_Pixelate(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform, const Color& c0, int pixel_size); void QRP_GLSL_Color(int x, int y, int width, int height, const Color& c0); void QRP_GLSL_Color(int x, int y, int width, int height, const Color& c0, const Color& c1, const Color& c2, const Color& c3); void QRP_GLSL_ColorModTexAlpha(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform0, const Color& color); void QRP_GLSL_2Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1); void QRP_GLSL_2TexMod(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1); void QRP_GLSL_4Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm& texxform0, const Color& color0, ObjectPtr DeviceTexture1, TexCoordXForm& texxform1, const Color& color1, ObjectPtr DeviceTexture2, TexCoordXForm& texxform2, const Color& color2, ObjectPtr DeviceTexture3, TexCoordXForm& texxform3, const Color& color3); void QRP_GLSL_Triangle (int x0, int y0, int x1, int y1, int x2, int y2, Color c0); void QRP_GLSL_Triangle (int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2); void QRP_GLSL_Line (int x0, int y0, int x1, int y1, Color c0); void QRP_GLSL_Line (int x0, int y0, int x1, int y1, Color c0, Color c1); void QRP_GLSL_QuadWireframe(int x0, int y0, int width, int height, Color c0, Color c1, Color c2, Color c3); void QRP_GLSL_Power (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, Vector4 exponent); void QRP_GLSL_AlphaReplicate (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0); void QRP_GLSL_HorizontalGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_GLSL_VerticalGauss (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_GLSL_HorizontalHQGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_GLSL_VerticalHQGauss (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_GLSL_HorizontalLSGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_GLSL_VerticalLSGauss (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f); void QRP_GLSL_ColorMatrix (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, Matrix4 color_matrix, Vector4 offset); /*! @param device_texture The texture that is to be blurred. @param texxform Texture transformation of device_texture. @param x Position of the source texture in result buffer. @param y Position of the source texture in result buffer. @param buffer_width Width of result texture. @param buffer_height Height of result texture. */ ObjectPtr QRP_GLSL_GetBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); ObjectPtr QRP_GLSL_GetLSBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); ObjectPtr QRP_GLSL_GetAlphaTexture( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0); ObjectPtr QRP_GLSL_GetColorMatrixTexture( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, Matrix4 color_matrix, Vector4 offset); ObjectPtr QRP_GLSL_GetPower( ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, const Vector4& exponent); ObjectPtr QRP_GLSL_GetLQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0); ObjectPtr QRP_GLSL_GetHQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); void QRP_GLSL_GetHQBlurFx( int x, int y, int buffer_width, int buffer_height, FxStructure* fx_structure, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); void QRP_GLSL_GetLSBlurFx( int x, int y, int buffer_width, int buffer_height, FxStructure *fx_structure, TexCoordXForm &texxform, const Color& c0, float sigma = 1.0f, int num_pass = 1); void QRP_GLSL_DisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm& texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm& texxform1, const Color& c1); ObjectPtr QRP_GLSL_GetDisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm& texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm& texxform1, const Color& c1); void QRP_GLSL_GetDisturbedTextureFx( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm& texxform0, const Color& c0, FxStructure* fx_structure, TexCoordXForm& texxform1, const Color& c1); //! Pixel blocks. /*! @param device_texture Source texture. @param texxform Texture transformation parameter. @param color Modulation color. @param pixel_size Size of pixel blocks. @return A texture pixelated version of the source texture. */ ObjectPtr QRP_GLSL_GetPixelBlocks( ObjectPtr device_texture, TexCoordXForm& texxform0, const Color& c0, int pixel_size); void QRP_GLSL_GetCopyTexture( int width, int height, ObjectPtr& dst_device_texture, ObjectPtr& src_device_texture, TexCoordXForm& texxform0, const Color& c0); ////////////////////// // DRAW CLIPPING // ////////////////////// mutable std::vector ClippingRect; void PushClippingRectangle(Rect const& rect); void PopClippingRectangle(); void EmptyClippingRegion(); //! Set the clipping according to the clipping rectangle stack. void ApplyClippingRectangle(); void SetGlobalClippingRectangle(Rect const& rect); void DisableGlobalClippingRectangle(); //! Bypass the clipping rectangle stack and set a different clipping rectangle region. /*! You may restore the clipping rectangle stack with ApplyClippingRectangle. */ void SetClippingRectangle(const Rect& rect); //! Bypass the clipping rectangle stack and set a different clipping rectangle region. void SetOpenGLClippingRectangle(int x, int y, unsigned int width, unsigned int height); Rect GetClippingRegion() const; int GetNumberOfClippingRegions() const; void AddClipOffset(int x, int y); //!< Deprecated. Use PushClipOffset. void PushClipOffset(int x, int y); void PopClipOffset(); void ClearAreaColorDepthStencil(int x, int y, int width, int height, Color clearcolor, float cleardepth, int clearstencil); void ClearAreaColor(int x, int y, int width, int height, Color clearcolor); void ClearAreaDepthStencil(int x, int y, int width, int height, float cleardepth, int clearstencil); void Set3DView(int w, int h); //! Push a screen aligned 2D matrix. void Push2DWindow(int w, int h); void Pop2DWindow(); void Push2DModelViewMatrix(Matrix4 mat); Matrix4 Pop2DModelViewMatrix(); void Clear2DModelViewMatrix(); std::list m_2DModelViewMatricesStack; void SetViewport(int x, int y, int w, int h); Rect GetViewportRect() const; int GetViewportWidth() const; int GetViewportHeight() const; int GetViewportX() const; int GetViewportY() const; void GetViewportSize(int& viewport_width, int& viewport_height) const; void SetScissor(int x, int y, int w, int h); /*! When setting a matrix to translate the widgets, the scissor region is not translated accordingly. This function provides a mean to offset the scissor region. It is useful when translating a widget during and overlay drawing. See an example in the code of NUX-01. @param x Clipping area offset. @param y Clipping area offset. */ void SetScissorOffset(int x, int y); Rect const& GetScissorRect() const; void EnableScissoring(bool b); // void LoadPainterImages(); // const PainterImage* GetImage(UXStyleImageRef style); // Rect GetImageGeometry(UXStyleImageRef style); // std::list m_PainterImageList; int RenderColorText(ObjectPtr Font, int x, int y, std::string const& Str, const Color& TextColor, bool WriteAlphaChannel, int NumCharacter); int RenderColorTextLineStatic(ObjectPtr Font, const PageBBox& pageSize, std::string const& Str, const Color& TextColor, bool WriteAlphaChannel, TextAlignment alignment); int RenderColorTextLineEdit(ObjectPtr Font, const PageBBox& pageSize, std::string const& Str, const Color& TextColor, bool WriteAlphaChannel, const Color& SelectedTextColor, const Color& SelectedTextBackgroundColor, const Color& TextBlinkColor, const Color& CursorColor, bool ShowCursor, unsigned int CursorPosition, int offset = 0, int selection_start = 0, int selection_end = 0); ObjectPtr CreateTextureFromBackBuffer(int x, int y, int width, int height); //Statistics void ResetStats(); /*! Cache a resource if it has previously been cached. If the resource does not contain valid data then the returned value is not valid. Check that the returned hardware resource is valid by calling ObjectPtr.IsValid(). @param Resource The resource to cache. @return A hardware resource. */ ObjectPtr CacheResource(ResourceData* Resource); /*! Update a resource if it has previously been cached. @param Resource The resource to cache. */ void UpdateResource(ResourceData* Resource); bool FlushCachedResourceData(ResourceData* Resource); bool IsResourceCached(ResourceData* Resource); NResourceCache ResourceCache; Matrix4 GetProjectionMatrix(); //! Return the transpose version of GetProjectionMatrix(); Matrix4 GetOpenGLProjectionMatrix(); void SetProjectionMatrix(const Matrix4& matrix); //! Set orthographic projection matrix. /*! The default projection matrix used by nux. @param viewport_width Viewport width. @param viewport_height Viewport height. */ void SetOrthographicProjectionMatrix(int viewport_width, int viewport_height); //! Set orthographic projection matrix. /*! The default projection matrix used by nux. @param left coordinate of viewport location. @param right coordinate of viewport location. @param top coordinate of viewport location. @param bottom coordinate of viewport location. */ void SetOrthographicProjectionMatrix(int left, int right, int bottom, int top); //! Reset the projection matrix to identity. void ResetProjectionMatrix(); Matrix4 GetModelViewMatrix(); //! Return the transpose version of GetModelViewMatrix(); Matrix4 GetOpenGLModelViewMatrix(); Matrix4 GetModelViewProjectionMatrix(); Matrix4 GetOpenGLModelViewProjectionMatrix(); GpuRenderStates& GetRenderStates() { return *_graphics_display.m_DeviceFactory->gpu_render_states_; } void ResetRenderStates() { _graphics_display.m_DeviceFactory->gpu_render_states_->ResetStateChangeToDefault(); } void VerifyRenderStates() { _graphics_display.m_DeviceFactory->gpu_render_states_->CheckStateChange(); } ObjectPtr GetFont(); ObjectPtr GetBoldFont(); //! Return True is GraphicsEngine is using the GLSL shader code path. /*! @return True is the system is using the GLSL shader code path. */ bool UsingGLSLCodePath(); //! Return True is GraphicsEngine is using the ARB program code path. /*! @return True is the system is using the ARB program code path. */ bool UsingARBProgramCodePath(); //! Push a model view matrix on the stack. void PushModelViewMatrix(const Matrix4& matrix); //! Push an Identity model view matrix on the stack. void PushIdentityModelViewMatrix(); //! Push a 2D Translation model view matrix. /*! This is used by Nux to harmonize quads and lines pixel rendering in OpenGL. */ void Push2DTranslationModelViewMatrix(float tx, float ty, float tz); //! Pop a model view matrix off the stack. /*! Return True is a matrix was successfully popped. False if there was no matrix to pop. */ bool PopModelViewMatrix(); //! Reset the model view matrix to identity. void ResetModelViewMatrixStack(); //! Bypass the model view matrix stack and set a custom matrix. /*! You may restore the view matrix stack by calling ApplyModelViewMatrix. */ void SetModelViewMatrix(const Matrix4& matrix); //! Set the model view matrix according to the model view matrix stack. void ApplyModelViewMatrix(); //! Transform a rectangle with the model view matrix. /*! This transformation is only good as long as the model view matrix only contains 2D translations. The output rectangle width and height are the same as the input rectangle. @param rect The rectangle to transform. */ Rect ModelViewXFormRect(const Rect& rect); //! Return the depth of the model view matrix stack. /*! @return The depth of the model view matrix stack. */ int ModelViewStackDepth(); //! Push a projection matrix on the stack. void PushProjectionMatrix(const Matrix4& matrix); //! Pop a projection matrix off the stack. /*! Return True is a matrix was successfully popped. False if there was no matrix to pop. */ bool PopProjectionMatrix(); //! Return the depth of the projection matrix stack. /*! @return The depth of the projection matrix stack. */ int ProjectionStackDepth(); //! Push a raster operation configuration setting on the stack. void PushPorterDuffBlend(const PorterDuffOperator& porter_duff_op); //! Push a state that disables the blending. void PushDisableBlend(); //! Push a custom blend state. /*! @param src_blend OpenGL source blending mode. @param dst_blend OpenGL destination blending mode. */ void PushBlend(unsigned int src_blend, unsigned int dst_blend); //! Pop a raster operation configuration setting off the stack. /*! Return True is a matrix was successfully popped. False if there was no matrix to pop. */ bool PopBlend(); //! Return the depth of the raster operation stack. /*! @return The depth of the raster operation stack. */ int BlendStackDepth(); //! Blends a color layer over a texture. /*! Blends a color over a texture layer. @param bkg_device_texture Background texture. @param frg_color Foreground color. */ void QRP_GLSL_ColorLayerOverTexture(int x, int y, int width, int height, ObjectPtr bkg_device_texture, TexCoordXForm& bkg_texxform, const Color& bkg_color, const Color& frg_color, LayerBlendMode layer_blend_mode); //! Blends a texture layer over a color. /*! Blends a texture over a color layer. @param bkg_color Background color. @param frg_device_texture Foreground texture. */ void QRP_GLSL_TextureLayerOverColor(int x, int y, int width, int height, const Color& bkg_color, ObjectPtr frg_device_texture, TexCoordXForm& frg_texxform, const Color& frg_color, LayerBlendMode layer_blend_mode); //! Blends a texture layer over a texture. /*! Uses a layer blending operation to render two textures. @param bkg_device_texture Background texture layer. @param frg_device_texture Foreground texture layer. */ void QRP_GLSL_TextureLayerOverTexture(int x, int y, int width, int height, ObjectPtr bkg_device_texture, TexCoordXForm& bkg_texxform, const Color& bkg_color, ObjectPtr frg_device_texture, TexCoordXForm& frg_texxform, const Color& frg_color, LayerBlendMode layer_blend_mode); //! Blends a color layer over a color. /*! Uses a layer blending operation to render two colors. @param bkg_color Background color layer. @param frg_color Foreground color layer. */ void QRP_GLSL_ColorLayerOverColor(int x, int y, int width, int height, const Color& bkg_color, const Color& frg_color, LayerBlendMode layer_blend_mode); private: ObjectPtr _normal_font; //!< The normal font renderer ObjectPtr _bold_font; //!< The bold font renderer void InitShaders(); //! Helper function to compute a Gaussian filter weights void GaussianWeights(float **weights, float sigma, unsigned int num_tap); int LinearSampleGaussianWeights(std::vector& weights, std::vector& offsets, float sigma); //! Helper function to set an fbo void SetFrameBufferHelper( ObjectPtr& fbo, ObjectPtr& colorbuffer, ObjectPtr& depthbuffer, int width, int height); #ifndef NUX_OPENGLES_20 void InitAsmColorShader(); //! Render polygons with a single color. ObjectPtr m_AsmColor; void InitAsmTextureShader(); //! Render polygons with a texture modulated by a color. ObjectPtr m_AsmTextureModColor; //! Same as m_AsmTextureModColor for rectangle textures. ObjectPtr m_AsmTextureRectModColor; void InitAsmTexturePremultiplyShader(); //! Render polygons with a texture modulated by a color. ObjectPtr m_AsmTexturePremultiplyModColor; //! Same as m_AsmTextureModColor for rectangle textures. ObjectPtr m_AsmTexturePremultiplyRectModColor; void InitAsmPixelateShader(); //! Render a pixelated texture over a polygon. ObjectPtr m_AsmPixelate; //! Render a pixelated texture rectangle over a polygon. ObjectPtr m_AsmPixelateRect; void InitAsmColorModTexMaskAlpha(); //! Render polygons with a color masked by the alpha provided sampling a texture. //! Requires: Enable GPU Alpha Blending ObjectPtr m_AsmColorModTexMaskAlpha; ObjectPtr m_AsmColorModTexRectMaskAlpha; void InitAsm2TextureAdd(); //! Render polygons with 2 textures, each modulated by a color, and added together. ObjectPtr m_Asm2TextureAdd; ObjectPtr m_Asm2TextureRectAdd; void InitAsm2TextureMod(); //! Render polygons with 2 textures, each modulated by a color, and then multiplied together. ObjectPtr m_Asm2TextureMod; ObjectPtr m_Asm2TextureRectMod; void InitAsm4TextureAdd(); //! Render polygons with 4 textures, each modulated by a color, and added together. ObjectPtr m_Asm4TextureAdd; ObjectPtr m_Asm4TextureRectAdd; void InitAsmPower(); //! Raise a texture component to a power. /*! result = color0 * (tex0)^(exponent) = (tex0.r^exponent.r, tex0.g^exponent.g, tex0.b^exponent.b, tex0.a^exponent.a); */ ObjectPtr _asm_tex_component_exponentiation_prog; ObjectPtr _asm_texrect_component_exponentiation_prog; void InitAsmAlphaReplicate(); //! Replicate the alpha component into r, g and b. /*! result = color0 * (tex0.a, tex0.a, tex0.a, tex0.a); */ ObjectPtr _asm_tex_alpha_replicate_prog; ObjectPtr _asm_texrect_alpha_replicate_prog; void InitAsmSeparableGaussFilter(); //! Gauss horizontal filter. ObjectPtr _asm_tex_separable_gauss_filter_prog; ObjectPtr _asm_texrect_separable_gauss_filter_prog; // void InitAsmSeparableGaussFilter2(); // //! Gauss horizontal filter. // ObjectPtr _asm_tex_separable_gauss_filter_prog2; // ObjectPtr _asm_texrect_separable_gauss_filter_prog2; void InitAsmColorMatrixFilter(); //! Color matrix filter. ObjectPtr _asm_tex_color_matrix_filter_prog; ObjectPtr _asm_texrect_color_matrix_filter_prog; void InitAsm2TextureDepRead(); ObjectPtr m_ASM2TextureDepRead; ObjectPtr m_ASM2TextureRectDepRead; void InitAsmBlendModes(); ObjectPtr m_AsmPSBNormal; ObjectPtr m_AsmPSBLighten; ObjectPtr m_AsmPSBDarken; ObjectPtr m_AsmPSBMultiply; #endif void InitSlColorShader(); //! Render polygons with a single color. ObjectPtr m_SlColor; void InitSlTextureShader(); //! Render polygons with a texture modulated by a color. ObjectPtr m_SlTextureModColor; void InitSlTexturePremultiplyShader(); //! Render polygons with a premultiplied texture modulated by a color. ObjectPtr m_SlTexturePremultiplyModColor; void InitSlPixelateShader(); //! Render a pixelated texture over a polygon. ObjectPtr m_SLPixelate; void InitSlColorModTexMaskAlpha(); //! Render polygons with a color masked by the alpha provided sampling a texture. //! Requires: Enable GPU Alpha Blending ObjectPtr m_SlColorModTexMaskAlpha; ObjectPtr m_SlColorModTexRectMaskAlpha; void InitSl2TextureAdd(); //! Render polygons with 2 textures, each modulated by a color, and added together. //! result = (tex0*color0)+(tex1*color1) ObjectPtr m_Sl2TextureAdd; void InitSl2TextureDepRead(); //! Render a quad with 2 textures. One texture sample is use to offset the coordinates of the second texture read. //! result = (tex1(coord1.xy + tex0.xy)*color1) ObjectPtr m_Sl2TextureDepRead; void InitSl2TextureMod(); //! Render polygons with 2 textures, each modulated by a color, and then multiplied together. //! result = (tex0*color0)*(tex1*color1) ObjectPtr m_Sl2TextureMod; void InitSl4TextureAdd(); //! Render polygons with 4 textures, each modulated by a color, and added together. ObjectPtr m_Sl4TextureAdd; void InitSLPower(); //! Raise a texture component to a power. /*! result = color0 * (tex0)^(exponent) = (tex0.r^exponent.r, tex0.g^exponent.g, tex0.b^exponent.b, tex0.a^exponent.a); */ ObjectPtr _component_exponentiation_prog; void InitSLAlphaReplicate(); //! Replicate the alpha component into r, g and b. /*! result = color0 * (tex0.a, tex0.a, tex0.a, tex0.a); */ ObjectPtr _alpha_replicate_prog; void InitSLHorizontalGaussFilter(); //! Gauss horizontal filter. ObjectPtr _horizontal_gauss_filter_prog; void InitSLVerticalGaussFilter(); //! Gauss vertical filter. ObjectPtr _vertical_gauss_filter_prog; void InitSLHorizontalHQGaussFilter(int sigma); //! Gauss horizontal filter. ObjectPtr _horizontal_hq_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; void InitSLVerticalHQGaussFilter(int sigma); //! Gauss vertical filter. ObjectPtr _vertical_hq_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; void InitSLHorizontalLSGaussFilter(int k); //! Gauss horizontal filter. ObjectPtr _horizontal_ls_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; void InitSLVerticalLSGaussFilter(int k); //! Gauss vertical filter. ObjectPtr _vertical_ls_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; void InitSLColorMatrixFilter(); //! Color matrix filter. ObjectPtr _color_matrix_filter_prog; void InitSLDesaturation(); ObjectPtr desaturation_prog_; void InitSlBlendModes(); void InitBlendModeNormal(); void InitBlendModeLighten(); void InitBlendModeDarken(); ObjectPtr shader_layer_blend_normal_; ObjectPtr shader_layer_blend_lighten_; ObjectPtr shader_layer_blend_darken_; ObjectPtr shader_layer_blend_multiply_; // Blend modes ObjectPtr blend_tex_color_prog_[LAYER_BLEND_MODE_LAST]; ObjectPtr blend_color_tex_prog_[LAYER_BLEND_MODE_LAST]; ObjectPtr blend_tex_tex_prog_[LAYER_BLEND_MODE_LAST]; ObjectPtr blend_color_color_prog_[LAYER_BLEND_MODE_LAST]; std::string GetBlendModeBlendFunc(LayerBlendMode layer_blend_mode); std::string GetBlendModeString(LayerBlendMode layer_blend_mode); ObjectPtr GetColorBlendOverTexProgram(LayerBlendMode layer_blend_mode); ObjectPtr GetTextureLayerOverColorProgram(LayerBlendMode layer_blend_mode); ObjectPtr GetTextureLayerOverTextureProgram(LayerBlendMode layer_blend_mode); ObjectPtr GetColorLayerOverColorProgram(LayerBlendMode layer_blend_mode); //! Test the gpu features and set variables such as \e _use_glsl_shaders. void EvaluateGpuCaps(); bool _use_glsl_shaders; //!< True if the system is using the glsl code path. ObjectPtr _offscreen_fbo; ObjectPtr _offscreen_color_rt0; ObjectPtr _offscreen_depth_rt0; ObjectPtr _offscreen_color_rt1; ObjectPtr _offscreen_depth_rt1; ObjectPtr _offscreen_color_rt2; ObjectPtr _offscreen_depth_rt2; ObjectPtr _offscreen_color_rt3; ObjectPtr _offscreen_depth_rt3; Matrix4 _projection_matrix; Matrix4 _model_view_matrix; std::list _model_view_stack; std::list _blend_stack; //! The system GraphicsDisplay object GraphicsDisplay& _graphics_display; Rect _viewport; Rect _scissor; int _clip_offset_x; int _clip_offset_y; Rect _clipping_rect; //! Set to \i true to enable the global clipping rectangle. /*! When rendering directly to the OpenGL back buffer, we may enable a global clipping rectangle. This is mostly useful in embedded mode. \sa _global_clipping_rect; */ bool _global_clipping_enabled; //! Define a global clipping rectangle. Rect _global_clipping_rect; std::list _clip_offset_stack; FontRenderer* _font_renderer; //Statistics mutable long m_quad_stats; mutable long m_quad_tex_stats; mutable long m_triangle_stats; mutable long m_triangle_tex_stats; mutable long m_line_stats; GraphicsEngine(const GraphicsEngine&); // Does not make sense for a singleton. This is a self assignment. GraphicsEngine& operator = (const GraphicsEngine&); // Declare operator address-of as private GraphicsEngine* operator & (); }; } #endif // OPENGLENGINE_H nux-4.0.6+14.04.20140409/NuxGraphics/GraphicsDisplay.h0000644000015301777760000000206712321344237022434 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GRAPHICSDISPLAY_H #define GRAPHICSDISPLAY_H #if defined(NUX_OS_WINDOWS) #include "GraphicsDisplayWin.h" #elif defined(USE_X11) #include "GraphicsDisplayX11.h" #else #error "GraphicsDisplay.h" is not implemented for this platform. #endif #endif //GRAPHICSDISPLAY_H nux-4.0.6+14.04.20140409/NuxGraphics/GpuDeviceVertex.cpp0000755000015301777760000003655612321344237022767 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLDeviceFrameBufferObject.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" namespace nux { static STREAMSOURCE _StreamSource[MAX_NUM_STREAM]; ObjectPtr GpuDevice::CreateVertexBuffer(int Length, VBO_USAGE Usage) { ObjectPtr result; result.Adopt(new IOpenGLVertexBuffer(Length, Usage, NUX_TRACKER_LOCATION)); return result; } ObjectPtr GpuDevice::CreateIndexBuffer(int Length, VBO_USAGE Usage , INDEX_FORMAT Format) { ObjectPtr result; result.Adopt(new IOpenGLIndexBuffer(Length, Usage, Format, NUX_TRACKER_LOCATION)); return result; } ObjectPtr GpuDevice::CreatePixelBufferObject(int Size, VBO_USAGE Usage) { ObjectPtr result; result.Adopt(new IOpenGLPixelBufferObject(Size, Usage, NUX_TRACKER_LOCATION)); return result; } ObjectPtr GpuDevice::CreateVertexDeclaration( const VERTEXELEMENT *pVertexElements) { ObjectPtr result; result.Adopt(new IOpenGLVertexDeclaration(pVertexElements)); return result; } void GpuDevice::InvalidateVertexBuffer() { CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); } void GpuDevice::InvalidateIndexBuffer() { CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); } int GpuDevice::DrawIndexedPrimitive(ObjectPtr IndexBuffer, ObjectPtr VertexDeclaration, PRIMITIVE_TYPE PrimitiveType, int index_count) { nuxAssert(VertexDeclaration.IsValid()); if (!VertexDeclaration.IsValid()) return OGL_ERROR; int decl = 0; for (int i = 0; i < 16; i++) { VertexDeclaration->_valid_vertex_input[i] = 0; } while (VertexDeclaration->_declarations_array[decl].Stream != 0xFF) { VERTEXELEMENT vtxelement = VertexDeclaration->_declarations_array[decl]; int shader_attribute_location = VertexDeclaration->GetVertexShaderAttributeLocation(decl); if (shader_attribute_location == -1) { ++decl; continue; } VertexDeclaration->GetVertexBuffer(vtxelement.Stream)->BindVertexBuffer(); glEnableVertexAttribArrayARB(shader_attribute_location); CHECKGL(glVertexAttribPointer(shader_attribute_location, vtxelement.NumComponent, vtxelement.Type, GL_FALSE, vtxelement.stride_, (void*)vtxelement.Offset)); VertexDeclaration->_valid_vertex_input[shader_attribute_location] = 1; ++decl; } { IndexBuffer->BindIndexBuffer(); GLenum primitive = PrimitiveType; GLenum index_format = GL_UNSIGNED_SHORT; if (IndexBuffer->GetStride() == 4) index_format = GL_UNSIGNED_INT; // switch(PrimitiveType) // { // case PRIMITIVE_TYPE_POINTLIST: // ElementCount = PrimitiveCount; // break; // // case PRIMITIVE_TYPE_LINELIST: // ElementCount = PrimitiveCount * 2; // break; // // case PRIMITIVE_TYPE_LINESTRIP: // ElementCount = PrimitiveCount + 1; // break; // // case PRIMITIVE_TYPE_TRIANGLELIST: // ElementCount = PrimitiveCount * 3; // break; // // case PRIMITIVE_TYPE_TRIANGLEFAN: // case PRIMITIVE_TYPE_TRIANGLESTRIP: // ElementCount = PrimitiveCount + 2; // break; // default: // // Unknown primitive type. This should not happen. // nuxAssertMsg(0, "[GpuDevice::DrawIndexedPrimitive] Unknown Primitive Type."); // } CHECKGL(glDrawElements(primitive, index_count, index_format, 0)); } { for (int index = 0; index < 16; index++) { if (VertexDeclaration->_valid_vertex_input[index]) glDisableVertexAttribArrayARB(index); } InvalidateVertexBuffer(); InvalidateIndexBuffer(); } // for (int i = 0; i < 8; i++) // { // CHECKGL(glClientActiveTexture(GL_TEXTURE0 + i)); // CHECKGL(glDisable(GL_TEXTURE_3D)); // CHECKGL(glDisable(GL_TEXTURE_2D)); // CHECKGL(glDisable(GL_TEXTURE_1D)); // CHECKGL(glDisable(GL_TEXTURE_CUBE_MAP_ARB)); // CHECKGL(glEnable(GL_TEXTURE_2D)); // CHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); // } return OGL_OK; } #ifndef NUX_OPENGLES_20 // Draw Primitive without index buffer int GpuDevice::DrawPrimitive(ObjectPtr /* VertexDeclaration */, PRIMITIVE_TYPE /* PrimitiveType */, unsigned /* vtx_start_ */, unsigned /* PrimitiveCount */) { // return OGL_OK; // glDisable(GL_CULL_FACE); // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // // // Maps a vertex declaration usage to a vertex shader input index. // // I want to make this a static array defined outside of this function but their seems to be a problem // // with initialization... // /*static*/ // int sVertexInputMap[] = // { // 0, // ATTRIB_USAGE_DECL_POSITION // 14, // ATTRIB_USAGE_DECL_BLENDWEIGHT // 15, // ATTRIB_USAGE_DECL_BLENDINDICES // 1, // ATTRIB_USAGE_DECL_NORMAL // 4, // ATTRIB_USAGE_DECL_COLOR, ATTRIB_USAGE_DECL_COLOR0 // 5, // ATTRIB_USAGE_DECL_COLOR1 // 6, // ATTRIB_USAGE_DECL_FOGCOORD // 7, // ATTRIB_USAGE_DECL_PSIZE // 8, // ATTRIB_USAGE_DECL_TEXCOORD, ATTRIB_USAGE_DECL_TEXCOORD0 // 9, // ATTRIB_USAGE_DECL_TEXCOORD1 // 10, // ATTRIB_USAGE_DECL_TEXCOORD2 // 11, // ATTRIB_USAGE_DECL_TEXCOORD3 // 12, // ATTRIB_USAGE_DECL_TEXCOORD4 // 13, // ATTRIB_USAGE_DECL_TEXCOORD5 // 14, // ATTRIB_USAGE_DECL_TEXCOORD6 // 15, // ATTRIB_USAGE_DECL_TEXCOORD7 // 2, // ATTRIB_USAGE_DECL_TANGENT // 3, // ATTRIB_USAGE_DECL_BINORMAL // }; // // nuxAssert(VertexDeclaration.IsValid()); // // if (!VertexDeclaration.IsValid()) // return OGL_ERROR; // // int decl = 0; // // for (int i = 0; i < 16; i++) // VertexDeclaration->_valid_vertex_input[i] = 0; // // while (VertexDeclaration->_declarations_array[decl].Stream != 0xFF) // { // VERTEXELEMENT vtxelement = VertexDeclaration->_declarations_array[decl]; // int vtxInput = sVertexInputMap[vtxelement.Usage + vtxelement.UsageIndex]; // // nuxAssert(vtxInput < GetGpuInfo().GetMaxFboAttachment()); // // Eneble the vertex attribute(0 to 10) // glEnableVertexAttribArrayARB( vtxInput ); // // Bind the vertex buffer // _StreamSource[vtxelement.Stream].VertexBuffer->BindVertexBuffer(); // // CHECKGL(glVertexAttribPointer(vtxInput, // vtxelement.NumComponent, // vtxelement.Type, // GL_FALSE, // _StreamSource[vtxelement.Stream].StreamStride, // (GLvoid *) (&_StreamSource[vtxelement.Stream].StreamOffset + vtxelement.Offset))); // // VertexDeclaration->_valid_vertex_input[sVertexInputMap[vtxelement.Usage + vtxelement.UsageIndex]] = 1; // decl++; // } // // { // InvalidateIndexBuffer(); // // GLenum primitive = PrimitiveType; // int ElementCount = 0; // // switch(PrimitiveType) // { // case PRIMITIVE_TYPE_POINTLIST: // ElementCount = PrimitiveCount; // break; // // case PRIMITIVE_TYPE_LINELIST: // ElementCount = PrimitiveCount * 2; // break; // // case PRIMITIVE_TYPE_LINESTRIP: // ElementCount = PrimitiveCount + 1; // break; // // case PRIMITIVE_TYPE_TRIANGLELIST: // ElementCount = PrimitiveCount * 3; // break; // // case PRIMITIVE_TYPE_TRIANGLEFAN: // case PRIMITIVE_TYPE_TRIANGLESTRIP: // ElementCount = PrimitiveCount + 2; // break; // default: // // Unknown primitive type. This should not happen. // nuxAssertMsg(0, "[GpuDevice::DrawPrimitive] Unknown Primitive Type."); // return OGL_ERROR; // } // // CHECKGL(glDrawArrays(primitive, // ElementCount, // vtx_start_)); // } // // { // for (int index = 0; index < 16; index++) // { // if (VertexDeclaration->_valid_vertex_input[index]) // glDisableVertexAttribArrayARB( index ); // } // // InvalidateVertexBuffer(); // InvalidateIndexBuffer(); // } // // // for (int i = 0; i < 8; i++) // // { // // CHECKGL(glClientActiveTexture(GL_TEXTURE0 + i)); // // CHECKGL(glDisable(GL_TEXTURE_3D)); // // CHECKGL(glDisable(GL_TEXTURE_2D)); // // CHECKGL(glDisable(GL_TEXTURE_1D)); // // CHECKGL(glDisable(GL_TEXTURE_CUBE_MAP_ARB)); // // CHECKGL(glEnable(GL_TEXTURE_2D)); // // CHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); // // } return OGL_OK; } // Draw Primitive without index buffer, and use a user pointer for the source of the stream. int GpuDevice::DrawPrimitiveUP(ObjectPtr /* VertexDeclaration */, PRIMITIVE_TYPE /* PrimitiveType */, unsigned int /* PrimitiveCount */, const void * /* pVertexStreamZeroData */, unsigned int /* VertexStreamZeroStride */) { // nuxAssertMsg(VertexDeclaration->IsUsingMoreThanStreamZero(), "[GpuDevice::DrawPrimitiveUP] Declaration is using more than stream 0."); // VERTEXELEMENT vtxelement = VertexDeclaration->GetUsage(ATTRIB_USAGE_DECL_POSITION); // int Stream = vtxelement.Stream; // // if (Stream != 0xFF) // { // glDisable(GL_CULL_FACE); // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // // InvalidateVertexBuffer(); // InvalidateVertexBuffer(); // // size_t ptr = * (size_t *) pVertexStreamZeroData + _StreamSource[vtxelement.Stream].StreamOffset; // CHECKGL(glEnableClientState(GL_VERTEX_ARRAY)); // CHECKGL(glVertexPointer( vtxelement.NumComponent, // vtxelement.Type, // VertexStreamZeroStride, // (GLvoid *) &ptr)); // // InvalidateIndexBuffer(); // // GLenum primitive = PrimitiveType; // int ElementCount = 0; // // switch(PrimitiveType) // { // case PRIMITIVE_TYPE_POINTLIST: // ElementCount = PrimitiveCount; // break; // // case PRIMITIVE_TYPE_LINELIST: // ElementCount = PrimitiveCount * 2; // break; // // case PRIMITIVE_TYPE_LINESTRIP: // ElementCount = PrimitiveCount + 1; // break; // // case PRIMITIVE_TYPE_TRIANGLELIST: // ElementCount = PrimitiveCount * 3; // break; // // case PRIMITIVE_TYPE_TRIANGLEFAN: // case PRIMITIVE_TYPE_TRIANGLESTRIP: // ElementCount = PrimitiveCount + 2; // break; // default: // // Unknown primitive type. This should not happen. // nuxAssertMsg(0, "[GpuDevice::DrawPrimitiveUP] Unknown Primitive Type."); // return OGL_ERROR; // } // // CHECKGL(glDrawArrays(primitive, // ElementCount, // 0)); // // CHECKGL(glDisableClientState(GL_VERTEX_ARRAY)); // // } // // // for (int i = 0; i < 8; i++) // // { // // CHECKGL(glClientActiveTexture(GL_TEXTURE0 + i)); // // CHECKGL(glDisable(GL_TEXTURE_3D)); // // CHECKGL(glDisable(GL_TEXTURE_2D)); // // CHECKGL(glDisable(GL_TEXTURE_1D)); // // CHECKGL(glDisable(GL_TEXTURE_CUBE_MAP_ARB)); // // CHECKGL(glEnable(GL_TEXTURE_2D)); // // CHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); // // } return OGL_OK; } #endif // // DirectX Matrix // // | 2/W 0 0 -(W+1)/W | // // | 0 -2/H 0 (H+1)/H | // // | 0 0 1 0 | // // | 0 0 0 1 | // // // // Screen Quad(0, 0, W, H) // // Normalized Coord (Xn+1)/2 * W Screen Coord // // X: 0 ---> -(1+1/W) ---> -0.5 // // X: W ---> 1-1/W ---> W-0.5 // // -(Yn-1)/2 * H // // Y: 0 ---> (1+1/H) ---> -0.5 // // Y: W ---> -1-1/H ---> H-0.5 // // // // The Matrix above is good to do quad on screen in DirectX. DirectX requires that the vertex coordinates be shifted // // by(-0.5,-0.5) in order for the center of texel to be located at the center of pixel. // // Note: OpenGL maps integral texture coordinates to the texel center // // whereas Direct3D maps integral texture coordinates to the upper, left texel corner. // // // In OpenGL we will use this matrix instead: // // | 2/W 0 0 -1 | // // | 0 -2/H 0 1 | // // | 0 0 1 0 | // // | 0 0 0 1 | // // // // Screen Quad(0, 0, W, H) // // Normalized Coord (Xn+1)/2 * W Screen Coord // // X: 0 ---> -1 ---> 0.0 // // X: W ---> 1 ---> W // // -(Yn-1)/2 * H // // Y: 0 ---> 1 ---> 0.0 // // Y: W ---> -1 int GpuDevice::SetStreamSource( unsigned int StreamNumber, ObjectPtr pStreamData, unsigned int OffsetInBytes, unsigned int Stride) { nuxAssert(StreamNumber < MAX_NUM_STREAM); _StreamSource[StreamNumber].Stream = StreamNumber; _StreamSource[StreamNumber].StreamOffset = OffsetInBytes; _StreamSource[StreamNumber].VertexBuffer = pStreamData; _StreamSource[StreamNumber].StreamStride = Stride; return OGL_OK; } } nux-4.0.6+14.04.20140409/NuxGraphics/GLVertexResourceManager.cpp0000644000015301777760000003060512321344237024403 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GLResourceManager.h" #include "GLDeviceObjects.h" #include "GpuDevice.h" #include "GLVertexResourceManager.h" #include "GraphicsEngine.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(VertexBuffer); NUX_IMPLEMENT_OBJECT_TYPE(IndexBuffer); NUX_IMPLEMENT_OBJECT_TYPE(VertexDeclaration); NUX_IMPLEMENT_OBJECT_TYPE(MeshBuffer); NUX_IMPLEMENT_OBJECT_TYPE(CachedVertexBuffer); NUX_IMPLEMENT_OBJECT_TYPE(CachedIndexBuffer); NUX_IMPLEMENT_OBJECT_TYPE(CachedVertexDeclaration); NUX_IMPLEMENT_OBJECT_TYPE(CachedMeshBuffer); VertexBuffer::VertexBuffer() { _Stride = 0; } VertexBuffer::~VertexBuffer() { _Data.clear(); } VertexBuffer::VertexBuffer(int num_element, int size) { Allocate(num_element, size); } void VertexBuffer::Allocate(int num_element, int size) { nuxAssert(num_element > 0); nuxAssert(size > 0); if ((size <= 0) || (num_element <= 0)) { _Data.clear(); _Stride = 0; return; } // Make sure Size is a multiple of Stride int sz = size * num_element; _Stride = size; _Data.clear(); _Data.resize(sz); } int VertexBuffer::GetSize() const { return _Data.size(); } int VertexBuffer::GetStride() const { return _Stride; } int VertexBuffer::GetNumElement() const { return _Data.size() / _Stride; } const void* VertexBuffer::GetPtrRawData() const { if (_Data.empty()) return 0; return NUX_STATIC_CAST(const void*, &_Data[0]); } void* VertexBuffer::GetPtrRawData() { if (_Data.empty()) return 0; return NUX_CONST_CAST(void*, ((NUX_CONST_CAST(const VertexBuffer*, this))->GetPtrRawData())); } IndexBuffer::IndexBuffer() { _Stride = 0; } IndexBuffer::~IndexBuffer() { _Data.clear(); } IndexBuffer::IndexBuffer(int num_element, int size) { Allocate(num_element, size); } void IndexBuffer::Allocate(int num_index, int size) { nuxAssert(num_index > 0); nuxAssert(size > 0); nuxAssert((size == 2) || (size == 4)); if ((size <= 0) || (num_index <= 0)) { _Data.clear(); _Stride = 0; return; } _num_index = num_index; // Make sure Size is a multiple of Stride int sz = _num_index * size; _Stride = size; _Data.clear(); _Data.resize(sz); } int IndexBuffer::GetSize() const { return _Data.size(); } int IndexBuffer::GetStride() const { return _Stride; } int IndexBuffer::GetNumIndex() const { return _num_index; } const void* IndexBuffer::GetPtrRawData() const { return NUX_STATIC_CAST(const void*, &_Data[0]); } void* IndexBuffer::GetPtrRawData() { return NUX_CONST_CAST(void*, ((NUX_CONST_CAST(const IndexBuffer*, this))->GetPtrRawData())); } VertexDeclaration::VertexDeclaration() { _declaration.clear(); } VertexDeclaration::~VertexDeclaration() { _declaration.clear(); } void VertexDeclaration::AddVertexComponent(VERTEXELEMENT Component) { _declaration.push_back(Component); } CachedVertexBuffer::CachedVertexBuffer(NResourceSet* ResourceManager, VertexBuffer* SourceVtxBuffer) : CachedResourceData(ResourceManager) , _Size(0) , _Stride(0) { UpdateResource(SourceVtxBuffer); } CachedVertexBuffer::~CachedVertexBuffer() { // Not necessary for a smart pointer but do it anyway to be clear; _vertex_buffer = ObjectPtr (0); } bool CachedVertexBuffer::UpdateResource(ResourceData* Source) { if (Source == 0) { _Stride = 0; _vertex_buffer.Release(); return true; } VertexBuffer* SourceVtxBuffer = 0; nuxAssert(Source->Type().IsDerivedFromType(VertexBuffer::StaticObjectType)); if (Source->Type().IsDerivedFromType(VertexBuffer::StaticObjectType)) { SourceVtxBuffer = NUX_STATIC_CAST(VertexBuffer* , Source); } else { return false; } if ((SourceVtxBuffer->GetSize() == 0) || (SourceVtxBuffer->GetStride() == 0)) { _Stride = 0; _vertex_buffer.Release(); return true; } if (_Size != SourceVtxBuffer->GetSize()) { // The current size of the cached buffer is not the same as the requested one. // Delete the previously allocated buffer and create a new one. _Size = SourceVtxBuffer->GetSize(); _Stride = SourceVtxBuffer->GetStride(); //Release the previous vertex buffer if any. _vertex_buffer.Release(); _vertex_buffer = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexBuffer(_Size, VBO_USAGE_STATIC); LoadVertexData(SourceVtxBuffer); } else { // The buffer size has changed. Delete the previously allocated buffer and create a new one. _Stride = SourceVtxBuffer->GetStride(); LoadVertexData(SourceVtxBuffer); } return true; } void CachedVertexBuffer::LoadVertexData(VertexBuffer* SourceVtxBuffer) { if ((SourceVtxBuffer == 0) || (SourceVtxBuffer->GetSize() == 0) || (SourceVtxBuffer->GetStride() == 0)) { return; } unsigned char* pData; _vertex_buffer->Lock(0, 0, (void**) &pData); Memcpy(pData, SourceVtxBuffer->GetPtrRawData(), SourceVtxBuffer->GetSize()); _vertex_buffer->Unlock(); } int CachedVertexBuffer::GetElementSize() const { return _Size; } int CachedVertexBuffer::GetBufferStride() const { return _Stride; } CachedIndexBuffer::CachedIndexBuffer(NResourceSet* ResourceManager, IndexBuffer* SourceIdxBuffer) : CachedResourceData(ResourceManager) , _Size(0) , _Stride(0) { UpdateResource(SourceIdxBuffer); } CachedIndexBuffer::~CachedIndexBuffer() { // Not necessary for a smart pointer but do it anyway to be clear; _index_buffer = ObjectPtr (0); } bool CachedIndexBuffer::UpdateResource(ResourceData* Source) { if (Source == 0) { _Size = 0; _Stride = 0; _index_buffer.Release(); return true; } IndexBuffer* SourceIdxBuffer = 0; nuxAssert(Source->Type().IsDerivedFromType(IndexBuffer::StaticObjectType)); if (Source->Type().IsDerivedFromType(IndexBuffer::StaticObjectType)) { SourceIdxBuffer = NUX_STATIC_CAST(IndexBuffer*, Source); } else { return false; } if ((SourceIdxBuffer->GetSize() == 0) || (SourceIdxBuffer->GetStride() == 0)) { _Size = 0; _Stride = 0; _index_buffer.Release(); return true; } if (_Size != SourceIdxBuffer->GetSize()) { _Size = SourceIdxBuffer->GetSize(); _Stride = SourceIdxBuffer->GetStride(); //Release the previous vertex buffer if any. _index_buffer.Release(); _index_buffer = GetGraphicsDisplay()->GetGpuDevice()->CreateIndexBuffer(_Size, VBO_USAGE_STATIC, (SourceIdxBuffer->GetStride() == 2) ? INDEX_FORMAT_USHORT : INDEX_FORMAT_UINT); LoadIndexData(SourceIdxBuffer); } else { _Stride = SourceIdxBuffer->GetStride(); LoadIndexData(SourceIdxBuffer); } _num_index = SourceIdxBuffer->GetNumIndex(); return true; } void CachedIndexBuffer::LoadIndexData(IndexBuffer* SourceIdxBuffer) { if ((SourceIdxBuffer == 0) || (SourceIdxBuffer->GetSize() == 0) || (SourceIdxBuffer->GetStride() == 0)) { return; } unsigned char* pData; _index_buffer->Lock(0, 0, (void**) &pData); Memcpy(pData, SourceIdxBuffer->GetPtrRawData(), SourceIdxBuffer->GetSize()); _index_buffer->Unlock(); } int CachedIndexBuffer::GetElementSize() const { return _Size; } int CachedIndexBuffer::GetBufferStride() const { return _Stride; } int CachedIndexBuffer::GetNumIndex() const { return _num_index; } CachedVertexDeclaration::CachedVertexDeclaration(NResourceSet* ResourceManager, VertexDeclaration* SourceVertexDeclaration) : CachedResourceData(ResourceManager) { UpdateResource(SourceVertexDeclaration); } CachedVertexDeclaration::~CachedVertexDeclaration() { _declaration = ObjectPtr (0); } bool CachedVertexDeclaration::UpdateResource(ResourceData* Source) { if (Source == 0) { _declaration = ObjectPtr (0); return true; } VertexDeclaration* SourceVertexDeclaration = 0; nuxAssert(Source->Type().IsDerivedFromType(VertexDeclaration::StaticObjectType)); if (Source->Type().IsDerivedFromType(VertexDeclaration::StaticObjectType)) { SourceVertexDeclaration = NUX_STATIC_CAST(VertexDeclaration*, Source); } else { return false; } if (SourceVertexDeclaration == 0) { _declaration = ObjectPtr (0); return true; } _declaration = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexDeclaration(&SourceVertexDeclaration->_declaration[0]); return true; } MeshBuffer::MeshBuffer(NUX_FILE_LINE_DECL) : ResourceData(NUX_FILE_LINE_PARAM) { _vertex_buffer = 0; _index_buffer = 0; _vertex_declaration = 0; } MeshBuffer::~MeshBuffer() { if (_vertex_buffer) _vertex_buffer->UnReference(); if (_index_buffer) _index_buffer->UnReference(); if (_vertex_declaration) _vertex_declaration->UnReference(); } bool MeshBuffer::Update(const MeshData* mesh_data) { int num_element = mesh_data->_num_element; int element_size = mesh_data->_element_size; _mesh_primitive_type = mesh_data->_mesh_primitive_type; _vertex_buffer = new VertexBuffer(); _vertex_buffer->Allocate(num_element, element_size); memcpy(_vertex_buffer->GetPtrRawData(), mesh_data->_vertex_data, num_element * element_size); int num_index = mesh_data->_num_index; int index_size = mesh_data->_index_size; _index_buffer = new IndexBuffer(); _index_buffer->Allocate(num_index, index_size); memcpy(_index_buffer->GetPtrRawData(), mesh_data->_index_data, num_index * index_size); _vertex_declaration = new VertexDeclaration(); VERTEXELEMENT ve_position(0, 0, ATTRIB_CT_FLOAT, 4, 36); VERTEXELEMENT ve_normal(0, 16, ATTRIB_CT_FLOAT, 3, 36); VERTEXELEMENT ve_texcoord(0, 28, ATTRIB_CT_FLOAT, 2, 36); _vertex_declaration->AddVertexComponent(ve_position); _vertex_declaration->AddVertexComponent(ve_normal); _vertex_declaration->AddVertexComponent(ve_texcoord); _vertex_declaration->AddVertexComponent(DECL_END); return true; } ObjectPtr MeshBuffer::GetCachedMeshBuffer() { return GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(this); } CachedMeshBuffer::CachedMeshBuffer(NResourceSet* ResourceManager, MeshBuffer* resource) : CachedResourceData(ResourceManager) { UpdateResource(resource); } CachedMeshBuffer::~CachedMeshBuffer() { } bool CachedMeshBuffer::UpdateResource(ResourceData* source) { nuxAssert(source->Type().IsDerivedFromType(MeshBuffer::StaticObjectType)); MeshBuffer* mesh_buffer = NUX_STATIC_CAST(MeshBuffer*, source); _cached_vertex_buffer = GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(mesh_buffer->_vertex_buffer); _cached_index_buffer = GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(mesh_buffer->_index_buffer); _cached_vertex_declaration = GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(mesh_buffer->_vertex_declaration); _cached_vertex_declaration->_declaration->SetVertexBuffer(0, _cached_vertex_buffer->_vertex_buffer); _cached_vertex_declaration->_declaration->SetVertexBuffer(1, _cached_vertex_buffer->_vertex_buffer); _cached_vertex_declaration->_declaration->SetVertexBuffer(2, _cached_vertex_buffer->_vertex_buffer); _mesh_primitive_type = mesh_buffer->_mesh_primitive_type; return true; } } nux-4.0.6+14.04.20140409/NuxGraphics/NuxGraphics.h0000644000015301777760000000242012321344237021572 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUXGRAPHICS_H #define NUXGRAPHICS_H namespace nux { class GraphicsDisplay; class GpuDevice; class GraphicsEngine; GraphicsDisplay* GetGraphicsDisplay(); #define NUX_FINDRESOURCELOCATION(a) GNuxGraphicsResources.FindResourceLocation(a, false) #define NUX_FIND_RESOURCE_LOCATION_NOFAIL(a) GNuxGraphicsResources.FindResourceLocation(a, true) inlDeclareThreadLocalStorage(GraphicsDisplay *, 1, _TLS_GraphicsDisplay); void NuxGraphicsInitialize(); } #endif // NUXGRAPHICS_H nux-4.0.6+14.04.20140409/NuxGraphics/GpuDeviceTexture.cpp0000644000015301777760000001553112321344237023135 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLDeviceFrameBufferObject.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" namespace nux { ObjectPtr GpuDevice::CreateTexture( int Width , int Height , int Levels , BitmapFormat pixel_format , NUX_FILE_LINE_DECL) { if ((pixel_format == BITFMT_D24S8) && (!GetGpuInfo().Support_Depth_Buffer())) { // No support for depth buffers return ObjectPtr(); } GpuInfo gpu_info = GetGpuInfo(); int msz = gpu_info.GetMaxTextureSize(); if(Width <= 0 || Height <= 0 || Width > msz || Height > msz) { return ObjectPtr(); } unsigned int NumTotalMipLevel = 1 + floorf(Log2(Max(Width, Height))); unsigned int NumMipLevel = 0; if (Levels == 0) { NumMipLevel = NumTotalMipLevel; } else if (Levels > (int)NumTotalMipLevel) { NumMipLevel = NumTotalMipLevel; } else { NumMipLevel = Levels; } ObjectPtr result; result.Adopt(new IOpenGLTexture2D(Width, Height, NumMipLevel, pixel_format, false, NUX_FILE_LINE_PARAM)); return result; } ObjectPtr GpuDevice::CreateTexture2DFromID(int id , int width , int height , int levels , BitmapFormat pixel_format , NUX_FILE_LINE_DECL) { if ((pixel_format == BITFMT_D24S8) && (!GetGpuInfo().Support_Depth_Buffer())) { // No support for depth buffers return ObjectPtr(); } GpuInfo gpu_info = GetGpuInfo(); int msz = gpu_info.GetMaxTextureSize(); if(width <= 0 || height <=0 || width > msz || height > msz) { return ObjectPtr(); } ObjectPtr result; result.Adopt(new IOpenGLTexture2D(width, height, levels, pixel_format, true, NUX_FILE_LINE_PARAM)); /* Assign the external id to the internal id. This allows us * to use the foreign texture as if it were a native one. * * This is really important. Don't remove it */ result->_OpenGLID = id; return result; } ObjectPtr GpuDevice::CreateRectangleTexture( int Width , int Height , int Levels , BitmapFormat pixel_format , NUX_FILE_LINE_DECL) { if ((pixel_format == BITFMT_D24S8) && (!GetGpuInfo().Support_Depth_Buffer())) { // No support for depth buffers return ObjectPtr(); } GpuInfo gpu_info = GetGpuInfo(); int msz = gpu_info.GetMaxTextureSize(); if(Width <= 0 || Height <= 0 || Width > msz || Height > msz) { return ObjectPtr(); } unsigned int NumTotalMipLevel = 1 + floorf(Log2(Max(Width, Height))); unsigned int NumMipLevel = 0; if (Levels == 0) { NumMipLevel = 1; } else if (Levels > (int)NumTotalMipLevel) { NumMipLevel = 1; } else { NumMipLevel = 1; } ObjectPtr result; result.Adopt(new IOpenGLRectangleTexture(Width, Height, NumMipLevel, pixel_format, false, NUX_FILE_LINE_PARAM)); return result; } ObjectPtr GpuDevice::CreateCubeTexture( int EdgeLength , int Levels , BitmapFormat pixel_format , const char * /* __Nux_FileName__ */ , int /* __Nux_LineNumber__ */) { if ((pixel_format == BITFMT_D24S8) && (!GetGpuInfo().Support_Depth_Buffer())) { // No support for depth buffers return ObjectPtr(); } unsigned int NumTotalMipLevel = 1 + floorf(Log2(EdgeLength)); unsigned int NumMipLevel = 0; if (Levels == 0) { NumMipLevel = NumTotalMipLevel; } else if (Levels > (int)NumTotalMipLevel) { NumMipLevel = NumTotalMipLevel; } else { NumMipLevel = Levels; } ObjectPtr result; result.Adopt(new IOpenGLCubeTexture(EdgeLength, NumMipLevel, pixel_format)); return result; } ObjectPtr GpuDevice::CreateVolumeTexture( int Width , int Height , int Depth , int Levels , BitmapFormat pixel_format , const char * /* __Nux_FileName__ */ , int /* __Nux_LineNumber__ */) { if ((pixel_format == BITFMT_D24S8) && (!GetGpuInfo().Support_Depth_Buffer())) { // No support for depth buffers return ObjectPtr(); } GpuInfo gpu_info = GetGpuInfo(); int msz = gpu_info.GetMaxTextureSize(); if(Width <= 0 || Height <= 0 || Width > msz || Height > msz) { return ObjectPtr(); } unsigned int NumTotalMipLevel = 1 + floorf(Log2(Max(Max(Width, Height), Depth))); unsigned int NumMipLevel = 0; if (Levels == 0) { NumMipLevel = NumTotalMipLevel; } else if (Levels > (int)NumTotalMipLevel) { NumMipLevel = NumTotalMipLevel; } else { NumMipLevel = Levels; } ObjectPtr result; result.Adopt(new IOpenGLVolumeTexture(Width, Height, Depth, NumMipLevel, pixel_format)); return result; } ObjectPtr GpuDevice::CreateAnimatedTexture( int Width , int Height , int Depth , BitmapFormat pixel_format) { if ((pixel_format == BITFMT_D24S8) && (!GetGpuInfo().Support_Depth_Buffer())) { // No support for depth buffers return ObjectPtr(); } GpuInfo gpu_info = GetGpuInfo(); int msz = gpu_info.GetMaxTextureSize(); if(Width <= 0 || Height <= 0 || Width > msz || Height > msz) { return ObjectPtr(); } ObjectPtr result; result.Adopt(new IOpenGLAnimatedTexture(Width, Height, Depth, pixel_format)); return result; } ObjectPtr GpuDevice::CreateQuery(QUERY_TYPE Type) { ObjectPtr result; result.Adopt(new IOpenGLQuery(Type)); return result; } } nux-4.0.6+14.04.20140409/NuxGraphics/GLSh_Fill.cpp0000644000015301777760000001025212321344237021437 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLSh_Fill.h" #include "GLShaderParameter.h" #include "GpuDevice.h" #include "GLTemplatePrimitiveBuffer.h" #include "NuxCore/Math/Matrix4.h" namespace nux { GLSh_Fill::GLSh_Fill() { // Color = new GLShaderParameter(0, "ColorFill", eFRAGMENTUNIFORMTYPE, TRUE); // ViewProjectionMatrix = new GLShaderParameter(0, "ViewProjectionMatrix", eVERTEXUNIFORMTYPE, TRUE); // Scale = new GLShaderParameter(0, "Scale", eVERTEXUNIFORMTYPE, TRUE); // Offset = new GLShaderParameter(0, "Offset", eVERTEXUNIFORMTYPE, TRUE); // // vs = GetGpuDevice()->CreateVertexShader(); // ps = GetGpuDevice()->CreatePixelShader(); // sprog = GetGpuDevice()->CreateShaderProgram(); // // sprog->AddShaderParameter(Color); // sprog->AddShaderParameter(ViewProjectionMatrix); // sprog->AddShaderParameter(Scale); // sprog->AddShaderParameter(Offset); // // NString SourceCode; // LoadFileToString(SourceCode, "..//Shaders//Fill.glsl"); // NString VertexShaderSource; // ExtractShaderString3("[Vertex Shader]", SourceCode, VertexShaderSource); // NString PixelShaderSource; // ExtractShaderString3("[Fragment Shader]", SourceCode, PixelShaderSource); // // vs->SetShaderCode(VertexShaderSource.GetTCharPtr()); // ps->SetShaderCode(PixelShaderSource.GetTCharPtr()); // vs->Compile(); // ps->Compile(); // // sprog->AddShaderObject(vs); // sprog->AddShaderObject(ps); // sprog->Link(); // // m_QuadBuffer = new TemplateQuadBuffer(GetGpuDevice()); // // Vector4 v[] = // // { // // Vector4(1, 0, 0, 0), // // Vector4(1, 0, 0, 0), // // Vector4(0, 0, 1, 0), // // Vector4(0, 0, 1, 0), // // }; // // m_QuadBuffer->SetPerVertexAttribute(1, 4, v); } GLSh_Fill::~GLSh_Fill() { NUX_SAFE_DELETE(m_QuadBuffer); NUX_SAFE_DELETE(Color); NUX_SAFE_DELETE(ViewProjectionMatrix); NUX_SAFE_DELETE(Scale); NUX_SAFE_DELETE(Offset); } void GLSh_Fill::SetColor(FLOAT R, FLOAT G, FLOAT B, FLOAT A) { _R = R; _G = G; _B = B; _A = A; } void GLSh_Fill::SetTransformMatrix(const Matrix4 &TransformMatrix) { m_TransformMatrix = TransformMatrix; } void GLSh_Fill::Render(INT x, INT y, INT /* z */, INT width, INT height) { return; CHECKGL(glDisable(GL_CULL_FACE)); sprog->Begin(); //Matrix4 ProjectionMatrix; //ProjectionMatrix.Orthographic(0, 640, 480, 0, 0.0, 10000.0); //ProjectionMatrix.Transpose(); ViewProjectionMatrix->SetUniformMatrix4fv(1, (GLfloat *) m_TransformMatrix.m, GL_FALSE); Scale->SetUniform4f(width, height, 1, 1); Offset->SetUniform4f(x, y, 0, 0); Color->SetUniform4f(_R, _G, _B, _A); INT VertexLocation = sprog->GetAttributeLocation("Vertex"); m_QuadBuffer->BindAttribute(VertexLocation, 0); // INT VertexColorLocation = sprog->GetAttributeLocation("VertexColor"); // m_QuadBuffer->BindAttribute(VertexColorLocation, 1); m_QuadBuffer->Render(1); m_QuadBuffer->UnBindAttribute(VertexLocation); // m_QuadBuffer->UnBindAttribute(VertexColorLocation); m_QuadBuffer->UnBind(); // Unbind the vertex and index buffer. sprog->End(); } void GLSh_Fill::CacheShader() { } } nux-4.0.6+14.04.20140409/NuxGraphics/VirtualKeyCodes.h0000644000015301777760000002664612321344237022434 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef VIRTUALKEYCODES_H #define VIRTUALKEYCODES_H namespace nux { // Virtual key codes // The following table shows the symbolic constant names, hexadecimal values, and mouse or keyboard equivalents for the virtual-key codes used by the system. The codes are listed in numeric order. // Symbolic constant name Value(hex) Mouse or keyboard equivalents #define NUX_VK_SPACE 0x020 #define NUX_VK_EXCLAM 0x021 #define NUX_VK_QUOTEDBL 0x022 #define NUX_VK_NUMBERSIGN 0x023 #define NUX_VK_DOLLAR 0x024 #define NUX_VK_PERCENT 0x025 #define NUX_VK_AMPERSAND 0x026 #define NUX_VK_APOSTROPHE 0x027 #define NUX_VK_QUOTERIGHT 0x027 /* deprecated */ #define NUX_VK_PARENLEFT 0x028 #define NUX_VK_PARENRIGHT 0x029 #define NUX_VK_MULTIPLY 0x02a #define NUX_VK_ADD 0x02b #define NUX_VK_COMMA 0x02c #define NUX_VK_SUBTRACT 0x02d #define NUX_VK_DECIMAL 0x02e #define NUX_VK_SLASH 0x02f #define NUX_VK_0 0x030 #define NUX_VK_1 0x031 #define NUX_VK_2 0x032 #define NUX_VK_3 0x033 #define NUX_VK_4 0x034 #define NUX_VK_5 0x035 #define NUX_VK_6 0x036 #define NUX_VK_7 0x037 #define NUX_VK_8 0x038 #define NUX_VK_9 0x039 #define NUX_VK_COLON 0x03a #define NUX_VK_SEMICOLON 0x03b #define NUX_VK_LESS 0x03c #define NUX_VK_EQUAL 0x03d #define NUX_VK_GREATER 0x03e #define NUX_VK_QUESTION 0x03f #define NUX_VK_AT 0x040 #define NUX_VK_A 0x041 #define NUX_VK_B 0x042 #define NUX_VK_C 0x043 #define NUX_VK_D 0x044 #define NUX_VK_E 0x045 #define NUX_VK_F 0x046 #define NUX_VK_G 0x047 #define NUX_VK_H 0x048 #define NUX_VK_I 0x049 #define NUX_VK_J 0x04a #define NUX_VK_K 0x04b #define NUX_VK_L 0x04c #define NUX_VK_M 0x04d #define NUX_VK_N 0x04e #define NUX_VK_O 0x04f #define NUX_VK_P 0x050 #define NUX_VK_Q 0x051 #define NUX_VK_R 0x052 #define NUX_VK_S 0x053 #define NUX_VK_T 0x054 #define NUX_VK_U 0x055 #define NUX_VK_V 0x056 #define NUX_VK_W 0x057 #define NUX_VK_X 0x058 #define NUX_VK_Y 0x059 #define NUX_VK_Z 0x05a #define NUX_VK_BRACKETLEFT 0x05b #define NUX_VK_BACKSLASH 0x05c #define NUX_VK_BRACKETRIGHT 0x05d #define NUX_VK_ASCIICIRCUM 0x05e #define NUX_VK_UNDERSCORE 0x05f #define NUX_VK_GRAVE 0x060 #define NUX_VK_QUOTELEFT 0x060 /* deprecated */ #define NUX_VK_a 0x061 #define NUX_VK_b 0x062 #define NUX_VK_c 0x063 #define NUX_VK_d 0x064 #define NUX_VK_e 0x065 #define NUX_VK_f 0x066 #define NUX_VK_g 0x067 #define NUX_VK_h 0x068 #define NUX_VK_i 0x069 #define NUX_VK_j 0x06a #define NUX_VK_k 0x06b #define NUX_VK_l 0x06c #define NUX_VK_m 0x06d #define NUX_VK_n 0x06e #define NUX_VK_o 0x06f #define NUX_VK_p 0x070 #define NUX_VK_q 0x071 #define NUX_VK_r 0x072 #define NUX_VK_s 0x073 #define NUX_VK_t 0x074 #define NUX_VK_u 0x075 #define NUX_VK_v 0x076 #define NUX_VK_w 0x077 #define NUX_VK_x 0x078 #define NUX_VK_y 0x079 #define NUX_VK_z 0x07a #define NUX_VK_BRACELEFT 0x07b #define NUX_VK_BAR 0x07c #define NUX_VK_BRACERIGHT 0x07d #define NUX_VK_ASCIITILDE 0x07e // Modifiers #define NUX_VK_LSHIFT 0xA0 // Left SHIFT key #define NUX_VK_RSHIFT 0xA1 // Right SHIFT key #define NUX_VK_LCONTROL 0xA2 // Left CONTROL key #define NUX_VK_RCONTROL 0xA3 // Right CONTROL key // To match VK in X11 file. #define NUX_VK_CONTROL NUX_VK_LCONTROL #define NUX_VK_CAPITAL 0x14 // CAPS LOCK key #define NUX_VK_LSUPER 0x5B // Left Windows key(Microsoft Natural Keyboard) #define NUX_VK_RSUPER 0x5C // Right Windows key(Microsoft Natural Keyboard) // To match VK in X11 file. #define NUX_VK_LWIN NUX_VK_LSUPER #define NUX_VK_RWIN NUX_VK_RSUPER #define NUX_VK_LALT 0xA4 // Left MENU key #define NUX_VK_RALT 0xA5 // Right MENU key // Cursor control and motion #define NUX_VK_HOME 0x24 // HOME key #define NUX_VK_LEFT 0x25 // LEFT ARROW key #define NUX_VK_UP 0x26 // UP ARROW key #define NUX_VK_RIGHT 0x27 // RIGHT ARROW key #define NUX_VK_DOWN 0x28 // DOWN ARROW key #define NUX_VK_PAGE_UP 0x21 // PAGE UP key #define NUX_VK_PAGE_DOWN 0x22 // PAGE DOWN key #define NUX_VK_END 0x23 // END key // Functions #define NUX_VK_BACKSPACE 0x08 // BACKSPACE key #define NUX_VK_ESCAPE 0x1B // ESC key #define NUX_VK_TAB 0x09 // TAB key #define NUX_VK_ENTER 0x0D // ENTER key #define NUX_VK_NUMLOCK 0x90 // NUM LOCK key #define NUX_VK_SCROLL 0x91 // SCROLL LOCK key #define NUX_VK_DELETE 0x2E // DEL key #define NUX_VK_INSERT 0x2D // INS key #define NUX_VK_CANCEL 0x03 // Control-break processing #define NUX_VK_CLEAR 0x0C // CLEAR key #define NUX_VK_SHIFT 0x10 // SHIFT key #define NUX_VK_PAUSE 0x13 // PAUSE key // #define NUX_VK_MULTIPLY 0x6A // Multiply key // #define NUX_VK_ADD 0x6B // Add key // #define NUX_VK_SEPARATOR 0x6C // Separator key // #define NUX_VK_SUBTRACT 0x6D // Subtract key // #define NUX_VK_DECIMAL 0x6E // Decimal key // #define NUX_VK_DIVIDE 0x6F // Divide key #define NUX_KP_0 0xFFB0 #define NUX_KP_1 0xFFB1 #define NUX_KP_2 0xFFB2 #define NUX_KP_3 0xFFB3 #define NUX_KP_4 0xFFB4 #define NUX_KP_5 0xFFB5 #define NUX_KP_6 0xFFB6 #define NUX_KP_7 0xFFB7 #define NUX_KP_8 0xFFB8 #define NUX_KP_9 0xFFB9 #define NUX_KP_HOME 0xFF95 #define NUX_KP_LEFT 0xFF96 #define NUX_KP_UP 0xFF97 #define NUX_KP_RIGHT 0xFF98 #define NUX_KP_DOWN 0xFF99 #define NUX_KP_PRIOR 0xFF9A #define NUX_KP_PAGE_UP 0xFF9A #define NUX_KP_NEXT 0xFF9B #define NUX_KP_PAGE_DOWN 0xFF9B #define NUX_KP_END 0xFF9C #define NUX_KP_BEGIN 0xFF9D #define NUX_KP_INSERT 0xFF9E #define NUX_KP_DELETE 0xFF9F #define NUX_KP_EQUAL 0xFFBD /* equals */ #define NUX_KP_MULTIPLY 0xFFAA #define NUX_KP_ADD 0xFFAB #define NUX_KP_SEPARATOR 0xFFAC /* separator, often comma */ #define NUX_KP_SUBTRACT 0xFFAD #define NUX_KP_DECIMAL 0xFFAE #define NUX_KP_DIVIDE 0xFFAF #define NUX_KP_ENTER 0xAAAA // todo #define NUX_VK_LEFT_TAB 0xAAAB // todo #define NUX_VK_F1 0x70 // F1 key #define NUX_VK_F2 0x71 // F2 key #define NUX_VK_F3 0x72 // F3 key #define NUX_VK_F4 0x73 // F4 key #define NUX_VK_F5 0x74 // F5 key #define NUX_VK_F6 0x75 // F6 key #define NUX_VK_F7 0x76 // F7 key #define NUX_VK_F8 0x77 // F8 key #define NUX_VK_F9 0x78 // F9 key #define NUX_VK_F10 0x79 // F10 key #define NUX_VK_F11 0x7A // F11 key #define NUX_VK_F12 0x7B // F12 key #define NUX_VK_F13 0x7C // F13 key #define NUX_VK_F14 0x7D // F14 key #define NUX_VK_F15 0x7E // F15 key #define NUX_VK_F16 0x7F // F16 key #define NUX_VK_F17 0x80 // F17 key #define NUX_VK_F18 0x81 // F18 key #define NUX_VK_F19 0x82 // F19 key #define NUX_VK_F20 0x83 // F20 key #define NUX_VK_F21 0x84 // F21 key #define NUX_VK_F22 0x85 // F22 key #define NUX_VK_F23 0x86 // F23 key #define NUX_VK_F24 0x87 // F24 key #define NUX_MAX_VK 256 } #endif // VIRTUALKEYCODES_H nux-4.0.6+14.04.20140409/NuxGraphics/NuxGraphics.cpp0000644000015301777760000000277612321344237022143 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "FontTexture.h" #include "NuxGraphics.h" #include "GLResourceManager.h" #if defined(NUX_OS_WINDOWS) #include "GraphicsDisplay.h" #elif defined(NUX_OS_LINUX) #include "GraphicsDisplay.h" #endif namespace nux { void NuxGraphicsInitialize() { inlRegisterThreadLocalIndex(1, _TLS_GraphicsDisplay, NULL); #if defined(NUX_OS_WINDOWS) #endif #if defined(NUX_OS_LINUX) && G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION) <= GLIB_VERSION_2_34 // Necessary in order to use gdk g_type_init(); #endif GNuxGraphicsResources.InitializeResources(); } GraphicsDisplay* GetGraphicsDisplay() { return(GraphicsDisplay *) inlGetThreadLocalStorage(_TLS_GraphicsDisplay); } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLPixelBufferOject.cpp0000644000015301777760000000775012321344237024263 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLDeviceObjects.h" #include "IOpenGLPixelBufferOject.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLPixelBufferObject); IOpenGLPixelBufferObject::IOpenGLPixelBufferObject(unsigned int Size, VBO_USAGE Usage, NUX_FILE_LINE_DECL) : IOpenGLResource(RTVERTEXBUFFER, NUX_FILE_LINE_PARAM) , _Length(Size) , _Usage(Usage) , _MemMap(0) , _OffsetToLock(0) , _SizeToLock(0) { CHECKGL(glGenBuffersARB(1, &_OpenGLID)); CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, _OpenGLID)); CHECKGL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, _Length, NULL, Usage)); CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); GRunTimeStats.Register(this); } IOpenGLPixelBufferObject::~IOpenGLPixelBufferObject() { CHECKGL(glDeleteBuffersARB(1, &_OpenGLID)); _OpenGLID = 0; GRunTimeStats.UnRegister(this); } int IOpenGLPixelBufferObject::Lock( unsigned int OffsetToLock, unsigned int SizeToLock, void **ppbData) { nuxAssert(SizeToLock <= _Length); nuxAssert(OffsetToLock + SizeToLock <= _Length); if (SizeToLock == 0) { if (OffsetToLock == 0) { // lock the entire buffer SizeToLock = _Length; } else return OGL_INVALID_CALL; } // If _MemMap, _OffsetToLock and _SizeToLock are not equal to zero, then we have already mapped the buffer // Unlock it before locking again. nuxAssert(_MemMap == 0); nuxAssert(_OffsetToLock == 0); nuxAssert(_SizeToLock == 0); #ifndef NUX_OPENGLES_20 //FIXME: GLES 2.0 doesn't support PBOs, we need to allocate client memory and copy data there // When locking it shouldn't matter if we use GL_PIXEL_UNPACK_BUFFER_ARB or GL_PIXEL_PACK_BUFFER_ARB. // We just want a pointer to the data. CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, _OpenGLID)); // Map the Entire buffer into system memory _MemMap = (BYTE *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE); // we maybe reading or writing to the PBO. CHECKGL_MSG(glMapBufferARB); *ppbData = (void *) (_MemMap + OffsetToLock); _OffsetToLock = OffsetToLock; _SizeToLock = SizeToLock; CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); #endif return OGL_OK; } int IOpenGLPixelBufferObject::Unlock() { #ifndef NUX_OPENGLES_20 CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, _OpenGLID)); //CHECKGL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, _OffsetToLock, _SizeToLock, _MemMap)); CHECKGL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); #endif _MemMap = 0; _OffsetToLock = 0; _SizeToLock = 0; return OGL_OK; } void IOpenGLPixelBufferObject::BindPackPixelBufferObject() { #ifndef NUX_OPENGLES_20 CHECKGL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, _OpenGLID)); #endif } void IOpenGLPixelBufferObject::BindUnpackPixelBufferObject() { #ifndef NUX_OPENGLES_20 CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, _OpenGLID)); #endif } unsigned int IOpenGLPixelBufferObject::GetSize() { return _Length; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLSurface.h0000644000015301777760000001005212321344237022105 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLSURFACE_H #define IOPENGLSURFACE_H namespace nux { class IOpenGLResource; class IOpenGLSurface: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLSurface, IOpenGLResource); public: virtual int RefCount() const; int LockRect( SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect); int UnlockRect(); BitmapFormat GetPixelFormat() const; int GetWidth() const; int GetHeight() const; int GetMipLevel() const; int GetSurfaceTarget() const; int GetDesc(SURFACE_DESC *pDesc); //! Copy the render target into the texture mip level. void CopyRenderTarget(int x, int y, int width, int height); //! Return the mipmap data. /*! Return the mipmap data. @param width Returns the width in pixel of the image data. @param height Returns the height in pixel of the image data. @param stride Returns the row stride of the image data. */ unsigned char* GetSurfaceData(int &width, int &height, int &stride); private: virtual ~IOpenGLSurface(); int InitializeLevel(); // By Default, the surface refers to the face 0 of the texture and to the mip level 0 of that face. // IOpenGLSurface(IOpenGLBaseTexture* DeviceBaseTexture, GLenum OpenGLID) // : _STextureTarget(GL_TEXTURE_2D) // , _SSurfaceTarget(GL_TEXTURE_2D) // , _SMipLevel(0) // , _BaseTexture(DeviceBaseTexture) // , IOpenGLResource(RTSURFACE) // { // // IOpenGLSurface surfaces are created inside a IOpenGLTexture2D, IOpenGLCubeTexture and IOpenGLVolumeTexture. // // They reside within those classes. The reference counting starts once a call to GetSurfaceLevel, // // GetCubeMapSurface or GetVolumeLevel is made to the container object. // _RefCount = 0; // _OpenGLID = OpenGLID; // } IOpenGLSurface(IOpenGLBaseTexture *DeviceBaseTexture , GLenum OpenGLID , GLenum TextureTarget , GLenum SurfaceTarget , int MipLevel , int Slice = 0 /*for volume textures*/ , NUX_FILE_LINE_PROTO); // _STextureTarget may be // GL_TEXTURE_2D // GL_TEXTURE_RECTANGLE_ARB // GL_TEXTURE_CUBE_MAP // GL_TEXTURE_3D GLenum _STextureTarget; // _SSurfaceTarget may be // GL_TEXTURE_2D // GL_TEXTURE_3D // GL_TEXTURE_RECTANGLE_ARB // GL_TEXTURE_CUBE_MAP_POSITIVE_X // GL_TEXTURE_CUBE_MAP_NEGATIVE_X // GL_TEXTURE_CUBE_MAP_POSITIVE_Y // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y // GL_TEXTURE_CUBE_MAP_POSITIVE_Z // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z GLenum _SSurfaceTarget; int _SMipLevel; int _SSlice; // for volume texture SURFACE_LOCKED_RECT _LockedRect; SURFACE_RECT _Rect; int _CompressedDataSize; IOpenGLBaseTexture *_BaseTexture; bool _Initialized; int _AllocatedUnpackBuffer; friend class IOpenGLTexture2D; friend class IOpenGLRectangleTexture; friend class IOpenGLCubeTexture; friend class IOpenGLVolumeTexture; friend class IOpenGLAnimatedTexture; friend class ObjectPtr; }; } #endif // IOPENGLSURFACE_H nux-4.0.6+14.04.20140409/NuxGraphics/RunTimeStats.h0000644000015301777760000000424412321344237021747 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RUNTIMESTATS_H #define RUNTIMESTATS_H namespace nux { class RenderingStats { NUX_DECLARE_GLOBAL_OBJECT(RenderingStats, NuxGraphicsGlobalSingletonInitializer); public: static unsigned int m_NumTex2D; static unsigned int m_GPUSizeTex2D; static unsigned int m_NumTexRectangle; static unsigned int m_GPUSizeTexRectangle; static unsigned int m_NumTexCube; static unsigned int m_GPUSizeTexCube; static unsigned int m_NumTexVolume; static unsigned int m_GPUSizeTexVolume; static unsigned int m_NumTexAnimated; static unsigned int m_GPUSizeTexAnimated; static unsigned int m_NumPBO; static unsigned int m_GPUSizePBO; static unsigned int m_NumFrameBufferObject; static unsigned int m_NumQueryObject; static unsigned int m_NumVertexBuffer; static unsigned int m_GPUSizeVertexBuffer; static unsigned int m_NumIndexBuffer; static unsigned int m_GPUSizeIndexBuffer; static unsigned int m_NumVertexShader; static unsigned int m_NumPixelShader; static unsigned int m_NumShaderProgram; static unsigned int m_TotalGPUSize; void Register(IOpenGLResource *GraphicsObject); void UnRegister(IOpenGLResource *GraphicsObject); std::vector _texture_2d_array; std::vector _texture_rect_array; }; } #define GRunTimeStats NUX_GLOBAL_OBJECT_INSTANCE(nux::RenderingStats) #endif // RUNTIMESTATS_H nux-4.0.6+14.04.20140409/NuxGraphics/GLDeviceFrameBufferObject.h0000644000015301777760000001671412321344237024230 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLDEVICEFRAMEBUFFEROBJECT_H #define GLDEVICEFRAMEBUFFEROBJECT_H /*! FramebufferObject Class. This class encapsulates the FramebufferObject (FBO) OpenGL spec. See the official spec at: http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt for details. A framebuffer object(FBO) is conceptually a structure containing pointers to GPU memory. The memory pointed to is either an OpenGL texture or an OpenGL RenderBuffer. FBOs can be used to render to one or more textures, share depth buffers between multiple sets of color buffers/textures and are a complete replacement for pbuffers. Performance Notes: 1) It is more efficient(but not required) to call Bind() on an FBO before making multiple method calls. For example: FramebufferObject fbo; fbo.Bind(); fbo.AttachTexture(GL_COLOR_ATTACHMENT0_EXT, texId0); fbo.AttachTexture(GL_COLOR_ATTACHMENT1_EXT, texId1); fbo.IsValid(); To provide a complete encapsulation, the following usage pattern works correctly but is less efficient: FramebufferObject fbo; // NOTE : No Bind() call fbo.AttachTexture(GL_COLOR_ATTACHMENT0_EXT, texId0); fbo.AttachTexture(GL_COLOR_ATTACHMENT1_EXT, texId1); fbo.IsValid(); The first usage pattern binds the FBO only once, whereas the second usage binds/unbinds the FBO for each method call. 2) Use FramebufferObject::Disable() sparingly. We have intentionally left out an "Unbind()" method because it is largely unnecessary and encourages rendundant Bind/Unbind coding. Binding an FBO is usually much faster than enabling/disabling a pbuffer, but is still a costly operation. When switching between multiple FBOs and a visible OpenGL framebuffer, the following usage pattern is recommended: FramebufferObject fbo1, fbo2; fbo1.Bind(); ... Render ... // NOTE : No Unbind/Disable here... fbo2.Bind(); ... Render ... // Disable FBO rendering and return to visible window // OpenGL framebuffer. FramebufferObject::Disable(); */ namespace nux { class GLFramebufferObject { public: /// Ctor/Dtor GLFramebufferObject(); virtual ~GLFramebufferObject(); /// Bind this FBO as current render target void Bind(); /// Bind a texture to the "attachment" point of this FBO virtual void AttachTexture( GLenum attachment, GLenum texType, GLuint texId, int mipLevel = 0, int zSlice = 0); /// Bind an array of textures to multiple "attachment" points of this FBO /// - By default, the first 'numTextures' attachments are used, /// starting with GL_COLOR_ATTACHMENT0_EXT virtual void AttachTextures( int numTextures, GLenum texTarget[], GLuint texId[], GLenum attachment[] = NULL, int mipLevel[] = NULL, int zSlice[] = NULL ); /// Bind a render buffer to the "attachment" point of this FBO virtual void AttachRenderBuffer( GLenum attachment, GLuint buffId ); /// Free any resource bound to the "attachment" point of this FBO void Unattach( GLenum attachment ); /// Is this FBO currently a valid render target? /// - Sends output to std::cerr by default but can /// be a user-defined C++ stream /// /// NOTE : This function works correctly in debug build /// mode but always returns "true" if NDEBUG is /// is defined(optimized builds) bool IsValid(); /// BEGIN : Accessors /// Is attached type GL_RENDERBUFFER_EXT or GL_TEXTURE? GLenum GetAttachedType( GLenum attachment ); /// What is the Id of Renderbuffer/texture currently /// attached to "attachement?" GLuint GetAttachedId( GLenum attachment ); /// Which mipmap level is currently attached to "attachement?" GLint GetAttachedMipLevel( GLenum attachment ); /// Which cube face is currently attached to "attachment?" GLint GetAttachedCubeFace( GLenum attachment ); /// Which z-slice is currently attached to "attachment?" GLint GetAttachedZSlice( GLenum attachment ); /// END : Accessors /// BEGIN : Static methods global to all FBOs /// Return number of color attachments permitted static int GetMaxColorAttachments(); /// Disable all FBO rendering and return to traditional, /// windowing-system controlled framebuffer /// NOTE: /// This is NOT an "unbind" for this specific FBO, but rather /// disables all FBO rendering. This call is intentionally "static" /// and named "Disable" instead of "Unbind" for this reason. The /// motivation for this strange semantic is performance. Providing "Unbind" /// would likely lead to a large number of unnecessary FBO enablings/disabling. static void Disable(); /// END : Static methods global to all FBOs private: GLint m_fboId; GLint m_savedFboId; void _GuardedBind(); void _GuardedUnbind(); void _FramebufferTextureND( GLenum attachment, GLenum texType, GLuint texId, int mipLevel, int zSlice ); static GLuint _GenerateFboId(); }; /*! Renderbuffer Class. This class encapsulates the Renderbuffer OpenGL object described in the FramebufferObject(FBO) OpenGL spec. See the official spec at: http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt for complete details. A "Renderbuffer" is a chunk of GPU memory used by FramebufferObjects to represent "traditional" framebuffer memory(depth, stencil, and color buffers). By "traditional," we mean that the memory cannot be bound as a texture. With respect to GPU shaders, Renderbuffer memory is "write-only." Framebuffer operations such as alpha blending, depth test, alpha test, stencil test, etc. read from this memory in post-fragement-shader(ROP) operations. The most common use of Renderbuffers is to create depth and stencil buffers. Note that as of 7/1/05, NVIDIA drivers to do not support stencil Renderbuffers. Usage Notes: 1) "internalFormat" can be any of the following: Valid OpenGL internal formats beginning with: RGB, RGBA, DEPTH_COMPONENT or a stencil buffer format(not currently supported in NVIDIA drivers as of 7/1/05). STENCIL_INDEX1_EXT STENCIL_INDEX4_EXT STENCIL_INDEX8_EXT STENCIL_INDEX16_EXT */ class GLRenderbuffer { public: /// Ctors/Dtors GLRenderbuffer(); GLRenderbuffer(GLenum internalFormat, int width, int height); ~GLRenderbuffer(); void Bind(); void Unbind(); void Set(GLenum internalFormat, int width, int height); GLuint GetId() const; static GLint GetMaxSize(); private: GLuint m_bufId; static GLuint _CreateBufferId(); }; } #endif // GLDEVICEFRAMEBUFFEROBJECT_H nux-4.0.6+14.04.20140409/NuxGraphics/GLSh_DrawFunction.h0000644000015301777760000000325212321344237022623 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLSH_DRAWFUNCTION_H #define GLSH_DRAWFUNCTION_H #include "GLShader.h" #include "GLShaderParameter.h" #include "NuxCore/Color.h" #include "NuxCore/Math/Matrix4.h" #include "GLDeviceObjects.h" namespace nux { class TemplateQuadBuffer; class GLSh_DrawFunction { public: GLSh_DrawFunction(); ~GLSh_DrawFunction(); void SetBackgroundColor(Color const& color); void SetTextureFunction(ObjectPtr device_texture); void Render(int x, int y, int z, int width, int height, int WindowWidth, int WindowHeight); void SetScreenPositionOffset(float x, float y); private: Color background_color_; ObjectPtr sprog; #ifndef NUX_OPENGLES_20 ObjectPtr m_AsmProg; #endif float _ScreenOffsetX, _ScreenOffsetY; ObjectPtr m_device_texture; }; } #endif // GLSH_DRAWFUNCTION_H nux-4.0.6+14.04.20140409/NuxGraphics/Readme.txt0000644000015301777760000001411512321344237021130 0ustar pbusernogroup00000000000000 Using GLSL texture: ------------------- // Get the sampler uniform location. GLint BumpMapLoc = glGetUniformLocationARB(prog, "BumpTex"); // Bind the texture to texture unit i. glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, texture_gl_object_id); // Pass i as an integer by glUniform. glUniform1iARB(BumpMapLoc, i); GLSL Built-in vertex attribute(Deprecated in GLSL 1.30) ------------------------------- Built-in vertex attribute name Incompatible aliased vertex attribute index gl_Vertex 0 gl_Normal 2 gl_Color 3 gl_SecondaryColor 4 gl_FogCoord 5 gl_MultiTexCoord0 8 gl_MultiTexCoord1 9 gl_MultiTexCoord2 10 gl_MultiTexCoord3 11 gl_MultiTexCoord4 12 gl_MultiTexCoord5 13 gl_MultiTexCoord6 14 gl_MultiTexCoord7 15 gl_Vertex: - glVertex{234sifd} - glEnableClientState/glDisableClientState(GL_VERTEX_ARRAY); glVertexPointer(...); gl_Normal: - glNormal{3sifd} - glEnableClientState/glDisableClientState(GL_NORMAL_ARRAY); glNormalPointer(...); gl_Color: - glColor{34sifd} - glEnableClientState/glDisableClientState(GL_COLOR_ARRAY); glColorPointer(...); gl_SecondaryColor(requires GL_EXT_secondary_color) - glSecondaryColor3{bsifd}; - glEnableClientState/glDisableClientState(SECONDARY_COLOR_ARRAY_EXT); glSecondaryColorPointerEXT(...); gl_FogCoord(requires GL_EXT_fog_coord) - glFogCoord{fd}; - glEnableClientState/glDisableClientState(FOG_COORDINATE_ARRAY_EXT); glFogCoordPointerEXT(...); gl_MultiTexCoordXXX - glMultiTexCoord{234fd} - glClientActiveTextureARB(GL_TEXTUREXXX_ARB); glEnableClientState/glDisableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(...); GLSL Vertex Shader Special output variables(write) ---------------------------------------------------- gl_Position (must be written to) gl_PointSize (may be written to) gl_ClipVertex (may be written to) GLSL Vertex Shader Built-in varying(write) GLSL Fragment Shader Built-in varying(read) ------------------------------------------- ------------------------------------------- varying vec4 gl_FrontColor; ----> gl_Color varying vec4 gl_BackColor; ----> gl_Color varying vec4 gl_FrontSecondaryColor; ----> gl_SecondaryColor varying vec4 gl_BackSecondaryColor; ----> gl_SecondaryColor varying vec4 gl_TexCoord[]; ----> gl_TexCoord[] varying float gl_FogFragCoord; ----> gl_FogFragCoord GLSL Fragment Built-in variables -------------------------------- vec4 gl_FragCoord (read only) bool gl_FrontFacing (read only) vec2 gl_PointCoord (read only) GLSL Fragment Shader Special output variables --------------------------------------------- vec4 gl_FragColor (may be written to) vec4 gl_FragData[gl_MaxDrawBuffers] (may be written to) float gl_FragDepth (may be written to) vec2 gl_PointCoord (read only) Binding Semantics for Cg programs Binding Semantics for Varying Input/Output Data ----------------------------------------------- Table 23 summarizes the valid binding semantics for varying input parameters in the vp30 profile. One can also use TANGENT and BINORMAL instead of TEXCOORD6 and TEXCOORD7. These binding semantics map to NV_vertex_program2 input attribute parameters. The two sets act as aliases to each other. Table 23 vp30 Varying Input Binding Semantics Binding Semantics Name Corresponding Data POSITION, ATTR0 Input Vertex, Generic Attribute 0 BLENDWEIGHT, ATTR1 Input vertex weight, Generic Attribute 1 NORMAL, ATTR2 Input normal, Generic Attribute 2 COLOR0, DIFFUSE, ATTR3 Input primary color, Generic Attribute 3 COLOR1, SPECULAR, ATTR4 Input secondary color, Generic Attribute 4 TESSFACTOR, FOGCOORD, ATTR5 Input fog coordinate, Generic Attribute 5 PSIZE, ATTR6 Input point size, Generic Attribute 6 BLENDINDICES, ATTR7 Generic Attribute 7 TEXCOORD0-TEXCOORD7, ATTR8-ATTR15 Input texture coordinates(texcoord0-texcoord7), Generic Attributes 815 TANGENT, ATTR14 Generic Attribute 14 BINORMAL, ATTR15 Generic Attribute 15 Table 24 summarizes the valid binding semantics for varying output parameters in the vp30 profile. These binding semantics map to NV_vertex_program2 output registers. The two sets act as aliases to each other. Table 24 vp30 Varying Output Binding Semantics Binding Semantics Name Corresponding Data POSITION, HPOS Output position PSIZE, PSIZ Output point size FOG, FOGC Output fog coordinate COLOR0, COL0 Output primary color COLOR1, COL1 Output secondary color BCOL0 Output backface primary color BCOL1 Output backface secondary color TEXCOORD0-TEXCOORD7, TEX0-TEX7 Output texture coordinates CLP0-CL5 Output Clip distances Using NVidia CG texture: ------------------------ CGparameter BumpMapParam = cgGetNamedParameter(cgprog, "BumpTexture"); cgGLSetTextureParameter(BumpMapParam, texture_gl_object_id); cgGLEnableTextureParameter(BumpMapParam);nux-4.0.6+14.04.20140409/NuxGraphics/GLSh_DrawFunction.cpp0000644000015301777760000002245412321344237023163 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GLResourceManager.h" #include "GpuDevice.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" #include "GLSh_DrawFunction.h" namespace nux { static std::string VtxShader = " \n\ uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 VertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * AVertex; \n\ }"; static std::string FrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ uniform sampler2D TextureFunction; \n\ uniform vec4 RectPosition; \n\ uniform vec4 RectDimension; \n\ uniform vec4 Color; \n\ void main() \n\ { \n\ float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x; \n\ float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y; \n\ float s = texture2D(TextureFunction, vec2(x, 0.0)).r; \n\ if (y > s) \n\ { \n\ s = 0.0; \n\ gl_FragColor = Color; \n\ discard; \n\ } \n\ else \n\ { \n\ s = 1.0 - (s-y) / s; \n\ gl_FragColor = Color; \n\ } \n\ }"; static std::string AsmVtxShader = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ PARAM mvp[4] = {state.matrix.mvp}; \n\ OUTPUT oPos = result.position; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, mvp[0], iPos; \n\ DP4 oPos.y, mvp[1], iPos; \n\ DP4 oPos.z, mvp[2], iPos; \n\ DP4 oPos.w, mvp[3], iPos; \n\ END"; std::string AsmFrgShader = "!!ARBfp1.0 \n\ PARAM RectPosition = program.local[0]; \n\ PARAM RectDimension = program.local[1]; \n\ PARAM Color = program.local[2]; \n\ TEMP temp0; \n\ TEMP temp1; \n\ TEMP tex0; \n\ SUB temp0.x, fragment.position.x, RectPosition.x; \n\ SUB temp0.y, fragment.position.y, RectPosition.y; \n\ RCP temp1.x, RectDimension.x; \n\ RCP temp1.y, RectDimension.y; \n\ MUL temp1.xy, temp0, temp1; \n\ TEX tex0, temp1, texture[0], 2D; \n\ SUB temp0, tex0.xxxx, temp1.yyyy; \n\ KIL temp0; \n\ MOV result.color, Color; \n\ END"; GLSh_DrawFunction::GLSh_DrawFunction() : _ScreenOffsetX(0) , _ScreenOffsetY(0) { if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath() && (GetGraphicsDisplay()->GetGpuDevice()->GetGPUBrand() != GPU_BRAND_INTEL)) { sprog = GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); sprog->LoadVertexShader(VtxShader.c_str(), NULL); sprog->LoadPixelShader(FrgShader.c_str(), NULL); sprog->Link(); } else { #ifndef NUX_OPENGLES_20 m_AsmProg = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmProg->LoadVertexShader(AsmVtxShader.c_str()); m_AsmProg->LoadPixelShader(AsmFrgShader.c_str()); m_AsmProg->Link(); #endif } } GLSh_DrawFunction::~GLSh_DrawFunction() { sprog = ObjectPtr (0); } void GLSh_DrawFunction::SetBackgroundColor(Color const& color) { background_color_ = color; } void GLSh_DrawFunction::Render(int x, int y, int z, int width, int height, int /* WindowWidth */, int WindowHeight) { float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, }; if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath() && (GetGraphicsDisplay()->GetGpuDevice()->GetGPUBrand() != GPU_BRAND_INTEL)) { CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); sprog->Begin(); int VertexLocation = sprog->GetAttributeLocation("AVertex"); int VPMatrixLocation = sprog->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLModelViewProjectionMatrix(); sprog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); GetGraphicsDisplay()->GetGraphicsEngine()->SetTexture(GL_TEXTURE0, m_device_texture); int ColorBase = sprog->GetUniformLocationARB("Color"); int RectPosition = sprog->GetUniformLocationARB("RectPosition"); int RectDimension = sprog->GetUniformLocationARB("RectDimension"); int TextureFunction = sprog->GetUniformLocationARB("TextureFunction"); if (ColorBase != -1) CHECKGL(glUniform4fARB(ColorBase, background_color_.red, background_color_.green, background_color_.blue, background_color_.alpha)); if (RectPosition != -1) CHECKGL(glUniform4fARB(RectPosition, x + _ScreenOffsetX, WindowHeight - y - height - _ScreenOffsetY, z, 0.0f)); if (RectDimension != -1) CHECKGL(glUniform4fARB(RectDimension, width, height, 0.0f, 0.0f)); if (TextureFunction != -1) CHECKGL(glUniform1iARB(TextureFunction, 0)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 16, VtxBuffer)); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); sprog->End(); } #ifndef NUX_OPENGLES_20 else { CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); m_AsmProg->Begin(); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; GetGraphicsDisplay()->GetGraphicsEngine()->SetTexture(GL_TEXTURE0, m_device_texture); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, x + _ScreenOffsetX, WindowHeight - y - height - _ScreenOffsetY, z, 0.0f)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, width, height, 0.0f, 0.0f)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, background_color_.red, background_color_.green, background_color_.blue, background_color_.alpha)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 16, VtxBuffer)); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); m_AsmProg->End(); } #endif } void GLSh_DrawFunction::SetTextureFunction(ObjectPtr device_texture) { m_device_texture = device_texture; } void GLSh_DrawFunction::SetScreenPositionOffset(float x, float y) { _ScreenOffsetX = x; _ScreenOffsetY = y; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLTexture2D.cpp0000644000015301777760000001155612321344237022710 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLDeviceObjects.h" #include "IOpenGLTexture2D.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLTexture2D); IOpenGLTexture2D::IOpenGLTexture2D(unsigned int Width , unsigned int Height , unsigned int Levels , BitmapFormat PixelFormat, bool Dummy, NUX_FILE_LINE_DECL) : IOpenGLBaseTexture(RTTEXTURE, Width, Height, 1, Levels, PixelFormat, NUX_FILE_LINE_PARAM) { external_id_ = Dummy; if (external_id_ == false) { CHECKGL(glGenTextures(1, &_OpenGLID)); CHECKGL(glBindTexture(GL_TEXTURE_2D, _OpenGLID)); } //_SurfaceArray.Empty(Levels); for (unsigned int l = 0; l < Levels; l++) { IOpenGLSurface *surface = new IOpenGLSurface(this, _OpenGLID, GL_TEXTURE_2D, GL_TEXTURE_2D, l, 0, NUX_FILE_LINE_PARAM); if (Dummy == false) surface->InitializeLevel(); _SurfaceArray.push_back(ObjectPtr (surface)); surface->UnReference(); } SetFiltering(GL_NEAREST, GL_NEAREST); SetWrap(GL_REPEAT, GL_REPEAT, GL_REPEAT); #ifdef NUX_OPENGLES_20 // NPOT textures in GLES2 only support GL_CLAMP_TO_EDGE unless // GL_OES_texture_npot is supported. // TODO: Check for GL_OES_texture_npot if (!_IsPOT) { SetWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); } #endif SetRenderStates(); GRunTimeStats.Register(this); } IOpenGLTexture2D::~IOpenGLTexture2D() { for (int l = 0; l < _NumMipLevel; l++) { _SurfaceArray[l] = ObjectPtr (0);; } _SurfaceArray.clear(); if (external_id_ == false) { CHECKGL(glDeleteTextures(1, &_OpenGLID)); } GRunTimeStats.UnRegister(this); _OpenGLID = 0; } ObjectPtr IOpenGLTexture2D::GetSurfaceLevel(int Level) { if ((Level >= 0) && (Level < _NumMipLevel)) { return _SurfaceArray[Level]; } else { nuxAssertMsg(0, "[IOpenGLTexture2D::GetSurfaceLevel] Invalid surface level"); } return ObjectPtr (0); } void IOpenGLTexture2D::GetSurfaceLevel(int Level, ObjectPtr& surface) { surface = GetSurfaceLevel(Level); } int IOpenGLTexture2D::LockRect( int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect) { nuxAssertMsg(pLockedRect, "[IOpenGLTexture2D::LockRect] Invalid parameter 'pLockedRect'."); nuxAssertMsg(Level >= 0, "[IOpenGLTexture2D::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLTexture2D::LockRect] Invalid mipmap level."); if (Level < _NumMipLevel) { ObjectPtr pSurfaceLevel = _SurfaceArray[Level]; return pSurfaceLevel->LockRect(pLockedRect, pRect); } else { pLockedRect->pBits = 0; pLockedRect->Pitch = 0; return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } int IOpenGLTexture2D::UnlockRect(int Level) { nuxAssertMsg(Level >= 0, "[IOpenGLTexture2D::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLTexture2D::LockRect] Invalid mipmap level."); if (Level < _NumMipLevel) { ObjectPtr pSurfaceLevel = _SurfaceArray[Level]; return pSurfaceLevel->UnlockRect(); } else { return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } unsigned int IOpenGLTexture2D::EnableGammaCorrection(bool /* b */) { nuxAssert(_OpenGLID); return OGL_OK; } unsigned char* IOpenGLTexture2D::GetSurfaceData(int level, int &width, int &height, int &stride) { width = 0; height = 0; stride = 0; if (level < 0) { nuxAssertMsg(level >= 0, "[IOpenGLTexture2D::GetSurfaceData] Invalid mipmap level."); return NULL; } if (level >= _NumMipLevel) { nuxAssertMsg(level < _NumMipLevel, "[IOpenGLTexture2D::GetSurfaceData] Invalid mipmap level."); return NULL; } ObjectPtr pSurfaceLevel = _SurfaceArray[level]; return pSurfaceLevel->GetSurfaceData(width, height, stride); } } nux-4.0.6+14.04.20140409/NuxGraphics/BitmapFormats.cpp0000644000015301777760000002111312321344237022442 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "BitmapFormats.h" namespace nux { PixelFormatInfo GPixelFormats[] = { // Name BlockSizeX BlockSizeY BlockSizeZ BlockBytes NumComponents Platform Internal Memory Flags Supported // Format Format Alignment { "BITFMT_UNKNOWN", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false }, // BITFMT_Unknown { "BITFMT_R8G8B8A8", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_R8G8B8A8 { "BITFMT_B8G8R8A8", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_B8G8R8A8 { "BITFMT_R8G8B8", 1, 1, 1, 3, 3, 0, 0, 0, 1, 0, true }, // BITFMT_R8G8B8 { "BITFMT_R5G6B5", 1, 1, 1, 2, 3, 0, 0, 0, 1, 0, true }, // BITFMT_R5G6B5 { "BITFMT_D24S8", 1, 1, 1, 4, 2, 0, 0, 0, 1, 0, true }, // BITFMT_D24S8 { "BITFMT_A8", 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, true }, // BITFMT_A8 { "BITFMT_DXT1", 4, 4, 1, 8, 3, 0, 0, 0, 1, 0, true }, // BITFMT_DXT1 { "BITFMT_DXT2", 4, 4, 1, 16, 4, 0, 0, 0, 1, 0, true }, // BITFMT_DXT2 { "BITFMT_DXT3", 4, 4, 1, 16, 4, 0, 0, 0, 1, 0, true }, // BITFMT_DXT3 { "BITFMT_DXT4", 4, 4, 1, 16, 4, 0, 0, 0, 1, 0, true }, // BITFMT_DXT4 { "BITFMT_DXT5", 4, 4, 1, 16, 4, 0, 0, 0, 1, 0, true }, // BITFMT_DXT5 #ifndef NUX_OPENGLES_20 { "BITFMT_A8R8G8B8", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_A8R8G8B8 { "BITFMT_A8B8G8R8", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_A8B8G8R8 { "BITFMT_B8G8R8", 1, 1, 1, 3, 3, 0, 0, 0, 1, 0, true }, // BITFMT_B8G8R8 { "BITFMT_RGBA16F", 1, 1, 1, 8, 4, 0, 0, 0, 1, 0, true }, // BITFMT_RGBA16F { "BITFMT_RGB32F", 1, 1, 1, 12, 3, 0, 0, 0, 1, 0, true }, // BITFMT_RGB32F { "BITFMT_RGBA32F", 1, 1, 1, 16, 4, 0, 0, 0, 1, 0, true }, // BITFMT_RGBA32F { "BITFMT_R10G10B10A2", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_R10G10B10A2 { "BITFMT_B10G10R10A2", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_B10G10R10A2 { "BITFMT_A2R10G10B10", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_A2R10G10B10 { "BITFMT_A2B10G10R10", 1, 1, 1, 4, 4, 0, 0, 0, 4, 0, true }, // BITFMT_A2B10G10R10 #endif { "BITFMT_END_GFX_FORMATS", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false }, // BITFMT_END_GFX_FORMATS }; ReadBackPixelFormatInfo GReadBackPixelFormats[] = { // Name BlockBytes NumComponents Format Type Flags Supported { "BITFMT_UNKNOWN", 0, 0, 0, 0, 0, false }, // BITFMT_Unknown { "BITFMT_R8G8B8A8", 4, 4, 0, 0, 0, true }, // BITFMT_R8G8B8A8 { "BITFMT_B8G8R8A8", 4, 4, 0, 0, 0, true }, // BITFMT_B8G8R8A8 { "BITFMT_R8G8B8", 3, 3, 0, 0, 0, true }, // BITFMT_R8G8B8 { "BITFMT_R5G6B5", 2, 3, 0, 0, 0, true }, // BITFMT_R5G6B5 { "BITFMT_D24S8", 4, 2, 0, 0, 0, true }, // BITFMT_D24S8 { "BITFMT_A8", 1, 1, 0, 0, 0, true }, // BITFMT_A8 { "BITFMT_DXT1", 8, 3, 0, 0, 0, true }, // BITFMT_DXT1 { "BITFMT_DXT2", 16, 4, 0, 0, 0, true }, // BITFMT_DXT2 { "BITFMT_DXT3", 16, 4, 0, 0, 0, true }, // BITFMT_DXT3 { "BITFMT_DXT4", 16, 4, 0, 0, 0, true }, // BITFMT_DXT4 { "BITFMT_DXT5", 16, 4, 0, 0, 0, true }, // BITFMT_DXT5 #ifndef NUX_OPENGLES_20 { "BITFMT_A8R8G8B8", 4, 4, 0, 0, 0, true }, // BITFMT_A8R8G8B8 { "BITFMT_A8B8G8R8", 4, 4, 0, 0, 0, true }, // BITFMT_A8B8G8R8 { "BITFMT_B8G8R8", 3, 3, 0, 0, 0, true }, // BITFMT_B8G8R8 { "BITFMT_RGBA16F", 8, 4, 0, 0, 0, true }, // BITFMT_RGBA16F { "BITFMT_RGB32F", 12, 3, 0, 0, 0, true }, // BITFMT_RGBA32F { "BITFMT_RGBA32F", 16, 4, 0, 0, 0, true }, // BITFMT_RGBA32F { "BITFMT_R10G10B10A2", 4, 4, 0, 0, 0, true }, // BITFMT_R10G10B10A2 { "BITFMT_B10G10R10A2", 4, 4, 0, 0, 0, true }, // BITFMT_B10G10R10A2 { "BITFMT_A2B10G10R10", 4, 4, 0, 0, 0, true }, // BITFMT_A2B10G10R10 { "BITFMT_A2R10G10B10", 4, 4, 0, 0, 0, true }, // BITFMT_A2R10G10B10 #endif { "BITFMT_END_GFX_FORMATS", 0, 0, 0, 0, 0, false }, // BITFMT_END_GFX_FORMATS }; } nux-4.0.6+14.04.20140409/NuxGraphics/GraphicsEngine.cpp0000644000015301777760000012446512321344237022576 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "ImageSurface.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "FontTexture.h" #include "FontRenderer.h" #include "GraphicsEngine.h" namespace nux { BlendOperator::BlendOperator() { _enable = true; _src_blend = GL_ONE; _dst_blend = GL_ONE_MINUS_SRC_ALPHA; } BlendOperator::~BlendOperator() { _enable = true; _src_blend = GL_ONE; _dst_blend = GL_ONE_MINUS_SRC_ALPHA; } void BlendOperator::EnableBlending(bool enable) { _enable = enable; } void BlendOperator::SetPorterDuffOperator(PorterDuffOperator op) { switch(op) { case CLEAR: _src_blend = GL_ZERO; _dst_blend = GL_ZERO; break; case SRC: _src_blend = GL_ONE; _dst_blend = GL_ZERO; break; case DST: _src_blend = GL_ZERO; _dst_blend = GL_ONE; break; case SRC_OVER: _src_blend = GL_ONE; _dst_blend = GL_ONE_MINUS_SRC_ALPHA; break; case DST_OVER: _src_blend = GL_ONE_MINUS_DST_ALPHA; _dst_blend = GL_ONE; break; case SRC_IN: _src_blend = GL_DST_ALPHA; _dst_blend = GL_ZERO; break; case DST_IN: _src_blend = GL_ZERO; _dst_blend = GL_SRC_ALPHA; break; case SRC_OUT: _src_blend = GL_ONE_MINUS_DST_ALPHA; _dst_blend = GL_ZERO; break; case DST_OUT: _src_blend = GL_ZERO; _dst_blend = GL_ONE_MINUS_SRC_ALPHA; break; case SRC_ATOP: _src_blend = GL_DST_ALPHA; _dst_blend = GL_ONE_MINUS_SRC_ALPHA; break; case DST_ATOP: _src_blend = GL_ONE_MINUS_DST_ALPHA; _dst_blend = GL_SRC_ALPHA; break; case XOR: _src_blend = GL_ONE_MINUS_DST_ALPHA; _dst_blend = GL_ONE_MINUS_SRC_ALPHA; break; case PLUS: _src_blend = GL_ONE; _dst_blend = GL_ONE; break; default: // Use SRC_OVER _src_blend = GL_ONE; _dst_blend = GL_ONE_MINUS_SRC_ALPHA; break; } } void BlendOperator::SetCustomBlendOperator(unsigned int /* src_blend */, unsigned int /* dst_blend */) { } ROPConfig ROPConfig::Default; ROPConfig::ROPConfig() { Blend = false; SrcBlend = GL_SRC_ALPHA; DstBlend = GL_ONE_MINUS_SRC_ALPHA; } ROPConfig::~ROPConfig() { } FxStructure::FxStructure() { src_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(1, 1, 1, nux::BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); dst_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(1, 1, 1, nux::BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); temp_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(1, 1, 1, nux::BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); } FxStructure::~FxStructure() { } GraphicsEngine::GraphicsEngine(GraphicsDisplay& GlWindow, bool create_rendering_data) : _graphics_display(GlWindow) { IOpenGLShaderProgram::SetShaderTracking(true); _scissor.x = 0; _scissor.y = 0; _clip_offset_x = 0; _clip_offset_y = 0; _font_renderer = 0; _use_glsl_shaders = false; _global_clipping_enabled = false; // Evaluate the features provided by the GPU. EvaluateGpuCaps(); if (UsingGLSLCodePath()) { nuxDebugMsg("The GraphicsEngine is using the GLSL shader code path."); } else { nuxDebugMsg("The GraphicsEngine is using the assenbly shader code path."); } GlWindow.m_GraphicsContext = this; ResetStats(); _projection_matrix.Identity(); _model_view_matrix.Identity(); ResourceCache.InitializeResourceFactories(); m_CurrrentContext.x = 0; m_CurrrentContext.y = 0; m_CurrrentContext.width = _graphics_display.GetWindowWidth(); m_CurrrentContext.height = _graphics_display.GetWindowHeight(); SetViewport(0, 0, _graphics_display.GetWindowWidth(), _graphics_display.GetWindowHeight()); SetScissor(0, 0, _graphics_display.GetWindowWidth(), _graphics_display.GetWindowHeight()); EnableScissoring(true); GpuDevice* gpu_device = _graphics_display.GetGpuDevice(); const GpuInfo& gpu_info = gpu_device->GetGpuInfo(); if (create_rendering_data) { #ifndef NUX_OPENGLES_20 bool opengl_14_support = true; if ((gpu_device->GetOpenGLMajorVersion() == 1) && (gpu_device->GetOpenGLMinorVersion() < 4)) { // OpenGL version is less than OpenGL 1.4 opengl_14_support = false; } if (gpu_info.Support_ARB_Fragment_Shader() && gpu_info.Support_ARB_Vertex_Program() && opengl_14_support) { InitAsmColorShader(); InitAsmTextureShader(); InitAsmPixelateShader(); InitAsmColorModTexMaskAlpha(); InitAsm2TextureAdd(); InitAsm2TextureMod(); InitAsm4TextureAdd(); InitAsmBlendModes(); InitAsmPower(); InitAsmAlphaReplicate(); InitAsmSeparableGaussFilter(); InitAsmColorMatrixFilter(); //InitAsm2TextureDepRead(); // NUXTODO: fix the shader } #endif if ((gpu_info.Support_ARB_Vertex_Program() && gpu_info.Support_ARB_Fragment_Program()) || (gpu_info.Support_ARB_Vertex_Shader() && gpu_info.Support_ARB_Fragment_Shader())) { _font_renderer = new FontRenderer(*this); } if (gpu_info.Support_EXT_Framebuffer_Object()) _offscreen_fbo = gpu_device->CreateFrameBufferObject(); _offscreen_color_rt0 = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); _offscreen_color_rt1 = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); _offscreen_color_rt2 = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); _offscreen_color_rt3 = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); _offscreen_depth_rt0 = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); _offscreen_depth_rt1 = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } } GraphicsEngine::~GraphicsEngine() { _offscreen_color_rt0.Release(); _offscreen_color_rt1.Release(); _offscreen_depth_rt0.Release(); _offscreen_depth_rt1.Release(); _offscreen_fbo.Release(); ResourceCache.Flush(); NUX_SAFE_DELETE(_font_renderer); } void GraphicsEngine::EvaluateGpuCaps() { #ifdef NUX_OS_WINDOWS if (_graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Vertex_Shader() && _graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Fragment_Shader()) #else if (_graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Vertex_Shader() && _graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Fragment_Shader() && (_graphics_display.GetGpuDevice()->GetOpenGLMajorVersion() >= 2)) #endif { std::string renderer_string = ANSI_TO_TCHAR(NUX_REINTERPRET_CAST(const char* , glGetString(GL_RENDERER))); CHECKGL_MSG(glGetString(GL_RENDERER)); // Exclude Geforce FX from using GLSL if (renderer_string.find("GeForce FX", 0) != tstring::npos) { _use_glsl_shaders = false; return; } // Exclude Geforce FX Go from using GLSL: this case is not needed since it is detected by the one above. if (renderer_string.find("GeForce FX Go", 0) != tstring::npos) { _use_glsl_shaders = false; return; } _use_glsl_shaders = true; } else { _use_glsl_shaders = false; } } bool GraphicsEngine::UsingGLSLCodePath() { return _use_glsl_shaders; } bool GraphicsEngine::UsingARBProgramCodePath() { return !_use_glsl_shaders; } ObjectPtr GraphicsEngine::GetFont() { #if defined(NUX_OS_WINDOWS) if (_normal_font.IsNull()) { FontTexture* fnt = new FontTexture(GNuxGraphicsResources.FindResourceLocation("Fonts/Tahoma_size_8.txt", true).c_str(), NUX_TRACKER_LOCATION); _normal_font = ObjectPtr (fnt); fnt->UnReference(); } #else if (_normal_font.IsNull()) { FontTexture* fnt = new FontTexture(GNuxGraphicsResources.FindResourceLocation("Fonts/nuxfont_size_8.txt", true).c_str(), NUX_TRACKER_LOCATION); _normal_font = ObjectPtr (fnt); fnt->UnReference(); } #endif return _normal_font; } ObjectPtr GraphicsEngine::GetBoldFont() { #if defined(NUX_OS_WINDOWS) if (_bold_font.IsNull()) { FontTexture* fnt = new FontTexture(GNuxGraphicsResources.FindResourceLocation("Fonts/Tahoma_size_8_bold.txt", true).c_str(), NUX_TRACKER_LOCATION); _bold_font = ObjectPtr (fnt); fnt->UnReference(); } #else if (_bold_font.IsNull()) { FontTexture* fnt = new FontTexture(GNuxGraphicsResources.FindResourceLocation("Fonts/nuxfont_size_8_bold.txt", true).c_str(), NUX_TRACKER_LOCATION); _bold_font = ObjectPtr (fnt); fnt->UnReference(); } #endif return _bold_font; } void GraphicsEngine::SetContext(int x, int y, int width, int height) { m_CurrrentContext.x = x; m_CurrrentContext.y = y; if (width <= 0 || height <= 0) { //nuxAssertMsg(0, "[GraphicsEngine::SetContext] Incorrect context size."); if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { m_CurrrentContext.width = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetWidth(); m_CurrrentContext.height = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetHeight(); } else { m_CurrrentContext.width = GetWindowWidth(); m_CurrrentContext.height = GetWindowHeight(); } } else { m_CurrrentContext.width = width; m_CurrrentContext.height = height; } } void GraphicsEngine::GetContextSize(int& w, int& h) const { w = m_CurrrentContext.width; h = m_CurrrentContext.height; } int GraphicsEngine::GetContextWidth() const { return m_CurrrentContext.width; } int GraphicsEngine::GetContextHeight() const { return m_CurrrentContext.height; } int GraphicsEngine::GetContextX() const { return m_CurrrentContext.x; } int GraphicsEngine::GetContextY() const { return m_CurrrentContext.y; } void GraphicsEngine::GetWindowSize(int& w, int& h) const { _graphics_display.GetWindowSize(w, h); } int GraphicsEngine::GetWindowWidth() const { return _graphics_display.GetWindowWidth(); } int GraphicsEngine::GetWindowHeight() const { return _graphics_display.GetWindowHeight(); } int GraphicsEngine::RenderColorText(ObjectPtr Font, int x, int y, std::string const& Str, const Color& TextColor, bool WriteAlphaChannel, int NumCharacter) { if (_font_renderer) return _font_renderer->RenderColorText(Font, x, y, Str, TextColor, WriteAlphaChannel, NumCharacter); return 0; } int GraphicsEngine::RenderColorTextLineStatic(ObjectPtr Font, const PageBBox& pageSize, std::string const& Str, const Color& TextColor, bool WriteAlphaChannel, TextAlignment alignment) { if (_font_renderer) return _font_renderer->RenderColorTextLineStatic(Font, pageSize, Str, TextColor, WriteAlphaChannel, alignment); return 0; } int GraphicsEngine::RenderColorTextLineEdit(ObjectPtr Font, const PageBBox& pageSize, std::string const& Str, const Color& TextColor, bool WriteAlphaChannel, const Color& SelectedTextColor, const Color& SelectedTextBackgroundColor, const Color& TextBlinkColor, const Color& CursorColor, bool ShowCursor, unsigned int CursorPosition, int offset, int selection_start, int selection_end) { if (_font_renderer) return _font_renderer->RenderColorTextLineEdit(Font, pageSize, Str, TextColor, WriteAlphaChannel, SelectedTextColor, SelectedTextBackgroundColor, TextBlinkColor, CursorColor, ShowCursor, CursorPosition, offset, selection_start, selection_end); return 0; } void GraphicsEngine::SetTexture(int TextureUnit, BaseTexture* Texture) { nuxAssertMsg(Texture != 0, "[GraphicsEngine::SetTexture] Texture is NULL."); if ((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31)) return; ObjectPtr CachedTexture = ResourceCache.GetCachedResource(Texture); SetTexture(TextureUnit, CachedTexture->m_Texture); } void GraphicsEngine::SetTexture(int TextureUnit, ObjectPtr< IOpenGLBaseTexture > DeviceTexture) { NUX_RETURN_IF_FALSE(DeviceTexture.IsValid()); CHECKGL(glActiveTextureARB(TextureUnit)); DeviceTexture->BindTextureToUnit(TextureUnit); } void GraphicsEngine::EnableTextureMode(int TextureUnit, int TextureMode) { if ((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31)) return; CHECKGL(glActiveTextureARB(TextureUnit)); CHECKGL(glEnable(TextureMode)); } void GraphicsEngine::DisableTextureMode(int TextureUnit, int TextureMode) { if ((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31)) return; CHECKGL(glActiveTextureARB(TextureUnit)); CHECKGL(glDisable(TextureMode)); CHECKGL(glBindTexture(TextureMode, 0)); } void GraphicsEngine::DisableAllTextureMode(int TextureUnit) { if ((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31)) return; _graphics_display.GetGpuDevice()->InvalidateTextureUnit(TextureUnit); } ////////////////////// // DRAW CLIPPING // ////////////////////// void GraphicsEngine::PushClippingRectangle(Rect const& rect) { if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { // There is an active framebuffer set. Push the clipping rectangles to that fbo clipping stack. _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->PushClippingRegion(rect); return; } Rect r0 = ModelViewXFormRect(rect); Rect r1; unsigned int stacksize = (unsigned int) ClippingRect.size(); int x0, y0, x1, y1; int window_width, window_height; window_width = _viewport.width; window_height = _viewport.height; if (stacksize == 0) { r1.Set(0, 0, window_width, window_height); } else { r1 = ClippingRect[stacksize-1]; } // http://www.codecomments.com/archive263-2004-12-350347.html // If your rectangles are given in 2D as Top,Left,Bottom,Right coordinates, as typical for GUI programming, then it's simply: // intersect.Left = max(a.Left, b.Left); // intersect.Top = max(a.Top, b.Top); // intersect.Right = min(a.Right, b.Right ); // intersect.Bottom = min(a.Bottom, b.Bottom); // And the intersection is empty unless intersect.Right > intersect.Left && intersect.Bottom > intersect.Top x0 = Max(r0.x, r1.x); y0 = Max(r0.y, r1.y); x1 = Min(r0.x + r0.width, r1.x + r1.width); y1 = Min(r0.y + r0.height, r1.y + r1.height); if ((x1 > x0) && (y1 > y0)) { _clipping_rect.Set(x0, y0, x1 - x0, y1 - y0); ClippingRect.push_back(Rect(x0, y0, x1 - x0, y1 - y0)); EnableScissoring(true); SetOpenGLClippingRectangle(x0, window_height - y0 - (y1 - y0), x1 - x0, y1 - y0); } else { _clipping_rect.Set(0, 0, 0, 0); ClippingRect.push_back(_clipping_rect); EnableScissoring(true); SetOpenGLClippingRectangle(0, 0, 0, 0); } } void GraphicsEngine::PopClippingRectangle() { if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->PopClippingRegion(); return; } ClippingRect.pop_back(); unsigned int stacksize = (unsigned int) ClippingRect.size(); if (stacksize == 0) { _clipping_rect.Set(0, 0, _viewport.width, _viewport.height); EnableScissoring(true); SetOpenGLClippingRectangle(0, 0, _viewport.width, _viewport.height); } else { _clipping_rect = ClippingRect [stacksize-1]; Rect B = _clipping_rect; EnableScissoring(true); SetOpenGLClippingRectangle(B.x, _viewport.height - B.y - B.GetHeight(), B.GetWidth(), B.GetHeight()); } } void GraphicsEngine::ApplyClippingRectangle() { if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->ApplyClippingRegion(); return; } unsigned int stacksize = (unsigned int) ClippingRect.size(); if (stacksize == 0) { _clipping_rect.Set(0, 0, _viewport.width, _viewport.height); EnableScissoring(true); SetOpenGLClippingRectangle(0, 0, _viewport.width, _viewport.height); } else { _clipping_rect = ClippingRect[stacksize-1]; Rect B = _clipping_rect; EnableScissoring(true); SetOpenGLClippingRectangle(B.x, _viewport.height - B.y - B.GetHeight(), B.GetWidth(), B.GetHeight()); } } void GraphicsEngine::EmptyClippingRegion() { if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->EmptyClippingRegion(); return; } ClippingRect.clear(); { _clipping_rect.Set(0, 0, _viewport.width, _viewport.height); EnableScissoring(true); SetOpenGLClippingRectangle(0, 0, _viewport.width, _viewport.height); } } void GraphicsEngine::SetGlobalClippingRectangle(Rect const& rect) { _global_clipping_enabled = true; _global_clipping_rect.Set(rect.x, _viewport.height - rect.y - rect.height, rect.width, rect.height); ApplyClippingRectangle(); } void GraphicsEngine::DisableGlobalClippingRectangle() { _global_clipping_enabled = false; _global_clipping_rect.Set(0, 0, _viewport.width, _viewport.height); ApplyClippingRectangle(); } Rect GraphicsEngine::GetClippingRegion() const { if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { Rect r = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetClippingRegion(); return r; } return _clipping_rect; // unsigned int stacksize = (unsigned int) ClippingRect.size(); // // if (stacksize == 0) // { // return Rect(0, 0, _viewport.width, _viewport.height); // } // else // { // Rect r = ClippingRect[stacksize-1]; // return r; // } } void GraphicsEngine::SetClippingRectangle(const Rect& rect) { _clipping_rect = rect; SetOpenGLClippingRectangle(rect.x, _viewport.height - rect.y - rect.height, rect.width, rect.height); } void GraphicsEngine::SetOpenGLClippingRectangle(int x, int y, unsigned int width, unsigned int height) { if (!_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { if (_global_clipping_enabled) { Rect intersection = Rect(x, y, width, height).Intersect(_global_clipping_rect); SetScissor(intersection.x, intersection.y, intersection.width, intersection.height); } else { SetScissor(x, y, width, height); } } else { SetScissor(x, y, width, height); } } int GraphicsEngine::GetNumberOfClippingRegions() const { if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid()) { int n = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetNumberOfClippingRegions(); return n; } return(int) ClippingRect.size(); } void GraphicsEngine::AddClipOffset(int x, int y) { PushClipOffset(x, y); } void GraphicsEngine::PushClipOffset(int x, int y) { _clip_offset_stack.push_back(Point(x, y)); _clip_offset_x = 0; _clip_offset_y = 0; std::list::iterator it; for (it = _clip_offset_stack.begin(); it != _clip_offset_stack.end(); ++it) { _clip_offset_x += (*it).x; _clip_offset_y += (*it).y; } } void GraphicsEngine::PopClipOffset() { if (_clip_offset_stack.empty()) { _clip_offset_x = 0; _clip_offset_y = 0; } _clip_offset_stack.pop_back(); _clip_offset_x = 0; _clip_offset_y = 0; std::list::iterator it; for (it = _clip_offset_stack.begin(); it != _clip_offset_stack.end(); ++it) { _clip_offset_x += (*it).x; _clip_offset_y += (*it).y; } } /////////////////// // DRAW TEXTURE // /////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rendering calls // // From "OpenGL Programming Guide.pdf" // // If exact two-dimensional rasterization is desired, you must carefully specify both the orthographic // projection and the vertices of primitives that are to be rasterized. The orthographic projection // should be specified with integer coordinates, as shown in the following example: // gluOrtho2D(0, width, 0, height); // where width and height are the dimensions of the viewport. Given this projection matrix, polygon // vertices and pixel image positions should be placed at integer coordinates to rasterize predictably. // For example, glRecti(0, 0, 1, 1) reliably fills the lower left pixel of the viewport, and glRasterPos2i(0, // 0) reliably positions an unzoomed image at the lower left of the viewport. Point vertices, line // vertices, and bitmap positions should be placed at half-integer locations, however. For example, a // line drawn from(x1, 0.5) to(x2, 0.5) will be reliably rendered along the bottom row of pixels int the // viewport, and a point drawn at(0.5, 0.5) will reliably fill the same pixel as glRecti(0, 0, 1, 1). // An optimum compromise that allows all primitives to be specified at integer positions, while still // ensuring predictable rasterization, is to translate x and y by 0.375, as shown in the following code // fragment. Such a translation keeps polygon and pixel image edges safely away from the centers of // pixels, while moving line vertices close enough to the pixel centers. // glViewport(0, 0, width, height); // glMatrixMode(GL_PROJECTION); // glLoadIdentity(); // gluOrtho2D(0, width, 0, height); // glMatrixMode(GL_MODELVIEW); // glLoadIdentity(); // glTranslatef(0.375, 0.375, 0.0); /* render all primitives at integer positions */ const float RASTERIZATION_OFFSET = 0.0f; void GraphicsEngine::Push2DWindow(int w, int h) { #ifndef NUX_OPENGLES_20 { _model_view_matrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0); Matrix4 temp; std::list::iterator it; for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); ++it) { temp = _model_view_matrix; _model_view_matrix = temp * (*it); } } { _projection_matrix.Orthographic(0, w, h, 0, -1.0f, 1.0f); } #else // ModelView { _model_view_matrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0); Matrix4 temp; std::list::iterator it; for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++) { temp = _model_view_matrix; _model_view_matrix = temp * (*it); } } // Projection { _projection_matrix.Orthographic(0, w, h, 0, -1.0f, 1.0f); } #endif } void GraphicsEngine::Pop2DWindow() { #ifndef NUX_OPENGLES_20 CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glFrustum( -1.0, // left 1.0, // right -1.0, // bottom 1.0, // top 0.1, // near, 2000.0 // far )); #endif } void GraphicsEngine::Push2DModelViewMatrix(Matrix4 mat) { m_2DModelViewMatricesStack.push_back(mat); { _model_view_matrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0); Matrix4 temp; std::list::iterator it; for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); ++it) { temp = _model_view_matrix; _model_view_matrix = (*it) * temp; } } } Matrix4 GraphicsEngine::Pop2DModelViewMatrix() { Matrix4 Mat; Mat.Zero(); if (m_2DModelViewMatricesStack.empty()) return Mat; std::list::iterator it; it = m_2DModelViewMatricesStack.end(); --it; Mat = (*it); m_2DModelViewMatricesStack.pop_back(); { _model_view_matrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0); Matrix4 temp; std::list::iterator it; for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); ++it) { temp = _model_view_matrix; _model_view_matrix = temp * (*it); } } return Mat; } void GraphicsEngine::Clear2DModelViewMatrix() { m_2DModelViewMatricesStack.clear(); { _model_view_matrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0); Matrix4 temp; std::list::iterator it; for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); ++it) { temp = _model_view_matrix; _model_view_matrix = temp * (*it); } } } void GraphicsEngine::PushIdentityModelViewMatrix() { PushModelViewMatrix(Matrix4::IDENTITY()); } void GraphicsEngine::PushModelViewMatrix(const Matrix4& matrix) { if (_model_view_stack.empty()) _model_view_matrix = matrix; else _model_view_matrix = matrix * _model_view_stack.back(); _model_view_stack.push_back(_model_view_matrix); } void GraphicsEngine::Push2DTranslationModelViewMatrix(float tx, float ty, float tz) { Matrix4 temp; temp.Translate(tx, ty, tz); PushModelViewMatrix(temp); } bool GraphicsEngine::PopModelViewMatrix() { if (!_model_view_stack.empty()) _model_view_stack.pop_back(); if (_model_view_stack.empty()) { _model_view_matrix = Matrix4::IDENTITY(); return false; } _model_view_matrix = _model_view_stack.back(); return true; } void GraphicsEngine::ResetModelViewMatrixStack() { _model_view_stack.clear(); _model_view_matrix = Matrix4::IDENTITY(); } void GraphicsEngine::SetModelViewMatrix(const Matrix4& matrix) { _model_view_matrix = matrix; } void GraphicsEngine::ApplyModelViewMatrix() { if (_model_view_stack.empty()) _model_view_matrix = Matrix4::IDENTITY(); else _model_view_matrix = _model_view_stack.back(); } Rect GraphicsEngine::ModelViewXFormRect(const Rect& rect) { Vector4 v0(rect.x, rect.y, 0.0f, 1.0f); Vector4 v1 = _model_view_matrix * v0; Rect r(v1.x, v1.y, rect.width, rect.height); return r; } int GraphicsEngine::ModelViewStackDepth() { return(int)_model_view_stack.size(); } void GraphicsEngine::PushPorterDuffBlend(const PorterDuffOperator& porter_duff_op) { BlendOperator blend_op; blend_op.SetPorterDuffOperator(porter_duff_op); _blend_stack.push_front(blend_op); GetRenderStates().SetBlend(blend_op._enable, blend_op._src_blend, blend_op._dst_blend); } void GraphicsEngine::PushDisableBlend() { BlendOperator blend_op; blend_op.EnableBlending(false); _blend_stack.push_front(blend_op); GetRenderStates().SetBlend(blend_op._enable); } bool GraphicsEngine::PopBlend() { if (_blend_stack.empty()) { GetRenderStates().SetBlend(false, GL_ONE, GL_ZERO); return false; } _blend_stack.pop_front(); BlendOperator blend_op = (*_blend_stack.begin()); GetRenderStates().SetBlend(blend_op._enable, blend_op._src_blend, blend_op._dst_blend); return true; } int GraphicsEngine::BlendStackDepth() { return(int) _blend_stack.size(); } Matrix4 GraphicsEngine::GetProjectionMatrix() { return _projection_matrix; } Matrix4 GraphicsEngine::GetOpenGLProjectionMatrix() { Matrix4 mat = GetProjectionMatrix(); mat.Transpose(); return mat; } void GraphicsEngine::SetProjectionMatrix(const Matrix4& matrix) { _projection_matrix = matrix; } void GraphicsEngine::SetOrthographicProjectionMatrix(int viewport_width, int viewport_height) { _projection_matrix.Orthographic(0, viewport_width, viewport_height, 0, -1.0f, 1.0f); } void GraphicsEngine::SetOrthographicProjectionMatrix(int left, int right, int bottom, int top) { _projection_matrix.Orthographic(left, right, bottom, top, -1.0f, 1.0f); } void GraphicsEngine::ResetProjectionMatrix() { _projection_matrix = Matrix4::IDENTITY(); } Matrix4 GraphicsEngine::GetModelViewMatrix() { return _model_view_matrix; } Matrix4 GraphicsEngine::GetOpenGLModelViewMatrix() { Matrix4 mat = _model_view_matrix; mat.Transpose(); return mat; } Matrix4 GraphicsEngine::GetModelViewProjectionMatrix() { return _projection_matrix * _model_view_matrix; } Matrix4 GraphicsEngine::GetOpenGLModelViewProjectionMatrix() { // This matrix is the transposed version of GetModelViewProjectionMatrix. Matrix4 mat = _projection_matrix * _model_view_matrix; mat.Transpose(); return mat; } void GraphicsEngine::SetViewport(int origin_x, int origin_y, int w, int h) { nuxAssert(w >= 0); nuxAssert(h >= 0); _viewport.x = origin_x; _viewport.y = origin_y; _viewport.width = w; _viewport.height = h; if (_viewport.width < 0) { nuxAssertMsg(0, "[GraphicsEngine::SetViewport] Incorrect context size."); _viewport.width = 1; } if (_viewport.height < 0) { nuxAssertMsg(0, "[GraphicsEngine::SetViewport] Incorrect context size."); _viewport.height = 1; } CHECKGL(glViewport(origin_x, origin_y, _viewport.width, _viewport.height)); } // Rect GraphicsEngine::GetViewportRect() // { // return Rect(_viewport.x, _viewport.y, _viewport.width, _viewport.height); // } Rect GraphicsEngine::GetViewportRect() const { return _viewport; } int GraphicsEngine::GetViewportWidth() const { return _viewport.width; } int GraphicsEngine::GetViewportHeight() const { return _viewport.height; } int GraphicsEngine::GetViewportX() const { return _viewport.x; } int GraphicsEngine::GetViewportY() const { return _viewport.y; } void GraphicsEngine::GetViewportSize(int& viewport_width, int& viewport_height) const { viewport_width = _viewport.width; viewport_height = _viewport.height; } void GraphicsEngine::SetScissorOffset(int /* x */, int /* y */) { nuxAssertMsg(0, "[GraphicsEngine::SetScissorOffset] SetScissorOffset is deprecated."); // m_ScissorXOffset = x; // m_ScissorYOffset = y; } void GraphicsEngine::SetScissor(int x, int y, int w, int h) { nuxAssert(w >= 0); nuxAssert(h >= 0); NUX_RETURN_IF_FALSE(w >= 0); NUX_RETURN_IF_FALSE(h >= 0); _scissor.x = x; _scissor.y = y; _scissor.width = w; _scissor.height = h; if (_scissor.x < 0) { _scissor.width += _scissor.x; _scissor.x = 0; } if (_scissor.y < 0) { _scissor.height += _scissor.y; _scissor.y = 0; } if (_scissor.width <= 0) { // jaytaoko: This is a hack for what looks like a bug(#726033) in the radeon opensource driver // on R300/400/500. Rather than passing a null region to glScissor, we give the clip area a 1 pixel width. //_scissor.width = 1; CHECKGL(glScissor(0, 0, 1, 1)); return; } if (_scissor.height <= 0) { // jaytaoko: This is a hack for what looks like a bug(#726033) in the radeon opensource driver // on R300/400/500. Rather than passing a null region to glScissor, we give the clip area a 1 pixel height. //_scissor.height = 1; CHECKGL(glScissor(0, 0, 1, 1)); return; } CHECKGL(glScissor(_scissor.x, _scissor.y, _scissor.width, _scissor.height)); } Rect const& GraphicsEngine::GetScissorRect() const { return _scissor; } void GraphicsEngine::EnableScissoring(bool b) { GetRenderStates().EnableScissor(b); } ///////////////////////////////////////// // 2D Area Clear Color Depth Stencil // ///////////////////////////////////////// void GraphicsEngine::ClearAreaColorDepthStencil(int x, int y, int width, int height, Color clear_color, float /* cleardepth */, int clearstencil) { // enable stencil buffer CHECKGL(glEnable(GL_STENCIL_TEST)); // write a one to the stencil buffer everywhere we are about to draw CHECKGL(glStencilFunc(GL_ALWAYS, clearstencil, 0xFFFFFFFF)); // this is to always pass a one to the stencil buffer where we draw CHECKGL(glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE)); //CHECKGL(glEnable(GL_DEPTH_TEST)); //CHECKGL(glDepthFunc(GL_ALWAYS)); QRP_Color(x, y, width, height, clear_color); //CHECKGL(glDepthFunc(GL_LESS)); //CHECKGL(glDisable(GL_DEPTH_TEST)); CHECKGL(glDisable(GL_STENCIL_TEST)); } void GraphicsEngine::ClearAreaColor(int x, int y, int width, int height, Color clear_color) { QRP_Color(x, y, width, height, clear_color); } void GraphicsEngine::ClearAreaDepthStencil(int x, int y, int width, int height, float /* cleardepth */, int clearstencil) { // enable stencil buffer CHECKGL(glEnable(GL_STENCIL_TEST)); // write a one to the stencil buffer everywhere we are about to draw CHECKGL(glStencilFunc(GL_ALWAYS, clearstencil, 0xFFFFFFFF)); // this is to always pass a one to the stencil buffer where we draw CHECKGL(glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE)); CHECKGL(glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)); //CHECKGL(glEnable(GL_DEPTH_TEST)); //CHECKGL(glDepthFunc(GL_ALWAYS)); QRP_Color(x, y, width, height, color::Black); //CHECKGL(glDepthFunc(GL_LESS)); //CHECKGL(glDisable(GL_DEPTH_TEST)); CHECKGL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)); CHECKGL(glDisable(GL_STENCIL_TEST)); } //Statistics void GraphicsEngine::ResetStats() { m_quad_stats = 0; m_quad_tex_stats = 0; m_triangle_stats = 0; m_triangle_tex_stats = 0; m_line_stats = 0; } ObjectPtr< CachedResourceData > GraphicsEngine::CacheResource(ResourceData* Resource) { return ResourceCache.GetCachedResource(Resource); } bool GraphicsEngine::FlushCachedResourceData(ResourceData* Resource) { if (!IsResourceCached(Resource)) return false; ResourceCache.FlushResourceId(Resource->GetResourceIndex()); return true; } void GraphicsEngine::UpdateResource(ResourceData* Resource) { ObjectPtr GLResource = ResourceCache.FindCachedResourceById(Resource->GetResourceIndex()); //(CachedResourceData*)(*(ResourceCache.ResourceMap.find(Resource->ResourceIndex))).second; if (GLResource.IsValid()) { // Iterate through all resource updater types(list is sorted by subclass depth). for (unsigned int i = 0; i < ResourceCache.GetResourceUpdaters().size(); ++i) { NResourceUpdater* ResourceUpdater = ResourceCache.GetResourceUpdaters() [i]; nuxAssert(ResourceUpdater); // Check if the updater is valid for updating the resource. if (ResourceUpdater->UpdatesThisResource(Resource)) { ResourceUpdater->UpdateResource(GLResource, Resource); break; } } } } bool GraphicsEngine::IsResourceCached(ResourceData* Resource) { return ResourceCache.IsCachedResource(Resource); } void GraphicsEngine::SetFrameBufferHelper( ObjectPtr& fbo, ObjectPtr& colorbuffer, ObjectPtr& depthbuffer, int width, int height) { if ((colorbuffer.IsValid() == false) || (colorbuffer->GetWidth() != width) || (colorbuffer->GetHeight() != height)) { colorbuffer = _graphics_display.GetGpuDevice()->CreateTexture(width, height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); } bool use_depth_buffer = _graphics_display.GetGpuDevice()->GetGpuInfo().Support_Depth_Buffer(); if (use_depth_buffer && depthbuffer.IsValid() && ((depthbuffer->GetWidth() != width) || (depthbuffer->GetHeight() != height))) { // Generate a new depth texture only if a valid one was passed to this function. depthbuffer = _graphics_display.GetGpuDevice()->CreateTexture(width, height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION); } fbo->FormatFrameBufferObject(width, height, BITFMT_R8G8B8A8); fbo->SetRenderTarget(0, colorbuffer->GetSurfaceLevel(0)); if (use_depth_buffer && depthbuffer.IsValid()) fbo->SetDepthSurface(depthbuffer->GetSurfaceLevel(0)); else fbo->SetDepthSurface(ObjectPtr(NULL)); fbo->Activate(); fbo->EmptyClippingRegion(); SetContext(0, 0, width, height); SetViewport(0, 0, width, height); Push2DWindow(width, height); } /*! Description - This function calculates position offsets for our gaussian weight values to utilise the GPU bilinear sampling * which gets neighbouring pixel's data in just one sample. This serves to halve the loop for both vertical and * horizontal blur shaders. * Params - First two parameters are the weight and weight offsets which are passed as uniforms to our shader. * our sigma dictates how strong our blur will be. * Return - We return our loop count which is a #define in our vertical and horizontal shaders. */ int GraphicsEngine::LinearSampleGaussianWeights(std::vector& weights, std::vector& offsets, float sigma) { //Calculate our support which is used as our loop count. int support = int(sigma * 3.0f); weights.push_back(exp(-(0*0)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma)); float total = weights.back(); //Our first weight has an offset of 0. offsets.push_back(0); for (int i = 1; i <= support; i++) { float w1 = exp(-(i*i)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma); float w2 = exp(-((i+1)*(i+1))/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma); weights.push_back(w1 + w2); total += 2.0f * weights[i]; //Calculate our offset to utilise our GPU's bilinear sampling capability. By sampling in between texel we get the data of //neighbouring pixels with only one sample. offsets.push_back((i * w1 + (i + 1) * w2) / weights[i]); } //Normalise our weights. for (int i = 0; i < support; i++) { weights[i] /= total; } return support; } void GraphicsEngine::GaussianWeights(float **weights, float sigma, unsigned int num_tap) { *weights = new float[num_tap]; float sum = 0.0f; unsigned int i = 0; unsigned int half = (num_tap-1)/2; (*weights)[half] = (1.0f/(sqrt(2.0f*3.14159265358f)*sigma)) * exp(-0.0f/(2.0f*sigma*sigma)); sum += (*weights)[half]; for (i = 0; i < half; i++) { float X = (i + 1)*(i + 1); (*weights)[half - i - 1] = (*weights)[half + i + 1] = (1.0f/(sqrt(2.0f*3.14159265358f)*sigma)) * exp(-X/(2.0f*sigma*sigma)); sum += 2.0f * ((*weights)[half - i - 1]); } /* normalization */ for (i = 0; i < num_tap; i++) { (*weights)[i] = (*weights)[i] / sum; } } ObjectPtr GraphicsEngine::CreateTextureFromBackBuffer(int x, int y, int width, int height) { ObjectPtr fbo = _graphics_display.GetGpuDevice()->GetCurrentFrameBufferObject(); int X, Y, W, H; if (fbo.IsValid()) { int fbo_width = fbo->GetWidth(); int fbo_height = fbo->GetHeight(); X = Clamp (x, 0, fbo_width); Y = Clamp (y, 0, fbo_height); W = Min (fbo_width - x, width); H = Min (fbo_height - y, height); if ((W <= 0) || (H <= 0)) { nuxAssertMsg(0, "[GraphicsEngine::CreateTextureFromBackBuffer] Invalid request."); return ObjectPtr (0); } // Inverse Y because of OpenGL upside-down nature Y = fbo_height - Y - H; } else { // There is no fbo. Reading directly from the back-buffer. int bb_width = _graphics_display.GetWindowWidth(); int bb_height = _graphics_display.GetWindowHeight(); X = Clamp (x, 0, bb_width); Y = Clamp (y, 0, bb_height); W = Min (bb_width - x, width); H = Min (bb_height - y, height); if ((W <= 0) || (H <= 0)) { nuxAssertMsg(0, "[GraphicsEngine::CreateTextureFromBackBuffer] Invalid request."); return ObjectPtr (0); } // Inverse Y because of OpenGL upside-down nature Y = bb_height - Y - H; } ObjectPtr device_texture = _graphics_display.GetGpuDevice()->CreateSystemCapableDeviceTexture(W, H, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION); ObjectPtr sfc = device_texture->GetSurfaceLevel(0); sfc->CopyRenderTarget(X, Y, W, H); return device_texture; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLTexture2D.h0000644000015301777760000000624212321344237022351 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLTEXTURE2D_H #define IOPENGLTEXTURE2D_H namespace nux { class IOpenGLBaseTexture; class IOpenGLTexture2D: public IOpenGLBaseTexture { NUX_DECLARE_OBJECT_TYPE(IOpenGLTexture2D, IOpenGLBaseTexture); public: virtual ~IOpenGLTexture2D(); void GetSurfaceLevel(int Level, ObjectPtr& surface); ObjectPtr GetSurfaceLevel(int Level); int LockRect( int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect); int UnlockRect( int Level ); unsigned int EnableGammaCorrection(bool b); int GetLevelDesc( int Level, SURFACE_DESC *pDesc ) { nuxAssert(Level >= 0 ); nuxAssert(Level < _NumMipLevel); if ((Level < 0) || (Level > _NumMipLevel)) { pDesc->Width = 0; pDesc->Height = 0; pDesc->PixelFormat = BITFMT_UNKNOWN; pDesc->Type = _ResourceType; } else { pDesc->Width = Max (1, _Width >> Level); pDesc->Height = Max (1, _Height >> Level); pDesc->PixelFormat = _PixelFormat; pDesc->Type = _ResourceType; } return OGL_OK; } //! Return a pointer to a mipmap level data. /*! Return a pointer to a mipmap level data. The data is in the RGBA format.\n Inherited from IOpenGLBaseTexture. @param level The requested texture mipmap level data. @param width Returns the width in pixel of the image data. @param height Returns the height in pixel of the image data. @param stride Returns the row stride of the image data. @return A pointer to RGBA data. The caller must dlete the data by calling delete []. */ unsigned char* GetSurfaceData(int level, int &width, int &height, int &stride); private: // The Dummy boolean is used to create a skeletal frame for the default // render target texture and surface; Only GpuDevice uses it in its constructor. // Do not use it otherwise!!! IOpenGLTexture2D( unsigned int Width , unsigned int Height , unsigned int Levels , BitmapFormat PixelFormat, bool Dummy = false, NUX_FILE_LINE_PROTO); std::vector< ObjectPtr > _SurfaceArray; bool external_id_; friend class GpuDevice; friend class IOpenGLSurface; }; } #endif // IOPENGLTEXTURE2D_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLAnimatedTexture.cpp0000644000015301777760000000735112321344237024163 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GraphicsDisplay.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLAnimatedTexture.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLAnimatedTexture); IOpenGLAnimatedTexture::IOpenGLAnimatedTexture( int Width , int Height , int Depth , BitmapFormat PixelFormat) : IOpenGLBaseTexture(RTANIMATEDTEXTURE, Width, Height, Depth, 1, PixelFormat) , _CurrentFrame(0) { for (int i = 0; i < Depth; i++) { ObjectPtr Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(Width, Height, 1, PixelFormat, NUX_TRACKER_LOCATION); _FrameTextureArray.push_back(Texture); _FrameTimeArray.push_back(41); // 41 ms = 24 frames/second } _OpenGLID = _FrameTextureArray[0]->GetOpenGLID(); SetFiltering(GL_NEAREST, GL_NEAREST); SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); SetRenderStates(); } IOpenGLAnimatedTexture::~IOpenGLAnimatedTexture() { for (int i = 0; i < _Depth; i++) { _FrameTextureArray[i].Release(); } _FrameTextureArray.clear(); _FrameTimeArray.clear(); } ObjectPtr IOpenGLAnimatedTexture::GetSurfaceFrame(int Frame) { nuxAssert(Frame >= 0); nuxAssert(Frame < _Depth); if ((Frame >= 0) && (Frame < _Depth)) { return _FrameTextureArray[Frame]->GetSurfaceLevel(0); } else { nuxAssertMsg(0, "[IOpenGLAnimatedTexture::GetSurfaceFrame] Invalid surface level"); } return ObjectPtr (0); } void IOpenGLAnimatedTexture::GetSurfaceFrame(int Frame, ObjectPtr& surface) { surface = ObjectPtr (0); surface = GetSurfaceFrame(Frame); } int IOpenGLAnimatedTexture::LockRect( int Frame, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect) { return _FrameTextureArray[Frame]->LockRect(0, pLockedRect, pRect); } int IOpenGLAnimatedTexture::UnlockRect( int Frame) { return _FrameTextureArray[Frame]->UnlockRect(0); } void IOpenGLAnimatedTexture::PresentFirstFrame() { _CurrentFrame = 0; _OpenGLID = _FrameTextureArray[_CurrentFrame]->GetOpenGLID(); } void IOpenGLAnimatedTexture::PresentNextFrame() { ++_CurrentFrame; if (_CurrentFrame >= _Depth) _CurrentFrame = 0; _OpenGLID = _FrameTextureArray[_CurrentFrame]->GetOpenGLID(); } void IOpenGLAnimatedTexture::PresentLastFrame() { _CurrentFrame = _Depth - 1; _OpenGLID = _FrameTextureArray[_CurrentFrame]->GetOpenGLID(); } void IOpenGLAnimatedTexture::SetFrameTime(int Frame, int time_ms) { nuxAssert(_CurrentFrame < (int) _FrameTimeArray.size()); _FrameTimeArray[Frame] = time_ms; } int IOpenGLAnimatedTexture::GetFrameTime() { nuxAssert(_CurrentFrame < (int) _FrameTimeArray.size()); return _FrameTimeArray[_CurrentFrame]; } unsigned int IOpenGLAnimatedTexture::GetNumFrame() { return _Depth; } } nux-4.0.6+14.04.20140409/NuxGraphics/nux-graphics.pc.in0000644000015301777760000000057712321344237022542 0ustar pbusernogroup00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: NuxGraphics Description: Core OpenGL graphics functions for Nux Version: @VERSION@ Libs: -L${libdir} -lnux-graphics-@NUX_API_VERSION@ Cflags: -I${includedir}/Nux-@NUX_API_VERSION@ Requires: glib-2.0 cairo libpng gdk-pixbuf-2.0 nux-core-@NUX_API_VERSION@ @GL_PKGS@ xxf86vm xinerama @GEIS_PKGS@ nux-4.0.6+14.04.20140409/NuxGraphics/GLRenderStates.cpp0000644000015301777760000003205312321344237022525 0ustar pbusernogroup00000000000000/* * Copyright 2010-2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GLRenderStates.h" namespace nux { const struct StateLookUpTable { StateLookUpTable() { // setup render state map #define UL_MAP(state__, default_value__, checked__) \ default_render_state[GFXRS_##state__].iValue = default_value__; \ default_render_state[GFXRS_##state__].Checked = checked__; #define UL_MAP_FLOAT(state__, default_value__, checked__) \ default_render_state[GFXRS_##state__].fValue = default_value__; \ default_render_state[GFXRS_##state__].Checked = checked__; \ #ifndef NUX_OPENGLES_20 UL_MAP(FRONT_POLYGONMODE , GL_FILL , 1); UL_MAP(BACK_POLYGONMODE , GL_FILL , 1); #endif UL_MAP(CULLFACEENABLE , GL_FALSE , 1); UL_MAP(CULLFACE , GL_BACK , 1); UL_MAP(FRONTFACE , GL_CCW , 1); UL_MAP(SCISSORTESTENABLE , GL_FALSE , 1); UL_MAP(ZTESTENABLE , GL_FALSE , 1); UL_MAP(ZWRITEENABLE , GL_TRUE , 1); UL_MAP(ZFUNC , GL_LESS , 1); UL_MAP_FLOAT(ZNEAR , static_cast (0.0f) , 1); UL_MAP_FLOAT(ZFAR , static_cast (1.0f) , 1); UL_MAP(ALPHABLENDENABLE , GL_FALSE , 1); UL_MAP(BLENDOP , GL_FUNC_ADD , 1); UL_MAP(BLENDOPALPHA , GL_FUNC_ADD , 1); UL_MAP(SRCBLEND , GL_ONE , 1); UL_MAP(DESTBLEND , GL_ZERO , 1); UL_MAP(SRCBLENDALPHA , GL_ONE , 1); UL_MAP(DESTBLENDALPHA , GL_ZERO , 1); UL_MAP(ALPHATESTENABLE , GL_FALSE , 1); UL_MAP(ALPHATESTREF , 0x0 , 1); UL_MAP(ALPHATESTFUNC , GL_ALWAYS , 1); UL_MAP(STENCILENABLE , GL_FALSE , 1); UL_MAP(TWOSIDEDSTENCILENABLE , GL_FALSE , 1); UL_MAP(FRONT_STENCILWRITEMASK , 0xFFFFFFFF , 1); UL_MAP(BACK_STENCILWRITEMASK , 0xFFFFFFFF , 1); UL_MAP(FRONT_STENCILFUNC , GL_ALWAYS , 1); UL_MAP(FRONT_STENCILREF , 0x0 , 1); UL_MAP(FRONT_STENCILMASK , 0xFF , 1); UL_MAP(FRONT_STENCILFAIL , GL_KEEP , 1); UL_MAP(FRONT_STENCILZFAIL , GL_KEEP , 1); UL_MAP(FRONT_STENCILZPASS , GL_KEEP , 1); UL_MAP(BACK_STENCILFUNC , GL_ALWAYS , 1); UL_MAP(BACK_STENCILREF , 0x0 , 1); UL_MAP(BACK_STENCILMASK , 0xFF , 1); UL_MAP(BACK_STENCILFAIL , GL_KEEP , 1); UL_MAP(BACK_STENCILZFAIL , GL_KEEP , 1); UL_MAP(BACK_STENCILZPASS , GL_KEEP , 1); UL_MAP(LINESMOOTHENABLE , GL_FALSE , 1); UL_MAP(LINEWIDTH , 1 , 1); UL_MAP(LINEHINT , GL_FASTEST , 1); UL_MAP(COLORWRITEENABLE_R , GL_TRUE , 1); UL_MAP(COLORWRITEENABLE_G , GL_TRUE , 1); UL_MAP(COLORWRITEENABLE_B , GL_TRUE , 1); UL_MAP(COLORWRITEENABLE_A , GL_TRUE , 1); #undef UL_MAP #undef UL_MAP_FLOAT }; RenderStateMap default_render_state[GFXRS_MAX_RENDERSTATES]; RenderStateMap sampler_state_map[GFXSS_MAX_SAMPLERSTATES]; } s_StateLUT; GpuRenderStates::GpuRenderStates(GpuBrand board, GpuInfo* info) { gpu_brand_ = board; gpu_info_ = info; Memcpy(&render_state_changes_, &s_StateLUT.default_render_state, sizeof(render_state_changes_)); } GpuRenderStates::~GpuRenderStates() { } void GpuRenderStates::ResetDefault() { HW__EnableCulling( s_StateLUT.default_render_state[GFXRS_CULLFACEENABLE].iValue ); HW__SetFrontFace( s_StateLUT.default_render_state[GFXRS_FRONTFACE].iValue ); HW__SetCullFace( s_StateLUT.default_render_state[GFXRS_CULLFACE].iValue ); HW__SetDepthMask( s_StateLUT.default_render_state[GFXRS_ZWRITEENABLE].iValue ); HW__SetDepthFunc( s_StateLUT.default_render_state[GFXRS_ZFUNC].iValue ); HW__SetEnableDepthTest( s_StateLUT.default_render_state[GFXRS_ZTESTENABLE].iValue ); HW__SetDepthRange( s_StateLUT.default_render_state[GFXRS_ZNEAR].fValue, s_StateLUT.default_render_state[GFXRS_ZFAR].fValue ); HW__EnableAlphaBlend( s_StateLUT.default_render_state[GFXRS_ALPHABLENDENABLE].iValue ); HW__SetAlphaBlendOp( s_StateLUT.default_render_state[GFXRS_BLENDOP].iValue, s_StateLUT.default_render_state[GFXRS_BLENDOPALPHA].iValue ); HW__SetSeparateAlphaBlendFactors( s_StateLUT.default_render_state[GFXRS_SRCBLEND].iValue, s_StateLUT.default_render_state[GFXRS_DESTBLEND].iValue, s_StateLUT.default_render_state[GFXRS_SRCBLENDALPHA].iValue, s_StateLUT.default_render_state[GFXRS_DESTBLENDALPHA ].iValue ); #ifndef NUX_OPENGLES_20 HW__EnableAlphaTest( s_StateLUT.default_render_state[GFXRS_ALPHATESTENABLE].iValue ); HW__SetAlphaTestFunc( s_StateLUT.default_render_state[GFXRS_ALPHATESTFUNC].iValue, s_StateLUT.default_render_state[GFXRS_ALPHATESTREF].iValue ); #endif HW__EnableStencil( s_StateLUT.default_render_state[GFXRS_STENCILENABLE].iValue ); HW__SetStencilFunc( s_StateLUT.default_render_state[GFXRS_FRONT_STENCILFUNC].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILREF].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILMASK].iValue); HW__SetStencilOp( s_StateLUT.default_render_state[GFXRS_FRONT_STENCILFAIL].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILZFAIL].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILZPASS].iValue); #ifndef NUX_OPENGLES_20 HW__EnableLineSmooth(s_StateLUT.default_render_state[GFXRS_LINESMOOTHENABLE].iValue); #endif HW__SetLineWidth(s_StateLUT.default_render_state[GFXRS_LINEWIDTH].iValue, s_StateLUT.default_render_state[GFXRS_LINEHINT].iValue); #if 0 HW__EnableTwoSidedStencil( s_StateLUT.default_render_state[GFXRS_TWOSIDEDSTENCILENABLE].iValue ); HW__SetFrontFaceStencilFunc( s_StateLUT.default_render_state[GFXRS_FRONT_STENCILFUNC].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILREF].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILMASK].iValue ); HW__SetFrontFaceStencilOp( s_StateLUT.default_render_state[GFXRS_FRONT_STENCILFAIL].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILZFAIL].iValue, s_StateLUT.default_render_state[GFXRS_FRONT_STENCILZPASS].iValue ); HW__SetBackFaceStencilFunc( s_StateLUT.default_render_state[GFXRS_BACK_STENCILFUNC].iValue, s_StateLUT.default_render_state[GFXRS_BACK_STENCILREF].iValue, s_StateLUT.default_render_state[GFXRS_BACK_STENCILMASK].iValue ); HW__SetBackFaceStencilOp( s_StateLUT.default_render_state[GFXRS_BACK_STENCILFAIL].iValue, s_StateLUT.default_render_state[GFXRS_BACK_STENCILZFAIL].iValue, s_StateLUT.default_render_state[GFXRS_BACK_STENCILZPASS].iValue ); #endif HW__EnableScissor( s_StateLUT.default_render_state[GFXRS_SCISSORTESTENABLE].iValue ); } void GpuRenderStates::SubmitChangeStates() { HW__EnableCulling( render_state_changes_[GFXRS_CULLFACEENABLE].iValue ); HW__SetFrontFace( render_state_changes_[GFXRS_FRONTFACE].iValue ); HW__SetCullFace( render_state_changes_[GFXRS_CULLFACE].iValue ); HW__SetDepthMask( render_state_changes_[GFXRS_ZWRITEENABLE].iValue ); HW__SetDepthFunc( render_state_changes_[GFXRS_ZFUNC].iValue ); HW__SetEnableDepthTest( render_state_changes_[GFXRS_ZTESTENABLE].iValue ); HW__SetDepthRange( render_state_changes_[GFXRS_ZNEAR].fValue, render_state_changes_[GFXRS_ZFAR].fValue ); HW__EnableAlphaBlend( render_state_changes_[GFXRS_ALPHABLENDENABLE].iValue ); HW__SetAlphaBlendOp( render_state_changes_[GFXRS_BLENDOP].iValue, render_state_changes_[GFXRS_BLENDOPALPHA].iValue ); HW__SetSeparateAlphaBlendFactors( render_state_changes_[GFXRS_SRCBLEND].iValue, render_state_changes_[GFXRS_DESTBLEND].iValue, render_state_changes_[GFXRS_SRCBLENDALPHA].iValue, render_state_changes_[GFXRS_DESTBLENDALPHA ].iValue ); #ifndef NUX_OPENGLES_20 HW__EnableAlphaTest( render_state_changes_[GFXRS_ALPHATESTENABLE].iValue ); HW__SetAlphaTestFunc( render_state_changes_[GFXRS_ALPHATESTFUNC].iValue, render_state_changes_[GFXRS_ALPHATESTREF].iValue ); #endif HW__EnableStencil( render_state_changes_[GFXRS_STENCILENABLE].iValue ); HW__SetStencilFunc( render_state_changes_[GFXRS_FRONT_STENCILFUNC].iValue, render_state_changes_[GFXRS_FRONT_STENCILREF].iValue, render_state_changes_[GFXRS_FRONT_STENCILMASK].iValue); HW__SetStencilOp( render_state_changes_[GFXRS_FRONT_STENCILFAIL].iValue, render_state_changes_[GFXRS_FRONT_STENCILZFAIL].iValue, render_state_changes_[GFXRS_FRONT_STENCILZPASS].iValue); #ifndef NUX_OPENGLES_20 HW__EnableLineSmooth(render_state_changes_[GFXRS_LINESMOOTHENABLE].iValue); #endif HW__SetLineWidth(render_state_changes_[GFXRS_LINEWIDTH].iValue, render_state_changes_[GFXRS_LINEHINT].iValue); #if 0 HW__EnableTwoSidedStencil( s_StateLUT.default_render_state[GFXRS_TWOSIDEDSTENCILENABLE].iValue ); HW__SetFrontFaceStencilFunc( render_state_changes_[GFXRS_FRONT_STENCILFUNC].iValue, render_state_changes_[GFXRS_FRONT_STENCILREF].iValue, render_state_changes_[GFXRS_FRONT_STENCILMASK].iValue ); HW__SetFrontFaceStencilOp( render_state_changes_[GFXRS_FRONT_STENCILFAIL].iValue, render_state_changes_[GFXRS_FRONT_STENCILZFAIL].iValue, render_state_changes_[GFXRS_FRONT_STENCILZPASS].iValue ); HW__SetBackFaceStencilFunc( render_state_changes_[GFXRS_BACK_STENCILFUNC].iValue, render_state_changes_[GFXRS_BACK_STENCILREF].iValue, render_state_changes_[GFXRS_BACK_STENCILMASK].iValue ); HW__SetBackFaceStencilOp( render_state_changes_[GFXRS_BACK_STENCILFAIL].iValue, render_state_changes_[GFXRS_BACK_STENCILZFAIL].iValue, render_state_changes_[GFXRS_BACK_STENCILZPASS].iValue ); #endif HW__EnableScissor( render_state_changes_[GFXRS_SCISSORTESTENABLE].iValue ); } void GpuRenderStates::ResetStateChangeToDefault() { for (unsigned int i = 0; i < GFXRS_MAX_RENDERSTATES; i++) { if (render_state_changes_[i].Checked && ((render_state_changes_[i].iValue != s_StateLUT.default_render_state[i].iValue) || (render_state_changes_[i].fValue != s_StateLUT.default_render_state[i].fValue))) { render_state_changes_[i].iValue = s_StateLUT.default_render_state[i].iValue; render_state_changes_[i].fValue = s_StateLUT.default_render_state[i].fValue; } } } void GpuRenderStates::CheckStateChange() { for (unsigned int i = 0; i < GFXRS_MAX_RENDERSTATES; i++) { if (render_state_changes_[i].Checked && ((render_state_changes_[i].iValue != s_StateLUT.default_render_state[i].iValue) || (render_state_changes_[i].fValue != s_StateLUT.default_render_state[i].fValue))) { render_state_changes_[i].iValue = s_StateLUT.default_render_state[i].iValue; render_state_changes_[i].fValue = s_StateLUT.default_render_state[i].fValue; nuxError("[GpuRenderStates::Check] Render state doesn't have default value"); } } } } nux-4.0.6+14.04.20140409/NuxGraphics/NuxGraphicsResources.h0000644000015301777760000000337212321344237023474 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUXGRAPHICSRESOURCES_H #define NUXGRAPHICSRESOURCES_H namespace nux { class FontTexture; class NResourceCache; class NuxGraphicsResources { NUX_DECLARE_GLOBAL_OBJECT(NuxGraphicsResources, NuxGraphicsGlobalSingletonInitializer); public: void InitializeResources(); std::string FindResourceLocation(const char *ResourceFileName, bool ErrorOnFail = false); std::string FindUITextureLocation(const char *ResourceFileName, bool ErrorOnFail = false); std::string FindShaderLocation(const char *ResourceFileName, bool ErrorOnFail = false); std::string FindFontLocation(const char *ResourceFileName, bool ErrorOnFail = false); private: std::vector m_FontSearchPath; std::vector m_ShaderSearchPath; std::vector m_UITextureSearchPath; FilePath m_ResourcePathLocation; }; } #define GNuxGraphicsResources NUX_GLOBAL_OBJECT_INSTANCE(nux::NuxGraphicsResources) #endif // NUXGRAPHICSRESOURCES_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVertexDeclaration.h0000644000015301777760000000376312321344237024153 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLVERTEXDECLARATION_H #define IOPENGLVERTEXDECLARATION_H namespace nux { class IOpenGLResource; class IOpenGLVertexDeclaration: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLVertexDeclaration, IOpenGLResource); public: virtual ~IOpenGLVertexDeclaration(); VERTEXELEMENT GetUsage(ATTRIB_USAGE_DECL usage); bool IsUsingMoreThanStreamZero(); int GetStride(int vertex_input_number); void SetVertexShaderAttributeLocation(int input_index, int shader_attribute_location); int GetVertexShaderAttributeLocation(int input_index); private: void SetVertexBuffer(int input_index, ObjectPtr vertex_buffer); ObjectPtr GetVertexBuffer(int input_index); IOpenGLVertexDeclaration(const VERTEXELEMENT *pVertexElements); int _stride[8]; //!< Stride for each stream int _valid_vertex_input[16]; // Vertex Input valid for this vertex declaration int shader_attribute_location_array[8]; std::vector > vertex_buffer_array; std::vector _declarations_array; friend class GpuDevice; friend class CachedMeshBuffer; }; } #endif // IOPENGLVERTEXDECLARATION_H nux-4.0.6+14.04.20140409/NuxGraphics/RunTimeStats.cpp0000644000015301777760000001712512321344237022304 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include #include "GLResource.h" #include "IOpenGLResource.h" #include "IOpenGLBaseTexture.h" #include "IOpenGLIndexBuffer.h" #include "IOpenGLVertexBuffer.h" #include "RunTimeStats.h" namespace nux { NUX_IMPLEMENT_GLOBAL_OBJECT(RenderingStats); unsigned int RenderingStats::m_NumTex2D = 0; unsigned int RenderingStats::m_GPUSizeTex2D = 0; unsigned int RenderingStats::m_NumTexRectangle = 0; unsigned int RenderingStats::m_GPUSizeTexRectangle = 0; unsigned int RenderingStats::m_NumTexCube = 0; unsigned int RenderingStats::m_GPUSizeTexCube = 0; unsigned int RenderingStats::m_NumTexVolume = 0; unsigned int RenderingStats::m_GPUSizeTexVolume = 0; unsigned int RenderingStats::m_NumTexAnimated = 0; unsigned int RenderingStats::m_GPUSizeTexAnimated = 0; unsigned int RenderingStats::m_NumPBO = 0; // Counted as Vertex Buffer unsigned int RenderingStats::m_GPUSizePBO = 0; // Counted as Vertex Buffer unsigned int RenderingStats::m_NumQueryObject = 0; unsigned int RenderingStats::m_NumFrameBufferObject = 0; unsigned int RenderingStats::m_NumVertexBuffer = 0; unsigned int RenderingStats::m_GPUSizeVertexBuffer = 0; unsigned int RenderingStats::m_NumIndexBuffer = 0; unsigned int RenderingStats::m_GPUSizeIndexBuffer = 0; unsigned int RenderingStats::m_NumVertexShader = 0; unsigned int RenderingStats::m_NumPixelShader = 0; unsigned int RenderingStats::m_NumShaderProgram = 0; unsigned int RenderingStats::m_TotalGPUSize = 0; void RenderingStats::Constructor() { } void RenderingStats::Destructor() { #ifdef DEBUG if (m_NumIndexBuffer != 0) { std::cerr << "[RenderingStats::Destructor] Some index buffers have not been released."; } if (m_NumTex2D != 0) { std::cerr << "[RenderingStats::Destructor] Some 2D textures have not been released."; for (auto id: _texture_2d_array) { std::cerr << "[RenderingStats::Destructor] Remaining 2D textures: " << id; } } if (m_NumTexRectangle != 0) { std::cerr << "[RenderingStats::Destructor] Some rectangle textures buffers have not been released."; for (auto id: _texture_rect_array) { std::cerr << "[RenderingStats::Destructor] Remaining Rectangle textures: " << id; } } #endif } void RenderingStats::Register(IOpenGLResource *GraphicsObject) { switch(GraphicsObject->GetResourceType()) { case RTINDEXBUFFER: { m_NumIndexBuffer++; m_GPUSizeIndexBuffer += NUX_REINTERPRET_CAST(IOpenGLIndexBuffer *, GraphicsObject)->GetSize(); m_TotalGPUSize += m_GPUSizeIndexBuffer; break; } case RTVERTEXBUFFER: { m_NumVertexBuffer++; m_GPUSizeVertexBuffer += NUX_REINTERPRET_CAST(IOpenGLVertexBuffer *, GraphicsObject)->GetSize(); m_TotalGPUSize += m_GPUSizeVertexBuffer; break; } case RTTEXTURE: { int id = NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)->GetOpenGLID(); if (id) _texture_2d_array.push_back(NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)->GetOpenGLID()); m_NumTex2D++; m_GPUSizeTex2D += GetTextureSize(NUX_REINTERPRET_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize += m_GPUSizeTex2D; break; } case RTTEXTURERECTANGLE: { int id = NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)->GetOpenGLID(); if (id) _texture_rect_array.push_back(NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)->GetOpenGLID()); m_NumTexRectangle++; m_GPUSizeTexRectangle += GetTextureSize(NUX_REINTERPRET_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize += m_GPUSizeTexRectangle; break; } case RTCUBETEXTURE: { m_NumTexCube++; m_GPUSizeTexCube += GetTextureSize(NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize += m_GPUSizeTexCube; break; } case RTVOLUMETEXTURE: { m_NumTexVolume++; m_GPUSizeTexVolume += GetTextureSize(NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize += m_GPUSizeTexVolume; break; } case RTANIMATEDTEXTURE: { // Animated texture size is compted as rectangle textures; m_NumTexAnimated++; break; } case RTQUERY: { m_NumQueryObject++; break; } case RTFRAMEBUFFEROBJECT: { m_NumFrameBufferObject++; break; } default: break; } } void RenderingStats::UnRegister(IOpenGLResource *GraphicsObject) { switch(GraphicsObject->GetResourceType()) { case RTINDEXBUFFER: { m_NumIndexBuffer--; m_GPUSizeIndexBuffer -= NUX_REINTERPRET_CAST(IOpenGLIndexBuffer *, GraphicsObject)->GetSize(); m_TotalGPUSize -= m_GPUSizeIndexBuffer; break; } case RTVERTEXBUFFER: { m_NumVertexBuffer--; m_GPUSizeVertexBuffer -= NUX_REINTERPRET_CAST(IOpenGLVertexBuffer *, GraphicsObject)->GetSize(); m_TotalGPUSize -= m_GPUSizeVertexBuffer; break; } case RTTEXTURE: { int id = NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)->GetOpenGLID(); _texture_2d_array.erase(std::remove(_texture_2d_array.begin(), _texture_2d_array.end(), id), _texture_2d_array.end()); m_NumTex2D--; m_GPUSizeTex2D -= GetTextureSize(NUX_REINTERPRET_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize -= m_GPUSizeTex2D; break; } case RTTEXTURERECTANGLE: { int id = NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)->GetOpenGLID(); _texture_rect_array.erase(std::remove(_texture_rect_array.begin(), _texture_rect_array.end(), id), _texture_rect_array.end()); m_NumTexRectangle--; m_GPUSizeTexRectangle -= GetTextureSize(NUX_REINTERPRET_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize -= m_GPUSizeTexRectangle; break; } case RTCUBETEXTURE: { m_NumTexCube--; m_GPUSizeTexCube -= GetTextureSize(NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize -= m_GPUSizeTexCube; break; } case RTVOLUMETEXTURE: { m_NumTexVolume--; m_GPUSizeTexVolume -= GetTextureSize(NUX_STATIC_CAST(IOpenGLBaseTexture *, GraphicsObject)); m_TotalGPUSize -= m_GPUSizeTexVolume; break; } case RTANIMATEDTEXTURE: { // Animated texture size is compted as rectangle textures; m_NumTexAnimated--; break; } case RTQUERY: { m_NumQueryObject--; break; } case RTFRAMEBUFFEROBJECT: { m_NumFrameBufferObject--; break; } default: break; } } } nux-4.0.6+14.04.20140409/NuxGraphics/FreetypeFont.cpp0000644000015301777760000007372612321344237022325 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "FreetypeFont.h" #include "agg_rendering_buffer.h" #include "GLTextureManager.h" //#include "OpenGL/GLsdk/GL/gl.h" //#include "OpenGL/GLsdk/GL/glprocs.h" //#include #include #include "GfxServer.h" #include "OpenGLEngine/GLCheck.h" #include "OpenGLEngine/OpenGLEngine.h" FontMgr *FontMgr::pinstance = 0; int Dot_GlyphIndex; void GLDrawRectangle (int xmin, int ymin, int xmax, int ymax) { glColor3f (1.0f, 1.0f, 1.0f); glDisable (GL_TEXTURE_2D); glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); glBegin (GL_QUADS); glVertex3i (xmin, ymin, 1); glVertex3i (xmax, ymin, 1); glVertex3i (xmax, ymax, 1); glVertex3i (xmin, ymax, 1); glEnd(); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); glEnable (GL_TEXTURE_2D); } FontMgr::FontMgr() { m_font_list = new list ; current_font = NULL; current_style = NULL; } FontMgr *FontMgr::Instance() { if (pinstance == 0) pinstance = new FontMgr(); return pinstance; } bool FontMgr::load_font (const char *font_filename) { FT_Library library; // handle to library FT_Face face; // handle to face object FT_Error error; error = FT_Init_FreeType ( &library ); if (error ) { return false; } error = FT_New_Face ( library, font_filename, 0, &face ); if ( error == FT_Err_Unknown_File_Format ) { // the font file could be opened and read, but it appears // that its font format is unsupported } else if ( error ) { // another error code means that the font file could not; // be opened or read, or simply that it is broken...; return false; } int font_bitmap_width, font_bitmap_height; font_bitmap_width = 0; font_bitmap_height = 18; error = FT_Set_Pixel_Sizes ( face, // handle to face object font_bitmap_width, // pixel_width font_bitmap_height ); // pixel_height if (error) { return false; } FontStyle *fs = new FontStyle(); FontFamily *ff = new FontFamily(); ff->font_name = strdup (face->family_name); ff->m_face = face; ff->style_list = new list ; fs->style_name = strdup (face->style_name); set_current_font (face->family_name, face->style_name); // check if the font is already loaded if (find_font ((const char*)face->family_name, (const char*)face->style_name) ) return true; // the font is already loaded fs->charmap = new CharData[face->num_glyphs]; fs->ascent = face->ascender; fs->descent = face->descender; fs->texture_width = font_bitmap_width; fs->texture_height = font_bitmap_height; fs->line_spacing = face->ascender >> 6; fs->num_glyph = face->num_glyphs; int char_num; unsigned char *imgp, *imp; for (char_num = 0; char_num < face->num_glyphs; char_num++) { FT_UInt glyph_index = FT_Get_Char_Index (face, char_num); error = FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT); if (error) continue; error = FT_Render_Glyph (face->glyph, ft_render_mode_normal); if (error) continue; /*error = FT_Load_Char( face, char_num, FT_LOAD_RENDER );*/ unsigned int PO2w = NextPowerOfTwo (face->glyph->bitmap.width); unsigned int PO2h = NextPowerOfTwo (face->glyph->bitmap.rows); if ( ( (glyph_index == 0) && (char_num == 0) ) || (glyph_index != 0) ) { imgp = (unsigned char *) calloc (PO2h * PO2w * 4, sizeof (unsigned char) ); imp = imgp; //cout << "rows = " << face->glyph->bitmap.rows << endl; //cout << "width = " << face->glyph->bitmap.width << endl; //cout << "pitch = " << face->glyph->bitmap.pitch << endl; int i, j; int position = 0; for ( j = 0; j < face->glyph->bitmap.rows; j++) { for ( i = 0; i < face->glyph->bitmap.width; i++) { //if(imp < imgp + font_bitmap_height*font_bitmap_width*4) // sometimes a char has more rows than the texture { * (imp + 4 * i + 0) = * (face->glyph->bitmap.buffer + j * face->glyph->bitmap.pitch + i); // *(imp + 4*i+1) = *(face->glyph->bitmap.buffer + j*face->glyph->bitmap.pitch +i); // *(imp + 4*i+2) = *(face->glyph->bitmap.buffer + j*face->glyph->bitmap.pitch +i); /* if(*(imp + 4*i+0) == 0) *(imp + 4*i+3) = 0x0; if(*(imp + 4*i+0) == 255) *(imp + 4*i+3) = 0xff; else *(imp + 4*i+3) = *(imp + 4*i+0); */ //*(imp + 4*i+0) = 0; * (imp + 4 * i + 1) = * (imp + 4 * i + 0); * (imp + 4 * i + 2) = * (imp + 4 * i + 0); * (imp + 4 * i + 3) = * (imp + 4 * i + 0); } } //imp += 4*font_bitmap_width; imp += 4 * PO2w; // position += 4*font_bitmap_width; } //ImageFormat *image = new ImageFormat(); //image->allocate(BITFMT_GRAY8, font_bitmap_width, font_bitmap_height); /*image->width = font_bitmap_width; image->Height() = font_bitmap_height; image->bpp = 32; image->data = imgp;*/ //unsigned char* buffer = new unsigned char[font_bitmap_width * font_bitmap_height]; //agg::rendering_buffer rbuf(buffer, font_bitmap_width, font_bitmap_height, font_bitmap_height*4); //TextureMgr* texturemgr = TextureMgr::Instance(); GLuint texname; glPixelStorei (GL_UNPACK_ALIGNMENT, 1); CHECKGL(glGenTextures (1, &texname)); glBindTexture (GL_TEXTURE_2D, texname); /* float *border_color = new float[4]; *(border_color) = 0; *(border_color+1) = 1.0f; *(border_color+2) = 0; *(border_color+3) = 1.0f; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); glTexEnvfv(GL_TEXTURE_2D, GL_TEXTURE_ENV_COLOR, border_color); */ fs->charmap[char_num].gltexid = texname; fs->charmap[char_num].glTexWidth = PO2w; fs->charmap[char_num].glTexHeight = PO2h; glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, PO2w, PO2h, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgp); // fs->charmap[char_num].gltexid = texturemgr->load_image(image); } else fs->charmap[char_num].gltexid = fs->charmap[0].gltexid; // the missing glyph fs->charmap[char_num].hadvance = face->glyph->metrics.horiAdvance >> 6; // 1/64th of a pixel fs->charmap[char_num].vadvance = face->glyph->metrics.vertAdvance >> 6; fs->charmap[char_num].hbearingX = face->glyph->metrics.horiBearingX >> 6; fs->charmap[char_num].hbearingY = face->glyph->metrics.horiBearingY >> 6; fs->charmap[char_num].vbearingX = face->glyph->metrics.vertBearingX >> 6; fs->charmap[char_num].vbearingY = face->glyph->metrics.vertBearingY >> 6; fs->charmap[char_num].gwidth = face->glyph->metrics.width >> 6; fs->charmap[char_num].gheight = face->glyph->metrics.height >> 6; fs->charmap[char_num].bitmap_left_bearing = face->glyph->bitmap_left; fs->charmap[char_num].bitmap_top_bearing = face->glyph->bitmap_top; fs->charmap[char_num].bitmap_width = face->glyph->bitmap.width; fs->charmap[char_num].bitmap_height = face->glyph->bitmap.rows; fs->charmap[char_num].glyph_index = glyph_index; } ff->style_list->push_back (fs); m_font_list->push_back (ff); return true; } int FontMgr::get_character_texture_id (const char *font_name, int encoding, CharData *cd) { list ::iterator iter; for (iter = m_font_list->begin(); iter != m_font_list->end(); ++iter) { if (strcmp ( (*iter)->font_name, font_name) == 0) { cd->bitmap_width = (* (*iter)->style_list->begin() )->charmap[encoding].bitmap_width; cd->bitmap_height = (* (*iter)->style_list->begin() )->charmap[encoding].bitmap_height; cd->bitmap_left_bearing = (* (*iter)->style_list->begin() )->charmap[encoding].bitmap_left_bearing; cd->bitmap_top_bearing = (* (*iter)->style_list->begin() )->charmap[encoding].bitmap_top_bearing; cd->hadvance = (* (*iter)->style_list->begin() )->charmap[encoding].hadvance; cd->glTexWidth = (* (*iter)->style_list->begin() )->charmap[encoding].glTexWidth; cd->glTexHeight = (* (*iter)->style_list->begin() )->charmap[encoding].glTexHeight; return ( (* (*iter)->style_list->begin() )->charmap[encoding].gltexid); } } return 0; } int FontMgr::get_character_texture_id (int encoding, CharData *cd) { FontStyle *fs; fs = get_font_style (current_font, current_style); if (fs != NULL) { cd->bitmap_width = fs->charmap[encoding].bitmap_width; cd->bitmap_height = fs->charmap[encoding].bitmap_height; cd->bitmap_left_bearing = fs->charmap[encoding].bitmap_left_bearing; cd->bitmap_top_bearing = fs->charmap[encoding].bitmap_top_bearing; cd->hadvance = fs->charmap[encoding].hadvance; cd->gwidth = fs->charmap[encoding].gwidth; cd->gheight = fs->charmap[encoding].gheight; cd->glTexWidth = fs->charmap[encoding].glTexWidth; cd->glTexHeight = fs->charmap[encoding].glTexHeight; return fs->charmap[encoding].gltexid; } return 0; } void FontMgr::get_style_texture_size (const char *font_name, int *width, int *height) { list ::iterator iter; for (iter = m_font_list->begin(); iter != m_font_list->end(); ++iter) { if (strcmp ( (*iter)->font_name, font_name) == 0) { *width = (* (*iter)->style_list->begin() )->texture_width; *height = (* (*iter)->style_list->begin() )->texture_height; return; } } } void FontMgr::get_style_texture_size (int *width, int *height) { FontStyle *fs; fs = get_font_style (current_font, current_style); if (fs != NULL) { *width = fs->texture_width; *height = fs->texture_height; return; } } void FontMgr::get_style_line_spacing (const char *font_name, int *line_spacing) { list ::iterator iter; for (iter = m_font_list->begin(); iter != m_font_list->end(); ++iter) { if (strcmp ( (*iter)->font_name, font_name) == 0) { *line_spacing = (* (*iter)->style_list->begin() )->line_spacing; } } } void FontMgr::get_style_line_spacing (int *line_spacing) { FontStyle *fs; fs = get_font_style (current_font, current_style); if (fs != NULL) { *line_spacing = fs->line_spacing; return; } } unsigned int FontMgr::get_null_character_texture_id (const char *font_name) { list ::iterator iter; for (iter = m_font_list->begin(); iter != m_font_list->end(); ++iter) { if (strcmp ( (*iter)->font_name, font_name) == 0) { return ( (* (*iter)->style_list->begin() )->charmap[0].gltexid); } } return 0; } unsigned int FontMgr::get_null_character_texture_id() { FontStyle *fs; fs = get_font_style (current_font, current_style); if (fs != NULL) { return fs->charmap[0].gltexid; } return 0; } bool FontMgr::find_font (const char *font_name, const char *style_name) { list ::iterator iter; for (iter = m_font_list->begin(); iter != m_font_list->end(); ++iter) { if (strcmp ( (*iter)->font_name, font_name) == 0) { return true; } } return false; } FontFamily *FontMgr::get_font_family (const char *font_name) { list ::iterator iter; for (iter = m_font_list->begin(); iter != m_font_list->end(); ++iter) { if (strcmp ( (*iter)->font_name, font_name) == 0) { return (*iter); } } return NULL; } FontStyle *FontMgr::get_font_style (char *font_name, char *style_name) { list ::iterator iter; list ::iterator iter1; for (iter = m_font_list->begin(); iter != m_font_list->end(); ++iter) { if (strcmp ( (*iter)->font_name, font_name) == 0) { for (iter1 = ( (*iter)->style_list)->begin(); iter1 != ( (*iter)->style_list)->end(); ++iter1) if (strcmp ( (*iter1)->style_name, style_name) == 0) { return (*iter1); } } } return NULL; } void FontMgr::set_current_font (char *font_name, char *style_name) { if (current_font != NULL) free ( current_font); if (current_style != NULL) free (current_style); current_font = strdup (font_name); current_style = strdup (style_name); } FontMgr::~FontMgr() { } void enable_drawing_in_restricted_area (int xmin, int ymin, int xmax, int ymax) { glScissor (xmin, ymax, xmax - xmin, ymax - ymin); glEnable (GL_SCISSOR_TEST); } void disable_drawing_in_restricted_area() { glDisable (GL_SCISSOR_TEST); } void FontMgr::draw_text (int rect_xmin, int rect_ymin, int rect_xmax, int rect_ymax, const char *text, const char *sh_name) { int num_cararcter; int width, height, bitmap_x, bitmap_y; unsigned int ascii_code; int line_spacing; int x_cursor_position; int y_cursor_position; if ( (rect_xmin == 0) && (rect_xmax == 0) && (rect_ymin == 0) && (rect_ymax == 0) ) // the drawing area is invalid return; // if(num_cararcter == 0) // return; // NULL string; return //enable_drawing_in_restricted_area(rect_xmin, rect_ymin, rect_xmax, rect_ymax); // enable scissoring // FIXME (correct with the size of the Window 480-ymin, 480-ymax) glColor3f (1.0f, 1.0f, 1.0f); glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); glBegin (GL_QUADS); glVertex3i (rect_xmin, rect_ymin, 1); glVertex3i (rect_xmax, rect_ymin, 1); glVertex3i (rect_xmax, rect_ymax, 1); glVertex3i (rect_xmin, rect_ymax, 1); glEnd(); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); get_style_texture_size (&width, &height); get_style_line_spacing (&line_spacing); x_cursor_position = rect_xmin; y_cursor_position = rect_ymin + line_spacing; num_cararcter = strlen (text); glEnable (GL_TEXTURE_2D); for (int i = 0; i < num_cararcter; i++) { ascii_code = (unsigned int) text[i]; CharData cd; int texture_id = get_character_texture_id (ascii_code, &cd); glBindTexture (GL_TEXTURE_2D, texture_id /*TextureMgr::Instance()->glid(texture_id)*/); if (ascii_code == 13) // return caractere { x_cursor_position = rect_xmin; y_cursor_position += height + 2; // line_spacing; } if (texture_id != get_null_character_texture_id() ) { glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (x_cursor_position + cd.bitmap_left_bearing + cd.gwidth > rect_xmax - 5) // 5 pixel margin at the end of the line { x_cursor_position = rect_xmin; y_cursor_position += height + 2; // line_spacing; } bitmap_x = x_cursor_position + cd.bitmap_left_bearing; bitmap_y = y_cursor_position - cd.bitmap_top_bearing; glColor3f (1.0f, 0.0f, 1.0f); glBegin (GL_QUADS); glTexCoord2f (0.0f, 0.0f); glVertex3i (bitmap_x, bitmap_y, 1); glTexCoord2f (0.0f, 1.0f); glVertex3i (bitmap_x, bitmap_y + height, 1); glTexCoord2f (1.0f, 1.0f); glVertex3i (bitmap_x + width, bitmap_y + height, 1); glTexCoord2f (1.0f, 0.0f); glVertex3i (bitmap_x + width, bitmap_y, 1); glEnd(); x_cursor_position += cd.hadvance; if (x_cursor_position > rect_xmax) { x_cursor_position = rect_xmin; y_cursor_position += height + 2; // line_spacing; } } } glDisable (GL_TEXTURE_2D); //disable_drawing_in_restricted_area(); // disable scissoring } // We start by packing the information related to a single glyph image into a single structure instead of parallel arrays. // We thus define the following structure type: typedef struct TGlyph_ { FT_UInt index; // glyph index FT_Vector pos; // glyph origin on the baseline FT_Glyph glyph; // glyph image } TGlyphStruct, *PGlyphStruct; TGlyphStruct gGlyphs[1000]; // glyphs table int gNumGlyphs = 0; // We also translate each glyph image directly after it is loaded to its position on the baseline at load time. // As we will see, this as several advantages. Our glyph sequence loader thus becomes: void FontMgr::ComputeGlyphString (int x, int y, const char *text) { //FT_GlyphSlot slot = face->glyph; // a small shortcut FT_Bool use_kerning; FT_UInt previous; int pen_x, pen_y, n; PGlyphStruct ptrGlyph; // current glyph in table FT_Error error; int num_chars = strlen (text); //... create face object ... FT_Face face = get_font_family (current_font)->m_face; pen_x = x; // start at (0,0) pen_y = y; gNumGlyphs = 0; use_kerning = FT_HAS_KERNING ( face ); previous = 0; ptrGlyph = gGlyphs; for ( n = 0; n < num_chars; n++ ) { //ptrGlyph->index = FT_Get_Char_Index( face, text[n] ); ptrGlyph->index = get_font_style (current_font, current_style)->charmap[text[n]].glyph_index; if ( use_kerning && previous && ptrGlyph->index ) { FT_Vector delta; FT_Get_Kerning ( face, previous, ptrGlyph->index, FT_KERNING_DEFAULT, &delta ); pen_x += delta.x >> 6; } // store current pen position ptrGlyph->pos.x = pen_x; ptrGlyph->pos.y = pen_y; // error = FT_Load_Glyph(face, ptrGlyph->index, FT_LOAD_NO_BITMAP); // if ( error ) continue; // error = FT_Get_Glyph(face->glyph, &ptrGlyph->glyph); // if ( error ) continue; pen_x += get_font_style (current_font, current_style)->charmap[text[n]].hadvance; previous = ptrGlyph->index; // discard glyph image (bitmap or not) FT_Done_Glyph ( gGlyphs[n].glyph ); // increment number of glyphs ptrGlyph++; } // count number of glyphs loaded gNumGlyphs = ptrGlyph - gGlyphs; } unsigned int FontMgr::GetStringWidth (const std::string &text) { StringBBox stringBBox; ComputeStringBBox (stringBBox, text.c_str() ); return stringBBox.width; } unsigned int FontMgr::GetStringHeight (const std::string &text) { StringBBox stringBBox; ComputeStringBBox (stringBBox, text.c_str() ); return stringBBox.height; } void FontMgr::ComputeStringBBox (StringBBox &stringBBox, const char *text) { int numCharacter = strlen (text); FT_Face face = get_font_family (current_font)->m_face; FT_Bool use_kerning = FT_HAS_KERNING ( face ); int current_glyph_index = 0; int previous_glyph_index = 0; int width = 0; int max_ybearing = 0; int max_height = 0; int max_downline = 0; // for each glyph image, compute its bounding box, // translate it, and grow the string bbox for ( int n = 0; n < numCharacter; n++ ) { // set the character were interested in CharData cd = get_font_style (current_font, current_style)->charmap[text[n]]; current_glyph_index = cd.glyph_index; if (use_kerning && previous_glyph_index && cd.glyph_index) { FT_Vector delta; FT_Get_Kerning ( face, previous_glyph_index, current_glyph_index, FT_KERNING_DEFAULT, &delta ); width += delta.x >> 6; } width += cd.hadvance; if (cd.hbearingY > max_ybearing) max_ybearing = cd.hbearingY; if (cd.bitmap_height - cd.hbearingY > max_downline) max_downline = cd.bitmap_height - cd.hbearingY; if (cd.bitmap_height > max_height) max_height = cd.bitmap_height; previous_glyph_index = current_glyph_index; } stringBBox.x = 0; stringBBox.y = 0; stringBBox.width = width; stringBBox.height = max_ybearing + max_downline; stringBBox.ybearing = max_ybearing; stringBBox.downline = max_downline; } void FontMgr::PositionString (const PageBBox &pageBBox, StringBBox &strBBox, TextAlignment alignment) { int x, y; int xmin, ymin, xmax, ymax; xmin = pageBBox.xmin + pageBBox.x_margin; xmax = pageBBox.xmax - pageBBox.x_margin; ymin = pageBBox.ymin + pageBBox.y_margin; ymax = pageBBox.ymax - pageBBox.y_margin; switch (alignment) { case eAlignTextCenter: default: x = xmin + ( (float) (xmax - xmin) - (float) (strBBox.width) ) / 2.0f; y = ymin + ( (float) (ymax - ymin) - (float) (strBBox.height) ) / 2.0f + strBBox.ybearing; break; case eAlignTextLeft: x = xmin; y = ymin + ( (float) (ymax - ymin) - (float) (strBBox.height) ) / 2.0f + strBBox.ybearing; break; case eAlignTextRight: x = xmin + ( (float) (xmax - xmin) - (float) (strBBox.width) ); y = ymin + ( (float) (ymax - ymin) - (float) (strBBox.height) ) / 2.0f + strBBox.ybearing; break; } strBBox.x = x; strBBox.y = y; } void FontMgr::RenderGlyph (const PageBBox &pageSize, const char *text, TextAlignment alignment) { FT_Vector start; StringBBox stringBBox; // get bbox of original glyph sequence /*ComputeStringBBox(stringBBox, text); PositionString(pageSize, stringBBox, alignment); ComputeGlyphString(stringBBox.x, stringBBox.y, text);*/ // compute string dimensions in integer pixels //int string_width = stringBBox.width; //int string_height = stringBBox.height; // set up start position in 26.6 cartesian space //start.x = ( ( target_width - string_width ) / 2 ) * 64; //start.y = ( ( target_height - string_height ) / 2 ) * 64; float angle = 0; //FT_Matrix matrix; // set up transform (a rotation here) /*matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );*/ glEnable (GL_TEXTURE_2D); int bmpX; int bmpY; int bmpWidth; int bmpHeight; float u; float v; // int window_height = GfxServer::get_server()->getWindowHeight(); // glScissor(pageSize.xmin, window_height - pageSize.ymax, // pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin); gOpenGLEngine.PushClippingRectangle (inl::Rect (pageSize.xmin, pageSize.ymin, pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin) ); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for ( int n = 0; n < gNumGlyphs; n++ ) { unsigned int ascii_code = (unsigned int) text[n]; FT_Face face = get_font_family (current_font)->m_face; int gltexid = get_font_style ((char*)face->family_name, (char*)face->style_name)->charmap[ascii_code].gltexid; CharData cd = get_font_style ((char*)face->family_name, (char*)face->style_name)->charmap[ascii_code]; glBindTexture (GL_TEXTURE_2D, gltexid); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Set text Color here glColor4f (0.0f, 0.0f, 0.0f, 1); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (gltexid != get_null_character_texture_id() ) { bmpX = gGlyphs[n].pos.x + cd.bitmap_left_bearing; bmpY = gGlyphs[n].pos.y - cd.bitmap_top_bearing; bmpWidth = cd.bitmap_width; bmpHeight = cd.bitmap_height; if (cd.glTexWidth != 0 && cd.glTexHeight != 0) { u = float (cd.bitmap_width) / cd.glTexWidth; v = float (cd.bitmap_height) / cd.glTexHeight; } else { u = 1; v = 1; } glBegin (GL_QUADS); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.0f, 0.0f); glVertex3i (bmpX , bmpY, 1); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.0f, v); glVertex3i (bmpX , bmpY + bmpHeight, 1); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, u, v); glVertex3i (bmpX + bmpWidth, bmpY + bmpHeight, 1); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, u, 0.0f); glVertex3i (bmpX + bmpWidth, bmpY, 1); glEnd(); } } // FT_Face face = get_font_family(current_font)->m_face; // unsigned int ascii_code = (unsigned int) text[strlen(text)-1]; // CharData last_cd = get_font_style(face->family_name, face->style_name)->charmap[ascii_code]; // CharData dot_cd = get_font_style(face->family_name, face->style_name)->charmap['%']; // int dot_gltexid = get_font_style(face->family_name, face->style_name)->charmap['%'].gltexid; // // if(dot_cd.glTexWidth != 0 && dot_cd.glTexHeight != 0) // { // // This first check made sure that the GL texture for '.' has been loaded. // // Position of first dot // int posX = gGlyphs[gNumGlyphs-1].pos.x + last_cd.hadvance; // int posY = gGlyphs[gNumGlyphs-1].pos.y;// - dot_cd.bitmap_top_bearing; // // bmpWidth = dot_cd.bitmap_width; // bmpHeight = dot_cd.bitmap_height; // u = float(dot_cd.bitmap_width) / dot_cd.glTexWidth; // v = float(dot_cd.bitmap_height) / dot_cd.glTexHeight; // // glBindTexture(GL_TEXTURE_2D, dot_gltexid); // // int page_right_border_posX = pageSize.xmin + pageSize.xmax - pageSize.xmin; // while(posX + dot_cd.hadvance < page_right_border_posX) // { // bmpX = posX + dot_cd.bitmap_left_bearing; // bmpY = posY - dot_cd.bitmap_top_bearing; // // glBegin(GL_QUADS); // glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f); glVertex3i(bmpX , bmpY, 1); // glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, v); glVertex3i(bmpX , bmpY + bmpHeight, 1); // glMultiTexCoord2fARB(GL_TEXTURE0_ARB, u, v); glVertex3i(bmpX + bmpWidth, bmpY + bmpHeight, 1); // glMultiTexCoord2fARB(GL_TEXTURE0_ARB, u, 0.0f); glVertex3i(bmpX + bmpWidth, bmpY, 1); // glEnd(); // posX += dot_cd.hadvance; // } // } // GLDrawRectangle( // stringBBox.x, // stringBBox.y - stringBBox.ybearing, // stringBBox.x + stringBBox.width, // stringBBox.y - stringBBox.downline); glDisable (GL_BLEND); glDisable (GL_TEXTURE_2D); gOpenGLEngine.PopClippingRectangle(); } void FontMgr::RenderTextLineEdit (const PageBBox &pageSize, const std::string &Str, unsigned int CursorPosition, int offset) { FT_Vector start; StringBBox stringBBox; // get bbox of original glyph sequence ComputeStringBBox (stringBBox, Str.c_str() ); PositionString (pageSize, stringBBox, eAlignTextLeft); ComputeGlyphString (stringBBox.x + offset, stringBBox.y, Str.c_str() ); RenderGlyph (pageSize, Str.c_str(), eAlignTextLeft); // Render Cursor std::string temp = Str.substr (0, CursorPosition); int w = GetStringWidth (temp); int h = GetStringHeight (temp); glDisable (GL_TEXTURE_2D); glColor4f (1, 0, 0, 1); glBegin (GL_LINES); glVertex3i (pageSize.xmin + w + offset, pageSize.ymin, 1); glVertex3i (pageSize.xmin + w + offset, pageSize.ymax, 1); glEnd(); } void FontMgr::RenderTextLineStatic (const PageBBox &pageSize, const std::string &Str, TextAlignment alignment, char trailingchar) { return; FT_Vector start; StringBBox stringBBox; // get bbox of original glyph sequence ComputeStringBBox (stringBBox, Str.c_str() ); PositionString (pageSize, stringBBox, alignment); ComputeGlyphString (stringBBox.x, stringBBox.y, Str.c_str() ); RenderGlyph (pageSize, Str.c_str(), alignment); if (trailingchar == 0) return; const char *text = Str.c_str(); FT_Face face = get_font_family (current_font)->m_face; unsigned int ascii_code = (unsigned int) text[strlen (text)-1]; CharData last_cd = get_font_style ((char*)face->family_name, (char*)face->style_name)->charmap[ascii_code]; CharData dot_cd = get_font_style ((char*)face->family_name, (char*)face->style_name)->charmap[trailingchar]; int dot_gltexid = get_font_style ((char*)face->family_name, (char*)face->style_name)->charmap[trailingchar].gltexid; glEnable (GL_TEXTURE_2D); if (dot_cd.glTexWidth != 0 && dot_cd.glTexHeight != 0) { // This first check made sure that the GL texture for '.' has been loaded. // Position of first dot int posX = gGlyphs[gNumGlyphs-1].pos.x + last_cd.hadvance; int posY = gGlyphs[gNumGlyphs-1].pos.y; // - dot_cd.bitmap_top_bearing; int bmpWidth = dot_cd.bitmap_width; int bmpHeight = dot_cd.bitmap_height; float u = float (dot_cd.bitmap_width) / dot_cd.glTexWidth; float v = float (dot_cd.bitmap_height) / dot_cd.glTexHeight; // glBindTexture(GL_TEXTURE_2D, dot_gltexid); // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // // Set text Color here // glColor4f(0.0f, 0.0f, 0.0f, 1); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glEnable(GL_BLEND); // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); int page_right_border_posX = pageSize.xmin + pageSize.xmax - pageSize.xmin; while (posX + dot_cd.hadvance < page_right_border_posX) { int bmpX = posX + dot_cd.bitmap_left_bearing; int bmpY = posY - dot_cd.bitmap_top_bearing; glBegin (GL_QUADS); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.0f, 0.0f); glVertex3i (bmpX , bmpY, 1); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.0f, v); glVertex3i (bmpX , bmpY + bmpHeight, 1); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, u, v); glVertex3i (bmpX + bmpWidth, bmpY + bmpHeight, 1); glMultiTexCoord2fARB (GL_TEXTURE0_ARB, u, 0.0f); glVertex3i (bmpX + bmpWidth, bmpY, 1); glEnd(); posX += dot_cd.hadvance; } } glDisable (GL_BLEND); glDisable (GL_TEXTURE_2D); } nux-4.0.6+14.04.20140409/NuxGraphics/GLTemplatePrimitiveBuffer.cpp0000644000015301777760000002676212321344237024732 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GpuDevice.h" #include "GLTemplatePrimitiveBuffer.h" namespace nux { TemplateQuadBuffer::TemplateQuadBuffer(GpuDevice *pDeviceFactory, ShaderType Type, int NumQuads) : m_ShaderType(Type) { Memset(VertexAttributeBuffer, 0, 16); nuxAssert(pDeviceFactory); m_pDeviceFactory = pDeviceFactory; m_NumQuad = NumQuads; nuxAssert(m_NumQuad > 0); if (m_NumQuad < 0) m_NumQuad = 256; m_NumVertex = m_NumQuad * 6; FormatQuads(); } TemplateQuadBuffer::~TemplateQuadBuffer() { m_IB.Release(); for (unsigned int i = 0; i < 16; i++) { VertexAttributeBuffer[i].Release(); } } void TemplateQuadBuffer::FormatQuads() { // create vertex buffers for quad rendering // NumQuads * (4 vertices per Quad) * (4 Bytes per vertices) VertexAttributeBuffer[0] = m_pDeviceFactory->CreateVertexBuffer(m_NumQuad * 4 * 16, VBO_USAGE_DYNAMIC); // fill quad vertex buffer unsigned idx = 0; //BYTE* data0; float *data0; VertexAttributeBuffer[0]->Lock(0, m_NumQuad * 4 * 16, (void **) &data0); for (INT i = 0; i < m_NumQuad; ++i) { // (0, 0) _________(1, 0) // | /| // | / | // | / | // | / | // | / | // | / | // |/ | // (0, 1) --------- (1, 1) ((float *) data0) [idx++] = 0; // x ((float *) data0) [idx++] = 0; // y ((float *) data0) [idx++] = 0; // z ((float *) data0) [idx++] = 1.0f; // w ((float *) data0) [idx++] = 0; // x ((float *) data0) [idx++] = 1.0f; // y ((float *) data0) [idx++] = 0; // z ((float *) data0) [idx++] = 1; // w ((float *) data0) [idx++] = 1.0f; // x ((float *) data0) [idx++] = 1.0f; // y ((float *) data0) [idx++] = 0; // z ((float *) data0) [idx++] = 1; // w ((float *) data0) [idx++] = 1.0f; // x ((float *) data0) [idx++] = 0; // y ((float *) data0) [idx++] = 0; // z ((float *) data0) [idx++] = 1; // w // ((DWORD*)data0)[idx++]=((255*(0&1)))|((255*((0&2)>>1))<<8)|(0<<16)|(255<<24); // ((DWORD*)data0)[idx++]=((255*(1&1)))|((255*((1&2)>>1))<<8)|(0<<16)|(255<<24); // ((DWORD*)data0)[idx++]=((255*(3&1)))|((255*((3&2)>>1))<<8)|(0<<16)|(255<<24); // ((DWORD*)data0)[idx++]=((255*(2&1)))|((255*((2&2)>>1))<<8)|(0<<16)|(255<<24); } VertexAttributeBuffer[0]->Unlock(); // create index buffers for quad rendering // NumQuads * (6 index per Quad) * (2 Bytes per index) : each quad is 2 triangles => 6 indices. m_IB = m_pDeviceFactory->CreateIndexBuffer(m_NumQuad * 6 * 2, VBO_USAGE_DYNAMIC, INDEX_FORMAT_USHORT); // Fill quad index buffer // The index buffers defines 2 triangles for each quad. // Triangles are arranged as strips(that is 6 triangle index for a quad). WORD *data1; m_IB->Lock(0, m_NumQuad * 6 * 2, (void **) &data1); for (INT i = 0; i < m_NumQuad; ++i) { // // (0) _________(1) // | /| // | / | // | / | // | / | // | / | // | / | // |/ | // (3) --------- (2) // ((WORD *) data1) [i*6+0] = i * 4 + 0; ((WORD *) data1) [i*6+1] = i * 4 + 1; ((WORD *) data1) [i*6+2] = i * 4 + 3; ((WORD *) data1) [i*6+3] = i * 4 + 3; ((WORD *) data1) [i*6+4] = i * 4 + 1; ((WORD *) data1) [i*6+5] = i * 4 + 2; } m_IB->Unlock(); } void TemplateQuadBuffer::SetNumQuads(int NumQuads) { m_NumQuad = NumQuads; nuxAssert(m_NumQuad > 0); if (m_NumQuad < 0) m_NumQuad = 256; m_NumVertex = m_NumQuad * 6; m_IB = ObjectPtr (0);; for (int i = 0; i < 16; i++) VertexAttributeBuffer[i] = ObjectPtr (0); FormatQuads(); } int TemplateQuadBuffer::GetNumQuads() const { return m_NumQuad; } void TemplateQuadBuffer::UnBind() { m_pDeviceFactory->InvalidateIndexBuffer(); m_pDeviceFactory->InvalidateVertexBuffer(); } void TemplateQuadBuffer::BindAttribute(INT AttributeLocation, UINT AttributeIndex) { if (AttributeLocation < 0) { // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! return; } nuxAssert(AttributeIndex < 16); if (VertexAttributeBuffer[AttributeIndex].IsNull()) return; if (m_ShaderType == SHADER_TYPE_GLSL) { if (AttributeIndex == 0) { VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); CHECKGL(glEnableVertexAttribArrayARB(AttributeLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) AttributeLocation, 4, GL_FLOAT, GL_FALSE, 0, NUX_BUFFER_OFFSET(0))); } else { VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); CHECKGL(glEnableVertexAttribArrayARB(AttributeLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) AttributeLocation, 4, GL_FLOAT, GL_FALSE, 0, NUX_BUFFER_OFFSET(0))); } } else { nuxAssertMsg(0, "[TemplateQuadBuffer::BindCgAttribute] Use BindCGAttribute for CG attributes."); } } #if (NUX_ENABLE_CG_SHADERS) void TemplateQuadBuffer::BindCGAttribute(CGparameter AttributeLocation, UINT AttributeIndex) { if (AttributeLocation < 0) { // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! return; } nuxAssert(AttributeIndex >= 0); // Index 0 is the vertex position attribute. This on is set in the constructor. nuxAssert(AttributeIndex < 16); nuxAssert(AttributeLocation >= 0); if (VertexAttributeBuffer[AttributeIndex].IsNull()) return; if (m_ShaderType == SHADER_TYPE_CG) { if (AttributeIndex == 0) { VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); CHECKGL(cgGLEnableClientState((CGparameter) AttributeLocation)); CHECKGL(cgGLSetParameterPointer((CGparameter) AttributeLocation, 4, GL_FLOAT, 0, NUX_BUFFER_OFFSET(0))); } else { VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); CHECKGL(cgGLEnableClientState((CGparameter) AttributeLocation)); CHECKGL(cgGLSetParameterPointer((CGparameter) AttributeLocation, 4, GL_FLOAT, 0, NUX_BUFFER_OFFSET(0))); } } else { nuxAssertMsg(0, "[TemplateQuadBuffer::BindCGAttribute] Use BindAttribute for GLSL attributes."); } } #endif void TemplateQuadBuffer::UnBindAttribute(INT AttributeLocation) { if (AttributeLocation < 0) { // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! return; } if (m_ShaderType == SHADER_TYPE_GLSL) { CHECKGL(glDisableVertexAttribArrayARB(AttributeLocation)); } else { nuxAssertMsg(0, "[TemplateQuadBuffer::UnBindAttribute] Use UnBindCGAttribute for CG attributes."); } } #if (NUX_ENABLE_CG_SHADERS) void TemplateQuadBuffer::UnBindCGAttribute(CGparameter AttributeLocation) { if (AttributeLocation < 0) { // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! return; } if (m_ShaderType == SHADER_TYPE_CG) { CHECKGL(cgGLDisableClientState((CGparameter) AttributeLocation)); } else { nuxAssertMsg(0, "[TemplateQuadBuffer::UnBindCGAttribute] Use UnBindAttribute for GLSL attributes."); } } #endif void TemplateQuadBuffer::Render(INT NumPrimitives) { INT NumVertex = NumPrimitives * 6; // each quad is 2 triangles = 6 indices if (NumVertex > m_NumVertex) { NumVertex = m_NumVertex; } m_IB->BindIndexBuffer(); CHECKGL(glDrawElements( GL_TRIANGLES, NumVertex, GL_UNSIGNED_SHORT, NUX_BUFFER_OFFSET(0))); m_pDeviceFactory->InvalidateIndexBuffer(); } void TemplateQuadBuffer::SetPerQuadAttribute(UINT AttributeIndex, INT Num, Vector4 *pVector) { nuxAssert(AttributeIndex > 0); // Index 0 is the vertex position attribute. This on is set in the constructor. nuxAssert(AttributeIndex < 16); // Destroy the vertex buffer by setting it to NULL; VertexAttributeBuffer[AttributeIndex] = ObjectPtr (0);; VertexAttributeBuffer[AttributeIndex] = m_pDeviceFactory->CreateVertexBuffer(m_NumQuad * 4 * sizeof(Vector4), VBO_USAGE_DYNAMIC); FLOAT *data; VertexAttributeBuffer[AttributeIndex]->Lock(0, m_NumQuad * 4 * sizeof(Vector4), (void **) &data); INT i; for (i = 0; (i < m_NumQuad) && (i < Num); i++) { for (INT j = 0; j < 4; j++) { data[16*i + 4*j + 0] = pVector[i].x; data[16*i + 4*j + 1] = pVector[i].y; data[16*i + 4*j + 2] = pVector[i].z; data[16*i + 4*j + 3] = pVector[i].w; } } while (i < m_NumQuad) { // this happens if Num < m_NumQuad. // Fill the rest with the last element of the parameter array passed as argument of the function. for (INT j = 0; j < 4; j++) { data[16*i + 4*j + 0] = pVector[Num-1].x; data[16*i + 4*j + 1] = pVector[Num-1].y; data[16*i + 4*j + 2] = pVector[Num-1].z; data[16*i + 4*j + 3] = pVector[Num-1].w; } i++; } VertexAttributeBuffer[AttributeIndex]->Unlock(); } void TemplateQuadBuffer::SetPerVertexAttribute(UINT AttributeIndex, INT Num, Vector4 *pVector) { nuxAssert(AttributeIndex > 0); // Index 0 is the vertex position attribute. This on is set in the constructor. nuxAssert(AttributeIndex < 16); // Destroy the vertex buffer by setting it to NULL; VertexAttributeBuffer[AttributeIndex] = ObjectPtr (0);; VertexAttributeBuffer[AttributeIndex] = m_pDeviceFactory->CreateVertexBuffer(m_NumQuad * 4 * sizeof(Vector4), VBO_USAGE_DYNAMIC); FLOAT *data; VertexAttributeBuffer[AttributeIndex]->Lock(0, m_NumQuad * 4 * sizeof(Vector4), (void **) &data); INT i; for (i = 0; (i < m_NumQuad * 4) && (i < Num); i++) { data[4*i+0] = pVector[i].x; data[4*i+1] = pVector[i].y; data[4*i+2] = pVector[i].z; data[4*i+3] = pVector[i].w; } while (i < m_NumQuad * 4) { // this happens if Num < m_NumQuad. // Fill the rest with the last element of the parameter array passed as argument of the function. data[4*i+0] = pVector[Num-1].x; data[4*i+1] = pVector[Num-1].y; data[4*i+2] = pVector[Num-1].z; data[4*i+3] = pVector[Num-1].w; i++; } VertexAttributeBuffer[AttributeIndex]->Unlock(); } void TemplateQuadBuffer::UnSetQuadAttribute(UINT /* AttributeIndex */) { } } nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipeAsm.cpp0000644000015301777760000034213712321344237023102 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUX_OPENGLES_20 #include "GLResource.h" #include "IOpenGLBaseTexture.h" #include "RenderingPipe.h" #include "GraphicsEngine.h" namespace nux { // Conventional Attribute Binding Generic Attribute Binding // ------------------------------ ------------------------- // vertex.position vertex.attrib[0] // vertex.weight vertex.attrib[1] // vertex.weight[0] vertex.attrib[1] // vertex.normal vertex.attrib[2] // vertex.color vertex.attrib[3] // vertex.color.primary vertex.attrib[3] // vertex.color.secondary vertex.attrib[4] // vertex.fogcoord vertex.attrib[5] // vertex.texcoord vertex.attrib[8] // vertex.texcoord[0] vertex.attrib[8] // vertex.texcoord[1] vertex.attrib[9] // vertex.texcoord[2] vertex.attrib[10] // vertex.texcoord[3] vertex.attrib[11] // vertex.texcoord[4] vertex.attrib[12] // vertex.texcoord[5] vertex.attrib[13] // vertex.texcoord[6] vertex.attrib[14] // vertex.texcoord[7] vertex.attrib[15] // vertex.texcoord[n] vertex.attrib[8+n] // # Vertex Attribute Registers // # attribute Register Components Underlying State // # vertex.position (x,y,z,w) object position // # vertex.weight (w,w,w,w) vertex weights 0-3 // # vertex.weight[n] (w,w,w,w) vertex weights n-n+3 // # vertex.normal (x,y,z,1) NORMAL // # vertex.color (r,g,b,a) primary color // # vertex.color.primary (r,g,b,a) primary color // # vertex.color.secondary (r,g,b,a) secondary color // # vertex.fogcoord (f,0,0,1) fog coordinate // # vertex.texcoord (s,t,r,q) texture coordinate, unit 0 // # vertex.texcoord[n] (s,t,r,q) texture coordinate, unit n // # vertex.matrixindex (i,i,i,i) vertex matrix indices 0-3 // # vertex.matrixindex[n] (i,i,i,i) vertex matrix indices n-n+3 // # vertex.attrib[n] (x,y,z,w) generic vertex attribute n // // // # Result Register Components Description // # result.position (x,y,z,w) position in clip coordinates // # result.color (r,g,b,a) front-facing, primary color // # result.color.primary (r,g,b,a) front-facing, primary color // # result.color.front (r,g,b,a) front-facing, primary color // # result.color.front.primary (r,g,b,a) front-facing, primary color // # result.color.front.secondary (r,g,b,a) front-facing, secondary color // # result.color.back (r,g,b,a) back-facing, primary color // # result.color.back.primary (r,g,b,a) back-facing, primary color // # result.color.back.secondary (r,g,b,a) back-facing, secondary color // # result.fogcoord (f,*,*,*) fog coordinate // # result.pointsize (s,*,*,*) point size // # result.texcoord (s,t,r,q) texture coordinate, unit 0 // # result.color.secondary (r,g,b,a) front-facing, secondary color // # result.texcoord[n] (s,t,r,q) texture coordinate, unit n // # Fragment Attribute Binding Components Underlying State // # -------------------------- ---------- ---------------------------- // # fragment.color (r,g,b,a) primary color // # fragment.color.primary (r,g,b,a) primary color // # fragment.color.secondary (r,g,b,a) secondary color // # fragment.texcoord (s,t,r,q) texture coordinate, unit 0 // # fragment.texcoord[n] (s,t,r,q) texture coordinate, unit n // # fragment.fogcoord (f,0,0,1) fog distance/coordinate // # fragment.position (x,y,z,1/w) window position // # Fragment Program Results Components Description // # ----------------------------- ---------- ---------------------------- // # result.color (r,g,b,a) color // # result.depth (*,*,d,*) depth coordinate void GraphicsEngine::InitAsmColorShader() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ ATTRIB iColor = vertex.attrib[3]; \n\ PARAM mvp[4] = {state.matrix.mvp}; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oColor = result.color; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, mvp[0], iPos; \n\ DP4 oPos.y, mvp[1], iPos; \n\ DP4 oPos.z, mvp[2], iPos; \n\ DP4 oPos.w, mvp[3], iPos; \n\ MOV oColor, iColor; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ MOV result.color, fragment.color; \n\ END"; m_AsmColor = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmColor->LoadVertexShader(AsmVtx); m_AsmColor->LoadPixelShader(AsmFrg); m_AsmColor->Link(); } void GraphicsEngine::InitAsmTextureShader() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ ATTRIB iColor = vertex.attrib[3]; \n\ PARAM mvp[4] = {state.matrix.mvp}; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oColor = result.color; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, mvp[0], iPos; \n\ DP4 oPos.y, mvp[1], iPos; \n\ DP4 oPos.z, mvp[2], iPos; \n\ DP4 oPos.w, mvp[3], iPos; \n\ MOV oColor, iColor; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MUL result.color, fragment.color, tex0; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MUL result.color, fragment.color, tex0; \n\ END"; m_AsmTextureModColor = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmTextureModColor->LoadVertexShader(AsmVtx); m_AsmTextureModColor->LoadPixelShader(AsmFrg); m_AsmTextureModColor->Link(); m_AsmTextureRectModColor = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmTextureRectModColor->LoadVertexShader(AsmVtx); m_AsmTextureRectModColor->LoadPixelShader(AsmFrgRect); m_AsmTextureRectModColor->Link(); } void GraphicsEngine::InitAsmColorModTexMaskAlpha() { const char* AsmVtx = "!!ARBvp1.0 \n\ OUTPUT oPos = result.position; \n\ OUTPUT oColor = result.color; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oColor, vertex.attrib[3]; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MOV temp, fragment.color; \n\ MUL temp.w, fragment.color, tex0.wwww; \n\ MOV result.color, temp; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MOV temp, fragment.color; \n\ MUL temp.w, fragment.color, tex0.wwww; \n\ MOV result.color, temp; \n\ END"; m_AsmColorModTexMaskAlpha = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmColorModTexMaskAlpha->LoadVertexShader(AsmVtx); m_AsmColorModTexMaskAlpha->LoadPixelShader(AsmFrg); m_AsmColorModTexMaskAlpha->Link(); m_AsmColorModTexRectMaskAlpha = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmColorModTexRectMaskAlpha->LoadVertexShader(AsmVtx); m_AsmColorModTexRectMaskAlpha->LoadPixelShader(AsmFrgRect); m_AsmColorModTexRectMaskAlpha->Link(); } void GraphicsEngine::InitAsm2TextureAdd() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ OUTPUT oTexCoord1 = result.texcoord[1]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ MOV oTexCoord1, vertex.attrib[9]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MUL temp, color0, tex0; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ MAD temp, color1, tex1, temp; \n\ MOV result.color, temp; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MUL temp, color0, tex0; \n\ TEX tex1, fragment.texcoord[1], texture[1], RECT; \n\ MAD temp, color1, tex1, temp; \n\ MOV result.color, temp; \n\ END"; m_Asm2TextureAdd = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_Asm2TextureAdd->LoadVertexShader(AsmVtx); m_Asm2TextureAdd->LoadPixelShader(AsmFrg); m_Asm2TextureAdd->Link(); m_Asm2TextureRectAdd = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_Asm2TextureRectAdd->LoadVertexShader(AsmVtx); m_Asm2TextureRectAdd->LoadPixelShader(AsmFrgRect); m_Asm2TextureRectAdd->Link(); } void GraphicsEngine::InitAsm2TextureDepRead() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ OUTPUT oTexCoord1 = result.texcoord[1]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ MOV oTexCoord1, vertex.attrib[9]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp; \n\ TEMP temp0; \n\ TEMP temp1; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MAD temp, {2.0, 2.0, 2.0, 2.0}, tex0, {-1.0, -1.0, -1.0, -1.0}; \n\ MUL temp0, color0, temp; \n\ ADD temp1, texture[1]; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ MUL result.color, color1, tex1; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MAD temp, {2.0, 2.0, 2.0, 2.0}, tex0, {-1.0, -1.0, -1.0, -1.0}; \n\ MUL temp, color0, tex0; \n\ TEX tex1, fragment.texcoord[1], temp, RECT; \n\ MUL result.color, color1, tex1; \n\ END"; m_ASM2TextureDepRead = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_ASM2TextureDepRead->LoadVertexShader(AsmVtx); m_ASM2TextureDepRead->LoadPixelShader(AsmFrg); m_ASM2TextureDepRead->Link(); m_ASM2TextureRectDepRead = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_ASM2TextureRectDepRead->LoadVertexShader(AsmVtx); m_ASM2TextureRectDepRead->LoadPixelShader(AsmFrgRect); m_ASM2TextureRectDepRead->Link(); } void GraphicsEngine::InitAsm2TextureMod() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ OUTPUT oTexCoord1 = result.texcoord[1]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ MOV oTexCoord1, vertex.attrib[9]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp0; \n\ TEMP temp1; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MUL temp0, color0, tex0; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ MUL temp1, color1, tex1; \n\ MUL result.color, temp0, temp1; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp0; \n\ TEMP temp1; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MUL temp0, color0, tex0; \n\ TEX tex1, fragment.texcoord[1], texture[1], RECT; \n\ MUL temp1, color1, tex1; \n\ MUL result.color, temp0, temp1; \n\ END"; m_Asm2TextureMod = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_Asm2TextureMod->LoadVertexShader(AsmVtx); m_Asm2TextureMod->LoadPixelShader(AsmFrg); m_Asm2TextureMod->Link(); m_Asm2TextureRectMod = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_Asm2TextureRectMod->LoadVertexShader(AsmVtx); m_Asm2TextureRectMod->LoadPixelShader(AsmFrgRect); m_Asm2TextureRectMod->Link(); } void GraphicsEngine::InitAsm4TextureAdd() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ OUTPUT oTexCoord1 = result.texcoord[1]; \n\ OUTPUT oTexCoord2 = result.texcoord[2]; \n\ OUTPUT oTexCoord3 = result.texcoord[3]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ MOV oTexCoord1, vertex.attrib[9]; \n\ MOV oTexCoord2, vertex.attrib[10]; \n\ MOV oTexCoord3, vertex.attrib[11]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ PARAM color2 = program.local[2]; \n\ PARAM color3 = program.local[3]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP tex2; \n\ TEMP tex3; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MUL temp, color0, tex0; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ MAD temp, color1, tex1, temp; \n\ TEX tex2, fragment.texcoord[2], texture[2], 2D; \n\ MAD temp, color2, tex2, temp; \n\ TEX tex3, fragment.texcoord[3], texture[3], 2D; \n\ MAD temp, color3, tex3, temp; \n\ MOV result.color, temp; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM color1 = program.local[1]; \n\ PARAM color2 = program.local[2]; \n\ PARAM color3 = program.local[3]; \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP tex2; \n\ TEMP tex3; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MUL temp, color0, tex0; \n\ TEX tex1, fragment.texcoord[1], texture[1], RECT; \n\ MAD temp, color1, tex1, temp; \n\ TEX tex2, fragment.texcoord[2], texture[2], RECT; \n\ MAD temp, color2, tex2, temp; \n\ TEX tex3, fragment.texcoord[3], texture[3], RECT; \n\ MAD temp, color3, tex3, temp; \n\ MOV result.color, temp; \n\ END"; m_Asm4TextureAdd = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_Asm4TextureAdd->LoadVertexShader(AsmVtx); m_Asm4TextureAdd->LoadPixelShader(AsmFrg); m_Asm4TextureAdd->Link(); m_Asm4TextureRectAdd = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_Asm4TextureRectAdd->LoadVertexShader(AsmVtx); m_Asm4TextureRectAdd->LoadPixelShader(AsmFrgRect); m_Asm4TextureRectAdd->Link(); } void GraphicsEngine::InitAsmBlendModes() { const char* AsmVtx = "!!ARBvp1.0 \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ OUTPUT oTexCoord1 = result.texcoord[1]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ MOV oTexCoord1, vertex.attrib[9]; \n\ END"; const char* AsmPSBNormal = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ MOV result.color, tex0; \n\ END"; m_AsmPSBNormal = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmPSBNormal->LoadVertexShader(AsmVtx); m_AsmPSBNormal->LoadPixelShader(AsmPSBNormal); m_AsmPSBNormal->Link(); // Lighten const char* AsmPSBLighten = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp; \n\ TEMP cmpres; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ SUB temp, tex0, tex1; \n\ CMP cmpres, temp, tex1, tex0; \n\ MOV result.color, temp; \n\ END"; m_AsmPSBLighten = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmPSBLighten->LoadVertexShader(AsmVtx); m_AsmPSBLighten->LoadPixelShader(AsmPSBLighten); m_AsmPSBLighten->Link(); // Darken const char* AsmPSBDarken = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp; \n\ TEMP cmpres; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ SUB temp, tex1, tex0; \n\ CMP cmpres, temp, tex1, tex0; \n\ MOV result.color, temp; \n\ END"; m_AsmPSBDarken = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmPSBDarken->LoadVertexShader(AsmVtx); m_AsmPSBDarken->LoadPixelShader(AsmPSBDarken); m_AsmPSBDarken->Link(); // Multiply const char* AsmPSBMultiply = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP tex1; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ TEX tex1, fragment.texcoord[1], texture[1], 2D; \n\ MUL result.color, tex0, tex1; \n\ END"; m_AsmPSBMultiply = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmPSBMultiply->LoadVertexShader(AsmVtx); m_AsmPSBMultiply->LoadPixelShader(AsmPSBMultiply); m_AsmPSBMultiply->Link(); } void GraphicsEngine::QRP_ASM_Color(int x, int y, int width, int height, const Color &c0) { QRP_ASM_Color(x, y, width, height, c0, c0, c0, c0); } void GraphicsEngine::QRP_ASM_Color(int x, int y, int width, int height, const Color &c0, const Color &c1, const Color &c2, const Color &c3) { NUX_RETURN_IF_FALSE(m_AsmColor.IsValid()); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, c0.red, c0.green, c0.blue, c0.alpha, fx, fy + height, 0.0f, 1.0f, c1.red, c1.green, c1.blue, c1.alpha, fx + width, fy + height, 0.0f, 1.0f, c2.red, c2.green, c2.blue, c2.alpha, fx + width, fy, 0.0f, 1.0f, c3.red, c3.green, c3.blue, c3.alpha, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_AsmColor; shader_program->Begin(); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int VertexColorLocation = VTXATTRIB_COLOR; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); shader_program->End(); } void GraphicsEngine::QRP_ASM_1Tex(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color &color) { NUX_RETURN_IF_FALSE(m_AsmTextureModColor.IsValid()); NUX_RETURN_IF_FALSE(m_AsmTextureRectModColor.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_AsmTextureModColor; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_AsmTextureRectModColor; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int VertexColorLocation = VTXATTRIB_COLOR; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); shader_program->End(); } void GraphicsEngine::QRP_ASM_ColorModTexAlpha(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color &color) { NUX_RETURN_IF_FALSE(m_AsmColorModTexMaskAlpha.IsValid()); NUX_RETURN_IF_FALSE(m_AsmColorModTexRectMaskAlpha.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_AsmColorModTexMaskAlpha; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_AsmColorModTexRectMaskAlpha; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int VertexColorLocation = VTXATTRIB_COLOR; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); shader_program->End(); } void GraphicsEngine::QRP_ASM_2Tex(int x, int y, int width, int height, ObjectPtr device_texture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr device_texture1, TexCoordXForm &texxform1, const Color &color1) { NUX_RETURN_IF_FALSE(m_Asm2TextureAdd.IsValid()); NUX_RETURN_IF_FALSE(m_Asm2TextureRectAdd.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture0, texxform0); QRP_Compute_Texture_Coord(width, height, device_texture1, texxform1); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0.0f, 1.0f, texxform1.u0, texxform1.v0, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0.0f, 1.0f, texxform1.u0, texxform1.v1, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0.0f, 1.0f, texxform1.u1, texxform1.v1, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0.0f, 1.0f, texxform1.u1, texxform1.v0, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_Asm2TextureAdd; if (device_texture0->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_Asm2TextureRectAdd; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture0); SetTexture(GL_TEXTURE1, device_texture1); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int TextureCoord1Location = VTXATTRIB_TEXCOORD1; CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, color0.red, color0.green, color0.blue, color0.alpha )); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, color1.red, color1.green, color1.blue, color1.alpha )); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); shader_program->End(); } void GraphicsEngine::QRP_ASM_DisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm &texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm &texxform1, const Color& c1) { NUX_RETURN_IF_FALSE(m_ASM2TextureDepRead.IsValid()); NUX_RETURN_IF_FALSE(m_ASM2TextureRectDepRead.IsValid()); QRP_Compute_Texture_Coord(width, height, distorsion_texture, texxform0); QRP_Compute_Texture_Coord(width, height, src_device_texture, texxform1); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0.0f, 1.0f, texxform1.u0, texxform1.v0, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0.0f, 1.0f, texxform1.u0, texxform1.v1, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0.0f, 1.0f, texxform1.u1, texxform1.v1, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0.0f, 1.0f, texxform1.u1, texxform1.v0, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_ASM2TextureDepRead; if (src_device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_ASM2TextureRectDepRead; } shader_program->Begin(); SetTexture(GL_TEXTURE0, distorsion_texture); SetTexture(GL_TEXTURE1, src_device_texture); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int TextureCoord1Location = VTXATTRIB_TEXCOORD1; CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, c0.red, c0.green, c0.blue, c0.alpha )); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, c1.red, c1.green, c1.blue, c1.alpha )); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); shader_program->End(); } void GraphicsEngine::QRP_ASM_2TexMod(int x, int y, int width, int height, ObjectPtr device_texture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr device_texture1, TexCoordXForm &texxform1, const Color &color1) { NUX_RETURN_IF_FALSE(m_Asm2TextureMod.IsValid()); NUX_RETURN_IF_FALSE(m_Asm2TextureRectMod.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture0, texxform0); QRP_Compute_Texture_Coord(width, height, device_texture1, texxform1); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0.0f, 1.0f, texxform1.u0, texxform1.v0, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0.0f, 1.0f, texxform1.u0, texxform1.v1, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0.0f, 1.0f, texxform1.u1, texxform1.v1, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0.0f, 1.0f, texxform1.u1, texxform1.v0, 0.0f, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_Asm2TextureMod; if (device_texture0->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_Asm2TextureRectMod; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture0); SetTexture(GL_TEXTURE1, device_texture1); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int TextureCoord1Location = VTXATTRIB_TEXCOORD1; CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, color0.red, color0.green, color0.blue, color0.alpha )); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, color1.red, color1.green, color1.blue, color1.alpha )); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); shader_program->End(); } void GraphicsEngine::QRP_ASM_4Tex(int x, int y, int width, int height, ObjectPtr device_texture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr device_texture1, TexCoordXForm &texxform1, const Color &color1, ObjectPtr device_texture2, TexCoordXForm &texxform2, const Color &color2, ObjectPtr device_texture3, TexCoordXForm &texxform3, const Color &color3) { NUX_RETURN_IF_FALSE(m_Asm4TextureAdd.IsValid()); NUX_RETURN_IF_FALSE(m_Asm4TextureRectAdd.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture0, texxform0); QRP_Compute_Texture_Coord(width, height, device_texture1, texxform1); QRP_Compute_Texture_Coord(width, height, device_texture2, texxform1); QRP_Compute_Texture_Coord(width, height, device_texture3, texxform1); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 1.0f, texxform1.u0, texxform1.v0, 0, 1.0f, texxform2.u0, texxform2.v0, 0, 1.0f, texxform3.u0, texxform3.v0, 0, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 1.0f, texxform1.u0, texxform1.v1, 0, 1.0f, texxform2.u0, texxform2.v1, 0, 1.0f, texxform3.u0, texxform3.v1, 0, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 1.0f, texxform1.u1, texxform1.v1, 0, 1.0f, texxform2.u1, texxform2.v1, 0, 1.0f, texxform3.u1, texxform3.v1, 0, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 1.0f, texxform1.u1, texxform1.v0, 0, 1.0f, texxform2.u1, texxform2.v0, 0, 1.0f, texxform3.u1, texxform3.v0, 0, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_Asm4TextureAdd; if (device_texture0->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_Asm4TextureRectAdd; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture0); SetTexture(GL_TEXTURE1, device_texture1); SetTexture(GL_TEXTURE2, device_texture1); SetTexture(GL_TEXTURE3, device_texture1); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int TextureCoord1Location = VTXATTRIB_TEXCOORD1; int TextureCoord2Location = VTXATTRIB_TEXCOORD2; int TextureCoord3Location = VTXATTRIB_TEXCOORD3; CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, color0.red, color0.green, color0.blue, color0.alpha )); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, color1.red, color1.green, color1.blue, color1.alpha )); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, color2.red, color2.green, color2.blue, color2.alpha )); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 3, color3.red, color3.green, color3.blue, color3.alpha )); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 4)); } if (TextureCoord1Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 8)); } if (TextureCoord2Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord2Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord2Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 12)); } if (TextureCoord3Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord3Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord3Location, 4, GL_FLOAT, GL_FALSE, 80, VtxBuffer + 16)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); if (TextureCoord2Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord2Location)); if (TextureCoord3Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord3Location)); shader_program->End(); } //////////////////////////////////////////////////////////////////////////////////// void GraphicsEngine::QRP_ASM_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0) { QRP_ASM_Triangle(x0, y0, x1, y1, x2, y2, c0, c0, c0); } void GraphicsEngine::QRP_ASM_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2) { NUX_RETURN_IF_FALSE(m_AsmColor.IsValid()); float VtxBuffer[] = { static_cast(x0), static_cast(y0), 0.0f, 1.0f, c0.red, c0.green, c0.blue, c0.alpha, static_cast(x1), static_cast(y1), 0.0f, 1.0f, c1.red, c1.green, c1.blue, c1.alpha, static_cast(x2), static_cast(y2), 0.0f, 1.0f, c2.red, c2.green, c2.blue, c2.alpha, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr ShaderProg = m_AsmColor; ShaderProg->Begin(); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int VertexColorLocation = VTXATTRIB_COLOR; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); CHECKGL(glDrawArrays(GL_TRIANGLES, 0, 3)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); m_triangle_stats++; } ////////////////////// // DRAW LINES // ////////////////////// void GraphicsEngine::QRP_ASM_Line(int x0, int y0, int x1, int y1, Color c0) { QRP_ASM_Line(x0, y0, x1, y1, c0, c0); } void GraphicsEngine::QRP_ASM_Line(int x0, int y0, int x1, int y1, Color c0, Color c1) { NUX_RETURN_IF_FALSE(m_AsmColor.IsValid()); float VtxBuffer[] = { static_cast(x0), static_cast(y0), 0.0f, 1.0f, c0.red, c0.green, c0.blue, c0.alpha, static_cast(x1), static_cast(y1), 0.0f, 1.0f, c1.red, c1.green, c1.blue, c1.alpha, }; ObjectPtr ShaderProg = m_AsmColor; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int VertexColorLocation = VTXATTRIB_COLOR; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_LINES, 0, 2)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); m_line_stats++; } void GraphicsEngine::QRP_ASM_QuadWireframe(int x0, int y0, int width, int height, Color c0, Color c1, Color c2, Color c3) { NUX_RETURN_IF_FALSE(m_AsmColor.IsValid()); float fx0 = x0, fy0 = y0; float VtxBuffer[] = { fx0, fy0, 0.0f, 1.0f, c0.red, c0.green, c0.blue, c0.alpha, fx0, fy0 + height - 1, 0.0f, 1.0f, c1.red, c1.green, c1.blue, c1.alpha, fx0 + width - 1, fy0 + height - 1, 0.0f, 1.0f, c2.red, c2.green, c2.blue, c2.alpha, fx0 + width - 1, fy0, 0.0f, 1.0f, c3.red, c3.green, c3.blue, c3.alpha, fx0, fy0, 0.0f, 1.0f, c0.red, c0.green, c0.blue, c0.alpha, }; ObjectPtr ShaderProg = m_AsmColor; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ShaderProg->Begin(); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int VertexColorLocation = VTXATTRIB_COLOR; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_LINE_STRIP, 0, 5)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); ShaderProg->End(); m_line_stats++; } void GraphicsEngine::InitAsmPower() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM exponent = program.local[1]; \n\ TEMP tex0; \n\ TEMP final; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ POW final.r, tex0.r, exponent.r; \n\ POW final.g, tex0.g, exponent.g; \n\ POW final.b, tex0.b, exponent.b; \n\ MOV final.a, tex0.a; \n\ MUL result.color, color0, final; \n\ END"; _asm_tex_component_exponentiation_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_tex_component_exponentiation_prog->LoadVertexShader(AsmVtx); _asm_tex_component_exponentiation_prog->LoadPixelShader(AsmFrg); _asm_tex_component_exponentiation_prog->Link(); } void GraphicsEngine::QRP_ASM_Power (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color &c0, Vector4 exponent) { NUX_RETURN_IF_FALSE(_asm_tex_component_exponentiation_prog.IsValid()); NUX_RETURN_IF_FALSE(_asm_texrect_component_exponentiation_prog.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = _asm_tex_component_exponentiation_prog; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = _asm_texrect_component_exponentiation_prog; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, c0.red, c0.green, c0.blue, c0.alpha)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, exponent.x, exponent.y, exponent.z, exponent.w)); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); shader_program->End(); } void GraphicsEngine::InitAsmAlphaReplicate() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ TEMP tex0; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MUL result.color, color0, tex0.aaaa; \n\ END"; _asm_tex_alpha_replicate_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_tex_alpha_replicate_prog->LoadVertexShader(AsmVtx); _asm_tex_alpha_replicate_prog->LoadPixelShader(AsmFrg); _asm_tex_alpha_replicate_prog->Link(); } void GraphicsEngine::QRP_ASM_AlphaReplicate(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color &c0) { NUX_RETURN_IF_FALSE(_asm_tex_alpha_replicate_prog.IsValid()); NUX_RETURN_IF_FALSE(_asm_texrect_alpha_replicate_prog.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = _asm_tex_alpha_replicate_prog; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = _asm_texrect_alpha_replicate_prog; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, c0.red, c0.green, c0.blue, c0.alpha)); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); shader_program->End(); } void GraphicsEngine::InitAsmColorMatrixFilter() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM CM0 = program.local[1]; \n\ PARAM CM1 = program.local[2]; \n\ PARAM CM2 = program.local[3]; \n\ PARAM CM3 = program.local[4]; \n\ PARAM offset = program.local[5]; \n\ TEMP tex0; \n\ TEMP final; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MAD final.r, tex0, CM0, offset.r; \n\ MAD final.g, tex0, CM1, offset.g; \n\ MAD final.b, tex0, CM2, offset.b; \n\ MAD final.a, tex0, CM3, offset.a; \n\ MUL result.color, color0, final; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ PARAM color0 = program.local[0]; \n\ PARAM CM0 = program.local[1]; \n\ PARAM CM1 = program.local[2]; \n\ PARAM CM2 = program.local[3]; \n\ PARAM CM3 = program.local[4]; \n\ PARAM offset = program.local[5]; \n\ TEMP tex0; \n\ TEMP final; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MAD final.r, tex0, CM0, offset.r; \n\ MAD final.g, tex0, CM1, offset.g; \n\ MAD final.b, tex0, CM2, offset.b; \n\ MAD final.a, tex0, CM3, offset.a; \n\ MUL result.color, color0, final; \n\ END"; _asm_tex_color_matrix_filter_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_tex_color_matrix_filter_prog->LoadVertexShader(AsmVtx); _asm_tex_color_matrix_filter_prog->LoadPixelShader(AsmFrg); _asm_tex_color_matrix_filter_prog->Link(); _asm_texrect_color_matrix_filter_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_texrect_color_matrix_filter_prog->LoadVertexShader(AsmVtx); _asm_texrect_color_matrix_filter_prog->LoadPixelShader(AsmFrgRect); _asm_texrect_color_matrix_filter_prog->Link(); } void GraphicsEngine::QRP_ASM_ColorMatrix (int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color &c0, Matrix4 color_matrix, Vector4 offset) { NUX_RETURN_IF_FALSE(_asm_tex_color_matrix_filter_prog.IsValid()); NUX_RETURN_IF_FALSE(_asm_texrect_color_matrix_filter_prog.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = _asm_tex_color_matrix_filter_prog; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = _asm_texrect_color_matrix_filter_prog; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, c0.red, c0.green, c0.blue, c0.alpha)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, color_matrix.m[0][0], color_matrix.m[0][1], color_matrix.m[0][2], color_matrix.m[0][3])); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, color_matrix.m[1][0], color_matrix.m[1][1], color_matrix.m[1][2], color_matrix.m[1][3])); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 3, color_matrix.m[2][0], color_matrix.m[2][1], color_matrix.m[2][2], color_matrix.m[2][3])); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 4, color_matrix.m[3][0], color_matrix.m[3][1], color_matrix.m[3][2], color_matrix.m[3][3])); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 5, offset.x, offset.y, offset.z, offset.w)); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); shader_program->End(); } void GraphicsEngine::InitAsmSeparableGaussFilter() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ OUTPUT oTexCoord1 = result.texcoord[1]; \n\ OUTPUT oTexCoord2 = result.texcoord[2]; \n\ OUTPUT oTexCoord3 = result.texcoord[3]; \n\ OUTPUT oTexCoord4 = result.texcoord[4]; \n\ OUTPUT oTexCoord5 = result.texcoord[5]; \n\ OUTPUT oTexCoord6 = result.texcoord[6]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, state.matrix.mvp.row[0], vertex.position; \n\ DP4 oPos.y, state.matrix.mvp.row[1], vertex.position; \n\ DP4 oPos.z, state.matrix.mvp.row[2], vertex.position; \n\ DP4 oPos.w, state.matrix.mvp.row[3], vertex.position; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ MOV oTexCoord1, vertex.attrib[9]; \n\ MOV oTexCoord2, vertex.attrib[10]; \n\ MOV oTexCoord3, vertex.attrib[11]; \n\ MOV oTexCoord4, vertex.attrib[12]; \n\ MOV oTexCoord5, vertex.attrib[13]; \n\ MOV oTexCoord6, vertex.attrib[14]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP final; \n\ MOV final, {0, 0, 0, 0}; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MAD final, tex0, program.local[0], final; \n\ TEX tex0, fragment.texcoord[1], texture[0], 2D; \n\ MAD final, tex0, program.local[1], final; \n\ TEX tex0, fragment.texcoord[2], texture[0], 2D; \n\ MAD final, tex0, program.local[2], final; \n\ TEX tex0, fragment.texcoord[3], texture[0], 2D; \n\ MAD final, tex0, program.local[3], final; \n\ TEX tex0, fragment.texcoord[4], texture[0], 2D; \n\ MAD final, tex0, program.local[4], final; \n\ TEX tex0, fragment.texcoord[5], texture[0], 2D; \n\ MAD final, tex0, program.local[5], final; \n\ TEX tex0, fragment.texcoord[6], texture[0], 2D; \n\ MAD final, tex0, program.local[6], final; \n\ MOV result.color, final; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP final; \n\ MOV final, {0, 0, 0, 0}; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MAD final, tex0, program.local[0], final; \n\ TEX tex0, fragment.texcoord[1], texture[0], RECT; \n\ MAD final, tex0, program.local[1], final; \n\ TEX tex0, fragment.texcoord[2], texture[0], RECT; \n\ MAD final, tex0, program.local[2], final; \n\ TEX tex0, fragment.texcoord[3], texture[0], RECT; \n\ MAD final, tex0, program.local[3], final; \n\ TEX tex0, fragment.texcoord[4], texture[0], RECT; \n\ MAD final, tex0, program.local[4], final; \n\ TEX tex0, fragment.texcoord[5], texture[0], RECT; \n\ MAD final, tex0, program.local[5], final; \n\ TEX tex0, fragment.texcoord[6], texture[0], RECT; \n\ MAD final, tex0, program.local[6], final; \n\ MOV result.color, final; \n\ END"; _asm_tex_separable_gauss_filter_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_tex_separable_gauss_filter_prog->LoadVertexShader(AsmVtx); _asm_tex_separable_gauss_filter_prog->LoadPixelShader(AsmFrg); _asm_tex_separable_gauss_filter_prog->Link(); _asm_texrect_separable_gauss_filter_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_texrect_separable_gauss_filter_prog->LoadVertexShader(AsmVtx); _asm_texrect_separable_gauss_filter_prog->LoadPixelShader(AsmFrgRect); _asm_texrect_separable_gauss_filter_prog->Link(); } void GraphicsEngine::QRP_ASM_HorizontalGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color & /* c0 */, float /* sigma */) { NUX_RETURN_IF_FALSE(_asm_tex_separable_gauss_filter_prog.IsValid()); NUX_RETURN_IF_FALSE(_asm_texrect_separable_gauss_filter_prog.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float delta = 1.0f / device_texture->GetWidth(); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0 - 3.0f * delta, texxform.v0, 0, 1.0f, texxform.u0 - 2.0f * delta, texxform.v0, 0, 1.0f, texxform.u0 - 1.0f * delta, texxform.v0, 0, 1.0f, texxform.u0 + 0.0f * delta, texxform.v0, 0, 1.0f, texxform.u0 + 1.0f * delta, texxform.v0, 0, 1.0f, texxform.u0 + 2.0f * delta, texxform.v0, 0, 1.0f, texxform.u0 + 3.0f * delta, texxform.v0, 0, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform.u0 - 3.0f * delta, texxform.v1, 0, 1.0f, texxform.u0 - 2.0f * delta, texxform.v1, 0, 1.0f, texxform.u0 - 1.0f * delta, texxform.v1, 0, 1.0f, texxform.u0 + 0.0f * delta, texxform.v1, 0, 1.0f, texxform.u0 + 1.0f * delta, texxform.v1, 0, 1.0f, texxform.u0 + 2.0f * delta, texxform.v1, 0, 1.0f, texxform.u0 + 3.0f * delta, texxform.v1, 0, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform.u1 - 3.0f * delta, texxform.v1, 0, 1.0f, texxform.u1 - 2.0f * delta, texxform.v1, 0, 1.0f, texxform.u1 - 1.0f * delta, texxform.v1, 0, 1.0f, texxform.u1 + 0.0f * delta, texxform.v1, 0, 1.0f, texxform.u1 + 1.0f * delta, texxform.v1, 0, 1.0f, texxform.u1 + 2.0f * delta, texxform.v1, 0, 1.0f, texxform.u1 + 3.0f * delta, texxform.v1, 0, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform.u1 - 3.0f * delta, texxform.v0, 0, 1.0f, texxform.u1 - 2.0f * delta, texxform.v0, 0, 1.0f, texxform.u1 - 1.0f * delta, texxform.v0, 0, 1.0f, texxform.u1 + 0.0f * delta, texxform.v0, 0, 1.0f, texxform.u1 + 1.0f * delta, texxform.v0, 0, 1.0f, texxform.u1 + 2.0f * delta, texxform.v0, 0, 1.0f, texxform.u1 + 3.0f * delta, texxform.v0, 0, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = _asm_tex_separable_gauss_filter_prog; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = _asm_texrect_separable_gauss_filter_prog; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); // Set the Gaussian weights { float *W; GaussianWeights(&W, 1, 7); for (int i = 0; i < 7; i++) { CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, i, W[i], W[i], W[i], W[i])); } delete[] W; } CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int TextureCoord1Location = VTXATTRIB_TEXCOORD1; int TextureCoord2Location = VTXATTRIB_TEXCOORD2; int TextureCoord3Location = VTXATTRIB_TEXCOORD3; int TextureCoord4Location = VTXATTRIB_TEXCOORD4; int TextureCoord5Location = VTXATTRIB_TEXCOORD5; int TextureCoord6Location = VTXATTRIB_TEXCOORD6; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer)); //if(TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord2Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord3Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord4Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord5Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord6Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 4)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 8)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord2Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 12)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord3Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 16)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord4Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 20)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord5Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 24)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord6Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 28)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); if (TextureCoord2Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord2Location)); if (TextureCoord3Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord3Location)); if (TextureCoord4Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord4Location)); if (TextureCoord5Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord5Location)); if (TextureCoord6Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord6Location)); shader_program->End(); } void GraphicsEngine::QRP_ASM_VerticalGauss(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color & /* c0 */, float /* sigma */) { NUX_RETURN_IF_FALSE(_asm_tex_separable_gauss_filter_prog.IsValid()); NUX_RETURN_IF_FALSE(_asm_texrect_separable_gauss_filter_prog.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float delta = 1.0f / device_texture->GetHeight(); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0 - 3.0f * delta, 0, 1.0f, texxform.u0, texxform.v0 - 2.0f * delta, 0, 1.0f, texxform.u0, texxform.v0 - 1.0f * delta, 0, 1.0f, texxform.u0, texxform.v0 + 0.0f * delta, 0, 1.0f, texxform.u0, texxform.v0 + 1.0f * delta, 0, 1.0f, texxform.u0, texxform.v0 + 2.0f * delta, 0, 1.0f, texxform.u0, texxform.v0 + 3.0f * delta, 0, 1.0f, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1 - 3.0f * delta, 0, 1.0f, texxform.u0, texxform.v1 - 2.0f * delta, 0, 1.0f, texxform.u0, texxform.v1 - 1.0f * delta, 0, 1.0f, texxform.u0, texxform.v1 + 0.0f * delta, 0, 1.0f, texxform.u0, texxform.v1 + 1.0f * delta, 0, 1.0f, texxform.u0, texxform.v1 + 2.0f * delta, 0, 1.0f, texxform.u0, texxform.v1 + 3.0f * delta, 0, 1.0f, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1 - 3.0f * delta, 0, 1.0f, texxform.u1, texxform.v1 - 2.0f * delta, 0, 1.0f, texxform.u1, texxform.v1 - 1.0f * delta, 0, 1.0f, texxform.u1, texxform.v1 + 0.0f * delta, 0, 1.0f, texxform.u1, texxform.v1 + 1.0f * delta, 0, 1.0f, texxform.u1, texxform.v1 + 2.0f * delta, 0, 1.0f, texxform.u1, texxform.v1 + 3.0f * delta, 0, 1.0f, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0 - 3.0f * delta, 0, 1.0f, texxform.u1, texxform.v0 - 2.0f * delta, 0, 1.0f, texxform.u1, texxform.v0 - 1.0f * delta, 0, 1.0f, texxform.u1, texxform.v0 + 0.0f * delta, 0, 1.0f, texxform.u1, texxform.v0 + 1.0f * delta, 0, 1.0f, texxform.u1, texxform.v0 + 2.0f * delta, 0, 1.0f, texxform.u1, texxform.v0 + 3.0f * delta, 0, 1.0f, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = _asm_tex_separable_gauss_filter_prog; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = _asm_texrect_separable_gauss_filter_prog; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); // Set the Gaussian weights { float *W; GaussianWeights(&W, 1, 7); for (int i = 0; i < 7; i++) { CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, i, W[i], W[i], W[i], W[i])); } delete[] W; } CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int TextureCoord1Location = VTXATTRIB_TEXCOORD1; int TextureCoord2Location = VTXATTRIB_TEXCOORD2; int TextureCoord3Location = VTXATTRIB_TEXCOORD3; int TextureCoord4Location = VTXATTRIB_TEXCOORD4; int TextureCoord5Location = VTXATTRIB_TEXCOORD5; int TextureCoord6Location = VTXATTRIB_TEXCOORD6; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer)); //if(TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord1Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord2Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord3Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord4Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord5Location)); CHECKGL(glEnableVertexAttribArrayARB(TextureCoord6Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 4)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord1Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 8)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord2Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 12)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord3Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 16)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord4Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 20)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord5Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 24)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord6Location, 4, GL_FLOAT, GL_FALSE, 128, VtxBuffer + 28)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (TextureCoord1Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord1Location)); if (TextureCoord2Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord2Location)); if (TextureCoord3Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord3Location)); if (TextureCoord4Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord4Location)); if (TextureCoord5Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord5Location)); if (TextureCoord6Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord6Location)); shader_program->End(); } ObjectPtr GraphicsEngine::QRP_ASM_GetBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, float /* sigma */, int num_pass) { // _offscreen_color_rt0.Release(); // _offscreen_color_rt1.Release(); // _offscreen_depth_rt0.Release(); // _offscreen_depth_rt1.Release(); int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); num_pass = Clamp (num_pass, 1, 5); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(x, y, quad_width, quad_height, device_texture, texxform, color::White); TexCoordXForm texxform1; for (int i = 0; i < num_pass; i++) { SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_HorizontalGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt0, texxform1, c0); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_VerticalGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt1, texxform1, c0); } _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } SetOrthographicProjectionMatrix(previous_width, previous_height); return _offscreen_color_rt0; } void GraphicsEngine::QRP_ASM_GetBlurTextureFx( int x, int y, int buffer_width, int buffer_height, FxStructure *fx_structure, TexCoordXForm &texxform, const Color& color, float /* sigma */, int num_pass) { int quad_width = fx_structure->src_texture->GetWidth(); int quad_height = fx_structure->src_texture->GetHeight(); num_pass = Clamp (num_pass, 1, 5); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); fx_structure->src_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->src_texture->SetFiltering(GL_NEAREST, GL_NEAREST); fx_structure->dst_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->dst_texture->SetFiltering(GL_NEAREST, GL_NEAREST); fx_structure->temp_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); fx_structure->temp_texture->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(x, y, quad_width, quad_height, fx_structure->src_texture, texxform, color::White); TexCoordXForm texxform1; for (int i = 0; i < num_pass; i++) { SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_HorizontalGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, color); SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_VerticalGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, color); } _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } } ObjectPtr GraphicsEngine::QRP_ASM_GetPower( ObjectPtr device_texture, TexCoordXForm &texxform, const Color & c0, const Vector4 &exponent) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(0, 0, quad_width, quad_height, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_Power(0, 0, quad_width, quad_height, _offscreen_color_rt0, texxform, c0, exponent); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } return _offscreen_color_rt1; } ObjectPtr GraphicsEngine::QRP_ASM_GetAlphaTexture( ObjectPtr device_texture, TexCoordXForm &texxform, const Color & c0) { // _offscreen_color_rt0.Release(); // _offscreen_color_rt1.Release(); // _offscreen_depth_rt0.Release(); // _offscreen_depth_rt1.Release(); int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(0, 0, quad_width, quad_height, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_AlphaReplicate(0, 0, quad_width, quad_height, _offscreen_color_rt0, texxform, c0); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } return _offscreen_color_rt1; } ObjectPtr GraphicsEngine::QRP_ASM_GetColorMatrixTexture( ObjectPtr device_texture, TexCoordXForm &texxform, const Color & c0, Matrix4 color_matrix, Vector4 offset) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(0, 0, quad_width, quad_height, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width, quad_height); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_ColorMatrix(0, 0, quad_width, quad_height, _offscreen_color_rt0, texxform, c0, color_matrix, offset); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } return _offscreen_color_rt1; } ObjectPtr GraphicsEngine::QRP_ASM_GetLQBlur( int /* x */, int /* y */, int /* buffer_width */, int /* buffer_height */, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& /* c0 */) { // _offscreen_color_rt0.Release(); // _offscreen_color_rt1.Release(); // _offscreen_depth_rt0.Release(); // _offscreen_depth_rt1.Release(); int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt2->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt2->SetFiltering(GL_NEAREST, GL_NEAREST); _offscreen_color_rt3->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); _offscreen_color_rt3->SetFiltering(GL_NEAREST, GL_NEAREST); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width/2, quad_height/2); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(0, 0, quad_width / 2, quad_height / 2, device_texture, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, quad_width/4, quad_height/4); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(0, 0, quad_width / 4, quad_height / 4, _offscreen_color_rt0, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt2, _offscreen_depth_rt2, quad_width/8, quad_height/8); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QRP_ASM_1Tex(0, 0, quad_width / 8, quad_height / 8, _offscreen_color_rt1, texxform, color::White); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt3, _offscreen_depth_rt3, quad_width, quad_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); TexCoordXForm texxform0; TexCoordXForm texxform1; TexCoordXForm texxform2; TexCoordXForm texxform3; texxform0.flip_v_coord = true; texxform2.flip_v_coord = true; QRP_ASM_4Tex(0, 0, quad_width, quad_height, device_texture, texxform0, Color(0.25, 0.25, 0.25, 0.25), _offscreen_color_rt0, texxform1, Color(0.25, 0.25, 0.25, 0.25), _offscreen_color_rt1, texxform2, Color(0.25, 0.25, 0.25, 0.25), _offscreen_color_rt2, texxform3, Color(0.25, 0.25, 0.25, 0.25)); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } return _offscreen_color_rt3; } void GraphicsEngine::InitAsmPixelateShader() { const char* AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ ATTRIB iColor = vertex.attrib[3]; \n\ PARAM mvp[4] = {state.matrix.mvp}; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oColor = result.color; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, mvp[0], iPos; \n\ DP4 oPos.y, mvp[1], iPos; \n\ DP4 oPos.z, mvp[2], iPos; \n\ DP4 oPos.w, mvp[3], iPos; \n\ MOV oColor, iColor; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"; const char* AsmFrg = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP tex_coord; \n\ PARAM pixel_size = program.local [0]; \n\ PARAM pixel_size_inv = program.local [1]; \n\ MUL tex_coord, fragment.texcoord[0], pixel_size_inv; \n\ FLR tex_coord, tex_coord; \n\ MUL tex_coord, tex_coord, pixel_size; \n\ TEX tex0, tex_coord, texture[0], 2D; \n\ MUL result.color, fragment.color, tex0; \n\ END"; const char* AsmFrgRect = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP tex_coord; \n\ PARAM pixel_size = program.local [0]; \n\ PARAM pixel_size_inv = program.local [1]; \n\ MUL tex_coord, fragment.texcoord[0], pixel_size_inv; \n\ FLR tex_coord, tex_coord; \n\ MUL tex_coord, tex_coord, pixel_size; \n\ TEX tex0, tex_coord, texture[0], RECT; \n\ MUL result.color, fragment.color, tex0; \n\ END"; m_AsmPixelate = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmPixelate->LoadVertexShader(AsmVtx); m_AsmPixelate->LoadPixelShader(AsmFrg); m_AsmPixelate->Link(); m_AsmPixelateRect = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmPixelateRect->LoadVertexShader(AsmVtx); m_AsmPixelateRect->LoadPixelShader(AsmFrgRect); m_AsmPixelateRect->Link(); } void GraphicsEngine::QRP_ASM_Pixelate(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color &color, int pixel_size) { NUX_RETURN_IF_FALSE(m_AsmPixelate.IsValid()); NUX_RETURN_IF_FALSE(m_AsmPixelateRect.IsValid()); if (pixel_size <= 0) pixel_size = 1; QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, }; float tex_width = device_texture->GetWidth(); float tex_height = device_texture->GetHeight(); CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); bool rectangle_texture = false; ObjectPtr shader_program = m_AsmPixelate; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_AsmPixelateRect; rectangle_texture = true; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int VertexColorLocation = VTXATTRIB_COLOR; if (rectangle_texture == false) { CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, (float)pixel_size/(float)tex_width, (float)pixel_size/(float)tex_height, 1.0f, 1.0f)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, (float)tex_width/(float)pixel_size, (float)tex_height/(float)pixel_size, 1.0f, 1.0f)); } else { CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, pixel_size, pixel_size, 1.0f, 1.0f)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0f/pixel_size, 1.0f/pixel_size, 1.0f, 1.0f)); } CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); shader_program->End(); } ObjectPtr GraphicsEngine::QRP_ASM_GetPixelBlocks( ObjectPtr device_texture, TexCoordXForm &texxform0, const Color& c0, int pixel_size) { int quad_width = device_texture->GetWidth(); int quad_height = device_texture->GetHeight(); ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } CHECKGL(glClearColor(0, 0, 0, 0)); SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, quad_width, quad_height); CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); QRP_ASM_Pixelate(0, 0, quad_width, quad_height, device_texture, texxform0, c0, pixel_size); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } return _offscreen_color_rt0; } void GraphicsEngine::QRP_ASM_GetCopyTexture( int width, int height, ObjectPtr& dst_device_texture, ObjectPtr& src_device_texture, TexCoordXForm &texxform0, const Color& c0) { if (src_device_texture.IsValid() == false) { return; } ObjectPtr prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); int previous_width = 0; int previous_height = 0; if (prevFBO.IsValid()) { previous_width = prevFBO->GetWidth(); previous_height = prevFBO->GetHeight(); } else { previous_width = _graphics_display.GetWindowWidth(); previous_height = _graphics_display.GetWindowHeight(); } if ((dst_device_texture.IsValid() == false) || (dst_device_texture->GetWidth() != width) || (dst_device_texture->GetHeight() != height) || (dst_device_texture->GetPixelFormat() != src_device_texture->GetPixelFormat())) { dst_device_texture = _graphics_display.GetGpuDevice()->CreateTexture(width, height, 1, src_device_texture->GetPixelFormat()); } CHECKGL(glClearColor(0, 0, 0, 0)); SetFrameBufferHelper(_offscreen_fbo, dst_device_texture, _offscreen_depth_rt0, width, height); CHECKGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); QRP_ASM_1Tex(0, 0, width, height, src_device_texture, texxform0, c0); _offscreen_fbo->Deactivate(); if (prevFBO.IsValid()) { prevFBO->Activate(true); SetViewport(0, 0, previous_width, previous_height); } else { SetViewport(0, 0, previous_width, previous_height); } } void GraphicsEngine::InitAsmTexturePremultiplyShader() { std::string AsmVtx = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ ATTRIB iColor = vertex.attrib[3]; \n\ PARAM mvp[4] = {state.matrix.mvp}; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oColor = result.color; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, mvp[0], iPos; \n\ DP4 oPos.y, mvp[1], iPos; \n\ DP4 oPos.z, mvp[2], iPos; \n\ DP4 oPos.w, mvp[3], iPos; \n\ MOV oColor, iColor; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"; std::string AsmFrg = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MUL temp.rgb, tex0, tex0.aaaa; \n\ MOV temp.a, tex0.aaaa; \n\ MUL result.color, fragment.color, temp; \n\ END"; std::string AsmFrgRect = "!!ARBfp1.0 \n\ TEMP tex0; \n\ TEMP temp; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MUL temp.rgb, tex0, tex0.aaaa; \n\ MOV temp.a, tex0.aaaa; \n\ MUL result.color, fragment.color, temp; \n\ END"; m_AsmTexturePremultiplyModColor = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmTexturePremultiplyModColor->LoadVertexShader(AsmVtx.c_str()); m_AsmTexturePremultiplyModColor->LoadPixelShader(AsmFrg.c_str()); m_AsmTexturePremultiplyModColor->Link(); m_AsmTexturePremultiplyRectModColor = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmTexturePremultiplyRectModColor->LoadVertexShader(AsmVtx.c_str()); m_AsmTexturePremultiplyRectModColor->LoadPixelShader(AsmFrgRect.c_str()); m_AsmTexturePremultiplyRectModColor->Link(); } void GraphicsEngine::QRP_ASM_1TexPremultiply(int x, int y, int width, int height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color &color) { if (device_texture.IsNull()) return; NUX_RETURN_IF_FALSE(m_AsmTexturePremultiplyModColor.IsValid()); NUX_RETURN_IF_FALSE(m_AsmTexturePremultiplyRectModColor.IsValid()); QRP_Compute_Texture_Coord(width, height, device_texture, texxform); float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, texxform.u0, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx, fy + height, 0.0f, 1.0f, texxform.u0, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy + height, 0.0f, 1.0f, texxform.u1, texxform.v1, 0, 1.0f, color.red, color.green, color.blue, color.alpha, fx + width, fy, 0.0f, 1.0f, texxform.u1, texxform.v0, 0, 1.0f, color.red, color.green, color.blue, color.alpha, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); ObjectPtr shader_program = m_AsmTexturePremultiplyModColor; if (device_texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = m_AsmTexturePremultiplyRectModColor; } shader_program->Begin(); SetTexture(GL_TEXTURE0, device_texture); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; int TextureCoord0Location = VTXATTRIB_TEXCOORD0; int VertexColorLocation = VTXATTRIB_COLOR; CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer)); if (TextureCoord0Location != -1) { CHECKGL(glEnableVertexAttribArrayARB(TextureCoord0Location)); CHECKGL(glVertexAttribPointerARB((GLuint) TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4)); } if (VertexColorLocation != -1) { CHECKGL(glEnableVertexAttribArrayARB(VertexColorLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8)); } CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); if (TextureCoord0Location != -1) CHECKGL(glDisableVertexAttribArrayARB(TextureCoord0Location)); if (VertexColorLocation != -1) CHECKGL(glDisableVertexAttribArrayARB(VertexColorLocation)); shader_program->End(); } } #endif // NUX_OPENGLES_20 nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLCubeTexture.cpp0000644000015301777760000001104312321344237023310 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLDeviceObjects.h" #include "IOpenGLCubeTexture.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLCubeTexture); IOpenGLCubeTexture::IOpenGLCubeTexture( unsigned int EdgeLength , int Levels , BitmapFormat PixelFormat) : IOpenGLBaseTexture(RTCUBETEXTURE, EdgeLength, EdgeLength, 1, Levels, PixelFormat) { CHECKGL(glGenTextures(1, &_OpenGLID)); CHECKGL(glBindTexture(GL_TEXTURE_CUBE_MAP, _OpenGLID)); for (unsigned int face = CUBEMAP_FACE_POSITIVE_X; face < CUBEMAP_FACE_NEGATIVE_Z + 1; face++) { std::vector *array = new std::vector(); _SurfaceArray[ (eCUBEMAP_FACES) face] = array; //array = (*(_SurfaceArray.find((eCUBEMAP_FACES)face))).second; for (int l = 0; l < Levels; l++) { IOpenGLSurface *surface = new IOpenGLSurface(this, _OpenGLID, GL_TEXTURE_CUBE_MAP, face, l); surface->InitializeLevel(); array->push_back( surface ); //IOpenGLSurface* surface = new(array) IOpenGLSurface(this, GL_TEXTURE_CUBE_MAP, face, l) ; } } CHECKGL(glBindTexture(GL_TEXTURE_CUBE_MAP, _OpenGLID)); SetFiltering(GL_NEAREST, GL_NEAREST); SetWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); SetRenderStates(); GRunTimeStats.Register(this); } IOpenGLCubeTexture::~IOpenGLCubeTexture() { for (unsigned int face = CUBEMAP_FACE_POSITIVE_X; face < CUBEMAP_FACE_NEGATIVE_Z + 1; face++) { std::vector *array = (_SurfaceArray.find((eCUBEMAP_FACES) face))->second; for (int l = 0; l < _NumMipLevel; l++) { ((*array) [l])->UnReference(); } array->clear(); delete array; } _SurfaceArray.clear(); CHECKGL(glDeleteTextures(1, &_OpenGLID)); _OpenGLID = 0; GRunTimeStats.UnRegister(this); } int IOpenGLCubeTexture::GetCubeMapSurface( eCUBEMAP_FACES FaceType, int Level, IOpenGLSurface **ppCubeMapSurface ) { if (Level < _NumMipLevel) { std::vector *array = (* (_SurfaceArray.find(FaceType))).second; *ppCubeMapSurface = (*array) [Level]; //(*ppCubeMapSurface)->AddRef(); } else { return OGL_INVALID_SURFACE_LEVEL; } return 1; } int IOpenGLCubeTexture::CubeLockRect( eCUBEMAP_FACES FaceType, int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect) { nuxAssertMsg(pLockedRect, "[IOpenGLCubeTexture::LockRect] Invalid parameter 'pLockedRect'."); nuxAssertMsg(Level >= 0, "[IOpenGLCubeTexture::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLCubeTexture::LockRect] Invalid mipmap level."); if (Level < _NumMipLevel) { std::vector *array = (* (_SurfaceArray.find(FaceType))).second; IOpenGLSurface *pCubeSurfaceLevel = (*array) [Level]; return pCubeSurfaceLevel->LockRect(pLockedRect, pRect); } else { pLockedRect->pBits = 0; pLockedRect->Pitch = 0; return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } int IOpenGLCubeTexture::CubeUnlockRect( eCUBEMAP_FACES FaceType, int Level ) { nuxAssertMsg(Level >= 0, "[IOpenGLCubeTexture::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLCubeTexture::LockRect] Invalid mipmap level."); if (Level < _NumMipLevel) { std::vector *array = (* (_SurfaceArray.find(FaceType))).second; IOpenGLSurface *pCubeSurfaceLevel = (*array) [Level]; return pCubeSurfaceLevel->UnlockRect(); } else { return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } unsigned int IOpenGLCubeTexture::EnableGammaCorrection(bool /* b */) { nuxAssert(_OpenGLID); return OGL_OK; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVolumeTexture.cpp0000644000015301777760000001346612321344237023714 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLDeviceObjects.h" #include "IOpenGLVolumeTexture.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLVolumeTexture); IOpenGLVolumeTexture::IOpenGLVolumeTexture( int Width , int Height , int Depth , int Levels , BitmapFormat PixelFormat) : IOpenGLBaseTexture(RTVOLUMETEXTURE, Width, Height, Depth, Levels, PixelFormat) { #ifndef NUX_OPENGLES_20 CHECKGL(glGenTextures(1, &_OpenGLID)); CHECKGL(glBindTexture(GL_TEXTURE_3D, _OpenGLID)); _VolumeSurfaceArray = new std::vector< ObjectPtr >[_NumMipLevel]; for (int mip = 0; mip < _NumMipLevel; mip++) { for (int slice = 0; slice < ImageSurface::GetLevelDim(_PixelFormat, _Depth, mip); slice++) { //IOpenGLSurface* surface = new IOpenGLSurface(this, _OpenGLID, GL_TEXTURE_3D, GL_TEXTURE_3D, mip, slice); //surface->InitializeLevel(); IOpenGLSurface* surface = new IOpenGLSurface(this, _OpenGLID, GL_TEXTURE_3D, GL_TEXTURE_3D, mip, slice); _VolumeSurfaceArray[mip].push_back(ObjectPtr (surface)); surface->UnReference(); } } for (int mip = 0; mip < _NumMipLevel; mip++) { IOpenGLVolume *volume = new IOpenGLVolume(this, _OpenGLID, GL_TEXTURE_3D, GL_TEXTURE_3D, mip); volume->InitializeLevel(); _VolumeArray.push_back(ObjectPtr (volume)); } CHECKGL(glBindTexture(GL_TEXTURE_3D, _OpenGLID)); SetFiltering(GL_NEAREST, GL_NEAREST); SetWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); SetRenderStates(); GRunTimeStats.Register(this); #endif } IOpenGLVolumeTexture::~IOpenGLVolumeTexture() { for (int mip = 0; mip < _NumMipLevel; mip++) { for (int slice = 0; slice < ImageSurface::GetLevelDim(_PixelFormat, _Depth, mip); slice++) { // destroying a surface _VolumeSurfaceArray[mip][slice] = ObjectPtr (0); } _VolumeSurfaceArray[mip].clear(); } NUX_SAFE_DELETE_ARRAY(_VolumeSurfaceArray); for (int mip = 0; mip < _NumMipLevel; mip++) { // destroying a IOpenGLVolume _VolumeArray[mip] = ObjectPtr (0); } CHECKGL(glDeleteTextures(1, &_OpenGLID)); _OpenGLID = 0; GRunTimeStats.UnRegister(this); } int IOpenGLVolumeTexture::VolumeLockRect( int Slice, int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect) { nuxAssertMsg(pLockedRect, "[IOpenGLVolumeTexture::LockRect] Invalid parameter 'pLockedRect'."); nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level."); nuxAssertMsg(Slice >= 0, "[IOpenGLVolumeTexture::LockRect] Invalid slice index."); nuxAssertMsg(Slice < ImageSurface::GetLevelDim(_PixelFormat, _Depth, Level), "[IOpenGLVolumeTexture::LockRect] Invalid slice index."); if (Slice < 0) Slice = 0; if (Slice >= _Depth) Slice = _Depth - 1; if (Level < _NumMipLevel) { ObjectPtr pVolumeSurfaceLevel = _VolumeSurfaceArray[Level][Slice]; return pVolumeSurfaceLevel->LockRect(pLockedRect, pRect); } else { pLockedRect->pBits = 0; pLockedRect->Pitch = 0; return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } int IOpenGLVolumeTexture::VolumeUnlockRect( int Slice, int Level ) { nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level."); if (Level < _NumMipLevel) { ObjectPtr pVolumeSurfaceLevel = _VolumeSurfaceArray[Level][Slice]; return pVolumeSurfaceLevel->UnlockRect(); } else { return OGL_INVALID_SURFACE_LEVEL; } return OGL_OK; } int IOpenGLVolumeTexture::LockBox(int Level, VOLUME_LOCKED_BOX *pLockedVolume, const VOLUME_BOX *pBox) { nuxAssertMsg(pLockedVolume, "[IOpenGLVolumeTexture::LockBox] Invalid parameter 'pLockedRect'."); nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level."); if (pBox) { nuxAssertMsg(pBox->Front >= 0, "[IOpenGLVolumeTexture::LockBox] Invalid slice index."); nuxAssertMsg(pBox->Front < pBox->Back, "[IOpenGLVolumeTexture::LockBox] Invalid slice index."); nuxAssertMsg(pBox->Back <= ImageSurface::GetLevelDim(_PixelFormat, _Depth, Level), "[IOpenGLVolumeTexture::LockBox] Invalid slice index."); } return _VolumeArray[Level]->LockBox(pLockedVolume, pBox); } int IOpenGLVolumeTexture::UnlockBox(int Level) { nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level."); nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level."); return _VolumeArray[Level]->UnlockBox(); } } nux-4.0.6+14.04.20140409/NuxGraphics/FontRenderer.cpp0000644000015301777760000006736212321344237022307 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "IOpenGLResource.h" #include "GLResourceManager.h" #include "IOpenGLBaseTexture.h" #include "GpuDevice.h" #include "GLTextureResourceManager.h" #include "GraphicsEngine.h" #include "FontRenderer.h" namespace nux { namespace { const int CURSOR_OFFSET = 0; static int CURSOR_SIZE = 2; // On NVidia system: // - declare the vertex attribute name before any other attribute. // - Give the vertex attribute a name that comes before any other attribute name. For instance prefix the vertex attribute name with "_". std::string gFontVtxShader(" \n\ attribute vec4 _Position; \n\ attribute vec4 iOffset; \n\ attribute vec4 iScale; \n\ attribute vec4 iTexUV; \n\ uniform mat4 ViewProjectionMatrix; \n\ varying vec4 oTexCoord0; \n\ void main() \n\ { \n\ oTexCoord0 = iTexUV; \n\ vec4 myvertex = _Position * iScale + iOffset; \n\ gl_Position = ViewProjectionMatrix * myvertex; \n\ }"); std::string gFontFragShader(" \n\ #extension GL_ARB_texture_rectangle : enable \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ uniform vec4 TextColor; \n\ varying vec4 oTexCoord0; \n\ #ifdef SAMPLERTEX2D \n\ uniform sampler2D FontTexture; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ } \n\ #elif defined SAMPLERTEX2DRECT \n\ uniform sampler2DRect FontTexture; \n\ vec4 SampleTexture(sampler2DRect TexObject, vec4 TexCoord) \n\ { \n\ return texture2DRect(TexObject, TexCoord.st); \n\ } \n\ #endif \n\ void main() \n\ { \n\ vec4 diffuse = SampleTexture(FontTexture, oTexCoord0); \n\ gl_FragColor = vec4(TextColor.x, TextColor.y, TextColor.z, diffuse.w); \n\ }"); std::string FontAsmVtx("!!ARBvp1.0 \n\ ATTRIB iScale = vertex.attrib[9]; \n\ ATTRIB iOffset = vertex.attrib[10]; \n\ OUTPUT oPos = result.position; \n\ OUTPUT oTexCoord0 = result.texcoord[0]; \n\ # Transform the vertex to clip coordinates. \n\ TEMP temp; \n\ MAD temp, vertex.position, iScale, iOffset; \n\ DP4 oPos.x, state.matrix.mvp.row[0], temp; \n\ DP4 oPos.y, state.matrix.mvp.row[1], temp; \n\ DP4 oPos.z, state.matrix.mvp.row[2], temp; \n\ DP4 oPos.w, state.matrix.mvp.row[3], temp; \n\ MOV oTexCoord0, vertex.attrib[8]; \n\ END"); std::string FontAsmFrg("!!ARBfp1.0 \n\ PARAM color = program.local[0]; \n\ TEMP temp; \n\ TEMP tex0; \n\ TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ MOV temp, color; \n\ MUL temp.w, color, tex0; \n\ MOV result.color, temp; \n\ END"); std::string FontAsmFrgRect("!!ARBfp1.0 \n\ PARAM color = program.local[0]; \n\ TEMP temp; \n\ TEMP tex0; \n\ TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ MOV temp, color; \n\ MUL temp.w, color, tex0; \n\ MOV result.color, temp; \n\ END"); } // anon namespace FontRenderer::FontRenderer(GraphicsEngine &graphics_engine) : _graphics_engine(graphics_engine) { if (_graphics_engine.UsingGLSLCodePath()) { _pixel_shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); _vertex_shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); _shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); _vertex_shader_prog->SetShaderCode(gFontVtxShader.c_str()); #ifndef NUX_OPENGLES_20 _pixel_shader_prog->SetShaderCode(gFontFragShader.c_str(), "#define SAMPLERTEX2DRECT"); #else _pixel_shader_prog->SetShaderCode(gFontFragShader.c_str(), "#define SAMPLERTEX2D"); #endif _shader_prog->ClearShaderObjects(); _shader_prog->AddShaderObject(_vertex_shader_prog); _shader_prog->AddShaderObject(_pixel_shader_prog); //CHECKGL(glBindAttribLocation(_shader_prog->GetOpenGLID(), 0, "_Position")); _shader_prog->Link(); } #ifndef NUX_OPENGLES_20 else { _asm_shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_shader_prog->LoadVertexShader(FontAsmVtx.c_str()); _asm_shader_prog->LoadPixelShader(FontAsmFrg.c_str()); _asm_shader_prog->Link(); _asm_font_texture_rect_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); _asm_font_texture_rect_prog->LoadVertexShader(FontAsmVtx.c_str()); _asm_font_texture_rect_prog->LoadPixelShader(FontAsmFrgRect.c_str()); _asm_font_texture_rect_prog->Link(); } #endif } FontRenderer::~FontRenderer() { } void FontRenderer::PositionString(ObjectPtr const& Font, std::string const& str, PageBBox const& pageBBox, StringBBox& strBBox, TextAlignment alignment, int NumCharacter) { int xmin = pageBBox.xmin + pageBBox.x_margin; int xmax = pageBBox.xmax - pageBBox.x_margin; int ymin = pageBBox.ymin + pageBBox.y_margin; int ymax = pageBBox.ymax - pageBBox.y_margin; int NumChar = 0; int str_len = str.size(); if (NumCharacter == 0) NumChar = str_len; else NumChar = std::min(str_len, NumCharacter); strBBox.width = Font->GetStringWidth(str, NumChar); strBBox.height = Font->GetLineHeight(); int x = 0; int y = 0; switch(alignment) { case eAlignTextCenter: if (strBBox.width > xmax - xmin) x = xmin; // the text is larger than the box: default to eAlignTextLeft for x. else x = xmin + ((float) (xmax - xmin) - (float) (strBBox.width)) / 2.0f; y = ymin + ((float) (ymax - ymin) - (float) (strBBox.height)) / 2.0f; break; case eAlignTextRight: x = xmin + ((float) (xmax - xmin) - (float) (strBBox.width)); y = ymin + ((float) (ymax - ymin) - (float) (strBBox.height)) / 2.0f; break; case eAlignTextLeft: default: x = xmin; y = ymin + ((float) (ymax - ymin) - (float) (strBBox.height)) / 2.0f; break; } strBBox.x = x; strBBox.y = y; } int FontRenderer::RenderColorText(ObjectPtr const& Font, int x, int y, std::string const& Str, Color const& color, bool WriteAlphaChannel, int NumCharacter) { return RenderText(Font, x, y, Str, color, WriteAlphaChannel, 0, NumCharacter); } int FontRenderer::RenderColorTextLineStatic(ObjectPtr const& Font, PageBBox const& pageSize, std::string const& Str, Color const& color, bool WriteAlphaChannel, TextAlignment alignment) { StringBBox stringBBox; _graphics_engine.PushClippingRectangle(Rect(pageSize.xmin, pageSize.ymin, pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin)); PositionString(Font, Str, pageSize, stringBBox, alignment); int off = RenderText(Font, stringBBox.x, stringBBox.y, Str, color, WriteAlphaChannel, 0, Str.size()); _graphics_engine.PopClippingRectangle(); return off; } int FontRenderer::RenderColorTextLineEdit(ObjectPtr const& Font, PageBBox const& pageSize, std::string const& Str, Color const& TextColor, bool WriteAlphaChannel, Color const& SelectedTextColor, Color const& SelectedTextBackgroundColor, Color const& TextBlinkColor, Color const& CursorColor, bool ShowCursor, unsigned int CursorPosition, int offset, int selection_start, int selection_end) { StringBBox stringBBox; Color selection_color(0xFF888888); // TODO: sanity checking on selection_start and end std::string substring = Str.substr(selection_start, selection_end - selection_start); unsigned int substring_width = Font->GetStringWidth(substring); int substring_pos = Font->GetStringWidth(Str, selection_start); _graphics_engine.PushClippingRectangle(Rect(pageSize.xmin, pageSize.ymin, pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin)); if (substring_width > 0) _graphics_engine.QRP_Color(pageSize.xmin + offset + substring_pos, pageSize.ymin, substring_width, pageSize.ymax - pageSize.ymin, SelectedTextBackgroundColor); _graphics_engine.PopClippingRectangle(); // TODO: double check this, pushing exactly sthe same rect as above _graphics_engine.PushClippingRectangle(Rect(pageSize.xmin, pageSize.ymin, pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin)); PositionString(Font, Str, pageSize, stringBBox, eAlignTextLeft); // Part before selected text int off = RenderText(Font, stringBBox.x + offset, stringBBox.y, Str, TextColor, WriteAlphaChannel, 0, selection_start); // Selection part off = RenderText(Font, stringBBox.x + offset, stringBBox.y, Str, SelectedTextColor, WriteAlphaChannel, selection_start, selection_end - selection_start); // Part after selected text off = RenderText(Font, stringBBox.x + offset, stringBBox.y, Str, TextColor, WriteAlphaChannel, selection_end, Str.size() - selection_end); _graphics_engine.PopClippingRectangle(); if (ShowCursor) { // Render Cursor std::string temp = Str.substr(0, CursorPosition); int w = Font->GetStringWidth(temp); int x = pageSize.xmin + w + offset + CURSOR_OFFSET; x = (x >= pageSize.xmax) ? pageSize.xmax - 1 : x; _graphics_engine.PushClippingRectangle(Rect(x, pageSize.ymin, CURSOR_SIZE, pageSize.ymax - pageSize.ymin)); _graphics_engine.QRP_Color(x, pageSize.ymin, CURSOR_SIZE, pageSize.ymax - pageSize.ymin, CursorColor); RenderText(Font, stringBBox.x + offset, stringBBox.y, Str, TextBlinkColor, WriteAlphaChannel, CursorPosition, 1); _graphics_engine.PopClippingRectangle(); } return off; } int FontRenderer::RenderText(ObjectPtr const& Font, int x, int y, std::string const& str, Color const& color, bool WriteAlphaChannel, int StartCharacter, int NumCharacters) { // !WARNING This call works if all the glyph of the font are in a single texture. int StrLength = str.size(); if (StrLength <= 0) return 0; nuxAssertMsg(NumCharacters >= 0, "[FontRenderer::RenderText] Incorrect value for NumCharacters."); nuxAssertMsg(StartCharacter >= 0, "[FontRenderer::RenderText] Incorrect value for StartCharacter."); nuxAssertMsg(StartCharacter <= StrLength, "[FontRenderer::RenderText] Incorrect value for StartCharacter."); int NumCharToDraw = std::min(StrLength - StartCharacter, NumCharacters); if (NumCharToDraw <= 0) return 0; CHECKGL(glDisable(GL_CULL_FACE)); int CurX = x; int CurY = y; _graphics_engine.GetRenderStates().SetBlend(TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); _graphics_engine.GetRenderStates().SetColorMask(TRUE, TRUE, TRUE, WriteAlphaChannel); // Do not write the alpha of characters GLshort *Index = new GLshort[StrLength*6]; Vector4 *Position = new Vector4[StrLength*4]; Vector4 *UV = new Vector4[StrLength*4]; Vector4 *Offset = new Vector4[StrLength*4]; Vector4 *Scale = new Vector4[StrLength*4]; ObjectPtr glTexture = _graphics_engine.ResourceCache.GetCachedResource(Font->TextureArray[0]); float tex_width = (float) glTexture->m_Texture->GetWidth(); float tex_height = (float) glTexture->m_Texture->GetHeight(); for (int i = 0; i < StrLength; ++i) { unsigned char c = static_cast (str[i]); unsigned int CharX = Font->m_Charset.Chars[c /*Str[i]*/].x; unsigned int CharY = Font->m_Charset.Chars[c /*Str[i]*/].y; unsigned int Width = Font->m_Charset.Chars[c /*Str[i]*/].Width; unsigned int Height = Font->m_Charset.Chars[c /*Str[i]*/].Height; //int OffsetX = Font->m_Charset.Chars[c /*Str[i]*/].XOffset; //int OffsetY = Font->m_Charset.Chars[c /*Str[i]*/].YOffset; int abcA = Font->m_Charset.Chars[c /*Str[i]*/].abcA; int abcB = Font->m_Charset.Chars[c /*Str[i]*/].abcB; int abcC = Font->m_Charset.Chars[c /*Str[i]*/].abcC; //int page = Font->m_Charset.Chars[c /*Str[i]*/].page; if ((i >= StartCharacter) && (i < StartCharacter + NumCharToDraw)) { int II = i - StartCharacter; Position[II*4 + 0].x = 0; // x Position[II*4 + 0].y = 0; // y Position[II*4 + 0].z = 0; // z Position[II*4 + 0].w = 1.0f; // w Position[II*4 + 1].x = 1.0f; // x Position[II*4 + 1].y = 0; // y Position[II*4 + 1].z = 0; // z Position[II*4 + 1].w = 1; // w Position[II*4 + 2].x = 1.0f; // x Position[II*4 + 2].y = 1.0f; // y Position[II*4 + 2].z = 0; // z Position[II*4 + 2].w = 1; // w Position[II*4 + 3].x = 0; // x Position[II*4 + 3].y = 1.0f; // y Position[II*4 + 3].z = 0; // z Position[II*4 + 3].w = 1; // w for (int j = 0; j < 4; j++) { Offset[II*4 + j].x = CurX + abcA; Offset[II*4 + j].y = CurY; Offset[II*4 + j].z = 0.0f; Offset[II*4 + j].w = 0.0f; Scale[II*4 + j].x = Width; Scale[II*4 + j].y = Height; Scale[II*4 + j].z = 1.0f; Scale[II*4 + j].w = 1.0f; } if (glTexture->m_Texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { //upper left UV[II*4 + 0].x = CharX; UV[II*4 + 0].y = CharY; UV[II*4 + 0].z = 0.0f; UV[II*4 + 0].w = 0.0f; //upper right UV[II*4 + 1].x = (CharX + Width); UV[II*4 + 1].y = CharY; UV[II*4 + 1].z = 0.0f; UV[II*4 + 1].w = 0.0f; //lower right UV[II*4 + 2].x = (CharX + Width); UV[II*4 + 2].y = (CharY + Height); UV[II*4 + 2].z = 0.0f; UV[II*4 + 2].w = 0.0f; //lower left UV[II*4 + 3].x = CharX; UV[II*4 + 3].y = (CharY + Height); UV[II*4 + 3].z = 0.0f; UV[II*4 + 3].w = 0.0f; } else { //upper left UV[II*4 + 0].x = CharX / tex_width; UV[II*4 + 0].y = CharY / tex_height; UV[II*4 + 0].z = 0.0f; UV[II*4 + 0].w = 0.0f; //upper right UV[II*4 + 1].x = (CharX + Width) / tex_width; UV[II*4 + 1].y = CharY / tex_height; UV[II*4 + 1].z = 0.0f; UV[II*4 + 1].w = 0.0f; //lower right UV[II*4 + 2].x = (CharX + Width) / tex_width; UV[II*4 + 2].y = (CharY + Height) / tex_height; UV[II*4 + 2].z = 0.0f; UV[II*4 + 2].w = 0.0f; //lower left UV[II*4 + 3].x = CharX / tex_width; UV[II*4 + 3].y = (CharY + Height) / tex_height; UV[II*4 + 3].z = 0.0f; UV[II*4 + 3].w = 0.0f; } } // Set up element array indices Index[i*6 + 0] = i*4; Index[i*6 + 1] = i*4 + 2; Index[i*6 + 2] = i*4 + 3; Index[i*6 + 3] = i*4; Index[i*6 + 4] = i*4 + 1; Index[i*6 + 5] = i*4 + 2; CurX += abcA + abcB + abcC; } CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); int in_attrib_position = 0; int in_attrib_tex_uv = 0; int in_attrib_scale = 0; int in_attrib_offset = 0; #ifndef NUX_OPENGLES_20 ObjectPtr shader_program; #endif if (_graphics_engine.UsingGLSLCodePath()) { _shader_prog->Begin(); int ViewProjectionMatrix = _shader_prog->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 mat = _graphics_engine.GetOpenGLModelViewProjectionMatrix(); _shader_prog->SetUniformLocMatrix4fv(ViewProjectionMatrix, 1, false, (float *) &mat); in_attrib_position = _shader_prog->GetAttributeLocation("_Position"); in_attrib_tex_uv = _shader_prog->GetAttributeLocation("iTexUV"); in_attrib_scale = _shader_prog->GetAttributeLocation("iScale"); in_attrib_offset = _shader_prog->GetAttributeLocation("iOffset"); int FontTexture = _shader_prog->GetUniformLocationARB("FontTexture"); int TextColor = _shader_prog->GetUniformLocationARB("TextColor"); _graphics_engine.SetTexture(GL_TEXTURE0, glTexture->m_Texture); if (FontTexture != -1) { CHECKGL(glUniform1iARB(FontTexture, 0)); } if (TextColor != -1) { CHECKGL(glUniform4fARB(TextColor, color.red, color.green, color.blue, color.alpha)); } } #ifndef NUX_OPENGLES_20 else { shader_program = _asm_shader_prog; if (glTexture->m_Texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { shader_program = _asm_font_texture_rect_prog; } shader_program->Begin(); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); Matrix4 model_view_matrix = _graphics_engine.GetModelViewMatrix(); model_view_matrix.Transpose(); CHECKGL(glLoadMatrixf((float *) model_view_matrix.m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); Matrix4 projection_matrix = GetGraphicsDisplay()->GetGraphicsEngine()->GetProjectionMatrix(); projection_matrix.Transpose(); CHECKGL(glLoadMatrixf((float *) projection_matrix.m)); in_attrib_position = VTXATTRIB_POSITION; in_attrib_tex_uv = VTXATTRIB_TEXCOORD0; in_attrib_scale = VTXATTRIB_TEXCOORD1; in_attrib_offset = VTXATTRIB_TEXCOORD2; CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, color.red, color.green, color.blue, color.alpha )); _graphics_engine.SetTexture(GL_TEXTURE0, glTexture->m_Texture); } #endif if (in_attrib_offset != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_attrib_offset)); CHECKGL(glVertexAttribPointerARB(in_attrib_offset, 4, GL_FLOAT, GL_FALSE, 16, Offset)); } if (in_attrib_position != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_attrib_position)); CHECKGL(glVertexAttribPointerARB(in_attrib_position, 4, GL_FLOAT, GL_FALSE, 16, Position)); } if (in_attrib_scale != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_attrib_scale)); CHECKGL(glVertexAttribPointerARB(in_attrib_scale, 4, GL_FLOAT, GL_FALSE, 16, Scale)); } if (in_attrib_tex_uv != -1) { CHECKGL(glEnableVertexAttribArrayARB(in_attrib_tex_uv)); CHECKGL(glVertexAttribPointerARB(in_attrib_tex_uv, 4, GL_FLOAT, GL_FALSE, 16, UV)); } if (NumCharToDraw > 0) CHECKGL(glDrawElements( GL_TRIANGLES, NumCharToDraw * 6, GL_UNSIGNED_SHORT, Index )); if (in_attrib_position != -1) CHECKGL(glDisableVertexAttribArrayARB(in_attrib_position)); if (in_attrib_offset != -1) CHECKGL(glDisableVertexAttribArrayARB(in_attrib_offset)); if (in_attrib_scale != -1) CHECKGL(glDisableVertexAttribArrayARB(in_attrib_scale)); if (in_attrib_tex_uv != -1) CHECKGL(glDisableVertexAttribArrayARB(in_attrib_tex_uv)); if (_graphics_engine.UsingGLSLCodePath()) { _shader_prog->End(); } else { #ifndef NUX_OPENGLES_20 shader_program->End(); #endif } _graphics_engine.GetRenderStates().SetColorMask(TRUE, TRUE, TRUE, TRUE); _graphics_engine.GetRenderStates().SetBlend(FALSE); CurX -= x + CURSOR_OFFSET; delete [] Index; delete [] Position; delete [] UV; delete [] Scale; delete [] Offset; return CurX; // number of pixel to offset before writing the next string. } int FontRenderer::RenderTextToBuffer(float *VertexBuffer, int VBSize, ObjectPtr const& Font, Rect const& geo, std::string const& str, Color const& color, TextAlignment alignment, int NumCharacter) { nuxAssertMsg(NumCharacter >= 0, "[FontRenderer::RenderTextToBuffer] Number of char to draw must be positive."); int NumCharToDraw = 0; if (NumCharacter == 0) NumCharToDraw = str.size(); else NumCharToDraw = Min((int) str.size(), NumCharacter); nuxAssertMsg(3 * NumCharToDraw * 16 <= VBSize, "[FontRenderer::RenderTextToBuffer] VertexBuffer not large enough."); if (3 * NumCharToDraw * 16 > VBSize) return 0; StringBBox stringBBox; PageBBox pageBox; pageBox.xmin = geo.x; pageBox.xmax = geo.x + geo.GetWidth(); pageBox.ymin = geo.y; pageBox.ymax = geo.y + geo.GetHeight(); pageBox.x_margin = 0; pageBox.y_margin = 0; PositionString(Font, str, pageBox, stringBBox, alignment); int CurX = stringBBox.x; int CurY = stringBBox.y; Vector4 *Position = (Vector4 *) VertexBuffer; for (int i = 0; i < NumCharToDraw; ++i) { unsigned char c = static_cast (str[i]); unsigned int CharX = Font->m_Charset.Chars[c /*Str[i]*/].x; unsigned int CharY = Font->m_Charset.Chars[c /*Str[i]*/].y; unsigned int Width = Font->m_Charset.Chars[c /*Str[i]*/].Width; unsigned int Height = Font->m_Charset.Chars[c /*Str[i]*/].Height; //int OffsetX = Font->m_Charset.Chars[c /*Str[i]*/].XOffset; //int OffsetY = Font->m_Charset.Chars[c /*Str[i]*/].YOffset; int abcA = Font->m_Charset.Chars[c /*Str[i]*/].abcA; int abcB = Font->m_Charset.Chars[c /*Str[i]*/].abcB; int abcC = Font->m_Charset.Chars[c /*Str[i]*/].abcC; //int page = Font->m_Charset.Chars[c /*Str[i]*/].page; // Position upper left // Scale Offset Position[i*12 + 0].x = 0.0f * Width + (CurX + abcA); // x Position[i*12 + 0].y = 0.0f * Height + (CurY); // y Position[i*12 + 0].z = 0.0f * 1.0f + 0.0f; // z Position[i*12 + 0].w = 1.0f * 1.0f + 0.0f; // w // texture coord Position[i*12 + 1].x = CharX; Position[i*12 + 1].y = CharY; Position[i*12 + 1].z = 0.0f; Position[i*12 + 1].w = 1.0f; // color Position[i*12 + 2].x = color.red; Position[i*12 + 2].y = color.green; Position[i*12 + 2].z = color.blue; Position[i*12 + 2].w = color.alpha; // Position lower left Position[i*12 + 9].x = 0.0f * Width + (CurX + abcA); // x Position[i*12 + 9].y = 1.0f * Height + (CurY); // y Position[i*12 + 9].z = 0.0f * 1.0f + 0.0f; // z Position[i*12 + 9].w = 1.0f * 1.0f + 0.0f; // w // texture coord Position[i*12 + 10].x = CharX; Position[i*12 + 10].y = CharY + Height; Position[i*12 + 10].z = 0.0f; Position[i*12 + 10].w = 1.0f; // color Position[i*12 + 11].x = color.red; Position[i*12 + 11].y = color.green; Position[i*12 + 11].z = color.blue; Position[i*12 + 11].w = color.alpha; // Position lower right Position[i*12 + 6].x = 1.0f * Width + (CurX + abcA); // x Position[i*12 + 6].y = 1.0f * Height + (CurY); // y Position[i*12 + 6].z = 0.0f * 1.0f + 0.0f; // z Position[i*12 + 6].w = 1.0f * 1.0f + 0.0f; // w // texture coord Position[i*12 + 7].x = CharX + Width; Position[i*12 + 7].y = CharY + Height; Position[i*12 + 7].z = 0.0f; Position[i*12 + 7].w = 1.0f; // color Position[i*12 + 8].x = color.red; Position[i*12 + 8].y = color.green; Position[i*12 + 8].z = color.blue; Position[i*12 + 8].w = color.alpha; // Position upper right Position[i*12 + 3].x = 1.0f * Width + (CurX + abcA); // x Position[i*12 + 3].y = 0.0f * Height + (CurY); // y Position[i*12 + 3].z = 0.0f * 1.0f + 0.0f; // z Position[i*12 + 3].w = 1.0f * 1.0f + 0.0f; // w // texture coord Position[i*12 + 4].x = CharX + Width; Position[i*12 + 4].y = CharY; Position[i*12 + 4].z = 0.0f; Position[i*12 + 4].w = 1.0f; // color Position[i*12 + 5].x = color.red; Position[i*12 + 5].y = color.green; Position[i*12 + 5].z = color.blue; Position[i*12 + 5].w = color.alpha; CurX += abcA + abcB + abcC; } CurX -= stringBBox.x + CURSOR_OFFSET; return NumCharToDraw; } } nux-4.0.6+14.04.20140409/NuxGraphics/GlobalGraphicsInitializer.h0000644000015301777760000000475512321344237024441 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUXGRAPHICSGLOBALINITIALIZER_H #define NUXGRAPHICSGLOBALINITIALIZER_H #define NUX_GLOBAL_GRAPHICS_OBJECT_INIT_SEQUENCE() \ NUX_GLOBAL_OBJECT_VARIABLE(RenderingStats); \ NUX_GLOBAL_OBJECT_VARIABLE(NuxGraphicsResources); namespace nux { class NuxGraphicsGlobalSingletonInitializer { NUX_DISABLE_OBJECT_COPY(NuxGraphicsGlobalSingletonInitializer); NuxGraphicsGlobalSingletonInitializer *operator & (); const NuxGraphicsGlobalSingletonInitializer *operator & () const; public: NuxGraphicsGlobalSingletonInitializer(); ~NuxGraphicsGlobalSingletonInitializer(); static bool Ready(); private: static bool m_NuxGraphicsGlobalObjectsReady; NUX_GLOBAL_GRAPHICS_OBJECT_INIT_SEQUENCE(); }; // Nifty Counter idiom. See http://www-d0.fnal.gov/KAI/doc/tutorials/static_initialization.html class NuxGraphicsGlobalInitializer { public: NuxGraphicsGlobalInitializer(); ~NuxGraphicsGlobalInitializer(); private: static int m_Count; }; // Every compilation unit that includes this file will have its own instance of sGlobalInitializer. sGlobalInitializer is initialized // before the main function of the program is called. The first time sGlobalInitializer is initialized, it calls SystemStart() to create // our global object singleton. In SystemStart() we have a change to create our singletons in any order we like. // When the program exits, every instance of sGlobalInitializer will be destroyed. The last instance destroyed will call SystemShutdown(). // In SystemShutdown() we can destroy our global objects in any order we like. static NuxGraphicsGlobalInitializer sNuxGraphicsGlobalInitializer; } #endif // NUXGRAPHICSGLOBALINITIALIZER_H nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipe.cpp0000644000015301777760000006033612321344237022437 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "IOpenGLBaseTexture.h" #include "IOpenGLTexture2D.h" #include "IOpenGLRectangleTexture.h" #include "RenderingPipe.h" #include "GraphicsEngine.h" namespace nux { struct TexWrapMapping { TexWrap tex_wrap_mode; unsigned int opengl_wrap_mode; }; struct TexWrapMapping TexWrapMappingArray [] = { {TEXWRAP_REPEAT, GL_REPEAT}, {TEXWRAP_CLAMP, GL_CLAMP}, {TEXWRAP_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE}, {TEXWRAP_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER}, {TEXWRAP_MIRRORED_REPEAT, GL_MIRRORED_REPEAT}, #ifndef NUX_OPENGLES_20 {TEXWRAP_MIRROR_CLAMP_EXT, GL_MIRROR_CLAMP_EXT}, {TEXWRAP_MIRROR_CLAMP_TO_EDGE_EXT, GL_MIRROR_CLAMP_TO_EDGE_EXT}, {TEXWRAP_MIRROR_CLAMP_TO_BORDER_EXT, GL_MIRROR_CLAMP_TO_BORDER_EXT}, #endif {TEXWRAP_UNKNOWN, 0} }; GLenum TexWrapGLMapping(TexWrap tex_wrap_mode) { int i = 0; while (TexWrapMappingArray[i].tex_wrap_mode != TEXWRAP_UNKNOWN) { if (TexWrapMappingArray[i].tex_wrap_mode == tex_wrap_mode) { return TexWrapMappingArray[i].opengl_wrap_mode; } ++i; } nuxAssertMsg(0, "[TexWrapGLMapping] Invalid texture wrap mode."); return GL_CLAMP; } struct TexFilterMapping { TexFilter tex_filter_mode; unsigned int opengl_filter_mode; }; struct TexFilterMapping TexFilterMappingArray [] = { {TEXFILTER_LINEAR, GL_LINEAR}, {TEXFILTER_NEAREST, GL_NEAREST}, {TEXFILTER_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_NEAREST}, {TEXFILTER_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST}, {TEXFILTER_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_LINEAR}, {TEXFILTER_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR}, {TEXFILTER_UNKNOWN, 0}, }; GLenum TexFilterGLMapping(TexFilter tex_filter_mode) { int i = 0; while (TexFilterMappingArray[i].tex_filter_mode != TEXFILTER_UNKNOWN) { if (TexFilterMappingArray[i].tex_filter_mode == tex_filter_mode) { return TexFilterMappingArray[i].opengl_filter_mode; } ++i; } nuxAssertMsg(0, "[TexFilterGLMapping] Invalid texture filter mode."); return GL_REPEAT; } struct RopBlendMapping { RopBlend rop_blend_mode; unsigned int opengl_blend_op; }; struct RopBlendMapping RopBlendMappingArray [] = { {ROPBLEND_ZERO, GL_ZERO}, {ROPBLEND_ONE, GL_ONE}, {ROPBLEND_SRC_COLOR, GL_SRC_COLOR}, {ROPBLEND_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR}, {ROPBLEND_DST_COLOR, GL_DST_COLOR}, {ROPBLEND_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_DST_COLOR}, {ROPBLEND_SRC_ALPHA, GL_SRC_ALPHA}, {ROPBLEND_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, {ROPBLEND_DST_ALPHA, GL_DST_ALPHA}, {ROPBLEND_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA}, {ROPBLEND_CONSTANT_COLOR, GL_CONSTANT_COLOR}, {ROPBLEND_ONE_MINUS_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR}, {ROPBLEND_CONSTANT_ALPHA, GL_CONSTANT_ALPHA}, {ROPBLEND_ONE_MINUS_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA}, {ROPBLEND_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE}, {ROPBLEND_UNKNOWN, 0}, }; GLenum RopBlendGLMapping(RopBlend rop_blend_mode) { int i = 0; while (RopBlendMappingArray[i].rop_blend_mode != ROPBLEND_UNKNOWN) { if (RopBlendMappingArray[i].rop_blend_mode == rop_blend_mode) { return RopBlendMappingArray[i].opengl_blend_op; } ++i; } nuxAssertMsg(0, "[RopBlendGLMapping] Invalid texture ROP operation."); return ROPBLEND_ONE; } TexCoordXForm::TexCoordXForm() { u0 = v0 = u1 = v1 = 0.0f; uscale = 1.0f; vscale = 1.0f; uoffset = 0.0f; voffset = 0.0f; flip_u_coord = false; flip_v_coord = false; uwrap = TEXWRAP_CLAMP; vwrap = TEXWRAP_CLAMP; min_filter = TEXFILTER_NEAREST; mag_filter = TEXFILTER_NEAREST; m_tex_coord_type = TexCoordXForm::OFFSET_SCALE_COORD; } void TexCoordXForm::FlipUCoord(bool b) { flip_u_coord = b; } void TexCoordXForm::FlipVCoord(bool b) { flip_v_coord = b; } void TexCoordXForm::FlipUVCoord(bool flip_u, bool flip_v) { flip_u_coord = flip_u; flip_v_coord = flip_v; } void TexCoordXForm::SetFilter(TexFilter minfitter, TexFilter magfilter) { min_filter = minfitter; mag_filter = magfilter; } void TexCoordXForm::SetWrap(TexWrap u_wrap, TexWrap v_wrap) { uwrap = u_wrap; vwrap = v_wrap; } void TexCoordXForm::SetTexCoordType(TexCoordType tex_coord_type) { m_tex_coord_type = tex_coord_type; } void QRP_Compute_Texture_Coord(int quad_width, int quad_height, ObjectPtr tex, TexCoordXForm &texxform) { float tex_width = tex->GetWidth(); float tex_height = tex->GetHeight(); if (tex->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) { if (texxform.m_tex_coord_type == TexCoordXForm::OFFSET_SCALE_COORD) { // Scale and offset the texture coordinates. // With a scale of 1.0 for both uscale and vscale, the texture is scaled over the entire surface of the quad. // If the texture and the quad have the same size, then the texture is mapped 1 to 1 with the pixels of the quad. texxform.u0 = texxform.uoffset; texxform.v0 = texxform.voffset; texxform.u1 = texxform.uoffset + texxform.uscale * (tex_width / (float)quad_width) * quad_width / tex_width; texxform.v1 = texxform.voffset + texxform.vscale * (tex_height / (float)quad_height) * quad_height / tex_height; } else if (texxform.m_tex_coord_type == TexCoordXForm::OFFSET_COORD) { // Offset the texture coordinates but preserve the proportion of the of the texture over the quad. // If the texture size is smaller than the quad, it will be tiled over it. texxform.u0 = texxform.uoffset; texxform.v0 = texxform.voffset; texxform.u1 = texxform.uoffset + quad_width / tex_width; texxform.v1 = texxform.voffset + quad_height / tex_height; } else if (texxform.m_tex_coord_type == TexCoordXForm::UNNORMALIZED_COORD) { texxform.u0 /= (float) tex_width; texxform.v0 /= (float) tex_height; texxform.u1 /= (float) tex_width; texxform.v1 /= (float) tex_height; } else if (texxform.m_tex_coord_type == TexCoordXForm::NORMALIZED_COORD || texxform.m_tex_coord_type == TexCoordXForm::FIXED_COORD) { // Use provided texture coordinates as is. } } else if (tex->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { if (texxform.m_tex_coord_type == TexCoordXForm::OFFSET_SCALE_COORD) { texxform.u0 = int(texxform.uoffset * tex_width); texxform.v0 = int(texxform.voffset * tex_height); texxform.u1 = texxform.u0 + tex_width * texxform.uscale; texxform.v1 = texxform.v0 + tex_height * texxform.vscale; } else if (texxform.m_tex_coord_type == TexCoordXForm::OFFSET_COORD) { texxform.u0 = texxform.uoffset; texxform.v0 = texxform.voffset; texxform.u1 = texxform.u0 + quad_width; texxform.v1 = texxform.v0 + quad_height; } else if (texxform.m_tex_coord_type == TexCoordXForm::NORMALIZED_COORD) { texxform.u0 *= (float) tex_width; texxform.v0 *= (float) tex_height; texxform.u1 *= (float) tex_width; texxform.v1 *= (float) tex_height; } else if (texxform.m_tex_coord_type == TexCoordXForm::UNNORMALIZED_COORD || texxform.m_tex_coord_type == TexCoordXForm::FIXED_COORD) { // Use provided texture coordinates as is. } } if (texxform.flip_u_coord) { texxform.u0 = 1.0f - texxform.u0; texxform.u1 = 1.0f - texxform.u1; } if (texxform.flip_v_coord) { texxform.v0 = 1.0f - texxform.v0; texxform.v1 = 1.0f - texxform.v1; } if (tex->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) { // A chance to avoid some potential errors! Rectangle textures support only GL_CLAMP, GL_CLAMP_TO_EDGE, and GL_CLAMP_TO_BORDER. // See http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt if (texxform.uwrap != TEXWRAP_CLAMP || texxform.uwrap != TEXWRAP_CLAMP_TO_EDGE || texxform.uwrap != TEXWRAP_CLAMP_TO_BORDER || texxform.vwrap != TEXWRAP_CLAMP || texxform.vwrap != TEXWRAP_CLAMP_TO_EDGE || texxform.vwrap != TEXWRAP_CLAMP_TO_BORDER) { texxform.uwrap = TEXWRAP_CLAMP; texxform.vwrap = TEXWRAP_CLAMP; } } #ifdef NUX_OPENGLES_20 // Enforce OpenGL ES 2.0 texture restrictions // 1. There is neither CLAMP nor CLAMP_TO_BORDER // 2. For NPOT textures, only CLAMP_TO_EDGE is supported // 3. For NPOT textures, only NEAREST and LINEAR are supported // // The last two constraints are relaxed by the GL_OES_texture_npot // extension which unfortunately is not supported by all implementations. // // Notes: we have mapped GL_CLAMP to GL_CLAMP_TO_EDGE in OpenGLMapping.h // so we also "support" TEXWRAP_CLAMP. if (texxform.uwrap == TEXWRAP_CLAMP_TO_BORDER || texxform.vwrap == TEXWRAP_CLAMP_TO_BORDER || (!tex->IsPowerOfTwo() && ((texxform.uwrap != TEXWRAP_CLAMP && texxform.uwrap != TEXWRAP_CLAMP_TO_EDGE) || (texxform.vwrap != TEXWRAP_CLAMP && texxform.vwrap != TEXWRAP_CLAMP_TO_EDGE)))) { texxform.uwrap = TEXWRAP_CLAMP_TO_EDGE; texxform.vwrap = TEXWRAP_CLAMP_TO_EDGE; } if (!tex->IsPowerOfTwo() && ((texxform.min_filter != TEXFILTER_NEAREST && texxform.min_filter != TEXFILTER_LINEAR) || (texxform.mag_filter != TEXFILTER_NEAREST && texxform.mag_filter != TEXFILTER_LINEAR))) { texxform.min_filter = TEXFILTER_LINEAR; texxform.mag_filter = TEXFILTER_LINEAR; } #endif tex->SetWrap(TexWrapGLMapping(texxform.uwrap), TexWrapGLMapping(texxform.vwrap), GL_CLAMP); tex->SetFiltering(TexFilterGLMapping(texxform.min_filter), TexFilterGLMapping(texxform.mag_filter)); } void GraphicsEngine::QRP_Color(int x, int y, int width, int height, const Color &color) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_Color(x, y, width, height, color, color, color, color); else QRP_ASM_Color(x, y, width, height, color, color, color, color); #else QRP_GLSL_Color(x, y, width, height, color, color, color, color); #endif } void GraphicsEngine::QRP_Color(int x, int y, int width, int height, const Color &c0, const Color &c1, const Color &c2, const Color &c3) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_Color(x, y, width, height, c0, c1, c2, c3); else QRP_ASM_Color(x, y, width, height, c0, c1, c2, c3); #else QRP_GLSL_Color(x, y, width, height, c0, c1, c2, c3); #endif } void GraphicsEngine::QRP_1Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm &texxform0, const Color &color0) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_1Tex(x, y, width, height, DeviceTexture, texxform0, color0); else QRP_ASM_1Tex(x, y, width, height, DeviceTexture, texxform0, color0); #else QRP_GLSL_1Tex(x, y, width, height, DeviceTexture, texxform0, color0); #endif } void GraphicsEngine::QRP_1TexPremultiply(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm &texxform0, const Color &color0) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_1TexPremultiply(x, y, width, height, DeviceTexture, texxform0, color0); else QRP_ASM_1TexPremultiply(x, y, width, height, DeviceTexture, texxform0, color0); #else QRP_GLSL_1TexPremultiply(x, y, width, height, DeviceTexture, texxform0, color0); #endif } void GraphicsEngine::QRP_TexDesaturate(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm& texxform0, const Color& color0, float desaturation_factor) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_TexDesaturate(x, y, width, height, DeviceTexture, texxform0, color0, desaturation_factor); else { // Todo! //QRP_ASM_TexDesaturate(x, y, width, height, DeviceTexture, texxform0, color0, desaturation_factor); } #else QRP_GLSL_TexDesaturate(x, y, width, height, DeviceTexture, texxform0, color0, desaturation_factor); #endif } void GraphicsEngine::QRP_Pixelate(int x, int y, int width, int height, ObjectPtr DeviceTexture, TexCoordXForm &texxform, const Color &c0, int pixel_size) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_Pixelate(x, y, width, height, DeviceTexture, texxform, c0, pixel_size); else QRP_ASM_Pixelate(x, y, width, height, DeviceTexture, texxform, c0, pixel_size); #else QRP_GLSL_Pixelate(x, y, width, height, DeviceTexture, texxform, c0, pixel_size); #endif } // Render the texture alpha into RGB and modulated by a color. void GraphicsEngine::QRP_ColorModTexAlpha(int x, int y, int width, int height, ObjectPtr< IOpenGLBaseTexture> DeviceTexture, TexCoordXForm &texxform, const Color &color) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_ColorModTexAlpha(x, y, width, height, DeviceTexture, texxform, color); else QRP_ASM_ColorModTexAlpha(x, y, width, height, DeviceTexture, texxform, color); #else QRP_GLSL_ColorModTexAlpha(x, y, width, height, DeviceTexture, texxform, color); #endif } // Blend 2 textures together void GraphicsEngine::QRP_2Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr DeviceTexture1, TexCoordXForm &texxform1, const Color &color1) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_2Tex(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1); else QRP_ASM_2Tex(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1); #else QRP_GLSL_2Tex(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1); #endif } void GraphicsEngine::QRP_2TexMod(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr DeviceTexture1, TexCoordXForm &texxform1, const Color &color1) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_2TexMod(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1); else QRP_ASM_2TexMod(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1); #else QRP_GLSL_2TexMod(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1); #endif } void GraphicsEngine::QRP_4Tex(int x, int y, int width, int height, ObjectPtr DeviceTexture0, TexCoordXForm &texxform0, const Color &color0, ObjectPtr DeviceTexture1, TexCoordXForm &texxform1, const Color &color1, ObjectPtr DeviceTexture2, TexCoordXForm &texxform2, const Color &color2, ObjectPtr DeviceTexture3, TexCoordXForm &texxform3, const Color &color3) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_4Tex(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1, DeviceTexture2, texxform2, color2, DeviceTexture3, texxform3, color3); else QRP_ASM_4Tex(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1, DeviceTexture2, texxform2, color2, DeviceTexture3, texxform3, color3); #else QRP_GLSL_4Tex(x, y, width, height, DeviceTexture0, texxform0, color0, DeviceTexture1, texxform1, color1, DeviceTexture2, texxform2, color2, DeviceTexture3, texxform3, color3); #endif } void GraphicsEngine::QRP_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_Triangle(x0, y0, x1, y1, x2, y2, c0, c0, c0); else QRP_ASM_Triangle(x0, y0, x1, y1, x2, y2, c0, c0, c0); #else QRP_GLSL_Triangle(x0, y0, x1, y1, x2, y2, c0, c0, c0); #endif } void GraphicsEngine::QRP_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, Color c0, Color c1, Color c2) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_Triangle(x0, y0, x1, y1, x2, y2, c0, c1, c2); else QRP_ASM_Triangle(x0, y0, x1, y1, x2, y2, c0, c1, c2); #else QRP_GLSL_Triangle(x0, y0, x1, y1, x2, y2, c0, c1, c2); #endif } void GraphicsEngine::QRP_Line(int x0, int y0, int x1, int y1, Color c0) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_Line(x0, y0, x1, y1, c0, c0); else QRP_ASM_Line(x0, y0, x1, y1, c0, c0); #else QRP_GLSL_Line(x0, y0, x1, y1, c0, c0); #endif } void GraphicsEngine::QRP_Line(int x0, int y0, int x1, int y1, Color c0, Color c1) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_Line(x0, y0, x1, y1, c0, c1); else QRP_ASM_Line(x0, y0, x1, y1, c0, c1); #else QRP_GLSL_Line(x0, y0, x1, y1, c0, c1); #endif } void GraphicsEngine::QRP_QuadWireframe(int x0, int y0, int width, int height, Color c0, Color c1, Color c2, Color c3) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_QuadWireframe(x0, y0, width, height, c0, c1, c2, c3); else QRP_ASM_QuadWireframe(x0, y0, width, height, c0, c1, c2, c3); #else QRP_GLSL_QuadWireframe(x0, y0, width, height, c0, c1, c2, c3); #endif } ObjectPtr GraphicsEngine::QRP_GetBlurTexture( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, float sigma, int num_pass) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) return QRP_GLSL_GetBlurTexture(x, y, buffer_width, buffer_height, device_texture, texxform, c0, sigma, num_pass); else return QRP_ASM_GetBlurTexture(x, y, buffer_width, buffer_height, device_texture, texxform, c0, sigma, num_pass); #else return QRP_GLSL_GetBlurTexture(x, y, buffer_width, buffer_height, device_texture, texxform, c0, sigma, num_pass); #endif } ObjectPtr GraphicsEngine::QRP_GetAlphaTexture( ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) return QRP_GLSL_GetAlphaTexture(device_texture, texxform, c0); else return QRP_ASM_GetAlphaTexture(device_texture, texxform, c0); #else return QRP_GLSL_GetAlphaTexture(device_texture, texxform, c0); #endif } ObjectPtr GraphicsEngine::QRP_GetColorMatrixTexture( ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, Matrix4 color_matrix, Vector4 offset) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) return QRP_GLSL_GetColorMatrixTexture(device_texture, texxform, c0, color_matrix, offset); else return QRP_ASM_GetColorMatrixTexture(device_texture, texxform, c0, color_matrix, offset); #else return QRP_GLSL_GetColorMatrixTexture(device_texture, texxform, c0, color_matrix, offset); #endif } ObjectPtr GraphicsEngine::QRP_GetPower( ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, const Vector4 &exponent) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) return QRP_GLSL_GetPower(device_texture, texxform, c0, exponent); else return QRP_ASM_GetPower(device_texture, texxform, c0, exponent); #else return QRP_GLSL_GetPower(device_texture, texxform, c0, exponent); #endif } ObjectPtr GraphicsEngine::QRP_GetLQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) return QRP_GLSL_GetLQBlur(x, y, buffer_width, buffer_height, device_texture, texxform, c0); else return QRP_ASM_GetLQBlur(x, y, buffer_width, buffer_height, device_texture, texxform, c0); #else return QRP_GLSL_GetLQBlur(x, y, buffer_width, buffer_height, device_texture, texxform, c0); #endif } ObjectPtr GraphicsEngine::QRP_GetHQBlur( int x, int y, int buffer_width, int buffer_height, ObjectPtr device_texture, TexCoordXForm &texxform, const Color& c0, float sigma, int num_pass) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath() && (_graphics_display.GetGpuDevice()->GetOpenGLMajorVersion() >= 2)) return QRP_GLSL_GetHQBlur(x, y, buffer_width, buffer_height, device_texture, texxform, c0, sigma, num_pass); else return QRP_ASM_GetBlurTexture(x, y, buffer_width, buffer_height, device_texture, texxform, c0, sigma, num_pass); #else return QRP_GLSL_GetBlurTexture(x, y, buffer_width, buffer_height, device_texture, texxform, c0, sigma, num_pass); #endif } void GraphicsEngine::QRP_DisturbedTexture( int x, int y, int width, int height, ObjectPtr distorsion_texture, TexCoordXForm &texxform0, const Color& c0, ObjectPtr src_device_texture, TexCoordXForm &texxform1, const Color& c1) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath()) QRP_GLSL_DisturbedTexture(x, y, width, height, distorsion_texture, texxform0, c0, src_device_texture, texxform1, c1); else { // NUXTODO //QRP_ASM_DisturbedTexture(x, y, width, height, distorsion_texture, texxform0, c0, src_device_texture, texxform1, c1); } #else QRP_GLSL_DisturbedTexture(x, y, width, height, distorsion_texture, texxform0, c0, src_device_texture, texxform1, c1); #endif } ObjectPtr GraphicsEngine::QRP_GetPixelBlocks( ObjectPtr device_texture, TexCoordXForm &texxform, const Color& color, int pixel_size) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath() && (_graphics_display.GetGpuDevice()->GetOpenGLMajorVersion() >= 2)) return QRP_GLSL_GetPixelBlocks(device_texture, texxform, color, pixel_size); else return QRP_ASM_GetPixelBlocks(device_texture, texxform, color, pixel_size); #else return QRP_GLSL_GetPixelBlocks(device_texture, texxform, color, pixel_size); #endif } void GraphicsEngine::QRP_GetCopyTexture( int width, int height, ObjectPtr& dst_device_texture, ObjectPtr& src_device_texture, TexCoordXForm &texxform0, const Color& c0) { #ifndef NUX_OPENGLES_20 if (UsingGLSLCodePath() && (_graphics_display.GetGpuDevice()->GetOpenGLMajorVersion() >= 2)) return QRP_GLSL_GetCopyTexture(width, height, dst_device_texture, src_device_texture, texxform0, c0); else return QRP_ASM_GetCopyTexture(width, height, dst_device_texture, src_device_texture, texxform0, c0); #else return QRP_GLSL_GetCopyTexture(width, height, dst_device_texture, src_device_texture, texxform0, c0); #endif } } nux-4.0.6+14.04.20140409/NuxGraphics/GfxEventsX11.h0000644000015301777760000003052712321344237021553 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GFXEVENTSX11_H #define GFXEVENTSX11_H #include "GLResource.h" #include "VirtualKeyCodesX11.h" //--------------------------------------------------------------key_code_e // Keyboard codes. There's also a restricted set of codes that are most // probably supported on different platforms. Any platform dependent codes // should be converted into these ones. There're only those codes are // defined that cannot be represented as printable ASCII-characters. // All printable ASCII-set can be used in a regilar C/C++ manner: // ' ', 'A', '0' '+' and so on. // Since the class is used for creating very simple demo-applications // we don't need very rich possibilities here, just basic ones. // Actually the numeric key codes are taken from the SDL library, so, // the implementation of the SDL support does not require any mapping. //enum eKeyCode //{ // // ASCII set. Should be supported everywhere // key_backspace = 8, // key_tab = 9, // key_clear = 12, // key_return = 13, // key_shift = 16, // key_control = 17, // key_pause = 19, // key_escape = 27, // // key_space = 32, // // // Keypad // key_delete = 127, // key_kp0 = 256, // key_kp1 = 257, // key_kp2 = 258, // key_kp3 = 259, // key_kp4 = 260, // key_kp5 = 261, // key_kp6 = 262, // key_kp7 = 263, // key_kp8 = 264, // key_kp9 = 265, // key_kp_period = 266, // key_kp_divide = 267, // key_kp_multiply = 268, // key_kp_minus = 269, // key_kp_plus = 270, // key_kp_enter = 271, // key_kp_equals = 272, // // // Arrow-keys and stuff // key_up = 273, // key_down = 274, // key_right = 275, // key_left = 276, // key_insert = 277, // key_home = 278, // key_end = 279, // key_page_up = 280, // key_page_down = 281, // // // Functional keys. You'd better avoid using // // f11...f15 in your applications if you want // // the applications to be portable // key_f1 = 282, // key_f2 = 283, // key_f3 = 284, // key_f4 = 285, // key_f5 = 286, // key_f6 = 287, // key_f7 = 288, // key_f8 = 289, // key_f9 = 290, // key_f10 = 291, // key_f11 = 292, // key_f12 = 293, // key_f13 = 294, // key_f14 = 295, // key_f15 = 296, // // // The possibility of using these keys is // // very restricted. Actually it's guaranteed // // only in win32_api and win32_sdl implementations // key_numlock = 300, // key_capslock = 301, // key_scrollock = 302, // // // Phew! // end_of_key_codes //}; namespace nux { const long I_ExposureMask = (1L << 15); const long I_StructureNotifyMask = (1L << 17); const long I_SubstructureNotifyMask = (1L << 19); #define NUX_BackSpace NUX_VK_BACK #define NUX_Tab NUX_VK_TAB #define NUX_Clear NUX_VK_CLEAR #define NUX_Enter NUX_VK_ENTER #define NUX_Shift_L NUX_VK_SHIFT #define NUX_Control_L NUX_VK_CONTROL #define NUX_Alt_L NUX_VK_MENU #define NUX_Pause NUX_VK_PAUSE #define NUX_Caps_Lock NUX_VK_CAPITAL #define NUX_Escape NUX_VK_ESCAPE #define NUX_SpaceBar NUX_VK_SPACE #define NUX_Page_Up NUX_VK_PAGE_UP #define NUX_Page_Down NUX_VK_PAGE_DOWN #define NUX_End NUX_VK_END #define NUX_Home NUX_VK_HOME #define NUX_Left NUX_VK_LEFT #define NUX_Up NUX_VK_UP #define NUX_Right NUX_VK_RIGHT #define NUX_Down NUX_VK_DOWN #define NUX_Print NUX_VK_SNAPSHOT #define NUX_Insert NUX_VK_INSERT #define NUX_Delete NUX_VK_DELETE #define NUX_LWin NUX_VK_LWIN #define NUX_RWin NUX_VK_RWIN #define NUX_APPS NUX_VK_APPS #define NUX_Multiply NUX_VK_MULTIPLY #define NUX_Add NUX_VK_ADD #define NUX_Subtract NUX_VK_SUBTRACT #define NUX_Decimal NUX_VK_DECIMAL #define NUX_Divide NUX_VK_DIVIDE #define NUX_Numlock NUX_VK_NUMLOCK #define NUX_Scroll NUX_VK_SCROLL #define NUX_KP_ENTER (0xff00 | NUX_VK_ENTER) #define NUX_EXT_Shift_R (0xff00 | NUX_VK_SHIFT) #define NUX_EXT_Control_R (0xff00 | NUX_VK_CONTROL) #define NUX_EXT_Alt_R (0xff00 | NUX_VK_MENU) #define NUX_KP_PAGE_UP (0xff00 | NUX_VK_PAGE_UP) #define NUX_KP_PAGE_DOWN (0xff00 | NUX_VK_PAGE_DOWN) #define NUX_KP_END (0xff00 | NUX_VK_END) #define NUX_KP_HOME (0xff00 | NUX_VK_HOME) #define NUX_KP_LEFT (0xff00 | NUX_VK_LEFT) #define NUX_KP_UP (0xff00 | NUX_VK_UP) #define NUX_KP_RIGHT (0xff00 | NUX_VK_RIGHT) #define NUX_KP_DOWN (0xff00 | NUX_VK_DOWN) #define NUX_KP_INSERT (0xff00 | NUX_VK_INSERT) #define NUX_KP_DELETE (0xff00 | NUX_VK_DELETE) #define NUX_F1 NUX_VK_F1 #define NUX_F2 NUX_VK_F2 #define NUX_F3 NUX_VK_F3 #define NUX_F4 NUX_VK_F4 #define NUX_F5 NUX_VK_F5 #define NUX_F6 NUX_VK_F6 #define NUX_F7 NUX_VK_F7 #define NUX_F8 NUX_VK_F8 #define NUX_F9 NUX_VK_F9 #define NUX_F10 NUX_VK_F10 #define NUX_F11 NUX_VK_F11 #define NUX_F12 NUX_VK_F12 #define NUX_F13 NUX_VK_F13 #define NUX_F14 NUX_VK_F14 #define NUX_F15 NUX_VK_F15 #define NUX_F16 NUX_VK_F16 #define NUX_F17 NUX_VK_F17 #define NUX_F18 NUX_VK_F18 #define NUX_F19 NUX_VK_F19 #define NUX_F20 NUX_VK_F20 #define NUX_F21 NUX_VK_F21 #define NUX_F22 NUX_VK_F22 #define NUX_F23 NUX_VK_F23 #define NUX_F24 NUX_VK_F24 #define NUX_LEFT_MOUSE 1 #define NUX_MIDDLE_MOUSE 2 #define NUX_RIGHT_MOUSE 3 // Key States. Set in e_key_modifiers. #define NUX_STATE_SHIFT 0x00010000 #define NUX_STATE_CAPS_LOCK 0x00020000 #define NUX_STATE_CTRL 0x00040000 #define NUX_STATE_ALT 0x00080000 #define NUX_STATE_NUMLOCK 0x00100000 // most X servers do this? #define NUX_STATE_META 0x00400000 // correct for XFree86 #define NUX_STATE_SCROLLLOCK 0x00800000 // correct for XFree86 // These flags describe the mouse button responsible for the mouse event. // They are valid only for the current frame. // Go in e_mouse_state. #define NUX_EVENT_BUTTON1_UP 0x00001000 #define NUX_EVENT_BUTTON2_UP 0x00002000 #define NUX_EVENT_BUTTON3_UP 0x00004000 #define NUX_EVENT_BUTTON1_DOWN 0x00010000 #define NUX_EVENT_BUTTON2_DOWN 0x00020000 #define NUX_EVENT_BUTTON3_DOWN 0x00040000 #define NUX_EVENT_BUTTON1 0x00010000 #define NUX_EVENT_BUTTON2 0x00020000 #define NUX_EVENT_BUTTON3 0x00040000 #define NUX_EVENT_MOUSEWHEEL 0x00080000 // These flags describe the state of the mouse buttons. // They persist over several frame until the mouse buttons change state. // Go in e_mouse_state. #define NUX_STATE_BUTTON1_DOWN 0x01000000 #define NUX_STATE_BUTTON2_DOWN 0x02000000 #define NUX_STATE_BUTTON3_DOWN 0x04000000 // These flags are set if the event is a double click. // They are valid only for the current frame. // Go in e_mouse_state. #define NUX_EVENT_BUTTON1_DBLCLICK 0x10000000 #define NUX_EVENT_BUTTON2_DBLCLICK 0x20000000 #define NUX_EVENT_BUTTON3_DBLCLICK 0x40000000 #define eLEFT_BUTTON NUX_EVENT_BUTTON1 #define eMIDDLE_BUTTON NUX_EVENT_BUTTON2 #define eRIGHT_BUTTON NUX_EVENT_BUTTON3 #define eLEFT_BUTTON_DOWN NUX_STATE_BUTTON1_DOWN #define eMIDDLE_BUTTON_DOWN NUX_STATE_BUTTON2_DOWN #define eRIGHT_BUTTON_DOWN NUX_STATE_BUTTON3_DOWN #define NUX_WIN32_MOUSEWHEEL_DELTA 120 // 120 correspond to one notch of the mouse wheel typedef unsigned char uchar; typedef unsigned long ulong; struct EventToNameStruct { int event; const TCHAR *EventName; }; enum { // events NUX_NO_EVENT = 0, NUX_MOUSE_PRESSED, NUX_MOUSE_RELEASED, NUX_KEYDOWN, NUX_KEYUP, NUX_MOUSE_MOVE, NUX_SIZE_CONFIGURATION, NUX_WINDOW_CONFIGURATION, NUX_WINDOW_ENTER_FOCUS, NUX_WINDOW_EXIT_FOCUS, NUX_WINDOW_DIRTY, NUX_WINDOW_MOUSELEAVE, NUX_MOUSEWHEEL, NUX_DESTROY_WINDOW, NUX_TERMINATE_APP }; typedef struct IEvent { int width, height; unsigned int ascii_code; int virtual_code; bool IsLeftMouseDown; bool IsRightMouseDown; bool IsMiddleMouseDown; int e_x, e_y, e_x_root, e_y_root, e_dx, e_dy, e_clicks, e_is_click, e_keysym; int e_wheeldelta; unsigned long e_key_modifiers; // key modifiers unsigned short e_key_repeat_count; // number of time a key is repeated; unsigned long e_mouse_state; char *e_text; int e_length; unsigned long e_event; IEvent() { IsLeftMouseDown = false; IsRightMouseDown = false; IsMiddleMouseDown = false; e_text = (char *) ""; for (int i = 0; i < NUX_MAX_VK; i++) { VirtualKeycodeState[i] = 0; } ascii_code = 0; virtual_code = 0; e_key_modifiers = 0; e_key_repeat_count = 0; e_mouse_state = 0; e_x = 0; e_y = 0; e_x_root = 0; e_y_root = 0; e_dx = 0; e_dy = 0; e_clicks = 0; e_is_click = 0; e_keysym = 0; e_wheeldelta = 0; //Application = 0; } int event_x() const { return e_x; } int event_y() const { return e_y; } int event_x_root() const { return e_x_root; } int event_y_root() const { return e_y_root; } int event_dx() const { return e_dx; } int event_dy() const { return e_dy; } void get_mouse (int &, int &); unsigned long event_key_state() const { return e_key_modifiers; } unsigned long event_mouse_state() const { return e_mouse_state; } //! Return virtual key code of the key that has triggered the last event. /*! Return virtual key code of the key that has triggered the last event. @return the virtual key code. */ unsigned long event_keysym() const { return e_keysym; } unsigned short event_key_auto_repeat_count() const { return e_key_repeat_count; } bool event_is_key_auto_repeat() const { if (e_key_repeat_count > 1) return true; return false; } const char *event_text() const { return e_text; } // Because an event is save in e_event instead of calling immediately the handling function, // we must clear the previous event each time before we test for new event in Gfx_OpenGLImpl::get_event. void Reset() { e_event = NUX_NO_EVENT; e_text = (char *) ""; e_keysym = 0; e_key_repeat_count = 0; e_wheeldelta = 0; } unsigned long VirtualKeycodeState[NUX_MAX_VK]; //! Return the state of the Virtual key /*! Return the state of the Virtual key. @param VirtualKey virtual key code. @return 1 if the key is pressed, 0 if the key is released. */ unsigned long GetVirtualKeyState (unsigned long VirtualKey) const { if (VirtualKey >= NUX_MAX_VK) return 0; if (VirtualKey <= 0) return 0; return VirtualKeycodeState[VirtualKey]; } //void* Application; } IEvent; } #endif // GFXEVENTSX11_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLRectangleTexture.h0000644000015301777760000000640412321344237024010 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLRECTANGLETEXTURE_H #define IOPENGLRECTANGLETEXTURE_H namespace nux { class IOpenGLBaseTexture; class IOpenGLRectangleTexture: public IOpenGLBaseTexture { NUX_DECLARE_OBJECT_TYPE(IOpenGLRectangleTexture, IOpenGLBaseTexture); public: virtual ~IOpenGLRectangleTexture(); void GetSurfaceLevel(int Level, ObjectPtr& surface); ObjectPtr GetSurfaceLevel(int Level); int LockRect( int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect); int UnlockRect( int Level ); unsigned int EnableGammaCorrection(bool b); int GetLevelDesc( int Level, SURFACE_DESC *pDesc ) { nuxAssert(Level >= 0); nuxAssert(Level < _NumMipLevel); if ((Level < 0) || (Level > _NumMipLevel)) { pDesc->Width = 0; pDesc->Height = 0; pDesc->PixelFormat = BITFMT_UNKNOWN; pDesc->Type = _ResourceType; } else { pDesc->Width = Max (1, _Width >> Level); pDesc->Height = Max (1, _Height >> Level); pDesc->PixelFormat = _PixelFormat; pDesc->Type = _ResourceType; } return OGL_OK; } //! Return a pointer to a mipmap level data. /*! Return a pointer to a mipmap level data. The data is in the RGBA format.\n Inherited from IOpenGLBaseTexture. @param level The requested texture mipmap level data. @param width Returns the width in pixel of the image data. @param height Returns the height in pixel of the image data. @param stride Returns the row stride of the image data. @return A pointer to RGBA data. The caller must dlete the data by calling delete []. */ unsigned char* GetSurfaceData(int level, int &width, int &height, int &stride); private: // The Dummy boolean is used to create a skeletal frame for the default // render target texture and surface; Only GpuDevice uses it in its constructor. // Do not use it otherwise!!! IOpenGLRectangleTexture( unsigned int Width , unsigned int Height , unsigned int Levels , BitmapFormat PixelFormat, bool Dummy = false, NUX_FILE_LINE_PROTO); // unsigned int _Width; // unsigned int _Height; std::vector< ObjectPtr > _SurfaceArray; friend class GpuDevice; friend class IOpenGLSurface; }; } #endif // IOPENGLRECTANGLETEXTURE_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLQuery.h0000644000015301777760000000357112321344237021632 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLQUERY_H #define IOPENGLQUERY_H namespace nux { class IOpenGLResource; class IOpenGLQuery: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLQuery, IOpenGLResource); public: int GetData( int *pData, unsigned int Size, unsigned int GetDataFlags ); unsigned int GetDataSize(); void GetDevice( GpuDevice **ppDevice ); QUERY_TYPE GetType(); void Issue( unsigned int IssueFlags ); // Convenient functions // Return True is the result is available. That is glGetQueryObjectuivARB won't block // if called with GL_QUERY_RESULT_ARB. bool IsResultAvailable(); // Return the result of the query. Make sure IsResultAvailable returned TRUE before calling this function. // If you fail to do that, GetResult will block before returning. unsigned int GetResult(); IOpenGLQuery(QUERY_TYPE Type); virtual ~IOpenGLQuery() {}; private: QUERY_TYPE _Type; bool _QueryStarted; friend class GpuDevice; static unsigned int _CurrentlyActiveQuery; }; } #endif // IOPENGLQUERY_H nux-4.0.6+14.04.20140409/NuxGraphics/MeshData.cpp0000644000015301777760000000322312321344237021362 0ustar pbusernogroup00000000000000#include "GLResource.h" #include "MeshData.h" namespace nux { MeshData::MeshData() { _num_index = 0; _index_size = 0; _num_element = 0; _vertex_data = 0; _index_data = 0; } MeshData::~MeshData() { NUX_SAFE_DELETE_ARRAY(_vertex_data); NUX_SAFE_DELETE_ARRAY(_index_data); } bool MeshData::Allocate(int num_mesh_primitive, NuxMeshPrimitiveType primitive_type, int num_element, int element_size) { NUX_RETURN_VALUE_IF_FALSE(num_element > 0, false); NUX_RETURN_VALUE_IF_FALSE(element_size > 0, false); NUX_SAFE_DELETE_ARRAY(_vertex_data); NUX_SAFE_DELETE_ARRAY(_index_data); _num_element = num_element; _element_size = element_size; _mesh_primitive_type = primitive_type; switch(primitive_type) { case NUX_MESH_TRIANGLE: _num_index = num_mesh_primitive * 3; break; case NUX_MESH_TRIANGLE_STRIP: case NUX_MESH_TRIANGLE_FAN: _num_index = num_mesh_primitive + 2; break; case NUX_MESH_LINE: _num_index = num_mesh_primitive * 2; break; case NUX_MESH_LINE_STRIP: case NUX_MESH_LINE_LOOP: _num_index = num_mesh_primitive + 1; break; case NUX_MESH_QUAD: _num_index = num_mesh_primitive * 4; break; case NUX_MESH_QUAD_STRIP: _num_index = num_mesh_primitive + 2; break; case NUX_MESH_POINT: _num_index = num_mesh_primitive; break; case NUX_MESH_PRIMITIVE_UNKNOWN: return false; break; } _index_size = 4; _vertex_data = new unsigned char[num_element * element_size]; _index_data = new unsigned char[_num_index * _index_size]; return true; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVolume.cpp0000644000015301777760000004357612321344237022340 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLDeviceObjects.h" #include "IOpenGLVolume.h" #include "GraphicsDisplay.h" #include "GpuDevice.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLVolume); IOpenGLVolume::~IOpenGLVolume() { } int IOpenGLVolume::RefCount() const { if (_VolumeTexture) return _VolumeTexture->RefCount(); nuxAssert(0); // Surface with no underlying texture. That should not happen. return 0; } int IOpenGLVolume::LockBox( VOLUME_LOCKED_BOX *pLockedVolume, const VOLUME_BOX *pBox) { #ifndef NUX_OPENGLES_20 // If _LockedRect.pBits or _LockedRect.Pitch are not equal to zero, then we have already Locked the buffer // Unlock it before locking again. nuxAssert(_LockedBox.pBits == 0); nuxAssert(_LockedBox.RowPitch == 0); //nuxAssert(_LockedBox.SlicePitch == 0); nuxAssert(_CompressedDataSize == 0); if ((_LockedBox.pBits != 0) || (_LockedBox.RowPitch != 0) || (_CompressedDataSize != 0)) { // already locked; return OGL_INVALID_LOCK; } _Box.Front = _Box.Back = _Box.Bottom = _Box.Left = _Box.Right = _Box.Top = 0; //GLint unpack_alignment = GPixelFormats[_VolumeTexture->_PixelFormat].RowMemoryAlignment; CHECKGL(glBindTexture(_STextureTarget, _VolumeTexture->_OpenGLID)); unsigned int surface_size = 0; IOpenGLVolumeTexture *texture = _VolumeTexture; if (_VolumeTexture->_ResourceType != RTVOLUMETEXTURE) { nuxAssertMsg(0, "Unknown resource type"); } int texwidth, texheight; texwidth = ImageSurface::GetLevelWidth(texture->_PixelFormat, texture->_Width, _SMipLevel); texheight = ImageSurface::GetLevelHeight(texture->_PixelFormat, texture->_Height, _SMipLevel); if ( texture->_PixelFormat == BITFMT_DXT1 || texture->_PixelFormat == BITFMT_DXT2 || texture->_PixelFormat == BITFMT_DXT3 || texture->_PixelFormat == BITFMT_DXT4 || texture->_PixelFormat == BITFMT_DXT5) { if (texture->_PixelFormat == BITFMT_DXT1) { // We can conceive a 4x4 DXT1 block as if each texel uses 4 bits. // Actually, for DXT, we have 2 16-bits colors(5:6:5), and each texel uses 2 bits to interpolate // between the 2 colors. // --------------------- // | COLOR0 | 16 bits // --------------------- // | COLOR1 | 16 bits // --------------------- // | xx | xx | xx | xx | xx = 2 bits // --------------------- // | xx | xx | xx | xx | // --------------------- // | xx | xx | xx | xx | // --------------------- // | xx | xx | xx | xx | // --------------------- // A line of n texel DXT1 data uses n/2 bytes(4 bits/texel). So the number of bytes used for a // texwidth texel, is texwidth/2 bytes. // Note that texwidth is divisible by 4(to to the upper rounding to 4), therefore, it is also divisible // by 2. // glCompressedTexImage2DARB, glCompressedTexImage3DARB, // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei. surface_size = ImageSurface::GetLevelSize(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); _LockedBox.RowPitch = ImageSurface::GetLevelPitch(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); if (_Initialized == false) { InitializeLevel(); } } else { // A line of n texel DXT3/5 data uses n bytes(1 byte/texel). So the number of bytes used for a // texwidth texels, is texwidth bytes. // glCompressedTexImage2DARB, glCompressedTexImage3DARB, // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei. surface_size = ImageSurface::GetLevelSize(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); _LockedBox.RowPitch = ImageSurface::GetLevelPitch(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); if (_Initialized == false) { InitializeLevel(); } } } else { _LockedBox.RowPitch = ImageSurface::GetLevelPitch(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); surface_size = ImageSurface::GetLevelSize(texture->_PixelFormat, texture->_Width, texture->_Height, _SMipLevel); if (_Initialized == false) { InitializeLevel(); } } _Box.Left = 0; _Box.Top = 0; _Box.Bottom = texheight; _Box.Right = texwidth; _Box.Front = 0; _Box.Back = ImageSurface::GetLevelDim(texture->_PixelFormat, texture->GetDepth(), _SMipLevel); if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { GetGraphicsDisplay()->GetGpuDevice()->AllocateUnpackPixelBufferIndex(&_AllocatedUnpackBuffer); } if (pBox == 0) { _CompressedDataSize = GetDepth() * surface_size; if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { // Mapping the entire area of the surface if (1) { _LockedBox.pBits = GetGraphicsDisplay()->GetGpuDevice()->LockUnpackPixelBufferIndex(_AllocatedUnpackBuffer, _CompressedDataSize); } else { GetGraphicsDisplay()->GetGpuDevice()->BindUnpackPixelBufferIndex(_AllocatedUnpackBuffer); CHECKGL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, _CompressedDataSize, NULL, GL_STREAM_DRAW_ARB)); _LockedBox.pBits = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); CHECKGL_MSG(glMapBufferARB ); CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); } pLockedVolume->pBits = _LockedBox.pBits; pLockedVolume->RowPitch = _LockedBox.RowPitch; pLockedVolume->SlicePitch = surface_size; } else { //[DEBUGGING - NO PBO] // Mapping the entire area of the surface _LockedBox.pBits = new BYTE[_CompressedDataSize]; pLockedVolume->pBits = _LockedBox.pBits; pLockedVolume->RowPitch = _LockedBox.RowPitch; pLockedVolume->SlicePitch = surface_size; } } else { nuxAssert(pBox->Front >= 0); nuxAssert(pBox->Back <= GetDepth()); nuxAssert(pBox->Front < pBox->Back); int RectWidth = pBox->Right - pBox->Left; int RectHeight = pBox->Bottom - pBox->Top; int NumSlice = pBox->Back - pBox->Front; nuxAssert(RectWidth >= 0); nuxAssert(RectHeight >= 0); nuxAssert(NumSlice >= 0); unsigned int RectSize = ImageSurface::GetLevelSize(GetPixelFormat(), RectWidth, RectHeight, 0); //(((RectWidth * BytePerPixel + (unpack_alignment-1)) >> (halfUnpack)) << (halfUnpack)) * RectHeight; if (RectSize == 0) { pLockedVolume->pBits = 0; pLockedVolume->RowPitch = 0; return OGL_INVALID_LOCK; } _CompressedDataSize = NumSlice * RectSize; if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { _LockedBox.pBits = GetGraphicsDisplay()->GetGpuDevice()->LockUnpackPixelBufferIndex(_AllocatedUnpackBuffer, NumSlice * RectSize); // GetGraphicsDisplay()->GetGpuDevice()->BindUnpackPixelBufferIndex(_AllocatedUnpackBuffer); // CHECKGL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, NumSlice * RectSize, NULL, GL_STATIC_DRAW_ARB)); // _LockedBox.pBits = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY); // CHECKGL_MSG(glMapBufferARB ); // CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); pLockedVolume->pBits = ((BYTE *) _LockedBox.pBits); pLockedVolume->RowPitch = ImageSurface::GetLevelPitch(GetPixelFormat(), RectWidth, RectHeight, 0); //(((RectWidth * BytePerPixel + (unpack_alignment-1)) >> (halfUnpack)) << (halfUnpack)); pLockedVolume->SlicePitch = RectSize; } else { //[DEBUGGING - NO PBO] _LockedBox.pBits = new BYTE[_CompressedDataSize]; pLockedVolume->pBits = ((BYTE *) _LockedBox.pBits); pLockedVolume->RowPitch = ImageSurface::GetLevelPitch(GetPixelFormat(), RectWidth, RectHeight, 0); //(((RectWidth * BytePerPixel + (unpack_alignment-1)) >> (halfUnpack)) << (halfUnpack)); pLockedVolume->SlicePitch = RectSize; } _Box.Left = pBox->Left; _Box.Top = pBox->Top; _Box.Bottom = pBox->Bottom; _Box.Right = pBox->Right; _Box.Front = pBox->Front; _Box.Back = pBox->Back; } #endif return OGL_OK; } int IOpenGLVolume::UnlockBox() { #ifndef NUX_OPENGLES_20 if (_LockedBox.pBits == 0) { return OGL_INVALID_UNLOCK; } int MemAlignment = ImageSurface::GetMemAlignment(_VolumeTexture->_PixelFormat); CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, MemAlignment)); nuxAssert(MemAlignment == _VolumeTexture->GetFormatRowMemoryAlignment()); if (_STextureTarget == GL_TEXTURE_3D) { BYTE *DataPtr = 0; CHECKGL(glBindTexture(_STextureTarget, _VolumeTexture->_OpenGLID)); if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { // Unmap the texture image buffer GetGraphicsDisplay()->GetGpuDevice()->BindUnpackPixelBufferIndex(_AllocatedUnpackBuffer); CHECKGL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); DataPtr = NUX_BUFFER_OFFSET(0); } else { CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); DataPtr = (BYTE *) _LockedBox.pBits; } IOpenGLTexture2D *texture = (IOpenGLTexture2D *) _VolumeTexture; int width = _Box.Right - _Box.Left; int height = _Box.Bottom - _Box.Top; int depth = _Box.Back - _Box.Front; int xoffset = _Box.Left; int yoffset = _Box.Top; int zoffset = _Box.Front; if ( texture->_PixelFormat == BITFMT_DXT1 || texture->_PixelFormat == BITFMT_DXT2 || texture->_PixelFormat == BITFMT_DXT3 || texture->_PixelFormat == BITFMT_DXT4 || texture->_PixelFormat == BITFMT_DXT5) { nuxAssert(_CompressedDataSize != 0); // This part does not work. The image is messed up. // Driver bug??? Tried glCompressedTexImage3DARB. Same result. // But I know the data that is loaded is correct. glCompressedTexSubImage3DARB(_SSurfaceTarget, _SMipLevel, // level xoffset, yoffset, zoffset, width, height, depth, GPixelFormats[texture->_PixelFormat].PlatformFormat, _CompressedDataSize, // image Size DataPtr // data ); CHECKGL_MSG(glCompressedTexSubImage3DARB); // glCompressedTexImage3DARB(_SSurfaceTarget, // _SMipLevel, // level // GPixelFormats[texture->_PixelFormat].PlatformFormat, // width, // height, // depth, // 0, // border // _CompressedDataSize, // image Size // DataPtr // data // ); // CHECKGL_MSG(glCompressedTexImage2DARB); } else { CHECKGL(glTexSubImage3D(_SSurfaceTarget, _SMipLevel, xoffset, yoffset, zoffset, // z offset width, height, depth, GPixelFormats[texture->_PixelFormat].Format, GPixelFormats[texture->_PixelFormat].type, DataPtr )); } } else { nuxAssertMsg(0, "Incorrect Texture Target."); } if (GetGraphicsDisplay()->GetGpuDevice()->UsePixelBufferObjects()) { CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); GetGraphicsDisplay()->GetGpuDevice()->FreeUnpackPixelBufferIndex(_AllocatedUnpackBuffer); } else { //[DEBUGGING - NO PBO] if (_LockedBox.pBits) { delete [] ((BYTE *) _LockedBox.pBits); } } CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, GetGraphicsDisplay()->GetGpuDevice()->GetPixelStoreAlignment())); _LockedBox.pBits = 0; _LockedBox.RowPitch = 0; _CompressedDataSize = 0; #endif return OGL_OK; } int IOpenGLVolume::InitializeLevel() { #ifndef NUX_OPENGLES_20 // Because we use SubImage when unlocking surfaces, we must first get some dummy data in the surface before we can make a lock. int volwidth = ImageSurface::GetLevelDim(_VolumeTexture->_PixelFormat, _VolumeTexture->_Width, _SMipLevel); int volheight = ImageSurface::GetLevelDim(_VolumeTexture->_PixelFormat, _VolumeTexture->_Height, _SMipLevel); int voldepth = ImageSurface::GetLevelDim(_VolumeTexture->_PixelFormat, _VolumeTexture->_Depth, _SMipLevel); int size = ImageSurface::GetLevelSize( _VolumeTexture->_PixelFormat, _VolumeTexture->_Width, _VolumeTexture->_Height, _VolumeTexture->_Depth, _SMipLevel); int MemAlignment = ImageSurface::GetMemAlignment(_VolumeTexture->_PixelFormat); nuxAssert( volwidth > 0 ); // Should never happen nuxAssert( volheight > 0 ); // Should never happen nuxAssert( voldepth > 0 ); // Should never happen nuxAssert( size > 0 ); // Should never happen BYTE *DummyBuffer = new BYTE[size]; Memset(DummyBuffer, 0, size); CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, MemAlignment)); if ( _VolumeTexture->_PixelFormat == BITFMT_DXT1 || _VolumeTexture->_PixelFormat == BITFMT_DXT2 || _VolumeTexture->_PixelFormat == BITFMT_DXT3 || _VolumeTexture->_PixelFormat == BITFMT_DXT4 || _VolumeTexture->_PixelFormat == BITFMT_DXT5) { { glCompressedTexImage3DARB( _SSurfaceTarget, _SMipLevel, // level GPixelFormats[_VolumeTexture->_PixelFormat].PlatformFormat, volwidth, volheight, voldepth, 0, // border size, // image Size DummyBuffer // data ); CHECKGL_MSG(glCompressedTexImage3DARB); } } else { glTexImage3D( _SSurfaceTarget, _SMipLevel, // level GPixelFormats[_VolumeTexture->_PixelFormat].PlatformFormat, volwidth, volheight, voldepth, 0, // border GPixelFormats[_VolumeTexture->_PixelFormat].Format, GPixelFormats[_VolumeTexture->_PixelFormat].type, DummyBuffer); CHECKGL_MSG(glTexImage3D); } delete [] DummyBuffer; // { //[DEBUGGING - Red Texture] // // This is going to put some red in the texture. // // The texture is not compressed. // BYTE *color_array = new BYTE[texwidth*texheight*4]; // for (unsigned int i = 0; i < texwidth*texheight*4; i += 4) // { // color_array[i + 0] = 0xff; // color_array[i + 1] = _SMipLevel * 0x3F; // color_array[i + 2] = 0x0; // color_array[i + 3] = 0xFF; // } // glTexImage2D(GL_TEXTURE_2D, // _SMipLevel, // GL_RGBA8, texwidth, texheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, color_array); // CHECKGL_MSG(glTexImage2D); // delete [] color_array; // } CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, GetGraphicsDisplay()->GetGpuDevice()->GetPixelStoreAlignment())); _Initialized = true; #endif return OGL_OK; } BitmapFormat IOpenGLVolume::GetPixelFormat() const { if (_VolumeTexture == 0) return BITFMT_UNKNOWN; else return _VolumeTexture->GetPixelFormat(); } int IOpenGLVolume::GetWidth() const { if (_VolumeTexture->_ResourceType == RTVOLUMETEXTURE) return ImageSurface::GetLevelDim(_VolumeTexture->_PixelFormat, _VolumeTexture->_Width, _SMipLevel); nuxAssert(0); // Should not happen return 0; } int IOpenGLVolume::GetHeight() const { if (_VolumeTexture->_ResourceType == RTVOLUMETEXTURE) return ImageSurface::GetLevelDim(_VolumeTexture->_PixelFormat, _VolumeTexture->_Height, _SMipLevel); nuxAssert(0); // Should not happen return 0; } int IOpenGLVolume::GetDepth() const { if (_VolumeTexture->_ResourceType == RTVOLUMETEXTURE) return ImageSurface::GetLevelDim(_VolumeTexture->_PixelFormat, _VolumeTexture->_Depth, _SMipLevel); nuxAssert(0); // Should not happen return 0; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLGLSLShader.h0000644000015301777760000002123112321344237022406 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLSHADER_H #define IOPENGLSHADER_H namespace nux { class IOpenGLResource; bool ExtractShaderString3(const std::string &ShaderToken, const std::string &ShaderSource, std::string &RetSource, std::string ShaderPreprocessorDefines = std::string("")); class IOpenGLShader: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLShader, IOpenGLResource); IOpenGLShader(std::string ShaderName, OpenGLResourceType ResourceType); virtual ~IOpenGLShader(); public: virtual void SetShaderCode(const ANSICHAR *ShaderCode, const char *ShaderPreprocessorDefines = "") = 0; virtual bool Compile() = 0; virtual bool IsValid() = 0; std::string _ShaderName; std::string _ShaderCode; }; class IOpenGLVertexShader: public IOpenGLShader { NUX_DECLARE_OBJECT_TYPE(IOpenGLVertexShader, IOpenGLShader); public: virtual ~IOpenGLVertexShader(); virtual void SetShaderCode(const ANSICHAR *ShaderCode, const char *VtxShaderPreprocessorDefines = ""); virtual bool Compile(); virtual bool IsValid(); private: IOpenGLVertexShader(std::string ShaderName = std::string("Vertex Shader")); int m_CompiledAndReady; friend class GpuDevice; }; class IOpenGLPixelShader: public IOpenGLShader { NUX_DECLARE_OBJECT_TYPE(IOpenGLPixelShader, IOpenGLShader); public: virtual ~IOpenGLPixelShader(); virtual void SetShaderCode(const ANSICHAR *ShaderCode, const char *FrgShaderPreprocessorDefines = ""); virtual bool Compile(); virtual bool IsValid(); private: IOpenGLPixelShader(std::string ShaderName = std::string("Fragment Shader")); int m_CompiledAndReady; friend class GpuDevice; }; #if 0 class IOpenGLGeometryShader: public IOpenGLShader { NUX_DECLARE_OBJECT_TYPE(IOpenGLGeometryShader, IOpenGLShader); public: virtual ~IOpenGLGeometryShader(); virtual void SetShaderCode(const ANSICHAR *ShaderCode, const char *GeometryShaderPreprocessorDefines = ""); virtual bool Compile(); virtual bool IsValid(); void SetInputPrimitiveType(GLenum type); void SetOutputPrimitiveType(GLenum type); void SetMaxVertexOutput(int max_vertex_output); private: IOpenGLGeometryShader(std::string ShaderName = std::string("Geometry Shader")); int m_CompiledAndReady; friend class GpuDevice; }; #endif class IOpenGLShaderProgram: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLShaderProgram, IOpenGLResource); public: virtual ~IOpenGLShaderProgram(); // Load an inalogic shader. void LoadVertexShader(const char *glslshader, const char *VtxShaderPreprocessorDefines = ""); void LoadPixelShader(const char *glslshader, const char *FrgShaderPreprocessorDefines = ""); void LoadIShaderFile(const char *ShaderFileName, const char *VtxShaderPreprocessorDefines = "", const char *FrgShaderPreprocessorDefines = ""); void LoadIShader(const char *ShaderCode, const char *VtxShaderPreprocessorDefines = "", const char *FrgShaderPreprocessorDefines = ""); void AddShaderParameter(GLShaderParameter *Parameter); void AddShaderObject(ObjectPtr ShaderObject); void RemoveShaderObject(ObjectPtr ShaderObject); void ClearShaderObjects(); bool Link(); void Begin(); void End(); static void SetShaderTracking(bool enabled); public: bool SetUniform1f(char *varname, GLfloat v0); bool SetUniform2f(char *varname, GLfloat v0, GLfloat v1); bool SetUniform3f(char *varname, GLfloat v0, GLfloat v1, GLfloat v2); bool SetUniform4f(char *varname, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); bool SetUniform1i(char *varname, GLint v0); bool SetUniform2i(char *varname, GLint v0, GLint v1); bool SetUniform3i(char *varname, GLint v0, GLint v1, GLint v2); bool SetUniform4i(char *varname, GLint v0, GLint v1, GLint v2, GLint v3); bool SetUniform1fv(char *varname, GLsizei count, GLfloat *value); bool SetUniform2fv(char *varname, GLsizei count, GLfloat *value); bool SetUniform3fv(char *varname, GLsizei count, GLfloat *value); bool SetUniform4fv(char *varname, GLsizei count, GLfloat *value); bool SetUniform1iv(char *varname, GLsizei count, GLint *value); bool SetUniform2iv(char *varname, GLsizei count, GLint *value); bool SetUniform3iv(char *varname, GLsizei count, GLint *value); bool SetUniform4iv(char *varname, GLsizei count, GLint *value); bool SetUniformMatrix2fv(char *varname, GLsizei count, GLboolean transpose, GLfloat *value); bool SetUniformMatrix3fv(char *varname, GLsizei count, GLboolean transpose, GLfloat *value); bool SetUniformMatrix4fv(char *varname, GLsizei count, GLboolean transpose, GLfloat *value); bool SetUniform1f(GLint loc, GLfloat v0); bool SetUniform2f(GLint loc, GLfloat v0, GLfloat v1); bool SetUniform3f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2); bool SetUniform4f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); bool SetUniform1i(GLint loc, GLint v0); bool SetUniform2i(GLint loc, GLint v0, GLint v1); bool SetUniform3i(GLint loc, GLint v0, GLint v1, GLint v2); bool SetUniform4i(GLint loc, GLint v0, GLint v1, GLint v2, GLint v3); bool SetUniform1fv(GLint loc, GLsizei count, GLfloat *value); bool SetUniform2fv(GLint loc, GLsizei count, GLfloat *value); bool SetUniform3fv(GLint loc, GLsizei count, GLfloat *value); bool SetUniform4fv(GLint loc, GLsizei count, GLfloat *value); bool SetUniform1iv(GLint loc, GLsizei count, GLint *value); bool SetUniform2iv(GLint loc, GLsizei count, GLint *value); bool SetUniform3iv(GLint loc, GLsizei count, GLint *value); bool SetUniform4iv(GLint loc, GLsizei count, GLint *value); bool SetUniformLocMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value); bool SetUniformLocMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value); bool SetUniformLocMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value); void GetUniformfv(char *name, GLfloat *values); void GetUniformiv(char *name, GLint *values); int GetUniformLocationARB(const GLchar *name); void GetActiveUniformARB(GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name); // glGetObjectParameterARBfv Parameters // object // Specifies the handle of the object to be queried // // pname // Specifies the an object parameter. Accepted symbolic names are // GL_OBJECT_TYPE_ARB , // GL_OBJECT_SUBTYPE_ARB, // GL_OBJECT_DELETE_STATUS_ARB, // GL_OBJECT_LINK_STATUS_ARB, // GL_OBJECT_VALIDATE_STATUS_ARB, // GL_OBJECT_COMPILE_STATUS_ARB, // GL_OBJECT_INFO_LOG_LENGTH_ARB, // GL_OBJECT_ATTACHED_OBJECTS_ARB, // GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, // GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB, // GL_OBJECT_ACTIVE_UNIFORMS_ARB, // GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, // GL_OBJECT_SHADER_SOURCE_LENGTH_ARB // // params // Returns the requested object parameter // void GetObjectParameterfvARB(GLenum pname, GLfloat *params); bool SetSampler(char *name, int exture_unit); GLShaderParameter *_FirstParameter; void CheckAttributeLocation(); void CheckUniformLocation(); int GetAttributeLocation(const char *AttributeName); private: IOpenGLShaderProgram(std::string ShaderProgramName = std::string("ShaderProgram")); ShaderAttributeDefinition m_ProgramAttributeDefinition[16/*NUM_VERTEX_SHADER_INPUT_ATTRIBUTE*/]; std::vector > ShaderObjectList; bool m_CompiledAndReady; std::string _ShaderProgramName; friend class GpuDevice; }; } #endif // IOPENGLSHADER_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLCgShader.h0000644000015301777760000000531712321344237022205 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef ICGSHADER_H #define ICGSHADER_H namespace nux { class IOpenGLResource; class ICgShader: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(ICgShader, IOpenGLResource); public: ICgShader(std::string ShaderName, OpenGLResourceType ResourceType); virtual ~ICgShader(); virtual void CreateProgram(const ANSICHAR *ShaderCode, const ANSICHAR *EntryPoint) = 0; virtual void CreateProgramFromFileShaderCode(const char *Filename, const char *EntryPoint) = 0; virtual void BindProgram() = 0; const char *GetProgramString(); const char *GetProgramBinary(); virtual bool Compile() = 0; virtual bool IsValid() = 0; CGparameter GetNamedParameter(const char *parameter); std::string _ShaderName; std::string _ShaderCode; std::string _EntryPoint; CGprogram _CgProgram; }; class ICgVertexShader: public ICgShader { NUX_DECLARE_OBJECT_TYPE(ICgVertexShader, ICgShader); public: virtual ~ICgVertexShader(); virtual void CreateProgram(const ANSICHAR *ShaderCode, const ANSICHAR *EntryPoint); virtual void CreateProgramFromFileShaderCode(const char *Filename, const char *EntryPoint); virtual void BindProgram(); virtual bool Compile(); virtual bool IsValid(); private: ICgVertexShader(std::string ShaderName = std::string("VertexProgram")); int _ready; friend class GpuDevice; }; class ICgPixelShader: public ICgShader { NUX_DECLARE_OBJECT_TYPE(ICgPixelShader, ICgShader); public: virtual ~ICgPixelShader(); virtual void CreateProgram(const ANSICHAR *ShaderCode, const ANSICHAR *EntryPoint); virtual void CreateProgramFromFileShaderCode(const char *Filename, const char *EntryPoint); virtual void BindProgram(); virtual bool Compile(); virtual bool IsValid(); private: ICgPixelShader(std::string ShaderName = std::string("PixelProgram")); int _ready; friend class GpuDevice; }; } #endif // ICGSHADER_H nux-4.0.6+14.04.20140409/NuxGraphics/BitmapFormats.h0000644000015301777760000000610412321344237022112 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef BITMAPFORMATS_H #define BITMAPFORMATS_H namespace nux { typedef struct { const TCHAR *Name; int BlockSizeX; int BlockSizeY; int BlockSizeZ; int BlockBytes; int NumComponents; unsigned int PlatformFormat; // internal format int Format; int type; int RowMemoryAlignment; // best memory alignment in a row unsigned int Flags; bool Supported; } PixelFormatInfo; typedef struct { const TCHAR *Name; int BlockBytes; int NumComponents; unsigned int Format; int type; unsigned int Flags; bool Supported; } ReadBackPixelFormatInfo; typedef enum { BITFMT_UNKNOWN = 0, BITFMT_R8G8B8A8, // 32-bit RGBA pixel format with alpha, using 8 bits per channel. BITFMT_B8G8R8A8, // 32-bit BGRA pixel format with alpha, using 8 bits per channel. BITFMT_R8G8B8, // 24-bit RGB pixel format with 8 bits per channel. BITFMT_R5G6B5, // 16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue. BITFMT_D24S8, BITFMT_A8, // Gray level 8 bits BITFMT_DXT1, BITFMT_DXT2, BITFMT_DXT3, BITFMT_DXT4, BITFMT_DXT5, #ifndef NUX_OPENGLES_20 BITFMT_A8R8G8B8, // 32-bit ARGB pixel format with alpha, using 8 bits per channel. BITFMT_A8B8G8R8, // 32-bit ABGR pixel format with alpha, using 8 bits per channel. BITFMT_B8G8R8, // 24-bit RGB pixel format with 8 bits per channel. BITFMT_RGBA16F, BITFMT_RGB32F, BITFMT_RGBA32F, BITFMT_R10G10B10A2, // 32-bit pixel format using 10 bits for each color and 2 bits for alpha. BITFMT_B10G10R10A2, // 32-bit pixel format using 10 bits for each color and 2 bits for alpha. BITFMT_A2R10G10B10, // 32-bit pixel format using 10 bits for each color and 2 bits for alpha. BITFMT_A2B10G10R10, // 32-bit pixel format using 10 bits for each color and 2 bits for alpha. #endif BITFMT_END_GFX_FORMATS, } BitmapFormat; extern PixelFormatInfo GPixelFormats[]; extern ReadBackPixelFormatInfo GReadBackPixelFormats[]; } #endif // BITMAPFORMATS_H nux-4.0.6+14.04.20140409/NuxGraphics/XInputWindow.cpp0000644000015301777760000002765312321344237022330 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "XInputWindow.h" #include "GraphicsDisplayX11.h" #include "GLThread.h" namespace nux { std::vector XInputWindow::native_windows_; namespace atom { namespace { Atom WM_WINDOW_TYPE = 0; Atom WM_WINDOW_TYPE_DOCK = 0; Atom WM_STATE = 0; Atom WM_PID; Atom WM_CLIENT_MACHINE; Atom WM_TAKE_FOCUS = 0; Atom WM_STRUT_PARTIAL = 0; Atom X_DND_AWARE = 0; Atom OVERLAY_STRUT = 0; const unsigned STRUTS_SIZE = 12; const int X_DND_VERSION = 5; std::vector WM_STATES; void initialize(Display *dpy) { if (WM_WINDOW_TYPE) return; WM_WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); WM_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False); WM_PID = XInternAtom(dpy, "_NET_WM_PID", False); WM_CLIENT_MACHINE = XInternAtom(dpy, "WM_CLIENT_MACHINE", False); WM_TAKE_FOCUS = XInternAtom(dpy, "WM_TAKE_FOCUS", False); X_DND_AWARE = XInternAtom(dpy, "XdndAware", False); WM_STATES.push_back(XInternAtom(dpy, "_NET_WM_STATE_STICKY", False)); WM_STATES.push_back(XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False)); WM_STATES.push_back(XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False)); } } } XInputWindow::XInputWindow(const char* title, bool take_focus, int override_redirect) : strutsEnabled_(false) , overlayStrutsEnabled_(false) , display_(GetGraphicsDisplay()->GetX11Display()) , geometry_(0, 0, 1, 1) , shown_(false) , mapped_(false) { XSetWindowAttributes attrib; char hostname[256]; attrib.override_redirect = override_redirect; attrib.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | PropertyChangeMask | StructureNotifyMask | FocusChangeMask; window_ = XCreateWindow(display_, XDefaultRootWindow(display_), geometry_.x, geometry_.y, geometry_.width, geometry_.height, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect | CWEventMask, &attrib); native_windows_.push_back(window_); atom::initialize(display_); XChangeProperty(display_, window_, atom::WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) atom::WM_STATES.data(), atom::WM_STATES.size()); XChangeProperty(display_, window_, atom::WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *) &atom::WM_WINDOW_TYPE_DOCK, 1); if (gethostname(hostname, sizeof(hostname)) > -1) { hostname[sizeof(hostname)-1] = '\0'; XChangeProperty(display_, window_, atom::WM_CLIENT_MACHINE, XA_STRING, 8, PropModeReplace, (unsigned char *) hostname, strlen(hostname)); pid_t pid = getpid(); XChangeProperty(display_, window_, atom::WM_PID, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &pid, 1); } XStoreName(display_, window_, title); EnsureInputs(); if (take_focus) EnableTakeFocus(); EnableDnd(); } XInputWindow::~XInputWindow() { native_windows_.erase(std::find(native_windows_.begin(), native_windows_.end(), window_)); XDestroyWindow(display_, window_); } /* static */ std::vector const& XInputWindow::NativeHandleList() { return native_windows_; } std::vector XInputWindow::GetStrutsData() { int n_info; XineramaScreenInfo *info = XineramaQueryScreens(display_, &n_info); Region screen_region; Region total_screen_region = XCreateRegion(); Region input_window_region = XCreateRegion(); Region intersection = XCreateRegion(); XRectangle monitor; XRectangle tmp_rect; int largestWidth = 0, largestHeight = 0; int screenWidth, screenHeight; std::vector data(atom::STRUTS_SIZE, 0); /* Find the screen that this region intersects */ tmp_rect.x = geometry_.x; tmp_rect.y = geometry_.y; tmp_rect.width = geometry_.width; tmp_rect.height = geometry_.height; XUnionRectWithRegion(&tmp_rect, input_window_region, input_window_region); monitor = tmp_rect; /* If there is no Xinerama data available just use the geometry we have */ if (!info) { monitor = tmp_rect; n_info = 0; } for (int i = 0; i < n_info; i++) { tmp_rect.x = info[i].x_org; tmp_rect.y = info[i].y_org; tmp_rect.width = info[i].width; tmp_rect.height = info[i].height; screen_region = XCreateRegion(); XUnionRectWithRegion(&tmp_rect, screen_region, screen_region); XUnionRegion(screen_region, total_screen_region, total_screen_region); XIntersectRegion(screen_region, input_window_region, intersection); if (!XEmptyRegion(intersection)) { int width = intersection->extents.x2 - intersection->extents.x1; int height = intersection->extents.y2 - intersection->extents.y1; if ((width * height) > (largestWidth * largestHeight)) { largestWidth = width; largestHeight = height; monitor.x = info[i].x_org; monitor.y = info[i].y_org; monitor.width = info[i].width; monitor.height = info[i].height; } } XDestroyRegion(screen_region); } screenWidth = total_screen_region->extents.x2 - total_screen_region->extents.x1; screenHeight = total_screen_region->extents.y2 - total_screen_region->extents.y1; XDestroyRegion(input_window_region); XDestroyRegion(intersection); XDestroyRegion(total_screen_region); if (info) XFree(info); if (geometry_.width > geometry_.height) { if (geometry_.y - monitor.y < monitor.height / 2) { /* top */ data[2] = geometry_.y + geometry_.height; data[8] = geometry_.x; data[9] = geometry_.x + geometry_.width - 1; } else { /* bottom */ data[3] = (screenHeight - 1) - geometry_.y; data[10] = geometry_.x; data[11] = geometry_.x + geometry_.width - 1; } } else { if (geometry_.x - monitor.x < monitor.width / 2) { /* left */ data[0] = geometry_.x + geometry_.width; data[4] = geometry_.y; data[5] = geometry_.y + geometry_.height - 1; } else { /* right */ data[1] = (screenWidth - 1) - geometry_.y; data[6] = geometry_.y; data[7] = geometry_.y + geometry_.height - 1; } } return data; } void XInputWindow::SetStruts() { std::vector const& struts = GetStrutsData(); XChangeProperty(display_, window_, atom::WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) struts.data(), struts.size()); } void XInputWindow::UnsetStruts() { XDeleteProperty(display_, window_, atom::WM_STRUT_PARTIAL); } void XInputWindow::SetOverlayStruts() { std::vector const& struts = GetStrutsData(); XChangeProperty(display_, window_, atom::OVERLAY_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) struts.data(), struts.size()); } void XInputWindow::UnsetOverlayStruts() { XDeleteProperty(display_, window_, atom::OVERLAY_STRUT); } void XInputWindow::EnableStruts(bool enable) { if (strutsEnabled_ == enable) return; if (!atom::WM_STRUT_PARTIAL) atom::WM_STRUT_PARTIAL = XInternAtom(display_, "_NET_WM_STRUT_PARTIAL", False); strutsEnabled_ = enable; if (enable) SetStruts(); else UnsetStruts(); } bool XInputWindow::StrutsEnabled() { return strutsEnabled_; } void XInputWindow::EnableOverlayStruts(bool enable) { if (overlayStrutsEnabled_ == enable) return; if (!atom::OVERLAY_STRUT) atom::OVERLAY_STRUT = XInternAtom(display_, "_COMPIZ_NET_OVERLAY_STRUT", False); overlayStrutsEnabled_ = enable; if (enable) SetOverlayStruts(); else UnsetOverlayStruts(); } bool XInputWindow::OverlayStrutsEnabled() { return overlayStrutsEnabled_; } void XInputWindow::EnsureInputs() { XSelectInput(display_, window_, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | PropertyChangeMask | StructureNotifyMask | FocusChangeMask); } void XInputWindow::EnableTakeFocus() { XWMHints wmHints; wmHints.flags = InputHint; wmHints.input = False; XSetWMHints(display_, window_, &wmHints); XSetWMProtocols(display_, window_, &atom::WM_TAKE_FOCUS, 1); } void XInputWindow::EnableDnd() { XChangeProperty(display_, window_, atom::X_DND_AWARE, XA_ATOM, 32, PropModeReplace, (unsigned char *) &atom::X_DND_VERSION, 1); } void XInputWindow::DisableDnd() { XDeleteProperty(display_, window_, atom::X_DND_AWARE); } //! Set the position and size of the window void XInputWindow::SetGeometry(Rect const& geo) { geometry_ = geo; if (shown_) XMoveResizeWindow(display_, window_, geo.x, geo.y, geo.width, geo.height); EnsureInputs(); if (strutsEnabled_) SetStruts(); if (overlayStrutsEnabled_) SetOverlayStruts(); } //! Set the position and size of the window void XInputWindow::SetGeometry(int x, int y, int width, int height) { SetGeometry(Rect(x, y, width, height)); } //! Get the window geometry. Rect const& XInputWindow::GetGeometry() const { return geometry_; } Window XInputWindow::GetWindow() { return window_; } void XInputWindow::SetInputFocus() { XSetInputFocus(display_, window_, RevertToParent, CurrentTime); XSync(display_, False); } void XInputWindow::Hide() { XMoveResizeWindow(display_, window_, -100 - geometry_.width, -100 - geometry_.height, geometry_.width, geometry_.height); shown_ = false; } void XInputWindow::Show() { shown_ = true; if (!mapped_) { XMapRaised(display_, window_); mapped_ = true; XEvent xevent; while (XCheckTypedWindowEvent(display_, window_, MapNotify, &xevent)); XSetInputFocus(display_, window_, RevertToParent, CurrentTime); } XMoveResizeWindow(display_, window_, geometry_.x, geometry_.y, geometry_.width, geometry_.height); } } nux-4.0.6+14.04.20140409/NuxGraphics/NuxGraphicsResources.cpp0000644000015301777760000001455412321344237024033 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "FontTexture.h" #include "NuxGraphicsResources.h" #include "GLResourceManager.h" namespace nux { NUX_IMPLEMENT_GLOBAL_OBJECT(NuxGraphicsResources); void NuxGraphicsResources::Constructor() { } void NuxGraphicsResources::Destructor() { } void NuxGraphicsResources::InitializeResources() { #ifdef NUX_OS_LINUX m_ResourcePathLocation.AddSearchPath(PKGDATADIR); m_ResourcePathLocation.AddSearchPath(PKGDATADIR"/Fonts"); m_ResourcePathLocation.AddSearchPath(PKGDATADIR"/Meshes"); m_ResourcePathLocation.AddSearchPath(PKGDATADIR"/UITextures"); #ifdef NUX_DEBUG /* For examples */ m_ResourcePathLocation.AddSearchPath("../data"); m_ResourcePathLocation.AddSearchPath("../data/Fonts"); m_ResourcePathLocation.AddSearchPath("../data/Meshes"); m_ResourcePathLocation.AddSearchPath("../data/UITextures"); #endif #else m_ResourcePathLocation.AddSearchPath(""); m_ResourcePathLocation.AddSearchPath("./"); m_ResourcePathLocation.AddSearchPath("../"); m_ResourcePathLocation.AddSearchPath("../../"); m_ResourcePathLocation.AddSearchPath("./Data"); m_ResourcePathLocation.AddSearchPath("../Data"); m_ResourcePathLocation.AddSearchPath("../../Data"); m_ResourcePathLocation.AddSearchPath("../../../Data"); m_ResourcePathLocation.AddSearchPath("./Data/Fonts"); m_ResourcePathLocation.AddSearchPath("../Data/Fonts"); m_ResourcePathLocation.AddSearchPath("../../Data/Fonts"); m_ResourcePathLocation.AddSearchPath("../../../Data/Fonts"); m_ResourcePathLocation.AddSearchPath("./Data/UITextures"); m_ResourcePathLocation.AddSearchPath("../Data/UITextures"); m_ResourcePathLocation.AddSearchPath("../../Data/UITextures"); m_ResourcePathLocation.AddSearchPath("../../../Data/UITextures"); #endif m_ResourcePathLocation.AddSearchPath(m_FontSearchPath); m_ResourcePathLocation.AddSearchPath(m_ShaderSearchPath); m_ResourcePathLocation.AddSearchPath(m_UITextureSearchPath); } #ifdef NUX_OS_WINDOWS std::string NuxGraphicsResources::FindResourceLocation(const char *ResourceFileName, bool ErrorOnFail) { std::string path = m_ResourcePathLocation.GetFile(ResourceFileName); if (path == "" && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate resource file: %s.", ResourceFileName); return std::string(""); } return path; } std::string NuxGraphicsResources::FindUITextureLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_UITextureSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate ui texture file: %s.", ResourceFileName); return std::string(""); } return path; } std::string NuxGraphicsResources::FindShaderLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_ShaderSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate shader file: %s.", ResourceFileName); return std::string(""); } return path; } std::string NuxGraphicsResources::FindFontLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_FontSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate font file file: %s.", ResourceFileName); return std::string(""); } return path; } #elif defined(NUX_OS_LINUX) std::string NuxGraphicsResources::FindResourceLocation(const char *ResourceFileName, bool ErrorOnFail) { std::string path = m_ResourcePathLocation.GetFile(ResourceFileName); if (path == "" && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate resource file: %s.", ResourceFileName); return ""; } return path; } std::string NuxGraphicsResources::FindUITextureLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_UITextureSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate ui texture file: %s.", ResourceFileName); return std::string(""); } return path; } std::string NuxGraphicsResources::FindShaderLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_ShaderSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate shader file: %s.", ResourceFileName); return std::string(""); } return path; } std::string NuxGraphicsResources::FindFontLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_FontSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[NuxGraphicsResources::FindResourceLocation] Failed to locate font file file: %s.", ResourceFileName); return std::string(""); } return path; } #endif } nux-4.0.6+14.04.20140409/NuxGraphics/FontRenderer.h0000644000015301777760000000775012321344237021747 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef FONTRENDERER_H #define FONTRENDERER_H #include #include "GLResource.h" class IOpenGLPixelShader; namespace nux { class GraphicsEngine; class TextureRectangle; class ICgPixelShader; class ICgVertexShader; class TemplateQuadBuffer; class FontTexture; class FontRenderer { public: FontRenderer(GraphicsEngine &OpenGLEngine); ~FontRenderer(); void PositionString(ObjectPtr const& Font, std::string const& str, PageBBox const&, StringBBox&, TextAlignment align = eAlignTextCenter, int NumCharacter = 0); int RenderColorText(ObjectPtr const& Font, int x, int y, std::string const& Str, Color const& color, bool WriteAlphaChannel, int NumCharacter); int RenderColorTextLineStatic(ObjectPtr const& Font, PageBBox const& pageSize, std::string const& Str, Color const& color, bool WriteAlphaChannel, TextAlignment alignment); int RenderColorTextLineEdit(ObjectPtr const& Font, PageBBox const& pageSize, std::string const& Str, Color const& TextColor, bool WriteAlphaChannel, Color const& SelectedTextColor, Color const& SelectedTextBackgroundColor, Color const& TextBlinkColor, Color const& CursorColor, bool ShowCursor, unsigned int CursorPosition, int offset = 0, int selection_start = 0, int selection_end = 0); private: int RenderText(ObjectPtr const& Font, int x, int y, std::string const& str, Color const& color, bool WriteAlphaChannel, int StartCharacter = 0, int NumCharacters = 0); // TODO: delete this int RenderTextToBuffer(float *VertexBuffer, int VBSize, ObjectPtr const& Font, Rect const& geo, std::string const& str, Color const& color, TextAlignment alignment = eAlignTextCenter, int NumCharacter = 0); private: GraphicsEngine& _graphics_engine; ObjectPtr _pixel_shader_prog; ObjectPtr _vertex_shader_prog; ObjectPtr _shader_prog; #ifndef NUX_OPENGLES_20 ObjectPtr _asm_shader_prog; ObjectPtr _asm_font_texture_rect_prog; #endif }; } #endif //FONTRENDERER_H nux-4.0.6+14.04.20140409/NuxGraphics/ImageSurface.h0000644000015301777760000004113012321344237021673 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IMAGESURFACE_H #define IMAGESURFACE_H #include "BitmapFormats.h" #include "NuxCore/Math/MathUtility.h" #include #define DEBUG_ENTER(a) #define DEBUG_WARNING(a) #define DEBUG_EXIT(a) namespace nux { class RawData { public: RawData() {}; ~RawData() {}; //! Get number of elements. unsigned int GetElementCount() { return 0; } //! Get the number of bytes per elements. unsigned int GetElementSize() { return 0; } void GetSize() {}; }; struct DXTColBlock { unsigned short col0; unsigned short col1; unsigned char row[4]; }; struct DXT3AlphaBlock { unsigned short row[4]; }; struct DXT5AlphaBlock { unsigned char alpha0; unsigned char alpha1; unsigned char row[6]; }; //! Image Surface class /*! Represent and image surface inside a complex data structure such as a 2D texture, Volume texture or Cube map. */ class ImageSurface { public: ImageSurface(); ImageSurface(BitmapFormat format, unsigned int width, unsigned int height); ImageSurface(const ImageSurface &); ImageSurface(ImageSurface&&); ImageSurface &operator = (ImageSurface); bool IsNull() const; int GetWidth() const { return width_; } int GetHeight() const { return height_; } void Allocate(BitmapFormat format, int width, int height); void Write32b(int i, int j, unsigned int value); void Write24b(int i, int j, unsigned int value); void Write16b(int i, int j, unsigned short value); void Write8b(int i, int j, unsigned char value); void Write(int i, int j, unsigned char r, unsigned char g, unsigned char b, unsigned char a); //! Read an element of the surface. /*! Return a 32 bits value representing the image element at coordinates(i, j). For the RGBA format, the LSB of the returned value represent the read value, and the MSB represents the alpha value. | LSB: Red | Green | Blue | MSB: Alpha| @return The image element at coordinates(i, j). */ unsigned int Read(int i, int j); //! Set all surface elements to 0. void Clear(); //! Flip the surface horizontally. void FlipHorizontal(); //! Flip the surface vertically. void FlipVertical(); //! Returns the surface pitch. int GetPitch() const; int GetBlockHeight() const; int GetAlignment() const; int GetSize() const; BitmapFormat GetFormat() const; const unsigned char *GetPtrRawData() const; unsigned char *GetPtrRawData(); static int GetLevelPitch(BitmapFormat format, int width, int height, int miplevel); static int GetLevelPitchNoMemAlignment(BitmapFormat format, int width, int height, int miplevel); static int GetLevelSize(BitmapFormat format, int width, int height, int miplevel); static int GetLevelSize(BitmapFormat format, int width, int height, int depth, int miplevel); static int GetLevelWidth(BitmapFormat format, int width, int miplevel); static int GetLevelHeight(BitmapFormat format, int height, int miplevel); static int GetLevelDim(BitmapFormat format, int length, int miplevel); static int GetNumMipLevel(BitmapFormat format, int width, int height); static int GetMemAlignment(BitmapFormat format); static int GetLevelBlockWidth(BitmapFormat format, int width, int miplevel); static int GetLevelBlockHeight(BitmapFormat format, int height, int miplevel); // for DXT // Image Processing //! Compute the average color of the image surface. /*! Sum up all the image elements and divide by the number of elements. @return The average color of the image. */ Color AverageColor(); private: void FlipDXTVertical(); void SwapBlocks(void *byte1, void *byte2, int size); void FlipBlocksDXT1(DXTColBlock *line, int numBlocks); void FlipBlocksDXT3(DXTColBlock *line, int numBlocks); void FlipBlocksDXT5(DXTColBlock *line, int numBlocks); void FlipDXT5Alpha(DXT5AlphaBlock *block); friend void swap(ImageSurface&, ImageSurface&); int width_; //!< Image width int height_; //!< Image height. BitmapFormat format_; //!< Image format. int m_Pitch; //!< Image pitch. int bpe_; //!< Number of byte per element. int Alignment_; //!< Data alignment. std::vector RawData_; }; void swap(ImageSurface&, ImageSurface&); class NBitmapData { public: NBitmapData(); virtual ~NBitmapData(); virtual const ImageSurface &GetSurface(int MipLevel) const = 0; virtual ImageSurface &GetSurface(int MipLevel) = 0; virtual const ImageSurface &GetSurface(int face, int MipLevel) const = 0; virtual ImageSurface &GetSurface(int face, int MipLevel) = 0; virtual bool IsTextureData() const { return false; }; virtual bool IsCubemapTextureData() const { return false; } virtual bool IsVolumeTextureData() const { return false; } virtual bool IsAnimatedTextureData() const { return false; } virtual int GetNumMipmap() const = 0; virtual int GetWidth() const = 0; virtual int GetHeight() const = 0; virtual int GetDepth() const { return 0; } virtual BitmapFormat GetFormat() const = 0; virtual bool IsNull() const = 0; virtual int GetMemorySize() const { return m_TotalMemorySize; } protected: unsigned int m_TotalMemorySize; //protected: // unsigned int m_Width; // unsigned int m_Height; // BitmapFormat m_Format; }; class NTextureData: public NBitmapData { public: NTextureData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int NumMipmap = 1); virtual ~NTextureData() {} //! Copy constructor. NTextureData(const NTextureData &); //! Assignment constructor. NTextureData &operator = (NTextureData); //! Move constructor NTextureData(NTextureData&&); virtual void Allocate(BitmapFormat f, int width, int height, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int MipLevel) const { return m_MipSurfaceArray[MipLevel]; }; virtual ImageSurface &GetSurface(int MipLevel) { return const_cast ((const_cast< const NTextureData * > (this))->GetSurface(MipLevel)); } virtual const ImageSurface &GetSurface(int /* face */, int MipLevel) const { //nuxAssertMsg(0, "[NTextureData::GetSurface] Use GetSurface(unsigned int MipLevel) for NTextureData."); return GetSurface(MipLevel); } virtual ImageSurface &GetSurface(int /* face */, int MipLevel) { //nuxAssertMsg(0, "[NTextureData::GetSurface] Use GetSurface(unsigned int MipLevel) for NTextureData."); return GetSurface(MipLevel); } bool SetSurface(int MipLevel, const ImageSurface &object); virtual bool IsTextureData() const { return true; } virtual int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0].GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0].GetHeight(); } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0].GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0].IsNull(); } private: void swap(NTextureData& other); int m_NumMipmap; std::vector m_MipSurfaceArray; #if defined(NUX_OS_WINDOWS) friend NBitmapData *read_tga_file(const TCHAR *file_name); #endif }; class NCubemapData: public NBitmapData { public: NCubemapData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int NumMipmap = 1); virtual ~NCubemapData(); //! Copy constructor NCubemapData(const NCubemapData &); //! Assignment constructor NCubemapData &operator = (const NCubemapData &); virtual void Allocate(BitmapFormat f, int width, int height, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int face, int MipLevel) const { return *m_MipSurfaceArray[face][MipLevel]; }; virtual ImageSurface &GetSurface(int face, int MipLevel) { return const_cast ((const_cast< const NCubemapData * > (this))->GetSurface(face, MipLevel)); } virtual const ImageSurface &GetSurface(int MipLevel) const { nuxAssertMsg(0, "[NCubemapData::GetSurface] Use GetSurface(unsigned int face, unsigned int MipLevel) for NCubemapData."); return GetSurface(0, MipLevel); } virtual ImageSurface &GetSurface(int MipLevel) { nuxAssertMsg(0, "[NCubemapData::GetSurface] Use GetSurface(unsigned int face, unsigned int MipLevel) for NCubemapData."); return GetSurface(0, MipLevel); } bool SetSurface(int face, int MipLevel, const ImageSurface &object); virtual bool IsCubemapTextureData() const { return true; } virtual int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0][0]->GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0][0]->GetHeight(); } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0][0]->GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0][0]->IsNull(); } private: void ClearData(); int m_NumMipmap; std::vector m_MipSurfaceArray[6]; }; class NVolumeData: public NBitmapData { public: NVolumeData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int slice = 1, int NumMipmap = 1); virtual ~NVolumeData(); //! Copy constructor NVolumeData(const NVolumeData &); //! Assignment constructor NVolumeData &operator = (const NVolumeData &); virtual void Allocate(BitmapFormat f, int width, int height, int slice, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int slice, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int slice, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int slice, int MipLevel) const { return *m_MipSurfaceArray[MipLevel][slice]; }; virtual ImageSurface &GetSurface(int slice, int MipLevel) { return const_cast ((const_cast< const NVolumeData * > (this))->GetSurface(slice, MipLevel)); } virtual const ImageSurface &GetSurface(int MipLevel) const { nuxAssertMsg(0, "[NVolumeData::GetSurface] Use GetSurface(unsigned int MipLevel, unsigned int MipLevel) for NVolumeData."); return GetSurface(MipLevel, 0); } virtual ImageSurface &GetSurface(int MipLevel) { nuxAssertMsg(0, "[NVolumeData::GetSurface] Use GetSurface(unsigned int MipLevel, unsigned int MipLevel) for NVolumeData."); return GetSurface(MipLevel, 0); } bool SetSurface(int face, int MipLevel, const ImageSurface &object); virtual bool IsVolumeTextureData() const { return true; } int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0][0]->GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0][0]->GetHeight(); } virtual int GetDepth() const { return m_Depth; } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0][0]->GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0][0]->IsNull(); } private: void ClearData(); int m_NumMipmap; int m_Depth; std::vector *m_MipSurfaceArray; }; class NAnimatedTextureData: public NBitmapData { public: NAnimatedTextureData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int slice = 1 /*, unsigned int NumMipmap = 1*/); virtual ~NAnimatedTextureData(); //! Copy constructor NAnimatedTextureData(const NAnimatedTextureData &); //! Assignment constructor NAnimatedTextureData &operator = (const NAnimatedTextureData &); virtual void Allocate(BitmapFormat f, int width, int height, int slice, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int slice, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int slice, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int /* MipLevel */, int /* slice */) const { nuxAssertMsg(0, "[NAnimatedTextureData::GetSurface] Use GetSurface(unsigned int Frame) for NAnimatedTextureData."); return GetSurface(0); } virtual ImageSurface &GetSurface(int /* MipLevel */, int /* slice */) { nuxAssertMsg(0, "[NAnimatedTextureData::GetSurface] Use GetSurface(unsigned int Frame) for NAnimatedTextureData."); return GetSurface(0); } virtual const ImageSurface &GetSurface(int Frame) const { nuxAssert(Frame >= 0); nuxAssert(Frame < m_Depth); return *m_MipSurfaceArray[0][Frame]; } virtual ImageSurface &GetSurface(int Frame) { nuxAssert(Frame >= 0); nuxAssert(Frame < m_Depth); return const_cast ((const_cast< const NAnimatedTextureData * > (this))->GetSurface(Frame)); } bool SetSurface(int face, int MipLevel, const ImageSurface &object); virtual bool IsAnimatedTextureData() const { return true; } int GetFrameTime(int Frame) const { nuxAssert(Frame >= 0); nuxAssert(Frame < m_Depth); return m_FrameTimeArray[Frame]; } void AddFrameTime(unsigned int FrameTime) { m_FrameTimeArray.push_back(FrameTime); } int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0][0]->GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0][0]->GetHeight(); } virtual int GetDepth() const { return m_Depth; } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0][0]->GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0][0]->IsNull(); } private: void ClearData(); int m_NumMipmap; int m_Depth; std::vector *m_MipSurfaceArray; std::vector m_FrameTimeArray; }; struct ImageInfo { bool isDelegate; // true if delegate knows this format int width ; // Image size(if known) int height; int bytes_per_pixel; // Bytes per pixel(if known) int planes; // Number of planes(if known) 0=mono, 3=color std::string format; // Additional image format information }; void MakeCheckBoardImage(ImageSurface& Image, int width, int height, Color const& dark, Color const& light, int TileWidth = 4, int TileHeight = 4); bool HasOpenEXRSupport(); /*! Return and object that has to be destroyed with delete. @return A bitmap source. Destroy it with delete. */ NBitmapData* LoadGdkPixbuf(GdkPixbuf *pixbuf); /*! Return and object that has to be destroyed with delete. @return A bitmap source. Destroy it with delete. */ NBitmapData* LoadImageFile(const TCHAR *Filename); } #endif // IMAGE_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVertexBuffer.h0000644000015301777760000000326712321344237023136 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLVERTEXBUFFER_H #define IOPENGLVERTEXBUFFER_H #include "IOpenGLResource.h" namespace nux { class IOpenGLResource; class IOpenGLVertexBuffer: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLVertexBuffer, IOpenGLResource); public: virtual ~IOpenGLVertexBuffer(); int Lock( unsigned int OffsetToLock, unsigned int SizeToLock, void **ppbData); int Unlock(); int GetDescription(VERTEXBUFFER_DESC *desc) const { desc->Usage = _Usage; desc->Size = _Length; return OGL_OK; } void BindVertexBuffer(); unsigned int GetSize(); private: IOpenGLVertexBuffer(unsigned int Length, VBO_USAGE Usage, NUX_FILE_LINE_PROTO); unsigned int _Length; VBO_USAGE _Usage; BYTE *_MemMap; unsigned int _OffsetToLock; unsigned int _SizeToLock; friend class GpuDevice; }; } #endif // IOPENGLVERTEXBUFFER_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLIndexBuffer.h0000644000015301777760000000342412321344237022723 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLINDEXBUFFER_H #define IOPENGLINDEXBUFFER_H namespace nux { class IOpenGLResource; class IOpenGLIndexBuffer: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLIndexBuffer, IOpenGLResource); public: virtual ~IOpenGLIndexBuffer(); int Lock( unsigned int OffsetToLock, unsigned int SizeToLock, void **ppbData); int Unlock(); int GetStride(); int GetDescription(INDEXBUFFER_DESC *desc) const { desc->Format = _Format; desc->Usage = _Usage; desc->Size = _Length; return OGL_OK; } void BindIndexBuffer(); unsigned int GetSize(); private: IOpenGLIndexBuffer(unsigned int Length, VBO_USAGE Usage, INDEX_FORMAT Format, NUX_FILE_LINE_PROTO); unsigned int _Length; INDEX_FORMAT _Format; VBO_USAGE _Usage; BYTE *_MemMap; unsigned int _OffsetToLock; unsigned int _SizeToLock; friend class GpuDevice; }; } #endif // IOPENGLINDEXBUFFER_H nux-4.0.6+14.04.20140409/NuxGraphics/GraphicsDisplayWin.cpp0000755000015301777760000022466712321344237023464 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "NuxGraphics.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GraphicsEngine.h" #include "GLWindowManager.h" #include "Events.h" #include "GraphicsDisplay.h" namespace nux { // Compute the frame rate every FRAME_RATE_PERIODE; #define FRAME_RATE_PERIODE 10 void ClipOrCenterRectToMonitor(LPRECT prc, unsigned int flags) { HMONITOR hMonitor; MONITORINFO mi; RECT rc; int w = prc->right - prc->left; int h = prc->bottom - prc->top; // // get the nearest monitor to the passed rect. // hMonitor = MonitorFromRect(prc, MONITOR_DEFAULTTONEAREST); // // get the work area or entire monitor rect. // mi.cbSize = sizeof(mi); GetMonitorInfo(hMonitor, &mi); //if(flags & MONITOR_WORKAREA) rc = mi.rcWork; // else // rc = mi.rcMonitor; // // center or clip the passed rect to the monitor rect // //if(flags & MONITOR_CENTER) { prc->left = rc.left + (rc.right - rc.left - w) / 2; prc->top = rc.top + (rc.bottom - rc.top - h) / 2; prc->right = prc->left + w; prc->bottom = prc->top + h; } // else // { // prc->left = Max(rc.left, Min(rc.right-w, prc->left)); // prc->top = Max(rc.top, Min(rc.bottom-h, prc->top)); // prc->right = prc->left + w; // prc->bottom = prc->top + h; // } } EventToNameStruct EventToName[] = { {NUX_NO_EVENT, "NUX_NO_EVENT" }, {NUX_MOUSE_PRESSED, "NUX_MOUSE_PRESSED" }, {NUX_MOUSE_RELEASED, "NUX_MOUSE_RELEASED" }, {NUX_KEYDOWN, "NUX_KEYDOWN" }, {NUX_KEYUP, "NUX_KEYUP" }, {NUX_MOUSE_MOVE, "NUX_MOUSE_MOVE" }, {NUX_SIZE_CONFIGURATION, "NUX_SIZE_CONFIGURATION" }, {NUX_NC_WINDOW_CONFIGURATION, "NUX_NC_WINDOW_CONFIGURATION" }, {NUX_WINDOW_ENTER_FOCUS, "NUX_WINDOW_ENTER_FOCUS" }, {NUX_WINDOW_EXIT_FOCUS, "NUX_WINDOW_EXIT_FOCUS" }, {NUX_WINDOW_DIRTY, "NUX_WINDOW_DIRTY" }, {NUX_WINDOW_MOUSELEAVE, "NUX_WINDOW_MOUSELEAVE" }, {NUX_TERMINATE_APP, "NUX_TERMINATE_APP" } }; //--------------------------------------------------------------------------------------------------------- HGLRC GraphicsDisplay::sMainGLRC = 0; HDC GraphicsDisplay::sMainDC = 0; GraphicsDisplay::GraphicsDisplay() : gfx_interface_created_(false) , fullscreen_(false) , screen_bit_depth_(32) , m_DeviceFactory(0) , m_GraphicsContext(0) , m_Style(WINDOWSTYLE_NORMAL) , cursor_(0) , m_PauseGraphicsRendering(false) , parent_window_(0) , window_extended_style_(0) , window_style_(0) , device_context_(NULL) , wnd_handle_(NULL) { // Initialize Direct2D and DirectWrite d2d_factory_ = NULL; dw_factory_ = NULL; wic_factory_ = NULL; HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2d_factory_); if (hr == S_OK) { hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast(&dw_factory_)); } // Initialize COM CoInitialize(NULL); hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&wic_factory_); inlSetThreadLocalStorage(_TLS_GraphicsDisplay, this); gfx_interface_created_ = false; GetDisplayInfo(); window_size_.width = 0; window_size_.height = 0; // A window never starts in a minimized state. window_minimized_ = false; //_dnd_source_grab_active = false; _global_keyboard_grab_data = 0; _global_pointer_grab_data = 0; } //--------------------------------------------------------------------------------------------------------- GraphicsDisplay::~GraphicsDisplay() { NUX_SAFE_DELETE( m_GraphicsContext ); NUX_SAFE_DELETE( m_DeviceFactory ); DestroyOpenGLWindow(); inlSetThreadLocalStorage(_TLS_GraphicsDisplay, 0); if (dw_factory_) { dw_factory_->Release(); dw_factory_ = NULL; } if (d2d_factory_) { d2d_factory_->Release(); d2d_factory_ = NULL; } if (wic_factory_) { wic_factory_->Release(); wic_factory_ = NULL; } } ID2D1Factory* GraphicsDisplay::GetDirect2DFactory() { return d2d_factory_; } IDWriteFactory* GraphicsDisplay::GetDirectWriteFactory() { return dw_factory_; } IWICImagingFactory* GraphicsDisplay::GetWICFactory() { return wic_factory_; } //--------------------------------------------------------------------------------------------------------- bool GraphicsDisplay::IsGfxInterfaceCreated() { return gfx_interface_created_; } //--------------------------------------------------------------------------------------------------------- static NCriticalSection CreateOpenGLWindow_CriticalSection; bool GraphicsDisplay::CreateOpenGLWindow(const char *WindowTitle, unsigned int WindowWidth, unsigned int WindowHeight, WindowStyle Style, const GraphicsDisplay *Parent, bool fullscreen_flag, bool create_rendering_data) { NScopeLock Scope(&CreateOpenGLWindow_CriticalSection); RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values gfx_interface_created_ = false; // FIXME : put at the end viewport_size_.width = WindowWidth; viewport_size_.height = WindowHeight; window_size_.width = WindowWidth; window_size_.height = WindowHeight; // end of fixme WindowRect.left = (long) 0; WindowRect.right = (long) viewport_size_.width; WindowRect.top = (long) 0; WindowRect.bottom = (long) viewport_size_.height; fullscreen_ = fullscreen_flag; // Set The Global Fullscreen Flag if (fullscreen_) // Attempt Fullscreen Mode? { // check if resolution is supported bool mode_supported = false; for (int num_modes = 0 ; num_modes < m_num_gfx_device_modes; num_modes++) { if ((m_gfx_device_modes[num_modes].width == viewport_size_.width) && (m_gfx_device_modes[num_modes].height == viewport_size_.height) && (m_gfx_device_modes[num_modes].format == screen_bit_depth_)) { mode_supported = true; break; } } if (mode_supported == false) { if (inlWin32MessageBox(NULL, "Info", MBTYPE_Ok, MBICON_Information, MBMODAL_ApplicationModal, "The requested fullscreen mode is not supported by your monitor.\nUsing windowed mode instead.") == MBRES_Yes) { fullscreen_ = FALSE; // Windowed Mode Selected. Fullscreen = FALSE } } DEVMODE dmScreenSettings; // Device Mode memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size Of The Devmode Structure dmScreenSettings.dmPelsWidth = viewport_size_.width; // Selected Screen Width dmScreenSettings.dmPelsHeight = viewport_size_.height; // Selected Screen Height dmScreenSettings.dmBitsPerPel = screen_bit_depth_; // Selected Bits Per Pixel dmScreenSettings.dmDisplayFrequency = 60; dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { if (inlWin32MessageBox(NULL, "Info", MBTYPE_Ok, MBICON_Information, MBMODAL_ApplicationModal, "The requested fullscreen mode is not supported by your monitor.\nUsing windowed mode instead.") == MBRES_Yes) { fullscreen_ = FALSE; // Windowed Mode Selected. Fullscreen = FALSE } else { // Pop Up A Message Box Letting User Know The Program Is Closing. MessageBox(NULL, "Program Will Now Close.", "ERROR", MB_OK | MB_ICONSTOP); } } } window_extended_style_ = 0; window_style_ = 0; if (fullscreen_) // Are We Still In Fullscreen Mode? { window_extended_style_ = WS_EX_APPWINDOW; // Window Extended Style window_style_ = WS_POPUP; // Windows Style ShowCursor(FALSE); // Hide Mouse Pointer } else { // Window Extended Style window_extended_style_ = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Windows Style window_style_ = WS_OVERLAPPED; // Creates an overlapped window. An overlapped window has a title bar and a border // See Win32 Window Hierarchy and Styles: http://msdn.microsoft.com/en-us/library/ms997562.aspx //WS_EX_APPWINDOW // Forces a top-level window onto the taskbar when the window is visible //WS_EX_WINDOWEDGE // Specifies that a window has a border with a raised edge //WS_POPUP // Creates a pop-up window. This style cannot be used with the WS_CHILD style. //WS_SYSMENU // Creates a window that has a window menu on its title bar. The WS_CAPTION style must also be specified. //WS_SIZEBOX // Creates a window that has a sizing border. Same as the WS_THICKFRAME style. //WS_CAPTION // Creates a window that has a title bar(includes the WS_BORDER style). m_Style = Style; if (Style == WINDOWSTYLE_TOOL) { window_extended_style_ = WS_EX_TOOLWINDOW; window_style_ = WS_CAPTION | WS_SYSMENU; } else if (Style == WINDOWSTYLE_DIALOG) { window_extended_style_ = WS_EX_DLGMODALFRAME; window_style_ = WS_CAPTION | WS_SYSMENU; } else if (Style == WINDOWSTYLE_NOBORDER) { window_extended_style_ = WS_EX_TOPMOST | WS_EX_TOOLWINDOW; window_style_ = WS_POPUP; } else if (Style == WINDOWSTYLE_PANEL) { window_extended_style_ = 0; // Specifies that a window has a border with a raised edge window_style_ = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX; } else { // Normal Window: NormalWindow window_extended_style_ = WS_EX_APPWINDOW | // Forces a top-level window onto the taskbar when the window is visible WS_EX_WINDOWEDGE; // Specifies that a window has a border with a raised edge window_style_ |= WS_CAPTION | // Creates a window that has a title bar. WS_SYSMENU | // Creates a window that has a window menu on its title bar. The WS_CAPTION style must also be specified. WS_THICKFRAME | // Creates a window that has a sizing border. WS_MINIMIZEBOX | // Creates a window that has a minimize button. WS_MAXIMIZEBOX | // Creates a window that has a maximize button. WS_BORDER; // Creates a window that has a thin-line border. } } // The AdjustWindowRectEx function calculates the required size of the window rectangle, // based on the desired size of the client rectangle. The window rectangle can then be passed to // the CreateWindowEx function to create a window whose client area is the desired size. AdjustWindowRectEx(&WindowRect, window_style_, FALSE, window_extended_style_); // Adjust Window To True Requested Size RECT rect; rect.top = 0; rect.bottom = WindowRect.bottom - WindowRect.top; rect.left = 0; rect.right = WindowRect.right - WindowRect.left; int WindowX = 0; int WindowY = 0; if (Parent) { parent_window_ = Parent->GetWindowHandle(); GetWindowRect(parent_window_, &rect); int width = rect.right - rect.left; int height = rect.bottom - rect.top; WindowX = rect.left + (width - (WindowRect.right - WindowRect.left)) / 2; WindowY = rect.top + (height - (WindowRect.bottom - WindowRect.top)) / 2; } else if (!fullscreen_) { ClipOrCenterRectToMonitor(&rect, 0); WindowX = rect.left; WindowY = rect.top; } window_title_ = WindowTitle; // Create The Window if (! (wnd_handle_ = ::CreateWindowEx(window_extended_style_, // Extended Style For The Window WINDOW_CLASS_NAME, // Class Name window_title_.c_str(), // Window Title window_style_ | // Defined Window Style WS_CLIPSIBLINGS | // Required Window Style WS_CLIPCHILDREN, // Required Window Style WindowX, WindowY, // Window Position WindowRect.right - WindowRect.left, // Calculate Window Width WindowRect.bottom - WindowRect.top, // Calculate Window Height parent_window_, // No Parent Window NULL, // No Menu gGLWindowManager.GetInstance(), // Instance NULL))) // Don't Pass Anything To WM_CREATE { DestroyOpenGLWindow(); MessageBox(NULL, "Window Creation Error.", "ERROR", MB_OK | MB_ICONERROR); // Return FALSE } static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 24, // cColorBits // Specifies the number of color bitplanes in each color buffer. // For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. // For color-index pixels, it is the size of the color-index buffer. 0, // cRedBits // Specifies the number of red bitplanes in each RGBA color buffer. 0, // cRedShift // Specifies the shift count for red bitplanes in each RGBA color buffer. 0, // cGreenBits // Specifies the number of green bitplanes in each RGBA color buffer. 0, // cGreenShift // Specifies the shift count for green bitplanes in each RGBA color buffer. 0, // cBlueBits // Specifies the number of blue bitplanes in each RGBA color buffer. 0, // cBlueShift // Specifies the shift count for blue bitplanes in each RGBA color buffer. 0, // cAlphaBits // Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. 0, // cAlphaShift // Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. 0, // cAccumBits // Specifies the total number of bitplanes in the accumulation buffer. 0, // cAccumRedBits // Specifies the number of red bitplanes in the accumulation buffer. 0, // cAccumGreenBits // Specifies the number of green bitplanes in the accumulation buffer. 0, // cAccumBlueBits // Specifies the number of blue bitplanes in the accumulation buffer. 0, // cAccumAlphaBits // Specifies the number of alpha bitplanes in the accumulation buffer. 24,// cDepthBits // Specifies the depth of the depth(z-axis) buffer. 8, // cStencilBits // Specifies the depth of the stencil buffer. 0, // cAuxBuffers // Specifies the number of auxiliary buffers. Auxiliary buffers are not supported. PFD_MAIN_PLANE, // iLayerType // Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. 0, // bReserved // Specifies the number of overlay and underlay planes. Bits 0 through 3 specify up to 15 overlay planes and bits 4 through 7 specify up to 15 underlay planes. 0, // dwLayerMask // Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. 0, // dwVisibleMask // Specifies the transparent color or index of an underlay plane. When the pixel type is RGBA, dwVisibleMask is a transparent RGB color value. When the pixel type is color index, it is a transparent index value. 0, // dwDamageMask // Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. }; device_context_ = GetDC(wnd_handle_); if (device_context_ == NULL) // Did We Get A Device Context? { DestroyOpenGLWindow(); MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONERROR); return FALSE; } if (! (pixel_format_ = ChoosePixelFormat(device_context_, &pfd))) // Did Windows Find A Matching Pixel Format? { DestroyOpenGLWindow(); MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONERROR); return FALSE; } if (!SetPixelFormat(device_context_, pixel_format_, &pfd)) // Are We Able To Set The Pixel Format? { DestroyOpenGLWindow(); MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONERROR); return FALSE; } if (!(opengl_rendering_context_ = wglCreateContext(device_context_))) // Are We Able To Get A Rendering Context? { DestroyOpenGLWindow(); MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONERROR); return FALSE; } if (sMainGLRC == 0) { sMainGLRC = opengl_rendering_context_; sMainDC = device_context_; } else { // wglMakeCurrent(device_context_, 0); // // Make the newly created context share it resources with all the other OpenGL context // if (wglShareLists(sMainGLRC, opengl_rendering_context_) == FALSE) // { // DWORD err = GetLastError(); // DestroyOpenGLWindow(); // MessageBox(NULL, "Can't share GL context.", "ERROR", MB_OK|MB_ICONERROR); // return FALSE; // } } // This creates a warning. It is a 64-bits compatibility issue. // When not in 64-bit you can disable the warning: // Project Properties --> C/C++ tab --> General --> Select "NO" for - Detect 64-bit Portability Issues. // See also SetWindowLongPtr SetWindowLongPtr(wnd_handle_, GWLP_USERDATA, (long) this); //::ShowWindow(wnd_handle_,SW_SHOW); // Show The Window ::SetForegroundWindow(wnd_handle_); // Slightly Higher Priority ::SetFocus(wnd_handle_); // Sets Keyboard Focus To The Window MakeGLContextCurrent(); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); SwapBuffer(); gfx_interface_created_ = true; //m_GLEWContext = new GLEWContext(); //m_WGLEWContext = new WGLEWContext(); HGLRC new_opengl_rendering_context = opengl_rendering_context_; m_DeviceFactory = new GpuDevice(viewport_size_.width, viewport_size_.height, BITFMT_R8G8B8A8, device_context_, new_opengl_rendering_context, 1, 0, false); if (m_DeviceFactory->GetGpuInfo().Support_EXT_Framebuffer_Object()) m_DeviceFactory->GetFrameBufferObject()->SetupFrameBufferObject(); if (new_opengl_rendering_context != 0) { opengl_rendering_context_ = new_opengl_rendering_context; } m_GraphicsContext = new GraphicsEngine(*this, create_rendering_data); //EnableVSyncSwapControl(); //DisableVSyncSwapControl(); InitGlobalGrabWindow(); return true; } bool GraphicsDisplay::CreateFromOpenGLWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext) { // Do not make the opengl context current // Do not swap the framebuffer // Do not clear the depth or color buffer // Do not enable/disable VSync wnd_handle_ = WindowHandle; device_context_ = WindowDCHandle; opengl_rendering_context_ = OpenGLRenderingContext; RECT rect; ::GetClientRect(wnd_handle_, &rect); window_size_ = Size(rect.right - rect.left, rect.bottom - rect.top); viewport_size_ = Size(rect.right - rect.left, rect.bottom - rect.top); // The opengl context should be made current by an external entity. gfx_interface_created_ = true; m_DeviceFactory = new GpuDevice(viewport_size_.width, viewport_size_.height, BITFMT_R8G8B8A8, device_context_, opengl_rendering_context_); if (m_DeviceFactory->GetGpuInfo().Support_EXT_Framebuffer_Object()) m_DeviceFactory->GetFrameBufferObject()->SetupFrameBufferObject(); m_GraphicsContext = new GraphicsEngine(*this); InitGlobalGrabWindow(); return true; } GraphicsEngine* GraphicsDisplay::GetGraphicsEngine() const { return m_GraphicsContext; } GpuDevice* GraphicsDisplay::GetGpuDevice() const { return m_DeviceFactory; } //--------------------------------------------------------------------------------------------------------- // NUXTODO: remove this call. Make a direct access to GpuInfo via GpuDevice. bool GraphicsDisplay::HasFrameBufferSupport() { return m_DeviceFactory->GetGpuInfo().Support_EXT_Framebuffer_Object(); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::GetWindowSize(int &w, int &h) { w = window_size_.width; h = window_size_.height; } //--------------------------------------------------------------------------------------------------------- int GraphicsDisplay::GetWindowWidth() { return window_size_.width; } //--------------------------------------------------------------------------------------------------------- int GraphicsDisplay::GetWindowHeight() { return window_size_.height; } void GraphicsDisplay::ResetWindowSize() { RECT rect; ::GetClientRect(wnd_handle_, &rect); window_size_ = Size(rect.right - rect.left, rect.bottom - rect.top); viewport_size_ = Size(rect.right - rect.left, rect.bottom - rect.top); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::SetWindowSize(int width, int height) { RECT window_rect; RECT new_rect; ::GetWindowRect(wnd_handle_, &window_rect); new_rect.left = 0; new_rect.right = width; new_rect.top = 0; new_rect.bottom = height; BOOL b = ::AdjustWindowRectEx(&new_rect, window_style_, FALSE, window_extended_style_); // Adjust Window To True Requested Size ::MoveWindow(wnd_handle_, window_rect.left, window_rect.top, (new_rect.right - new_rect.left), (new_rect.bottom - new_rect.top), TRUE); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::SetViewPort(int x, int y, int width, int height) { if (IsGfxInterfaceCreated()) { //do not rely on viewport_size_: glViewport can be called directly viewport_size_.width = width; viewport_size_.height = height; m_GraphicsContext->SetViewport(x, y, viewport_size_.width, viewport_size_.height); m_GraphicsContext->SetScissor(0, 0, width, height); } } Point GraphicsDisplay::GetMouseScreenCoord() { POINT pt; ::GetCursorPos(&pt); ScreenToClient(wnd_handle_, &pt); Point point(pt.x, pt.y); return point; } Point GraphicsDisplay::GetMouseWindowCoord() { POINT pt; ::GetCursorPos(&pt); ::ScreenToClient(wnd_handle_, &pt); Point point(pt.x, pt.y); return point; } Point GraphicsDisplay::GetWindowCoord() { RECT rect; ::GetWindowRect(wnd_handle_, &rect); Point point(rect.left, rect.top); return point; } Rect GraphicsDisplay::GetWindowGeometry() { RECT rect; ::GetClientRect(wnd_handle_, &rect); Rect geo(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); return geo; } Rect GraphicsDisplay::GetNCWindowGeometry() { RECT rect; ::GetWindowRect(wnd_handle_, &rect); Rect geo(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); return geo; } void GraphicsDisplay::MakeGLContextCurrent(bool b) { HGLRC glrc = opengl_rendering_context_; if (b == false) { glrc = 0; } if (!wglMakeCurrent(device_context_, glrc)) { std::string error = inlGetSystemErrorMessage(); DestroyOpenGLWindow(); MessageBox(NULL, "Can't Activate The GL Rendering Context.", "ERROR", MB_OK | MB_ICONERROR); } } void GraphicsDisplay::SwapBuffer(bool glswap) { if (IsPauseThreadGraphicsRendering()) return; if (glswap) { SwapBuffers(device_context_); } m_FrameTime = m_Timer.PassedMilliseconds(); // if (16.6f - m_FrameTime > 0) // { // SleepForMilliseconds(16.6f - m_FrameTime); // } // // m_FrameTime = m_Timer.PassedMilliseconds(); // m_Timer.Reset(); // m_PeriodeTime += m_FrameTime; // // m_FrameCounter++; // m_FramePeriodeCounter++; // if (m_FramePeriodeCounter >= FRAME_RATE_PERIODE) // { // m_FrameRate = m_FramePeriodeCounter * 1000.0f / m_PeriodeTime; // m_PeriodeTime = 0.0f; // m_FramePeriodeCounter = 0; // } } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::DestroyOpenGLWindow() { if (gfx_interface_created_ == true) { if (fullscreen_) // Are We In Fullscreen Mode? { ChangeDisplaySettings(NULL, 0); // If So Switch Back To The Desktop ShowCursor(TRUE); // Show Mouse Pointer } if (opengl_rendering_context_) // Do We Have A Rendering Context? { if (!wglMakeCurrent(device_context_, NULL)) // Are We Able To Release The DC And RC Contexts? { MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } if (!wglDeleteContext(opengl_rendering_context_)) // Are We Able To Delete The RC? { MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } opengl_rendering_context_ = NULL; // Set RC To NULL } if (device_context_ && (ReleaseDC(wnd_handle_, device_context_) == 0)) // Are We Able To Release The DC { MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } device_context_ = NULL; // Set DC To NULL if (wnd_handle_ && (::DestroyWindow(wnd_handle_) == 0)) // Are We Able To Destroy The Window? { MessageBox(NULL, "Could Not Release window handle.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } wnd_handle_ = NULL; // Set Window Handle To NULL } gfx_interface_created_ = false; } // //--------------------------------------------------------------------------------------------------------- // // convert a MSWindows VK_x to an Fltk(X) Keysym: // // See also the inverse converter in Fl_get_key_win32.cxx // // This table is in numeric order by VK: // static const struct {unsigned short vk, fltk, extended;} vktab[] = { // {NUX_VK_BACK, NUX_BackSpace}, // {NUX_VK_TAB, NUX_Tab}, // {NUX_VK_CLEAR, NUX_Clear, 0xff0b/*XK_Clear*/}, // {NUX_VK_ENTER, NUX_Enter, NUX_KP_ENTER}, // {NUX_VK_SHIFT, NUX_Shift_L, NUX_EXT_Shift_R}, // {NUX_VK_CONTROL, NUX_Control_L, NUX_EXT_Control_R}, // {NUX_VK_MENU, NUX_Alt_L, NUX_EXT_Alt_R}, // {NUX_VK_PAUSE, NUX_Pause}, // {NUX_VK_CAPITAL, NUX_Caps_Lock}, // {NUX_VK_ESCAPE, NUX_Escape}, // {NUX_VK_SPACE, ' '}, // {NUX_VK_PAGE_UP, NUX_Page_Up /*KP+'9'*/, NUX_KP_PAGE_UP}, // {NUX_VK_PAGE_DOWN, NUX_Page_Down /*KP+'3'*/, NUX_KP_PAGE_DOWN}, // {NUX_VK_END, NUX_End /*KP+'1'*/, NUX_KP_END}, // {NUX_VK_HOME, NUX_Home /*KP+'7'*/, NUX_KP_HOME}, // {NUX_VK_LEFT, NUX_Left /*KP+'4'*/, NUX_KP_LEFT}, // {NUX_VK_UP, NUX_Up /*KP+'8'*/, NUX_KP_UP}, // {NUX_VK_RIGHT, NUX_Right /*KP+'6'*/, NUX_KP_RIGHT}, // {NUX_VK_DOWN, NUX_Down /*KP+'2'*/, NUX_KP_DOWN}, // {NUX_VK_SNAPSHOT, NUX_Print}, // does not work on NT // {NUX_VK_INSERT, NUX_Insert /*KP+'0'*/, NUX_KP_INSERT}, // {NUX_VK_DELETE, NUX_Delete /*KP+'.'*/, NUX_KP_DELETE}, // {NUX_VK_LWIN, NUX_LWin /*Meta_L*/}, // {NUX_VK_RWIN, NUX_RWin /*Meta_R*/}, // {NUX_VK_APPS, NUX_VK_APPS /*Menu*/}, // {NUX_VK_MULTIPLY, NUX_Multiply /*KP+'*'*/}, // {NUX_VK_ADD, NUX_Add /*KP+'+'*/}, // {NUX_VK_SUBTRACT, NUX_Subtract /*KP+'-'*/}, // {NUX_VK_DECIMAL, NUX_Decimal /*KP+'.'*/}, // {NUX_VK_DIVIDE, NUX_Divide /*KP+'/'*/}, // {NUX_VK_NUMLOCK, NUX_Numlock /*Num_Lock*/}, // {NUX_VK_SCROLL, NUX_Scroll /*Scroll_Lock*/}, // {0xba, ';'}, // {0xbb, '='}, // {0xbc, ','}, // {0xbd, '-'}, // {0xbe, '.'}, // {0xbf, '/'}, // {0xc0, '`'}, // {0xdb, '['}, // {0xdc, '\\'}, // {0xdd, ']'}, // {0xde, '\''} // }; /* The extended-key flag indicates whether the keystroke message originated from one of the additional keys on the enhanced keyboard. The extended keys consist of the ALT and CTRL keys on the right-hand side of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad; the NUM LOCK key; the BREAK(CTRL+PAUSE) key; the PRINT SCRN key; and the divide(/) and ENTER keys in the numeric keypad. The extended-key flag is set if the key is an extended key. */ //--------------------------------------------------------------------------------------------------------- /*static int ms2fltk(int vk, int extended) { static unsigned short vklut[256]; static unsigned short extendedlut[256]; if (!vklut[1]) { // init the table unsigned int i; for (i = 0; i < 256; i++) { vklut[i] = i; //tolower(i); } // for (i=VK_F1; i<=VK_F16; i++) // { // vklut[i] = i+(FL_F-(VK_F1-1)); // (FL_F + 1 -> VK_F1) ... (FL_F + 16 -> VK_F16) // } // for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) // { // vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0); // (FL_KP + '0' -> VK_NUMPAD0) ... (FL_KP + '9' = VK_NUMPAD9) // } for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) { vklut[vktab[i].vk] = vktab[i].fltk; extendedlut[vktab[i].vk] = vktab[i].extended; } for (i = 0; i < 256; i++) { if (!extendedlut[i]) extendedlut[i] = vklut[i]; } } return extended ? extendedlut[vk] : vklut[vk]; }*/ //--------------------------------------------------------------------------------------------------------- static int InspectMouseEvent(HWND window, Event& event, int what, int button, WPARAM wParam, LPARAM lParam) { static int pmx, pmy; event.x = (signed short) LOWORD(lParam); event.y = (signed short) HIWORD(lParam); event.x_root = 0; event.y_root = 0; POINT EventScreenPosition; ClientToScreen(window, &EventScreenPosition); EventScreenPosition.x = event.x; EventScreenPosition.y = event.y; POINT WindowScreenPosition; WindowScreenPosition.x = WindowScreenPosition.y = 0; ClientToScreen(window, &WindowScreenPosition); // Erase mouse event and mouse doubleclick events. Keep the mouse states. ulong _mouse_state = event.mouse_state & 0x0F000000; // establish cause of the event // if (button == 1) // _mouse_state |= NUX_EVENT_BUTTON1; // else if (button == 2) // _mouse_state |= NUX_EVENT_BUTTON2; // else if (button == 3) // _mouse_state |= NUX_EVENT_BUTTON3; // else if (button == 4) { event.mouse_state |= NUX_EVENT_MOUSEWHEEL; event.type = NUX_MOUSE_WHEEL; int zDelta = GET_WHEEL_DELTA_WPARAM(wParam); int xPos = (int) (short) LOWORD(lParam) - WindowScreenPosition.x; int yPos = (int) (short) HIWORD(lParam) - WindowScreenPosition.y; event.x = xPos; event.y = yPos; event.wheel_delta = zDelta; return 1; } // set the cause of the event switch(what) { case 0: { // mouse down if (button == 1) { _mouse_state |= NUX_STATE_BUTTON1_DOWN; _mouse_state |= NUX_EVENT_BUTTON1_DOWN; } else if (button == 2) { _mouse_state |= NUX_STATE_BUTTON2_DOWN; _mouse_state |= NUX_EVENT_BUTTON2_DOWN; } else if (button == 3) { _mouse_state |= NUX_STATE_BUTTON3_DOWN; _mouse_state |= NUX_EVENT_BUTTON3_DOWN; } } break; case 1: { // double click if (button == 1) { _mouse_state |= NUX_EVENT_BUTTON1_DBLCLICK; _mouse_state |= NUX_STATE_BUTTON1_DOWN; _mouse_state |= NUX_EVENT_BUTTON1_DOWN; } else if (button == 2) { _mouse_state |= NUX_EVENT_BUTTON2_DBLCLICK; _mouse_state |= NUX_STATE_BUTTON2_DOWN; _mouse_state |= NUX_EVENT_BUTTON2_DOWN; } else if (button == 3) { _mouse_state |= NUX_EVENT_BUTTON3_DBLCLICK; _mouse_state |= NUX_STATE_BUTTON3_DOWN; _mouse_state |= NUX_EVENT_BUTTON3_DOWN; } } break; case 2: { // button up if (button == 1) { _mouse_state &= ~NUX_STATE_BUTTON1_DOWN; _mouse_state |= NUX_EVENT_BUTTON1_UP; } else if (button == 2) { _mouse_state &= ~NUX_STATE_BUTTON2_DOWN; _mouse_state |= NUX_EVENT_BUTTON2_UP; } else if (button == 3) { _mouse_state &= ~NUX_STATE_BUTTON3_DOWN; _mouse_state |= NUX_EVENT_BUTTON3_UP; } } break; } event.mouse_state = _mouse_state; switch(what) { static int px, py; case 1: // double-click if (event.is_click) { event.clicks++; // The SetCapture function sets the mouse capture to the specified window belonging to // the current thread. SetCapture captures mouse input either when the mouse is over the // capturing window, or when the mouse button was pressed while the mouse was over the // capturing window and the button is still down. Only one window at a time can capture the mouse. SetCapture(window); event.is_click = 1; px = pmx = event.x; py = pmy = event.y; event.type = NUX_MOUSE_DOUBLECLICK; return 1; } case 0: // single-click event.clicks = 0; // The SetCapture function sets the mouse capture to the specified window belonging to // the current thread. SetCapture captures mouse input either when the mouse is over the // capturing window, or when the mouse button was pressed while the mouse was over the // capturing window and the button is still down. Only one window at a time can capture the mouse. SetCapture(window); event.is_click = 1; px = pmx = event.x; py = pmy = event.y; event.type = NUX_MOUSE_PRESSED; return 1; case 2: // release: // The ReleaseCapture function releases the mouse capture from a window in the current thread // and restores normal mouse input processing. A window that has captured the mouse receives all // mouse input, regardless of the position of the cursor, except when a mouse button is clicked // while the cursor hot spot is in the window of another thread. ReleaseCapture(); event.type = NUX_MOUSE_RELEASED; return 1; case 3: // move: default: // avoid compiler warning // MSWindows produces extra events even if mouse does not move, ignore them. // http://blogs.msdn.com/oldnewthing/archive/2003/10/01/55108.aspx: Why do I get spurious WM_MOUSEMOVE messages? if (event.x == pmx && event.y == pmy) return 1; pmx = event.x; pmy = event.y; // if (abs(event.x - px)>5 || abs(event.y - py)>5) // event.is_click = 0; event.type = NUX_MOUSE_MOVE; return 1; } return 0; } unsigned int GetModifierKeyState() { unsigned int state = 0; unsigned short r = 0; // For CapsLock, we don't want to know if the key is pressed Down or Up. // We really want to know the state of the the CapsLock: on(keyboard light is on) or off? r = GetKeyState(VK_CAPITAL); if (r & 1) state |= NUX_STATE_CAPS_LOCK; // For NumLock, we don't want to know if the key is pressed Down or Up. // We really want to know the state of the the NumLock: on(keyboard light is on) or off? r = GetKeyState(VK_NUMLOCK); if (r & 1) state |= NUX_STATE_NUMLOCK; r = GetKeyState(VK_SCROLL); if (r & 0x8000) state |= NUX_STATE_SCROLLLOCK; r = GetKeyState(VK_CONTROL); if (r & 0x8000) state |= NUX_STATE_CTRL; r = GetKeyState(VK_SHIFT); if (r & 0x8000) state |= NUX_STATE_SHIFT; r = GetKeyState(VK_MENU); if (r & 0x8000) state |= NUX_STATE_ALT; if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) &~1) { // WIN32 bug? GetKeyState returns garbage if the user hit the // meta key to pop up start menu. Sigh. if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) &~1) state |= NUX_STATE_SUPER; } return state; } //--------------------------------------------------------------------------------------------------------- bool GraphicsDisplay::GetSystemEvent(Event *event) { MSG msg; event_.Reset(); // Erase mouse event and mouse doubleclick states. Keep the mouse states. event_.mouse_state &= 0x0F000000; bool got_event; // Always set the second parameter of PeekMessage to NULL. Indeed, many services creates // windows on the program behalf. If pass the main window as filter, we will miss all the // messages from the other windows. // Same with GetMessage. if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // Is There A Message Waiting? If yes, remove it. { if (msg.message == NUX_THREADMSG_START_RENDERING) { m_PauseGraphicsRendering = false; MakeGLContextCurrent(true); } TranslateMessage(&msg); DispatchMessage(&msg); memcpy(event, &event_, sizeof(Event)); got_event = true; } else { memcpy(event, &event_, sizeof(Event)); got_event = false; } if (msg.message == WM_QUIT) { // Re-post the message that we retrieved so other modal loops will catch it. // See [Modality, part 3: The WM_QUIT message] http://blogs.msdn.com/oldnewthing/archive/2005/02/22/378018.aspx PostQuitMessage(msg.wParam); event_.type = NUX_TERMINATE_APP; memcpy(event, &event_, sizeof(Event)); } if (msg.message == -1) // error { event_.type = NUX_NO_EVENT; memcpy(event, &event_, sizeof(Event)); } return got_event; } void GraphicsDisplay::ProcessForeignWin32Event(HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, Event *event) { event_.Reset(); // Erase mouse event and mouse doubleclick states. Keep the mouse states. event_.mouse_state &= 0x0F000000; // Always set the second parameter of PeekMessage to NULL. Indeed, many services creates // windows on the program behalf. If pass the main window as filter, we will miss all the // messages from the other windows. // Same with GetMessage. ProcessWin32Event(hWnd, msg.message, wParam, lParam); memcpy(event, &event_, sizeof(Event)); if (msg.message != WM_QUIT) { // Re-post the message that we retrieved so other modal loops will catch it. // See [Modality, part 3: The WM_QUIT message] http://blogs.msdn.com/oldnewthing/archive/2005/02/22/378018.aspx PostQuitMessage(msg.wParam); event_.type = NUX_TERMINATE_APP; memcpy(event, &event_, sizeof(Event)); } if (msg.message == -1) // error { event_.type = NUX_NO_EVENT; memcpy(event, &event_, sizeof(Event)); } } const Event& GraphicsDisplay::GetCurrentEvent() const { return event_; } //--------------------------------------------------------------------------------------------------------- LRESULT CALLBACK WndProcManager(HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { // This creates a warning. It is a 64-bits compatibility issue. // When not in 64-bit you can disable the warning: // Project Properties --> C/C++ tab --> General --> Select "NO" for - Detect 64-bit Portability Issues. // See also GetWindowLongPtr GraphicsDisplay *GLWindow = reinterpret_cast (::GetWindowLongPtr(hWnd, GWLP_USERDATA)); if (GLWindow == 0) { switch(uMsg) { // These cases happens before GLWindow is set. So we must catch them here. case WM_NCCREATE: { // Non Client Area // WARNING: MUST RETURN TRUE TO CONTINUE WITH THE CREATION OF THE WINDOW // return TRUE; // WARNING: Continue with DefWindowProc if you want the title of the window to appears // or you have to set it yourself before returning true break; } case WM_CREATE: { // WARNING: MUST RETURN 0 TO CONTINUE WITH THE CREATION OF THE WINDOW return 0; } } return DefWindowProc(hWnd, uMsg, wParam, lParam); } return GLWindow->ProcessWin32Event(hWnd, uMsg, wParam, lParam); } LRESULT GraphicsDisplay::ProcessWin32Event(HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { switch(uMsg) { case WM_DESTROY: { nuxDebugMsg("[GraphicsDisplay::WndProc]: Window \"%s\" received WM_DESTROY message.", window_title_.c_str()); break; } case WM_CLOSE: { nuxDebugMsg("[GraphicsDisplay::WndProc]: Window \"%s\" received WM_CLOSE message.", window_title_.c_str()); // close? yes or no? PostQuitMessage(0); return 0; } case WM_PAINT: { ValidateRect(hWnd, NULL); // validate the surface to avoid receiving WM_PAINT continuously event_.type = NUX_WINDOW_DIRTY; break; } case WM_CAPTURECHANGED: { // The WM_CAPTURECHANGED message is sent to the window that is losing the mouse capture if ((HWND) lParam == hWnd) { // Cancel everything about the mouse state and send a NUX_WINDOW_EXIT_FOCUS message. event_.mouse_state = 0; //nuxDebugMsg("Windows Msg: WM_CAPTURECHANGED/NUX_WINDOW_EXIT_FOCUS"); return 0; } break; } case WM_ENTERSIZEMOVE: { return 0; } case WM_EXITSIZEMOVE: { RECT clientrect; GetClientRect( hWnd, &clientrect); event_.type = NUX_SIZE_CONFIGURATION; event_.width = clientrect.right - clientrect.left; event_.height = clientrect.bottom - clientrect.top; return 0; } case WM_SIZE: { RECT clientrect; GetClientRect( hWnd, &clientrect); event_.type = NUX_NO_EVENT; //NUX_SIZE_CONFIGURATION; event_.width = clientrect.right - clientrect.left; event_.height = clientrect.bottom - clientrect.top; //setViewPort(0, 0, clientrect.right - clientrect.left, clientrect.bottom - clientrect.top); window_size_.width = clientrect.right - clientrect.left; window_size_.height = clientrect.bottom - clientrect.top; if ((wParam == SIZE_MAXHIDE) || (wParam == SIZE_MINIMIZED)) { window_minimized_ = true; } else { window_minimized_ = false; } if ((wParam == SIZE_MAXIMIZED) || (wParam == SIZE_RESTORED)) { event_.type = NUX_SIZE_CONFIGURATION; } return 0; } case WM_SETFOCUS: { event_.type = NUX_WINDOW_ENTER_FOCUS; event_.mouse_state = 0; // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process(). // Because WM_SETFOCUS can happen with the mouse outside of the client area, we set x and y so that the mouse will be // outside of all widgets. A subsequent mouse down or mouse move event will set the correct values for x and y. event_.x = 0xFFFFFFFF; event_.y = 0xFFFFFFFF; event_.dx = 0; event_.dy = 0; event_.virtual_code = 0; //nuxDebugMsg("Windows Msg: WM_SETFOCUS/NUX_WINDOW_ENTER_FOCUS"); break; } case WM_KILLFOCUS: { event_.type = NUX_WINDOW_EXIT_FOCUS; event_.mouse_state = 0; // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process() event_.x = 0xFFFFFFFF; event_.y = 0xFFFFFFFF; event_.dx = 0; event_.dy = 0; event_.virtual_code = 0; //nuxDebugMsg("Windows Msg: WM_KILLFOCUS/NUX_WINDOW_EXIT_FOCUS"); break; } case WM_NCHITTEST: { break; } case WM_ACTIVATE: { if (LOWORD(wParam) != WA_INACTIVE) { event_.type = NUX_WINDOW_ENTER_FOCUS; } else { event_.type = NUX_WINDOW_EXIT_FOCUS; } event_.mouse_state = 0; // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process(). // Because WM_SETFOCUS can happen with the mouse outside of the client area, we set x and y so that the mouse will be // outside of all widgets. A subsequent mouse down or mouse move event will set the correct values for x and y. event_.x = 0xFFFFFFFF; event_.y = 0xFFFFFFFF; event_.dx = 0; event_.dy = 0; event_.virtual_code = 0; event_.key_modifiers = GetModifierKeyState(); return 0; } case WM_ACTIVATEAPP: { if (wParam) { event_.type = NUX_WINDOW_ENTER_FOCUS; } else { event_.type = NUX_WINDOW_EXIT_FOCUS; } event_.mouse_state = 0; // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process(). // Because WM_SETFOCUS can happen with the mouse outside of the client area, we set x and y so that the mouse will be // outside of all widgets. A subsequent mouse down or mouse move event will set the correct values for x and y. event_.x = 0xFFFFFFFF; event_.y = 0xFFFFFFFF; event_.dx = 0; event_.dy = 0; event_.virtual_code = 0; event_.key_modifiers = GetModifierKeyState(); return 0; } case WM_SYSKEYDOWN: case WM_KEYDOWN: { event_.type = NUX_KEYDOWN; event_.key_modifiers = GetModifierKeyState(); event_.win32_keysym = wParam; if ((uMsg == WM_KEYDOWN) || (uMsg == WM_SYSKEYDOWN)) { event_.VirtualKeycodeState[GraphicsDisplay::Win32KeySymToINL(wParam) ] = 1; } if (wParam == VK_CONTROL) { if (lParam & (1 << 24)) { event_.win32_keysym = NUX_VK_RCONTROL; } else { event_.win32_keysym = NUX_VK_LCONTROL; } } if (wParam == VK_MENU) { if (lParam & (1 << 24)) { event_.win32_keysym = NUX_VK_RALT; } else { event_.win32_keysym = NUX_VK_LALT; } } if (wParam == VK_SHIFT) { if (HIWORD(GetAsyncKeyState(VK_LSHIFT))) { event_.win32_keysym = NUX_VK_LSHIFT; } else if (HIWORD(GetAsyncKeyState(VK_RSHIFT))) { event_.win32_keysym = NUX_VK_RSHIFT; } } break; } case WM_SYSKEYUP: case WM_KEYUP: { event_.type = NUX_KEYUP; event_.key_modifiers = GetModifierKeyState(); event_.win32_keysym = wParam; if ((uMsg == WM_KEYUP) || (uMsg == WM_SYSKEYUP)) { event_.VirtualKeycodeState[GraphicsDisplay::Win32KeySymToINL(wParam) ] = 0; } break; } case WM_DEADCHAR: case WM_SYSDEADCHAR: case WM_CHAR: case WM_SYSCHAR: { event_.key_modifiers = GetModifierKeyState(); // reset key repeat count to 0. event_.key_repeat_count = 0; if (lParam & (1 << 31)) { // key up events. event_.type = NUX_KEYUP; return 0; } else { // key down events. event_.type = NUX_KEYDOWN; event_.key_repeat_count = (int) (lParam & 0xff); } if ((wParam == '\b') || // backspace (wParam == '\t') || // tab (wParam == '\n') || // linefeed (wParam == '\r')) // carriage return { return 0; } wchar_t *utf16_str = new wchar_t [4]; std::memset(utf16_str, 0, sizeof(wchar_t) * 4); std::memcpy(utf16_str, (int*) &wParam, sizeof(wParam)); wchar_t *temp0 = utf16_str; unsigned char *utf8_str = new unsigned char [NUX_EVENT_TEXT_BUFFER_SIZE]; std::memset(utf8_str, 0, sizeof(unsigned char) * NUX_EVENT_TEXT_BUFFER_SIZE); unsigned char *temp1 = utf8_str; ConversionResult res = ConvertUTF16toUTF8((const wchar_t **) &temp0, utf16_str + sizeof(wchar_t) * 4, &temp1, utf8_str + NUX_EVENT_TEXT_BUFFER_SIZE, lenientConversion); if (res == conversionOK) { std::memcpy(event_.text, utf8_str, NUX_EVENT_TEXT_BUFFER_SIZE); } delete utf8_str; delete utf16_str; return 0; } case WM_UNICHAR: { if (wParam == UNICODE_NOCHAR) return 1; event_.key_modifiers = GetModifierKeyState(); // reset key repeat count to 0. event_.key_repeat_count = 0; if (lParam & (1 << 31)) { // key up events. event_.type = NUX_KEYUP; return 0; } else { // key down events. event_.type = NUX_KEYDOWN; event_.key_repeat_count = (int) (lParam & 0xff); } unsigned int *utf32_str = new unsigned int [4]; std::memset(utf32_str, 0, sizeof(unsigned int) * 4); std::memcpy(utf32_str, (int*) &wParam, sizeof(wParam)); unsigned int *temp0 = utf32_str; unsigned char *utf8_str = new unsigned char [NUX_EVENT_TEXT_BUFFER_SIZE]; std::memset(utf8_str, 0, sizeof(unsigned char) * NUX_EVENT_TEXT_BUFFER_SIZE); unsigned char *temp1 = utf8_str; ConversionResult res = ConvertUTF32toUTF8((const unsigned int**) &temp0, utf32_str + sizeof(unsigned int) * 4, &temp1, utf8_str + NUX_EVENT_TEXT_BUFFER_SIZE, lenientConversion); if (res == conversionOK) { std::memcpy(event_.text, utf8_str, NUX_EVENT_TEXT_BUFFER_SIZE); } delete utf8_str; delete utf32_str; } case WM_LBUTTONDOWN: { InspectMouseEvent(hWnd, event_, 0, 1, wParam, lParam); //nuxDebugMsg("Windows Msg: WM_LBUTTONDOWN"); return 0; } case WM_LBUTTONDBLCLK: { InspectMouseEvent(hWnd, event_, 1, 1, wParam, lParam); //nuxDebugMsg("Windows Msg: WM_LBUTTONDBLCLK"); return 0; } case WM_LBUTTONUP: { InspectMouseEvent(hWnd, event_, 2, 1, wParam, lParam); //nuxDebugMsg("Windows Msg: WM_LBUTTONUP"); return 0; } case WM_MBUTTONDOWN: { InspectMouseEvent(hWnd, event_, 0, 2, wParam, lParam); break; } case WM_MBUTTONDBLCLK: { InspectMouseEvent(hWnd, event_, 1, 2, wParam, lParam); break; } case WM_MBUTTONUP: { InspectMouseEvent(hWnd, event_, 2, 2, wParam, lParam); break; } case WM_RBUTTONDOWN: { InspectMouseEvent(hWnd, event_, 0, 3, wParam, lParam); break; } case WM_RBUTTONDBLCLK: { InspectMouseEvent(hWnd, event_, 1, 3, wParam, lParam); break; } case WM_RBUTTONUP: { InspectMouseEvent(hWnd, event_, 2, 3, wParam, lParam); break; } case WM_MOUSEWHEEL: { InspectMouseEvent(hWnd, event_, 0, 4, wParam, lParam); break; } case WM_NCLBUTTONDBLCLK: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCLBUTTONDOWN: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCLBUTTONUP: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCMBUTTONDBLCLK: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCMBUTTONDOWN: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCMBUTTONUP: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCRBUTTONDBLCLK: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCRBUTTONDOWN: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_NCRBUTTONUP: { event_.type = NUX_NC_WINDOW_CONFIGURATION; break; } case WM_MOUSEMOVE: { InspectMouseEvent(hWnd, event_, 3, 0, wParam, lParam); //nuxDebugMsg("Windows Msg: WM_MOUSEMOVE"); TRACKMOUSEEVENT tme = { sizeof(tme) }; // Enable NUX_WINDOW_MOUSELEAVE event. tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); break; } // Note: there is no WM_MOUSEENTER. WM_MOUSEENTER is equivalent to WM_MOUSEMOVE after a WM_MOUSELEAVE. case WM_MOUSELEAVE: { // All tracking requested by TrackMouseEvent is canceled when this message is generated. // The application must call TrackMouseEvent when the mouse reenters its window if // it requires further tracking of mouse hover behavior. event_.type = NUX_WINDOW_MOUSELEAVE; // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process() event_.x = 0xFFFFFFFF; event_.y = 0xFFFFFFFF; //nuxDebugMsg("Windows Msg: WM_MOUSELEAVE/NUX_WINDOW_MOUSELEAVE"); break; } case WM_SETCURSOR: if ((LOWORD(lParam) == HTCLIENT) && cursor_) { SetCursor(cursor_); return TRUE; //return FALSE; } else break; case WM_COMMAND: { nuxDebugMsg("[GraphicsDisplay::WndProc]: Window \"%s\" received WM_COMMAND message.", window_title_.c_str()); break;; } case WM_SYSCOMMAND: // Intercept System Commands { switch(wParam) // Check System Calls { case SC_CLOSE: break; case SC_CONTEXTHELP: break; case SC_DEFAULT: break; case SC_HOTKEY: break; case SC_HSCROLL: break; case SC_KEYMENU: break; case SC_MAXIMIZE: break; case SC_MINIMIZE: break; case SC_MONITORPOWER: break; case SC_MOUSEMENU: break; case SC_MOVE: break; case SC_NEXTWINDOW: break; case SC_PREVWINDOW: break; case SC_RESTORE: break; case SC_SCREENSAVE: break; case SC_SIZE: break; case SC_TASKLIST: break; case SC_VSCROLL: break; } break; // Exit } } return DefWindowProc(hWnd, uMsg, wParam, lParam); } int GraphicsDisplay::Win32VKToNuxKey(int vk) { switch(vk) { case VK_CANCEL: return NUX_VK_CANCEL; case VK_BACK: return NUX_VK_BACKSPACE; case VK_TAB: return NUX_VK_TAB; case VK_CLEAR: return NUX_VK_CLEAR; case VK_RETURN: return NUX_VK_ENTER; case VK_SHIFT: return NUX_VK_SHIFT; case VK_CONTROL: return NUX_VK_LCONTROL; case VK_LCONTROL: return NUX_VK_LCONTROL; case VK_RCONTROL: return NUX_VK_RCONTROL; case VK_MENU: return NUX_VK_LALT; case VK_LMENU: return NUX_VK_LALT; case VK_RMENU: return NUX_VK_RALT; case VK_PAUSE: return NUX_VK_PAUSE; case VK_CAPITAL: return NUX_VK_CAPITAL; case VK_ESCAPE: return NUX_VK_ESCAPE; case VK_PRIOR: return NUX_VK_PAGE_UP; case VK_NEXT: return NUX_VK_PAGE_DOWN; case VK_END: return NUX_VK_END; case VK_HOME: return NUX_VK_HOME; case VK_LEFT: return NUX_VK_LEFT; case VK_UP: return NUX_VK_UP; case VK_RIGHT: return NUX_VK_RIGHT; case VK_DOWN: return NUX_VK_DOWN; case VK_INSERT: return NUX_VK_INSERT; case VK_DELETE: return NUX_VK_DELETE; case 0x30: return NUX_VK_0; case 0x31: return NUX_VK_1; case 0x32: return NUX_VK_2; case 0x33: return NUX_VK_3; case 0x34: return NUX_VK_4; case 0x35: return NUX_VK_5; case 0x36: return NUX_VK_6; case 0x37: return NUX_VK_7; case 0x38: return NUX_VK_8; case 0x39: return NUX_VK_9; case 0x41: return NUX_VK_A; case 0x42: return NUX_VK_B; case 0x43: return NUX_VK_C; case 0x44: return NUX_VK_D; case 0x45: return NUX_VK_E; case 0x46: return NUX_VK_F; case 0x47: return NUX_VK_G; case 0x48: return NUX_VK_H; case 0x49: return NUX_VK_I; case 0x4A: return NUX_VK_J; case 0x4B: return NUX_VK_K; case 0x4C: return NUX_VK_L; case 0x4D: return NUX_VK_M; case 0x4E: return NUX_VK_N; case 0x4F: return NUX_VK_O; case 0x50: return NUX_VK_P; case 0x51: return NUX_VK_Q; case 0x52: return NUX_VK_R; case 0x53: return NUX_VK_S; case 0x54: return NUX_VK_T; case 0x55: return NUX_VK_U; case 0x56: return NUX_VK_V; case 0x57: return NUX_VK_W; case 0x58: return NUX_VK_X; case 0x59: return NUX_VK_Y; case 0x5A: return NUX_VK_Z; case VK_LWIN: return NUX_VK_LSUPER; // Windows key left case VK_RWIN: return NUX_VK_RSUPER; // Windows key right case VK_NUMLOCK: return NUX_VK_NUMLOCK; case VK_SCROLL: return NUX_VK_SCROLL; case VK_LSHIFT: return NUX_VK_LSHIFT; case VK_RSHIFT: return NUX_VK_RSHIFT; case VK_NUMPAD0: return NUX_KP_0; case VK_NUMPAD1: return NUX_KP_1; case VK_NUMPAD2: return NUX_KP_2; case VK_NUMPAD3: return NUX_KP_3; case VK_NUMPAD4: return NUX_KP_4; case VK_NUMPAD5: return NUX_KP_5; case VK_NUMPAD6: return NUX_KP_6; case VK_NUMPAD7: return NUX_KP_7; case VK_NUMPAD8: return NUX_KP_8; case VK_NUMPAD9: return NUX_KP_9; case VK_MULTIPLY: return NUX_KP_MULTIPLY; case VK_ADD: return NUX_KP_ADD; case VK_SEPARATOR: return NUX_KP_SEPARATOR; case VK_SUBTRACT: return NUX_VK_SUBTRACT; case VK_DECIMAL: return NUX_VK_DECIMAL; case VK_DIVIDE: return NUX_VK_SLASH; case VK_F1: return NUX_VK_F1; case VK_F2: return NUX_VK_F2; case VK_F3: return NUX_VK_F3; case VK_F4: return NUX_VK_F4; case VK_F5: return NUX_VK_F5; case VK_F6: return NUX_VK_F6; case VK_F7: return NUX_VK_F7; case VK_F8: return NUX_VK_F8; case VK_F9: return NUX_VK_F9; case VK_F10: return NUX_VK_F10; case VK_F11: return NUX_VK_F11; case VK_F12: return NUX_VK_F12; case VK_F13: return NUX_VK_F13; case VK_F14: return NUX_VK_F14; case VK_F15: return NUX_VK_F15; case VK_F16: return NUX_VK_F16; case VK_F17: return NUX_VK_F17; case VK_F18: return NUX_VK_F18; case VK_F19: return NUX_VK_F19; case VK_F20: return NUX_VK_F20; case VK_F21: return NUX_VK_F21; case VK_F22: return NUX_VK_F22; case VK_F23: return NUX_VK_F23; case VK_F24: return NUX_VK_F24; default: return 0x0; } } int GraphicsDisplay::Win32KeySymToINL(int Keysym) { return Keysym; // switch(Keysym) // { // case VK_CANCEL: // return NUX_VK_CANCEL; // case VK_BACK: // return NUX_VK_BACKSPACE; // case VK_TAB: // return NUX_VK_TAB; // case VK_CLEAR: // return NUX_VK_CLEAR; // case VK_RETURN: // return NUX_VK_ENTER; // case VK_SHIFT: // return NUX_VK_SHIFT; // case VK_CONTROL: // return NUX_VK_CONTROL; // case VK_MENU: // return NUX_VK_MENU; // ALT key // case VK_PAUSE: // return NUX_VK_PAUSE; // case VK_CAPITAL: // return NUX_VK_CAPITAL; // case VK_ESCAPE: // return NUX_VK_ESCAPE; // case VK_SPACE: // return NUX_VK_SPACE; // case VK_PRIOR: // return NUX_VK_PAGE_UP; // case VK_NEXT: // return NUX_VK_PAGE_DOWN; // case VK_END: // return NUX_VK_END; // case VK_HOME: // return NUX_VK_HOME; // case VK_LEFT: // return NUX_VK_LEFT; // case VK_UP: // return NUX_VK_UP; // case VK_RIGHT: // return NUX_VK_RIGHT; // case VK_DOWN: // return NUX_VK_DOWN; // case VK_SELECT: // return NUX_VK_SELECT; // case VK_PRINT: // return NUX_VK_PRINT; // case VK_EXECUTE: // return NUX_VK_EXECUTE; // case VK_INSERT: // return NUX_VK_INSERT; // case VK_DELETE: // return NUX_VK_DELETE; // case VK_HELP: // return NUX_VK_HELP; // case 0x30: // return NUX_VK_0; // case 0x31: // return NUX_VK_1; // case 0x32: // return NUX_VK_2; // case 0x33: // return NUX_VK_3; // case 0x34: // return NUX_VK_4; // case 0x35: // return NUX_VK_5; // case 0x36: // return NUX_VK_6; // case 0x37: // return NUX_VK_7; // case 0x38: // return NUX_VK_8; // case 0x39: // return NUX_VK_9; // case 0x41: // return NUX_VK_A; // case 0x42: // return NUX_VK_B; // case 0x43: // return NUX_VK_C; // case 0x44: // return NUX_VK_D; // case 0x45: // return NUX_VK_E; // case 0x46: // return NUX_VK_F; // case 0x47: // return NUX_VK_G; // case 0x48: // return NUX_VK_H; // case 0x49: // return NUX_VK_I; // case 0x4A: // return NUX_VK_J; // case 0x4B: // return NUX_VK_K; // case 0x4C: // return NUX_VK_L; // case 0x4D: // return NUX_VK_M; // case 0x4E: // return NUX_VK_N; // case 0x4F: // return NUX_VK_O; // case 0x50: // return NUX_VK_P; // case 0x51: // return NUX_VK_Q; // case 0x52: // return NUX_VK_R; // case 0x53: // return NUX_VK_S; // case 0x54: // return NUX_VK_T; // case 0x55: // return NUX_VK_U; // case 0x56: // return NUX_VK_V; // case 0x57: // return NUX_VK_W; // case 0x58: // return NUX_VK_X; // case 0x59: // return NUX_VK_Y; // case 0x5A: // return NUX_VK_Z; // case VK_LWIN: // return NUX_VK_LWIN; // Windows key left // case VK_RWIN: // return NUX_VK_RWIN; // Windows key right // case VK_NUMPAD0: // return NUX_VK_NUMPAD0; // case VK_NUMPAD1: // return NUX_VK_NUMPAD1; // case VK_NUMPAD2: // return NUX_VK_NUMPAD2; // case VK_NUMPAD3: // return NUX_VK_NUMPAD3; // case VK_NUMPAD4: // return NUX_VK_NUMPAD4; // case VK_NUMPAD5: // return NUX_VK_NUMPAD5; // case VK_NUMPAD6: // return NUX_VK_NUMPAD6; // case VK_NUMPAD7: // return NUX_VK_NUMPAD7; // case VK_NUMPAD8: // return NUX_VK_NUMPAD8; // case VK_NUMPAD9: // return NUX_VK_NUMPAD9; // case VK_MULTIPLY: // return NUX_VK_MULTIPLY; // case VK_ADD: // return NUX_VK_ADD; // case VK_SEPARATOR: // return NUX_VK_SEPARATOR; // case VK_SUBTRACT: // return NUX_VK_SUBTRACT; // case VK_DECIMAL: // return NUX_VK_DECIMAL; // case VK_DIVIDE: // return NUX_VK_DIVIDE; // case VK_F1: // return NUX_VK_F1; // case VK_F2: // return NUX_VK_F2; // case VK_F3: // return NUX_VK_F3; // case VK_F4: // return NUX_VK_F4; // case VK_F5: // return NUX_VK_F5; // case VK_F6: // return NUX_VK_F6; // case VK_F7: // return NUX_VK_F7; // case VK_F8: // return NUX_VK_F8; // case VK_F9: // return NUX_VK_F9; // case VK_F10: // return NUX_VK_F10; // case VK_F11: // return NUX_VK_F11; // case VK_F12: // return NUX_VK_F12; // case VK_F13: // return NUX_VK_F13; // case VK_F14: // return NUX_VK_F14; // case VK_F15: // return NUX_VK_F15; // case VK_F16: // return NUX_VK_F16; // case VK_F17: // return NUX_VK_F17; // case VK_F18: // return NUX_VK_F18; // case VK_F19: // return NUX_VK_F19; // case VK_F20: // return NUX_VK_F20; // case VK_F21: // return NUX_VK_F21; // case VK_F22: // return NUX_VK_F22; // case VK_F23: // return NUX_VK_F23; // case VK_F24: // return NUX_VK_F24; // case VK_NUMLOCK: // return NUX_VK_NUMLOCK; // case VK_SCROLL: // return NUX_VK_SCROLL; // case VK_LSHIFT: // return NUX_VK_LSHIFT; // case VK_RSHIFT: // return NUX_VK_RSHIFT; // case VK_LCONTROL: // return NUX_VK_LCONTROL; // case VK_RCONTROL: // return NUX_VK_RCONTROL; // case VK_LMENU: // return NUX_VK_LMENU; // case VK_RMENU: // return NUX_VK_RMENU; // default: // return 0x0; // } } void GraphicsDisplay::InitGlobalGrabWindow() { } bool GraphicsDisplay::GrabPointer(GrabReleaseCallback callback, void *data, bool replace_existing) { return false; } bool GraphicsDisplay::UngrabPointer(void *data) { return true; } bool GraphicsDisplay::PointerIsGrabbed() { return false; } bool GraphicsDisplay::GrabKeyboard(GrabReleaseCallback callback, void *data, bool replace_existing) { return _global_keyboard_grab_active; } bool GraphicsDisplay::UngrabKeyboard(void *data) { return true; } bool GraphicsDisplay::KeyboardIsGrabbed() { return _global_keyboard_grab_active; } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::GetDisplayInfo() { DEVMODE devmode; INT iMode = 0; BOOL bRetVal; DeviceModes dm; m_num_gfx_device_modes = 0; do { bRetVal = ::EnumDisplaySettings(NULL, iMode, &devmode); iMode++; if (bRetVal) { dm.width = devmode.dmPelsWidth; dm.height = devmode.dmPelsHeight; dm.format = devmode.dmBitsPerPel; dm.refresh_rate = devmode.dmDisplayFrequency; m_gfx_device_modes.push_back(dm); m_num_gfx_device_modes++; } } while (bRetVal); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::ShowWindow() { ::ShowWindow(wnd_handle_, SW_SHOW); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::HideWindow() { ::ShowWindow(wnd_handle_, SW_HIDE); } bool GraphicsDisplay::IsWindowVisible() { return ::IsWindowVisible(wnd_handle_); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::EnterMaximizeWindow() { ::ShowWindow(wnd_handle_, SW_MAXIMIZE); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::ExitMaximizeWindow() { ::ShowWindow(wnd_handle_, SW_RESTORE); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::SetWindowTitle(const char *Title) { SetWindowText(wnd_handle_, Title); } //--------------------------------------------------------------------------------------------------------- // NUXTODO: remove this call. Make a direct access to GpuInfo via GpuDevice. bool GraphicsDisplay::HasVSyncSwapControl() const { return GetGpuDevice()->GetGpuInfo().Support_EXT_Swap_Control(); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::EnableVSyncSwapControl() { if (HasVSyncSwapControl()) { wglSwapIntervalEXT(1); } } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::DisableVSyncSwapControl() { if (HasVSyncSwapControl()) { wglSwapIntervalEXT(0); } } float GraphicsDisplay::GetFrameTime() const { return m_FrameTime; } void GraphicsDisplay::ResetFrameTime() { m_Timer.Reset(); } bool GraphicsDisplay::StartOpenFileDialog(FileDialogOption &fdo) { return Win32OpenFileDialog(GetWindowHandle(), fdo); } bool GraphicsDisplay::StartSaveFileDialog(FileDialogOption &fdo) { return Win32SaveFileDialog(GetWindowHandle(), fdo); } bool GraphicsDisplay::StartColorDialog(ColorDialogOption &cdo) { return Win32ColorDialog(GetWindowHandle(), cdo); } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::SetWindowCursor(HCURSOR cursor) { cursor_ = cursor; } //--------------------------------------------------------------------------------------------------------- HCURSOR GraphicsDisplay::GetWindowCursor() const { return cursor_; } //--------------------------------------------------------------------------------------------------------- void GraphicsDisplay::PauseThreadGraphicsRendering() { m_PauseGraphicsRendering = true; MakeGLContextCurrent(false); } //--------------------------------------------------------------------------------------------------------- bool GraphicsDisplay::IsPauseThreadGraphicsRendering() const { return m_PauseGraphicsRendering; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLQuery.cpp0000644000015301777760000000743412321344237022167 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLQuery.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLQuery); unsigned int IOpenGLQuery::_CurrentlyActiveQuery = 0; IOpenGLQuery::IOpenGLQuery(QUERY_TYPE Type) : IOpenGLResource(RTQUERY) , _Type(Type) , _QueryStarted(false) { #ifndef NUX_OPENGLES_20 CHECKGL(glGenQueriesARB(1, &_OpenGLID)) ; #endif } // The return type identifies the query state(see Queries). // The method returns 1(S_OK) if the query data is available and 0(S_FALSE) if it is not. // These are considered successful return values. int IOpenGLQuery::GetData( int *pData, unsigned int /* Size */, unsigned int /* GetDataFlags */ ) { #ifndef NUX_OPENGLES_20 unsigned int ResultReady = 0; glGetQueryObjectuivARB(_OpenGLID, GL_QUERY_RESULT_AVAILABLE_ARB, &ResultReady); CHECKGL_MSG( glGetQueryObjectuivARB ); if (ResultReady) { glGetQueryObjectuivARB(_OpenGLID, GL_QUERY_RESULT_ARB, (GLuint *) pData); CHECKGL_MSG( glGetQueryObjectuivARB ); return 1; } #endif return 0; } unsigned int IOpenGLQuery::GetDataSize() { return 0; } void IOpenGLQuery::GetDevice(GpuDevice **ppDevice) { // Do not call this function. *ppDevice = NULL; } QUERY_TYPE IOpenGLQuery::GetType() { return _Type; } void IOpenGLQuery::Issue( unsigned int IssueFlags ) { #ifndef NUX_OPENGLES_20 if (IssueFlags == (unsigned int) ISSUE_BEGIN) { nuxAssert(_CurrentlyActiveQuery == 0); if (_QueryStarted == true) { nuxError("The Query as already been activated"); } else { _QueryStarted = true; CHECKGL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, _OpenGLID)); _CurrentlyActiveQuery = _OpenGLID; } } else if (IssueFlags == (unsigned int) ISSUE_END) { nuxAssert(_CurrentlyActiveQuery == _OpenGLID); if (_QueryStarted == false) { nuxError("The Query as already been stoped"); } else { _QueryStarted = false; CHECKGL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); _CurrentlyActiveQuery = 0; } } #endif } // Return True is the result is available. That is glGetQueryObjectuivARB won't block // if called with GL_QUERY_RESULT_ARB. bool IOpenGLQuery::IsResultAvailable() { unsigned int ResultReady = 0; #ifndef NUX_OPENGLES_20 glGetQueryObjectuivARB(_OpenGLID, GL_QUERY_RESULT_AVAILABLE_ARB, &ResultReady); CHECKGL_MSG( glGetQueryObjectuivARB ); #endif return ResultReady != 0; } // Return the result of the query. Make sure IsResultAvailable returned TRUE before calling this function. // If you fail to do that, GetResult will block before returning. unsigned int IOpenGLQuery::GetResult() { unsigned int SamplesPassed = 0; #ifndef NUX_OPENGLES_20 glGetQueryObjectuivARB(_OpenGLID, GL_QUERY_RESULT_ARB, &SamplesPassed); CHECKGL_MSG( glGetQueryObjectuivARB ); #endif return SamplesPassed; } } nux-4.0.6+14.04.20140409/NuxGraphics/OpenGLMapping.h0000644000015301777760000001142012321344237021777 0ustar pbusernogroup00000000000000/* * Copyright 2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Travis Watkins * */ // A series of defines to map GL functions to GLES functions #ifndef OPENGLMAPPING_H #define OPENGLMAPPING_H #define GL_GLEXT_PROTOTYPES #define GLcharARB GLchar #define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0 #define GL_DEPTH_ATTACHMENT_EXT GL_DEPTH_ATTACHMENT #define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER #define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING #define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS #define GL_FRAMEBUFFER_UNSUPPORTED_EXT GL_FRAMEBUFFER_UNSUPPORTED #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL #define GL_RENDERBUFFER_EXT GL_RENDERBUFFER #define GL_RENDERBUFFER_BINDING_EXT GL_RENDERBUFFER_BINDING #define GL_MAX_RENDERBUFFER_SIZE_EXT GL_MAX_RENDERBUFFER_SIZE #define GL_ARRAY_BUFFER_ARB GL_ARRAY_BUFFER #define GL_ELEMENT_ARRAY_BUFFER_ARB GL_ELEMENT_ARRAY_BUFFER // not sure if this will work in all cases #define GL_CLAMP GL_CLAMP_TO_EDGE // needs extra shader code but otherwise is equivalent #define GL_CLAMP_TO_BORDER GL_CLAMP_TO_EDGE #define GL_WRITE_ONLY_ARB GL_WRITE_ONLY_OES #define GL_VERTEX_SHADER_ARB GL_VERTEX_SHADER #define GL_FRAGMENT_SHADER_ARB GL_FRAGMENT_SHADER #define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB GL_ACTIVE_ATTRIBUTES #define glActiveTextureARB glActiveTexture #define glGenBuffersARB glGenBuffers #define glDeleteBuffersARB glDeleteBuffers #define glBindBufferARB glBindBuffer #define glBufferDataARB glBufferData #define glMapBufferARB glMapBufferOES #define glUnmapBufferARB glUnmapBufferOES #define glBindBufferARB glBindBuffer #define glEnableVertexAttribArrayARB glEnableVertexAttribArray #define glDisableVertexAttribArrayARB glDisableVertexAttribArray #define glVertexAttribPointerARB glVertexAttribPointer #define glDeleteFramebuffersEXT glDeleteFramebuffers #define glBindFramebufferEXT glBindFramebuffer #define glGenFramebuffersEXT glGenFramebuffers #define glFramebufferTexture2DEXT glFramebufferTexture2D #define glCheckFramebufferStatusEXT glCheckFramebufferStatus #define glGetFramebufferAttachmentParameterivEXT glGetFramebufferAttachmentParameteriv #define glFramebufferRenderbufferEXT glFramebufferRenderbuffer #define glBindRenderbufferEXT glBindRenderbuffer #define glRenderbufferStorageEXT glRenderbufferStorage #define glGenRenderbuffersEXT glGenRenderbuffers #define glDeleteRenderbuffersEXT glDeleteRenderbuffers #define glUseProgramObjectARB glUseProgram #define glGetObjectParameteriv glGetProgramiv #define glUniform1iARB glUniform1i #define glUniform2iARB glUniform2i #define glUniform3iARB glUniform3i #define glUniform4iARB glUniform4i #define glUniform1ivARB glUniform1iv #define glUniform2ivARB glUniform2iv #define glUniform3ivARB glUniform3iv #define glUniform4ivARB glUniform4iv #define glUniform1fARB glUniform1f #define glUniform2fARB glUniform2f #define glUniform3fARB glUniform3f #define glUniform4fARB glUniform4f #define glUniform1fvARB glUniform1fv #define glUniform2fvARB glUniform2fv #define glUniform3fvARB glUniform3fv #define glUniform4fvARB glUniform4fv #define glGetUniformfvARB glGetUniformfv #define glGetUniformivARB glGetUniformiv #define glUniformMatrix2fvARB glUniformMatrix2fv #define glUniformMatrix3fvARB glUniformMatrix3fv #define glUniformMatrix4fvARB glUniformMatrix4fv #define glGetActiveAttribARB glGetActiveAttrib #define glGetActiveUniformARB glGetActiveUniform #define glGetObjectParameterivARB glGetObjectParameteriv #define glGetUniformLocationARB glGetUniformLocation #define glGetAttribLocationARB glGetAttribLocation #define glDepthRange glDepthRangef #define glClearDepth glClearDepthf #endif // OPENGLMAPPING_H nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipeGLSL.h0000644000015301777760000000000012321344237022544 0ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLAnimatedTexture.h0000644000015301777760000000503512321344237023625 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLANIMATEDTEXTURE_H #define IOPENGLANIMATEDTEXTURE_H namespace nux { class IOpenGLBaseTexture; // Note that for Animated texture, the Depth value is the number of frames. // The number of mipmap levels is always 1; class IOpenGLAnimatedTexture: public IOpenGLBaseTexture { NUX_DECLARE_OBJECT_TYPE(IOpenGLAnimatedTexture, IOpenGLBaseTexture); public: virtual ~IOpenGLAnimatedTexture(); void GetSurfaceFrame(int Frame, ObjectPtr& surface); ObjectPtr GetSurfaceFrame(int Level); int LockRect( int Frame, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect); int UnlockRect( int Frame ); int GetDepth(int /* MipLevel */) const { return _Depth; } int GetDesc(ANIMATEDTEXTURE_DESC *pDesc) { pDesc->Width = Max (1, _Width); pDesc->Height = Max (1, _Height); pDesc->Depth = _Depth; pDesc->PixelFormat = _PixelFormat; pDesc->Type = _ResourceType; return OGL_OK; } void PresentFirstFrame(); void PresentNextFrame(); void PresentLastFrame(); int GetFrameTime(); unsigned int GetNumFrame(); void SetFrameTime(int Frame, int time_ms); private: IOpenGLAnimatedTexture( int Width , int Height , int Depth , BitmapFormat PixelFormat); // unsigned int _Width; // unsigned int _Height; // unsigned int _Depth; //std::vector _VolumeArray; int _CurrentFrame; std::vector< ObjectPtr > _FrameTextureArray; std::vector< int > _FrameTimeArray; friend class GpuDevice; friend class IOpenGLSurface; }; } #endif // IOPENGLANIMATEDTEXTURE_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLCubeTexture.h0000644000015301777760000000465712321344237022772 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLCUBETEXTURE_H #define IOPENGLCUBETEXTURE_H namespace nux { class IOpenGLBaseTexture; class IOpenGLCubeTexture: public IOpenGLBaseTexture { NUX_DECLARE_OBJECT_TYPE(IOpenGLCubeTexture, IOpenGLBaseTexture); public: virtual ~IOpenGLCubeTexture(); int GetCubeMapSurface( eCUBEMAP_FACES FaceType, int Level, IOpenGLSurface **ppCubeMapSurface ); int CubeLockRect( eCUBEMAP_FACES FaceType, int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect); int CubeUnlockRect( eCUBEMAP_FACES FaceType, int Level ); unsigned int EnableGammaCorrection(bool b); int GetLevelDesc( int Level, SURFACE_DESC *pDesc ) { nuxAssert(Level >= 0 ); nuxAssert(Level < _NumMipLevel); if ((Level < 0) || (Level > _NumMipLevel)) { pDesc->Width = 0; pDesc->Height = 0; pDesc->PixelFormat = BITFMT_UNKNOWN; pDesc->Type = _ResourceType; } else { pDesc->Width = Max (1, _Width >> Level); pDesc->Height = Max (1, _Height >> Level); pDesc->PixelFormat = _PixelFormat; pDesc->Type = _ResourceType; } return OGL_OK; } private: IOpenGLCubeTexture( unsigned int EdgeLength , int Levels , BitmapFormat PixelFormat); // unsigned int _Width; // unsigned int _Height; std::map* > _SurfaceArray; friend class GpuDevice; friend class IOpenGLSurface; }; } #endif // IOPENGLCUBETEXTURE_H nux-4.0.6+14.04.20140409/NuxGraphics/GraphicsDisplayWin.h0000755000015301777760000002261512321344237023116 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GRAPHICSDISPLAYWIN_H #define GRAPHICSDISPLAYWIN_H #include "Gfx_Interface.h" #include "GLTimer.h" #include "GLDeviceObjects.h" #include "GLRenderStates.h" #include #include #include #include "Wincodec.h" namespace nux { class Event; class MainFBO; class GpuDevice; class GraphicsEngine; class IOpenGLFrameBufferObject; enum WindowStyle { WINDOWSTYLE_NORMAL, WINDOWSTYLE_PANEL, WINDOWSTYLE_DIALOG, WINDOWSTYLE_TOOL, WINDOWSTYLE_NOBORDER, }; #define NUX_THREADMSG (WM_APP+0) #define NUX_THREADMSG_START_RENDERING (WM_APP+1) // Connection established // start at WM_APP #define NUX_THREADMSG_CHILD_WINDOW_TERMINATED (WM_APP+2) // General failure - Wait Connection failed #define NUX_THREADMSG_THREAD_TERMINATED (WM_APP+3) // Set wParam = Thread ID, lParam = 0 // This will become GLWindow class GraphicsDisplay : public GraphicSystem { friend class GraphicsEngine; private: // WIN32 system variables HGLRC opengl_rendering_context_; //!< OpenGL Rendering Context. HDC device_context_; //!< Device Context. HWND wnd_handle_; //!< Window Handle. HWND parent_window_; //!< Parent window Handle. GLuint pixel_format_; //!< Holds The Results After Searching For A Match DWORD window_extended_style_; //!< Window Extended Style DWORD window_style_; //!< Window Style std::string window_title_; static HGLRC sMainGLRC; // Used as the first argument of wglShareLists to make all successive OpenGL context share their objects static HDC sMainDC; // Used as the first argument of wglShareLists to make all successive OpenGL context share their objects ID2D1Factory* d2d_factory_; IDWriteFactory* dw_factory_; IWICImagingFactory* wic_factory_; Size viewport_size_; //!< Viewport size. Size window_size_; //!< Window size. //! Full screen mode. bool fullscreen_; //! Screen bit depth. unsigned int screen_bit_depth_; //! State of the graphics interface. bool gfx_interface_created_; // Device information void GetDisplayInfo(); bool window_minimized_; HCURSOR cursor_; //!< Windows Cursor. static int Win32KeySymToINL(int Keysym); static int Win32VKToNuxKey(int vk); public: //! Last Win32 event. Event event_; // Creation bool IsGfxInterfaceCreated(); //! Create a window with and OpenGL context. /*! @param WindowTitle The window title. @param WindowWidth Initial window width. @param WindowHeight Initial window height. @param Style The window style. @param ParentWindow The parent window. @param fullscreen_flag Full screen flag. */ bool CreateOpenGLWindow( const char *WindowTitle, unsigned int WindowWidth, unsigned int WindowHeight, WindowStyle Style, const GraphicsDisplay *Parent, bool fullscreen_flag = false, bool create_rendering_data = true); //! Create a GLWindow from a window and device context. /*! @param WindowHandle Provided window. @param WindowDCHandle Provided device context. @param OpenGLRenderingContext And OpenGL rendering context. */ bool CreateFromOpenGLWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext); void DestroyOpenGLWindow(); void SetWindowTitle(const char *Title); void SetWindowSize(int width, int height); void SetViewPort(int x, int y, int width, int height); Point GetMouseScreenCoord(); Point GetMouseWindowCoord(); Point GetWindowCoord(); Rect GetWindowGeometry(); Rect GetNCWindowGeometry(); void MakeGLContextCurrent(bool b = true); void SwapBuffer(bool glswap = true); // Event methods /*! Returns true if there was a pending event to be fetched and false otherwise */ bool GetSystemEvent(Event *evt); const Event& GetCurrentEvent() const; bool isWindowMinimized() const { return window_minimized_; } void ShowWindow(); void HideWindow(); bool IsWindowVisible(); void EnterMaximizeWindow(); void ExitMaximizeWindow(); HWND GetWindowHandle() const { return wnd_handle_; } HWND GetParentWindowHandle() const { return parent_window_; } HDC GetWindowHDC() const { return device_context_; } bool IsChildWindow() const { return parent_window_ != 0; } ID2D1Factory* GetDirect2DFactory(); IDWriteFactory* GetDirectWriteFactory(); IWICImagingFactory* GetWICFactory(); // Return true if VSync swap control is available bool HasVSyncSwapControl() const; void EnableVSyncSwapControl(); void DisableVSyncSwapControl(); // m_FrameRate float GetFrameTime() const; void ResetFrameTime(); GraphicsEngine *GetGraphicsEngine() const; GpuDevice *GetGpuDevice() const; // Dialog bool StartOpenFileDialog(FileDialogOption &fdo); bool StartSaveFileDialog(FileDialogOption &fdo); bool StartColorDialog(ColorDialogOption &cdo); void GetWindowSize(int &w, int &h); int GetWindowWidth(); int GetWindowHeight(); //! Get the window size and reset the GraphicsEngine and GpuDevice accordingly. /*! This is a passive way to set the window size through out the NuxGraphics system. This call gets the current window size and sets its accordingly to all sub-system. */ void ResetWindowSize(); bool HasFrameBufferSupport(); void SetWindowCursor(HCURSOR cursor); HCURSOR GetWindowCursor() const; void ProcessForeignWin32Event(HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, Event *event); LRESULT ProcessWin32Event(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam); //! Pause graphics rendering. /*! Pause graphics rendering. This function also sets the current openGL context to 0 for this window. This is useful while a child window is being created and is sharing openGL objects with this context. For wglShareLists to work, both OpenGL context must be set to 0 in their respective thread. Send NUX_THREADMSG_START_RENDERING(PostThreadMessage) to this window to reactivate rendering. Never call this function while doing rendering. Call it only when processing events. */ void PauseThreadGraphicsRendering(); bool IsPauseThreadGraphicsRendering() const; // Pointer and keyboard grab API typedef void(*GrabReleaseCallback) (bool replaced, void *user_data); bool GrabPointer (GrabReleaseCallback callback, void *data, bool replace_existing); bool UngrabPointer(void *data); bool PointerIsGrabbed(); bool GrabKeyboard (GrabReleaseCallback callback, void *data, bool replace_existing); bool UngrabKeyboard(void *data); bool KeyboardIsGrabbed(); void * KeyboardGrabData() { return _global_keyboard_grab_data; } void * PointerGrabData() { return _global_pointer_grab_data; } private: void InitGlobalGrabWindow(); bool m_PauseGraphicsRendering; GLTimer m_Timer; float m_FrameTime; GpuDevice *m_DeviceFactory; GraphicsEngine *m_GraphicsContext; WindowStyle m_Style; HWND _global_grab_window; void *_global_pointer_grab_data; bool _global_pointer_grab_active; GrabReleaseCallback _global_pointer_grab_callback; void *_global_keyboard_grab_data; bool _global_keyboard_grab_active; GrabReleaseCallback _global_keyboard_grab_callback; public: ~GraphicsDisplay(); GLEWContext *GetGLEWContext() { return &m_GLEWContext; } WGLEWContext *GetWGLEWContext() { return &m_WGLEWContext; } private: GraphicsDisplay(); GraphicsDisplay(const GraphicsDisplay &); // Does not make sense for a singleton. This is a self assignment. GraphicsDisplay &operator= (const GraphicsDisplay &); GLEWContext m_GLEWContext; WGLEWContext m_WGLEWContext; friend class DisplayAccessController; }; LRESULT CALLBACK WndProcManager(HWND hWnd, // Handle For This Window unsigned int uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam); // Additional Message Information } #endif //GRAPHICSDISPLAYWIN_H nux-4.0.6+14.04.20140409/NuxGraphics/MeshData.h0000644000015301777760000000137712321344237021037 0ustar pbusernogroup00000000000000#ifndef MESHDATA_H #define MESHDATA_H namespace nux { enum NuxMeshPrimitiveType { NUX_MESH_PRIMITIVE_UNKNOWN = 0, NUX_MESH_TRIANGLE, NUX_MESH_TRIANGLE_STRIP, NUX_MESH_TRIANGLE_FAN, NUX_MESH_LINE, NUX_MESH_LINE_STRIP, NUX_MESH_LINE_LOOP, NUX_MESH_POINT, NUX_MESH_QUAD, NUX_MESH_QUAD_STRIP, }; class MeshData { public: MeshData(); ~MeshData(); bool Allocate(int num_mesh_primitive, NuxMeshPrimitiveType primitive_type, int num_elements, int element_size); public: unsigned char* _vertex_data; unsigned char* _index_data; NuxMeshPrimitiveType _mesh_primitive_type; int _num_element; int _element_size; int _num_index; int _index_size; }; } #endif // MESHDATA_H nux-4.0.6+14.04.20140409/NuxGraphics/GLSh_ColorPicker.h0000644000015301777760000000303612321344237022434 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLSH_COLORPICKER_H #define GLSH_COLORPICKER_H #include "IOpenGLGLSLShader.h" #include "GLShaderParameter.h" #include "GLDeviceObjects.h" namespace nux { class GLSh_ColorPicker { public: GLSh_ColorPicker(color::Channel cc); ~GLSh_ColorPicker(); void SetColor(float R, float G, float B, float A); void SetScreenPositionOffset(float x, float y); void Render(int x, int y, int z, int width, int height, int WindowWidth, int WindowHeight); private: float _R, _G, _B, _A; float _ScreenOffsetX, _ScreenOffsetY; ObjectPtr GlobalPixelShader; ObjectPtr sprog; #ifndef NUX_OPENGLES_20 ObjectPtr m_AsmProg; #endif }; } #endif // GLSH_COLORPICKER_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVertexBuffer.cpp0000644000015301777760000000676112321344237023473 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLVertexBuffer.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLVertexBuffer); IOpenGLVertexBuffer::IOpenGLVertexBuffer(unsigned int Length, VBO_USAGE Usage, NUX_FILE_LINE_DECL) : IOpenGLResource(RTVERTEXBUFFER, NUX_FILE_LINE_PARAM) , _Length(Length) , _Usage(Usage) , _MemMap(0) , _OffsetToLock(0) , _SizeToLock(0) { CHECKGL(glGenBuffersARB(1, &_OpenGLID)); CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, _OpenGLID)); CHECKGL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, _Length, NULL, Usage)); CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); GRunTimeStats.Register(this); } IOpenGLVertexBuffer::~IOpenGLVertexBuffer() { CHECKGL(glDeleteBuffersARB(1, &_OpenGLID)); _OpenGLID = 0; GRunTimeStats.UnRegister(this); } int IOpenGLVertexBuffer::Lock( unsigned int OffsetToLock, unsigned int SizeToLock, void **ppbData) { nuxAssert(SizeToLock <= _Length); nuxAssert(OffsetToLock + SizeToLock <= _Length); if (SizeToLock == 0) { if (OffsetToLock == 0) { // lock the entire buffer SizeToLock = _Length; } else { nuxDebugMsg("[IOpenGLVertexBuffer::Lock] Invalid parameters."); return OGL_INVALID_CALL; } } // If _MemMap, _OffsetToLock and _SizeToLock are not equal to zero, then we have already mapped the buffer // Unlock it before locking again. nuxAssert(_MemMap == 0); nuxAssert(_OffsetToLock == 0); nuxAssert(_SizeToLock == 0); CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, _OpenGLID)); #ifndef NUX_OPENGLES_20 // Map the Entire buffer into system memory _MemMap = (BYTE *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); CHECKGL_MSG(glMapBufferARB); *ppbData = (void *) (_MemMap + OffsetToLock); #else _MemMap = new BYTE[SizeToLock]; *ppbData = _MemMap; #endif _OffsetToLock = OffsetToLock; _SizeToLock = SizeToLock; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); return OGL_OK; } int IOpenGLVertexBuffer::Unlock() { CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, _OpenGLID)); #ifndef NUX_OPENGLES_20 CHECKGL(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)); #else CHECKGL(glBufferSubData(GL_ARRAY_BUFFER_ARB, _OffsetToLock, _SizeToLock, _MemMap)); delete [] _MemMap; #endif CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); _MemMap = 0; _OffsetToLock = 0; _SizeToLock = 0; return OGL_OK; } void IOpenGLVertexBuffer::BindVertexBuffer() { CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, _OpenGLID)); } unsigned int IOpenGLVertexBuffer::GetSize() { return _Length; } } nux-4.0.6+14.04.20140409/NuxGraphics/GLSh_ColorPicker.cpp0000644000015301777760000004511112321344237022767 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "NuxCore/Math/Matrix4.h" #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" #include "GLShaderParameter.h" #include "GLSh_ColorPicker.h" namespace nux { // The GLSL shaders may contain branches. Intel GPU so far fails on these shaders. // Use assembly shaders for Intel GPUs: ARB_fragment_program does not have the required // instruction to implement the HSV to RGB color conversion. const char* VtxShader = " \n\ uniform mat4 ViewProjectionMatrix; \n\ attribute vec4 AVertex; \n\ attribute vec4 VertexColor; \n\ void main() \n\ { \n\ gl_Position = ViewProjectionMatrix * AVertex; \n\ }"; const char* RedFrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ uniform vec4 RectPosition; \n\ uniform vec4 RectDimension; \n\ uniform vec4 Color; \n\ void main(void) \n\ { \n\ float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x; \n\ float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y; \n\ gl_FragColor = vec4(Color.r, y, x, 1.0); \n\ }"; const char* GreenFrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ uniform vec4 RectPosition; \n\ uniform vec4 RectDimension; \n\ uniform vec4 Color; \n\ void main(void) \n\ { \n\ float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x; \n\ float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y; \n\ gl_FragColor = vec4(y, Color.g, x, 1.0); \n\ }"; const char* BlueFrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ uniform vec4 RectPosition; \n\ uniform vec4 RectDimension; \n\ uniform vec4 Color; \n\ void main(void) \n\ { \n\ float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x; \n\ float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y; \n\ gl_FragColor = vec4(x, y, Color.b, 1.0); \n\ }"; const char* HueFrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ vec3 HSV_To_RGB(vec3 HSV); \n\ uniform vec4 RectPosition; \n\ uniform vec4 RectDimension; \n\ uniform vec4 Color; \n\ void main(void) \n\ { \n\ float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x; \n\ float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y; \n\ vec3 rgb = HSV_To_RGB(vec3(Color.x, x, y)); \n\ gl_FragColor = vec4(rgb, 1.0); \n\ }"; const char* SaturationFrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ vec3 HSV_To_RGB(vec3 HSV); \n\ uniform vec4 RectPosition; \n\ uniform vec4 RectDimension; \n\ uniform vec4 Color; \n\ void main(void) \n\ { \n\ float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x; \n\ float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y; \n\ vec3 rgb = HSV_To_RGB(vec3(x, Color.y, y)); \n\ gl_FragColor = vec4(rgb, 1.0); \n\ }"; const char* ValueFrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ vec3 HSV_To_RGB(vec3 HSV); \n\ uniform vec4 RectPosition; \n\ uniform vec4 RectDimension; \n\ uniform vec4 Color; \n\ void main(void) \n\ { \n\ float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x; \n\ float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y; \n\ vec3 rgb = HSV_To_RGB(vec3(x, y, Color.z)); \n\ gl_FragColor = vec4(rgb, 1.0); \n\ }"; const char* HSV_To_RGBFrgShader = " \n\ #ifdef GL_ES \n\ precision mediump float; \n\ #endif \n\ vec3 HSV_To_RGB(vec3 HSV) \n\ { \n\ vec3 RGB = vec3(HSV.z); \n\ if ( HSV.y != 0.0 ) \n\ { \n\ float var_h = HSV.x * 6.0; \n\ float var_i = floor(var_h); // Or ... var_i = floor( var_h ) \n\ float var_1 = HSV.z * (1.0 - HSV.y); \n\ float var_2 = HSV.z * (1.0 - HSV.y * (var_h-var_i)); \n\ float var_3 = HSV.z * (1.0 - HSV.y * (1.0-(var_h-var_i))); \n\ if (var_i == 0.0) { RGB = vec3(HSV.z, var_3, var_1); } \n\ else if (var_i == 1.0) { RGB = vec3(var_2, HSV.z, var_1); } \n\ else if (var_i == 2.0) { RGB = vec3(var_1, HSV.z, var_3); } \n\ else if (var_i == 3.0) { RGB = vec3(var_1, var_2, HSV.z); } \n\ else if (var_i == 4.0) { RGB = vec3(var_3, var_1, HSV.z); } \n\ else { RGB = vec3(HSV.z, var_1, var_2); } \n\ } \n\ return(RGB); \n\ }"; ////////////////////////////////////////////////////////////////////////////// const char* AsmVtxShader = "!!ARBvp1.0 \n\ ATTRIB iPos = vertex.position; \n\ PARAM mvp[4] = {state.matrix.mvp}; \n\ OUTPUT oPos = result.position; \n\ # Transform the vertex to clip coordinates. \n\ DP4 oPos.x, mvp[0], iPos; \n\ DP4 oPos.y, mvp[1], iPos; \n\ DP4 oPos.z, mvp[2], iPos; \n\ DP4 oPos.w, mvp[3], iPos; \n\ END"; const char* AsmRedFrgShader = "!!ARBfp1.0 \n\ PARAM RectPosition = program.local[0]; \n\ PARAM RectDimension = program.local[1]; \n\ PARAM Color = program.local[2]; \n\ TEMP temp0; \n\ TEMP temp1; \n\ SUB temp0.x, fragment.position.x, RectPosition.x; \n\ SUB temp0.y, fragment.position.y, RectPosition.y; \n\ RCP temp1.x, RectDimension.x; \n\ RCP temp1.y, RectDimension.y; \n\ MUL temp0.xy, temp0, temp1; \n\ MOV temp1.x, Color; \n\ MOV temp1.yz, temp0.yyxx; \n\ MOV temp1.w, {1, 1, 1, 1}; \n\ MOV result.color, temp1; \n\ END"; const char* AsmGreenFrgShader = "!!ARBfp1.0 \n\ PARAM RectPosition = program.local[0]; \n\ PARAM RectDimension = program.local[1]; \n\ PARAM Color = program.local[2]; \n\ TEMP temp0; \n\ TEMP temp1; \n\ SUB temp0.x, fragment.position.x, RectPosition.x; \n\ SUB temp0.y, fragment.position.y, RectPosition.y; \n\ RCP temp1.x, RectDimension.x; \n\ RCP temp1.y, RectDimension.y; \n\ MUL temp0.xy, temp0, temp1; \n\ MOV temp1.y, Color; \n\ MOV temp1.xz, temp0.yyxx; \n\ MOV temp1.w, {1, 1, 1, 1}; \n\ MOV result.color, temp1; \n\ END"; const char* AsmBlueFrgShader = "!!ARBfp1.0 \n\ PARAM RectPosition = program.local[0]; \n\ PARAM RectDimension = program.local[1]; \n\ PARAM Color = program.local[2]; \n\ TEMP temp0; \n\ TEMP temp1; \n\ SUB temp0.x, fragment.position.x, RectPosition.x; \n\ SUB temp0.y, fragment.position.y, RectPosition.y; \n\ RCP temp1.x, RectDimension.x; \n\ RCP temp1.y, RectDimension.y; \n\ MUL temp0.xy, temp0, temp1; \n\ MOV temp1.z, Color; \n\ MOV temp1.xy, temp0.xyxx; \n\ MOV temp1.w, {1, 1, 1, 1}; \n\ MOV result.color, temp1; \n\ END"; const char* AsmHueFrgShader = "!!ARBfp1.0 \n\ MOV result.color, {0, 0, 0, 0}; \n\ END"; const char* AsmSaturationFrgShader = "!!ARBfp1.0 \n\ MOV result.color, {0, 0, 0, 0}; \n\ END"; const char* AsmValueFrgShader = "!!ARBfp1.0 \n\ MOV result.color, {0, 0, 0, 0}; \n\ END"; GLSh_ColorPicker::GLSh_ColorPicker(color::Channel color_channel) : _R(1.0) , _G(0.0) , _B(0.0) , _A(1.0) , _ScreenOffsetX(0) , _ScreenOffsetY(0) { const char* FrgShaderCode; #ifdef NUX_ARCH_ARM if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath()) #else if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath() && (GetGraphicsDisplay()->GetGpuDevice()->GetGPUBrand() != GPU_BRAND_INTEL)) #endif { switch(color_channel) { case color::RED: { FrgShaderCode = RedFrgShader; break; } case color::GREEN: { FrgShaderCode = GreenFrgShader; break; } case color::BLUE: { FrgShaderCode = BlueFrgShader; break; } case color::HUE: { FrgShaderCode = HueFrgShader; break; } case color::SATURATION: { FrgShaderCode = SaturationFrgShader; break; } case color::VALUE: { FrgShaderCode = ValueFrgShader; break; } default: { nuxDebugMsg("[GLSh_ColorPicker::GLSh_ColorPicker] Unknown color channel"); FrgShaderCode = RedFrgShader; break; } } GlobalPixelShader = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); sprog = GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); GlobalPixelShader->SetShaderCode(HSV_To_RGBFrgShader); sprog->AddShaderObject(GlobalPixelShader); sprog->LoadVertexShader(VtxShader, NULL); sprog->LoadPixelShader(FrgShaderCode, NULL); sprog->Link(); } else { switch(color_channel) { case color::RED: { FrgShaderCode = AsmRedFrgShader; break; } case color::GREEN: { FrgShaderCode = AsmGreenFrgShader; break; } case color::BLUE: { FrgShaderCode = AsmBlueFrgShader; break; } case color::HUE: { FrgShaderCode = AsmHueFrgShader; break; } case color::SATURATION: { FrgShaderCode = AsmSaturationFrgShader; break; } case color::VALUE: { FrgShaderCode = AsmValueFrgShader; break; } default: { nuxDebugMsg("[GLSh_ColorPicker::GLSh_ColorPicker] Unknown color channel"); FrgShaderCode = RedFrgShader; break; } } #ifndef NUX_OPENGLES_20 m_AsmProg = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); m_AsmProg->LoadVertexShader(AsmVtxShader); m_AsmProg->LoadPixelShader(FrgShaderCode); m_AsmProg->Link(); #endif } } GLSh_ColorPicker::~GLSh_ColorPicker() { GlobalPixelShader = ObjectPtr (0); sprog.Release(); #ifndef NUX_OPENGLES_20 m_AsmProg.Release(); #endif } void GLSh_ColorPicker::SetColor(float R, float G, float B, float A) { _R = R; _G = G; _B = B; _A = A; } void GLSh_ColorPicker::SetScreenPositionOffset(float x, float y) { _ScreenOffsetX = x; _ScreenOffsetY = y; } void GLSh_ColorPicker::Render(int x, int y, int z, int width, int height, int /* WindowWidth */, int WindowHeight) { float fx = x, fy = y; float VtxBuffer[] = { fx, fy, 0.0f, 1.0f, fx, fy + height, 0.0f, 1.0f, fx + width, fy + height, 0.0f, 1.0f, fx + width, fy, 0.0f, 1.0f, }; #ifdef NUX_ARCH_ARM if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath()) #else if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath() && (GetGraphicsDisplay()->GetGpuDevice()->GetGPUBrand() != GPU_BRAND_INTEL)) #endif { CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); sprog->Begin(); int VertexLocation = sprog->GetAttributeLocation("AVertex"); int VPMatrixLocation = sprog->GetUniformLocationARB("ViewProjectionMatrix"); Matrix4 MVPMatrix = GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLModelViewProjectionMatrix(); sprog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); int ColorBase = sprog->GetUniformLocationARB("Color"); int RectPosition = sprog->GetUniformLocationARB("RectPosition"); int RectDimension = sprog->GetUniformLocationARB("RectDimension"); if (ColorBase != -1) CHECKGL(glUniform4fARB(ColorBase, _R, _G, _B, _A)); if (RectPosition != -1) CHECKGL(glUniform4fARB(RectPosition, x + _ScreenOffsetX, WindowHeight - y - height - _ScreenOffsetY, z, 0.0f)); if (RectDimension != -1) CHECKGL(glUniform4fARB(RectDimension, width, height, 0.0f, 0.0f)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 16, VtxBuffer)); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); sprog->End(); } #ifndef NUX_OPENGLES_20 else { CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); m_AsmProg->Begin(); CHECKGL(glMatrixMode(GL_MODELVIEW)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLModelViewMatrix().m)); CHECKGL(glMatrixMode(GL_PROJECTION)); CHECKGL(glLoadIdentity()); CHECKGL(glLoadMatrixf((FLOAT *) GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLProjectionMatrix().m)); int VertexLocation = VTXATTRIB_POSITION; CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, x + _ScreenOffsetX, WindowHeight - y - height - _ScreenOffsetY, z, 0.0f)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, width, height, 0.0f, 0.0f)); CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, _R, _G, _B, _A)); CHECKGL(glEnableVertexAttribArrayARB(VertexLocation)); CHECKGL(glVertexAttribPointerARB((GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 16, VtxBuffer)); CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); CHECKGL(glDisableVertexAttribArrayARB(VertexLocation)); m_AsmProg->End(); } #endif } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVolume.h0000644000015301777760000000601612321344237021771 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLVOLUME_H #define IOPENGLVOLUME_H namespace nux { class IOpenGLResource; class IOpenGLVolumeTexture; class IOpenGLVolume: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLVolume, IOpenGLResource); public: virtual int RefCount() const; int LockBox( VOLUME_LOCKED_BOX *pLockedVolume, const VOLUME_BOX *pBox); int UnlockBox(); BitmapFormat GetPixelFormat() const; int GetWidth() const; int GetHeight() const; int GetDepth() const; int GetMipLevel() const { return _SMipLevel; } int GetSurfaceTarget() const { return _SSurfaceTarget; } int GetLevelDesc(VOLUME_DESC *pDesc) { pDesc->Width = GetWidth(); pDesc->Height = GetHeight(); pDesc->Depth = GetDepth(); pDesc->PixelFormat = GetPixelFormat(); pDesc->Type = _ResourceType; return OGL_OK; } private: virtual ~IOpenGLVolume(); int InitializeLevel(); IOpenGLVolume(IOpenGLVolumeTexture *VolumeTexture, GLenum OpenGLID, GLenum TextureTarget, GLenum SurfaceTarget, unsigned int MipLevel) : IOpenGLResource(RTVOLUME) , _STextureTarget(TextureTarget) , _SSurfaceTarget(SurfaceTarget) , _SMipLevel(MipLevel) , _VolumeTexture(VolumeTexture) , _AllocatedUnpackBuffer(0xFFFFFFFF) { // IOpenGLVolume surfaces are created inside a IOpenGLVolumeTexture. // They reside within this class. The reference counting starts once a call to GetVolumeLevel is made to the container object. _RefCount = 0; _OpenGLID = OpenGLID; _LockedBox.pBits = 0; _LockedBox.RowPitch = 0; _CompressedDataSize = 0; _Initialized = 0; } // _STextureTarget may be // GL_TEXTURE_3D GLenum _STextureTarget; // _SSurfaceTarget may be // GL_TEXTURE_3D GLenum _SSurfaceTarget; int _SMipLevel; VOLUME_LOCKED_BOX _LockedBox; VOLUME_BOX _Box; int _CompressedDataSize; IOpenGLVolumeTexture *_VolumeTexture; bool _Initialized; int _AllocatedUnpackBuffer; friend class IOpenGLVolumeTexture; friend class ObjectPtr; }; } #endif // IOPENGLVOLUME_H nux-4.0.6+14.04.20140409/NuxGraphics/GpuDeviceShader.cpp0000644000015301777760000000511012321344237022673 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLDeviceFrameBufferObject.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" namespace nux { ObjectPtr GpuDevice::CreateShaderProgram() { ObjectPtr result; result.Adopt(new IOpenGLShaderProgram()); return result; } ObjectPtr GpuDevice::CreateVertexShader() { ObjectPtr result; result.Adopt(new IOpenGLVertexShader()); return result; } ObjectPtr GpuDevice::CreatePixelShader() { ObjectPtr result; result.Adopt(new IOpenGLPixelShader()); return result; } #ifndef NUX_OPENGLES_20 ObjectPtr GpuDevice::CreateAsmShaderProgram() { ObjectPtr result; result.Adopt(new IOpenGLAsmShaderProgram()); return result; } ObjectPtr GpuDevice::CreateAsmVertexShader() { ObjectPtr result; result.Adopt(new IOpenGLAsmVertexShader()); return result; } ObjectPtr GpuDevice::CreateAsmPixelShader() { ObjectPtr result; result.Adopt(new IOpenGLAsmPixelShader()); return result; } #endif #if (NUX_ENABLE_CG_SHADERS) ObjectPtr GpuDevice::CreateCGVertexShader() { ObjectPtr result; result.Adopt(new ICgVertexShader()); return result; } ObjectPtr GpuDevice::CreateCGPixelShader() { ObjectPtr result; result.Adopt(new ICgPixelShader()); return result; } #endif } nux-4.0.6+14.04.20140409/NuxGraphics/CairoGraphics.h0000644000015301777760000001056512321344237022066 0ustar pbusernogroup00000000000000/* * Copyright 2010, 2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef CAIROGRAPHICS_H #define CAIROGRAPHICS_H #ifdef NUX_ARCH_ARM #include "cairo.h" #else #include "cairo/cairo.h" #endif #include "BitmapFormats.h" #include "ImageSurface.h" #include namespace nux { class CairoFontOptions { public: CairoFontOptions() : font_options_(::cairo_font_options_create()) {} ~CairoFontOptions() { ::cairo_font_options_destroy(font_options_); } operator cairo_font_options_t*() { return font_options_; } private: cairo_font_options_t* font_options_; }; //! A cairo graphics container /*! CairoGraphics encapsulates a cairo surface and context. */ class CairoGraphics { public: CairoGraphics(cairo_format_t format, int width, int height); ~CairoGraphics(); //! Return a cairo context to the encapsulated surface. /*! Return the cairo context of this object. Call cairo_destroy to destroy the context when you are done with it. @return A cairo context. */ cairo_t *GetContext(); //! Return an internal cairo context to the encapsulated surface. Should not be destroyed. /*! Return the cairo context of this object. This cairo context should not be destroyed with cairo_destroy. @return A cairo context. */ cairo_t *GetInternalContext(); cairo_surface_t* GetSurface(); //! Create a NBitmapData pointer to a 2D texture data. /*! The returned data must be destroyed with delete. @return A pointer to a 2D texture data. */ NBitmapData *GetBitmap(); int GetWidth() const; int GetHeight() const; bool PushState(); bool PopState(); bool ClearCanvas(); bool ClearRect(double x, double y, double w, double h); bool DrawLine(double x0, double y0, double x1, double y1, double width, const Color &c); void TranslateCoordinates(double dx, double dy); bool DrawFilledRect(double x, double y, double w, double h, const Color &c); bool DrawCanvas(double x, double y, CairoGraphics *cg); bool DrawRoundedRectangle(cairo_t* cr, double aspect, double x, double y, double cornerRadius, double width, double height, bool align = false); bool BlurSurface(unsigned int radius, cairo_surface_t* surf = NULL); bool IntersectRectClipRegion(double x, double y, double w, double h); bool IntersectGeneralClipRegion(std::list ®ion); /** * Enum used to specify horizontal alignment. */ enum Alignment { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFY }; /** * Enum used to specify vertical alignment. */ enum VAlignment { VALIGN_TOP, VALIGN_MIDDLE, VALIGN_BOTTOM }; /** * Enum used to specify trimming type. */ enum Trimming { TRIMMING_NONE, TRIMMING_CHARACTER, TRIMMING_WORD, TRIMMING_CHARACTER_ELLIPSIS, TRIMMING_WORD_ELLIPSIS, TRIMMING_PATH_ELLIPSIS }; /** * Enum used to specify text flags. */ enum TextFlag { TEXT_FLAGS_NONE = 0, TEXT_FLAGS_UNDERLINE = 1, TEXT_FLAGS_STRIKEOUT = 2, TEXT_FLAGS_WORDWRAP = 4 }; private: //! Cairo surface format cairo_format_t m_surface_format; //! Cairo surface cairo_surface_t *_cairo_surface; cairo_t * _cr; int _width; //!< Surface width. int _height; //!< Surface height. double _zoom; float _opacity; std::stack _opacity_stack; }; } #endif // CAIROGRAPHICS_H nux-4.0.6+14.04.20140409/NuxGraphics/Gfx_Interface.h0000644000015301777760000000245012321344237022046 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GRAPHICINTERFACE_H #define GRAPHICINTERFACE_H #if defined(NUX_OS_WINDOWS) #include "Events.h" #elif defined(NUX_OS_LINUX) #include "Events.h" #else #error Undefined GfxEvents for this platform #endif namespace nux { typedef struct _DeviceModes { int width; int height; int format; bool fullscreen; int refresh_rate; } DeviceModes; class GraphicSystem { public: int m_num_gfx_device_modes; std::vector m_gfx_device_modes; }; } #endif //GRAPHICINTERFACE_H nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLFrameBufferObject.cpp0000644000015301777760000003713012321344237024371 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GraphicsDisplay.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLFrameBufferObject.h" #include "GraphicsEngine.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLFrameBufferObject); IOpenGLFrameBufferObject::IOpenGLFrameBufferObject(NUX_FILE_LINE_DECL) : IOpenGLResource(RTFRAMEBUFFEROBJECT, NUX_FILE_LINE_PARAM) , platform_support_for_depth_texture_(false) { attachment_width_ = 1; attachment_height_ = 1; _PixelFormat = BITFMT_R8G8B8A8; _IsActive = false; SetupFrameBufferObject(); GRunTimeStats.Register(this); } void IOpenGLFrameBufferObject::SetupFrameBufferObject() { if (!GetGraphicsDisplay()->GetGpuDevice()) return; auto const& gpu_info = GetGraphicsDisplay()->GetGpuDevice()->GetGpuInfo(); texture_attachment_array_.resize(gpu_info.GetMaxFboAttachment()); surface_attachment_array_.resize(gpu_info.GetMaxFboAttachment()); platform_support_for_depth_texture_ = gpu_info.Support_Depth_Buffer(); FormatFrameBufferObject(attachment_width_, attachment_height_, _PixelFormat); } IOpenGLFrameBufferObject::~IOpenGLFrameBufferObject() { // IOpenGLFrameBufferObject is an abstraction. Is does not have an opengl id. // _Fbo has an opengl id that is destroyed when the destructor is called. _OpenGLID = 0; GRunTimeStats.UnRegister(this); } int IOpenGLFrameBufferObject::FormatFrameBufferObject(int Width, int Height, BitmapFormat PixelFormat) { Deactivate(); texture_attachment_array_.clear(); surface_attachment_array_.clear(); depth_surface_attachment_ = ObjectPtr (0); stencil_surface_attachment_ = ObjectPtr (0); if ((attachment_width_ == Width) && (attachment_height_ == Height) && (_PixelFormat == PixelFormat)) return 1; // #ifndef NUX_OPENGLES_20 // _Rbo.Set(GL_DEPTH_COMPONENT, Width, Height); // #endif nuxAssertMsg(Width>0, "[IOpenGLFrameBufferObject::FormatFrameBufferObject] Invalid surface size."); nuxAssertMsg(Height>0, "[IOpenGLFrameBufferObject::FormatFrameBufferObject] Invalid surface size."); attachment_width_ = Width; attachment_height_ = Height; _PixelFormat = PixelFormat; // Clear clipping region stack EmptyClippingRegion(); return 1; } int IOpenGLFrameBufferObject::SetRenderTarget(int color_attachment_index, ObjectPtr pRenderTargetSurface) { nuxAssert(color_attachment_index < GetGraphicsDisplay()->GetGpuDevice()->GetGpuInfo().GetMaxFboAttachment()); if (pRenderTargetSurface.IsNull()) { // Invalid. texture_attachment_array_[color_attachment_index] = ObjectPtr (0); surface_attachment_array_[color_attachment_index] = ObjectPtr (0); return 0; } if (surface_attachment_array_[color_attachment_index] == pRenderTargetSurface) { // Already set. Return. return 1; } if (! (attachment_width_ == pRenderTargetSurface->GetWidth() && attachment_height_ == pRenderTargetSurface->GetHeight())) { nuxAssertMsg(0, "[IOpenGLFrameBufferObject::SetRenderTarget] Invalid surface size."); return 0; } texture_attachment_array_[color_attachment_index] = ObjectPtr (0); surface_attachment_array_[color_attachment_index] = pRenderTargetSurface; if (_IsActive) { Activate(); } return 1; } int IOpenGLFrameBufferObject::SetTextureAttachment(int color_attachment_index, ObjectPtr texture, int mip_level) { nuxAssert(color_attachment_index < GetGraphicsDisplay()->GetGpuDevice()->GetGpuInfo().GetMaxFboAttachment()); if (texture.IsNull()) { // Invalid. texture_attachment_array_[color_attachment_index] = ObjectPtr (0); surface_attachment_array_[color_attachment_index] = ObjectPtr (0); return 0; } if (!surface_attachment_array_.empty()) { if ((texture_attachment_array_[color_attachment_index] == texture) && (surface_attachment_array_[color_attachment_index] == texture->GetSurfaceLevel(mip_level))) { // Already set. Return. return 1; } } ObjectPtr surface = texture->GetSurfaceLevel(mip_level); if ((attachment_width_ != surface->GetWidth()) || (attachment_height_ != surface->GetHeight())) { nuxAssertMsg(0, "[IOpenGLFrameBufferObject::SetRenderTarget] Invalid surface size."); return 0; } texture_attachment_array_[color_attachment_index] = texture; surface_attachment_array_[color_attachment_index] = texture->GetSurfaceLevel(mip_level); if (_IsActive) { Activate(); } return 1; } ObjectPtr IOpenGLFrameBufferObject::TextureAttachment(int color_attachment_index) { return texture_attachment_array_[color_attachment_index]; } int IOpenGLFrameBufferObject::SetDepthSurface(ObjectPtr pDepthSurface) { if (!platform_support_for_depth_texture_) { return 0; } if (pDepthSurface.IsNull()) { depth_surface_attachment_ = ObjectPtr (0); stencil_surface_attachment_ = ObjectPtr (0); return 1; } if (! (attachment_width_ == pDepthSurface->GetWidth() && attachment_height_ == pDepthSurface->GetHeight())) { nuxAssertMsg(0, "The depth surface size is not compatible with the frame buffer size."); return 0; } if (depth_surface_attachment_ == pDepthSurface) return 1; // We rely on the fact that the depth texture is actually a D24_S8 texture. // That is, the surface for the depth and stencil attachment is the same. When we bound, the surface, // we explicitly bind the depth attachment and the stencil attachment with the same surface. depth_surface_attachment_ = pDepthSurface; stencil_surface_attachment_ = pDepthSurface; if (_IsActive) { Activate(); } return 1; } int IOpenGLFrameBufferObject::SetDepthTextureAttachment(ObjectPtr depth_texture, int mip_level) { if (!platform_support_for_depth_texture_) { return 0; } if (depth_texture.IsNull()) { depth_surface_attachment_ = ObjectPtr (0); stencil_surface_attachment_ = ObjectPtr (0); depth_texture_attachment_ = ObjectPtr (0); return 1; } if (depth_texture_attachment_ == depth_texture && depth_surface_attachment_ == depth_texture->GetSurfaceLevel(mip_level)) { return 1; } ObjectPtr depth_surface = depth_texture->GetSurfaceLevel(mip_level); if ((attachment_width_ != depth_surface->GetWidth()) || (attachment_height_ != depth_surface->GetHeight())) { nuxAssertMsg(0, "The depth surface size is not compatible with the frame buffer size."); return 0; } // We rely on the fact that the depth texture is actually a D24_S8 texture. // That is, the surface for the depth and stencil attachment is the same. When we bound, the surface, // we explicitly bind the depth attachment and the stencil attachment with the same surface. depth_surface_attachment_ = depth_surface; stencil_surface_attachment_ = depth_surface; depth_texture_attachment_ = depth_texture; if (_IsActive) { Activate(); } return 1; } ObjectPtr IOpenGLFrameBufferObject::DepthTextureAttachment() { return depth_texture_attachment_; } ObjectPtr IOpenGLFrameBufferObject::GetRenderTarget(int ColorAttachmentIndex) { nuxAssert(ColorAttachmentIndex < GetGraphicsDisplay()->GetGpuDevice()->GetGpuInfo().GetMaxFboAttachment()); return surface_attachment_array_[ColorAttachmentIndex]; } ObjectPtr IOpenGLFrameBufferObject::GetDepthRenderTarget() { return depth_surface_attachment_; } int IOpenGLFrameBufferObject::Activate(bool WithClippingStack) { GLuint NumBuffers = 0; _Fbo.Bind(); if (!GetGraphicsDisplay()->GetGpuDevice()) return 0; GetGraphicsDisplay()->GetGpuDevice()->SetCurrentFrameBufferObject(ObjectPtr (this)); for (int i = 0; i < GetGraphicsDisplay()->GetGpuDevice()->GetGpuInfo().GetMaxFboAttachment(); ++i) { if (surface_attachment_array_[i].IsValid()) { GLenum target = surface_attachment_array_[i]->GetSurfaceTarget(); GLenum glID = surface_attachment_array_[i]->GetOpenGLID(); GLint level = surface_attachment_array_[i]->GetMipLevel(); CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, target, glID, level)); #ifndef NUX_OPENGLES_20 CHECKGL(glDrawBuffer(GL_COLOR_ATTACHMENT0 + i)); #endif NumBuffers++; } else { CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0)); } } if (platform_support_for_depth_texture_) { if (depth_surface_attachment_.IsValid()) { GLenum target = depth_surface_attachment_->GetSurfaceTarget(); GLenum glID = depth_surface_attachment_->GetOpenGLID(); GLint level = depth_surface_attachment_->GetMipLevel(); CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, target, glID, level)); } else { CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); // On the PC you need to bing the same D24S8 surface to the depth and the stencil attachment. } } else { CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0)); } nuxAssert( _Fbo.IsValid() == true ); if (GetGraphicsDisplay()->GetGraphicsEngine()) GetGraphicsDisplay()->GetGraphicsEngine()->SetViewport(0, 0, attachment_width_, attachment_height_); if (WithClippingStack) ApplyClippingRegion(); _IsActive = true; return 1; } // Restore the original opengl back buffer as defined when creating the opengl context(color + depth + stencil). int IOpenGLFrameBufferObject::Deactivate() { #ifdef NUX_OPENGLES_20 GLenum binding = GL_FRAMEBUFFER; #else GLenum binding = GL_DRAW_FRAMEBUFFER_EXT; #endif CHECKGL(glBindFramebufferEXT( binding, 0 )); #ifndef NUX_OPENGLES_20 CHECKGL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0)); #endif if (GetGraphicsDisplay()->GetGpuDevice()) GetGraphicsDisplay()->GetGpuDevice()->SetCurrentFrameBufferObject(ObjectPtr (0)); if (GetGraphicsDisplay()->GetGraphicsEngine()) GetGraphicsDisplay()->GetGraphicsEngine()->SetScissor(0, 0, attachment_width_, attachment_height_); _IsActive = false; return 1; } void IOpenGLFrameBufferObject::PushClippingRegion(Rect const& rect) { Rect r0; if (GetGraphicsDisplay()->GetGraphicsEngine()) { r0 = GetGraphicsDisplay()->GetGraphicsEngine()->ModelViewXFormRect(rect); } Rect current_clip_rect; unsigned int stacksize = (unsigned int) _ClippingRegionStack.size(); if (stacksize == 0) { current_clip_rect.Set(0, 0, attachment_width_, attachment_height_); } else { current_clip_rect = _ClippingRegionStack[stacksize-1]; } Rect r1; if (GetGraphicsDisplay()->GetGraphicsEngine()) r1 = GetGraphicsDisplay()->GetGraphicsEngine()->GetViewportRect(); r0.OffsetPosition(r1.x, attachment_height_ - (r1.y + r1.GetHeight())); Rect Intersection = current_clip_rect.Intersect(r0); if (!Intersection.IsNull()) { _clipping_rect = Intersection; _ClippingRegionStack.push_back(Intersection); SetOpenGLClippingRectangle(Intersection.x + GetGraphicsDisplay()->GetGraphicsEngine()->GetViewportX(), attachment_height_ - Intersection.y - Intersection.GetHeight() - GetGraphicsDisplay()->GetGraphicsEngine()->GetViewportY(), Intersection.GetWidth(), Intersection.GetHeight()); } else { _clipping_rect.Set(0, 0, 0, 0); _ClippingRegionStack.push_back(Rect(0, 0, 0, 0)); SetOpenGLClippingRectangle(0, 0, 0, 0); } } void IOpenGLFrameBufferObject::PopClippingRegion() { _ClippingRegionStack.pop_back(); int stacksize = (int) _ClippingRegionStack.size(); if (stacksize == 0) { _clipping_rect.Set(0, 0, attachment_width_, attachment_height_); SetOpenGLClippingRectangle(0, 0, attachment_width_, attachment_height_); } else { _clipping_rect = _ClippingRegionStack [stacksize-1]; Rect current_clip_rect = _ClippingRegionStack [stacksize-1]; SetOpenGLClippingRectangle(current_clip_rect.x, attachment_height_ - current_clip_rect.y - current_clip_rect.GetHeight(), current_clip_rect.GetWidth(), current_clip_rect.GetHeight()); } } void IOpenGLFrameBufferObject::EmptyClippingRegion() { _ClippingRegionStack.clear(); { _clipping_rect.Set(0, 0, attachment_width_, attachment_height_); SetOpenGLClippingRectangle(0, 0, attachment_width_, attachment_height_); } } void IOpenGLFrameBufferObject::ApplyClippingRegion() { int stacksize = (int) _ClippingRegionStack.size(); if (stacksize == 0) { _clipping_rect.Set(0, 0, attachment_width_, attachment_height_); SetOpenGLClippingRectangle(0, 0, attachment_width_, attachment_height_); } else { _clipping_rect = _ClippingRegionStack [stacksize-1]; Rect current_clip_rect = _ClippingRegionStack [stacksize-1]; SetOpenGLClippingRectangle(current_clip_rect.x, attachment_height_ - current_clip_rect.y - current_clip_rect.GetHeight(), current_clip_rect.GetWidth(), current_clip_rect.GetHeight()); } } void IOpenGLFrameBufferObject::SetClippingRectangle(const Rect &rect) { if (GetGraphicsDisplay()->GetGraphicsEngine()) { _clipping_rect = rect; GetGraphicsDisplay()->GetGraphicsEngine()->SetScissor(rect.x, attachment_height_ - rect.y - rect.height, rect.width, rect.height); } } void IOpenGLFrameBufferObject::SetOpenGLClippingRectangle(int x, int y, int width, int height) { if (GetGraphicsDisplay()->GetGraphicsEngine()) { _clipping_rect.Set(x, y, width, height); GetGraphicsDisplay()->GetGraphicsEngine()->SetScissor(x, y, width, height); } } Rect IOpenGLFrameBufferObject::GetClippingRegion() { return _clipping_rect; // unsigned int stacksize = (unsigned int) _ClippingRegionStack.size(); // // if (stacksize == 0) // { // return Rect(0, 0, attachment_width_, attachment_height_); // } // else // { // Rect r = _ClippingRegionStack [stacksize-1]; // return r; // } } int IOpenGLFrameBufferObject::GetNumberOfClippingRegions() const { return _ClippingRegionStack.size(); } } nux-4.0.6+14.04.20140409/NuxGraphics/VirtualKeyCodesX11.h0000644000015301777760000003434512321344237022721 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef VIRTUALKEYCODESX11_H #define VIRTUALKEYCODESX11_H namespace nux { // Virtual key codes // The following table shows the symbolic constant names, hexadecimal values, and mouse or keyboard equivalents for the virtual-key codes used by the system. The codes are listed in numeric order. // Symbolic constant name Value (hex) Mouse or keyboard equivalents #define NUX_VK_BACKSPACE XK_BackSpace // BACKSPACE key #define NUX_VK_TAB XK_Tab // TAB key #define NUX_VK_LEFT_TAB XK_ISO_Left_Tab // SHIFT TAB key #define NUX_VK_CLEAR XK_Clear // CLEAR key #define NUX_VK_ENTER XK_Return // ENTER key #define NUX_VK_SHIFT XK_Shift_L // SHIFT key #define NUX_VK_CONTROL XK_Control_L // CTRL key #define NUX_VK_MENU XK_Alt_L // ALT key #define NUX_VK_PAUSE XK_Pause // PAUSE key #define NUX_VK_CAPITAL XK_Caps_Lock // CAPS LOCK key #define NUX_VK_ESCAPE XK_Escape // ESC key #define NUX_VK_SPACE XK_space // SPACEBAR #define NUX_VK_PAGE_UP XK_Page_Up // PAGE UP key #define NUX_VK_PAGE_DOWN XK_Page_Down // PAGE DOWN key #define NUX_VK_END XK_End // END key #define NUX_VK_HOME XK_Home // HOME key #define NUX_VK_LEFT XK_Left // LEFT ARROW key #define NUX_VK_UP XK_Up // UP ARROW key #define NUX_VK_RIGHT XK_Right // RIGHT ARROW key #define NUX_VK_DOWN XK_Down // DOWN ARROW key #define NUX_VK_PRINT XK_Print // PRINT key #define NUX_VK_EXECUTE XK_Execute // EXECUTE key #define NUX_VK_INSERT XK_Insert // INS key #define NUX_VK_DELETE XK_Delete // DEL key /*#define NUX_VK_Multiply XK_Multiply #define NUX_VK_Add XK_Aadd #define NUX_VK_Subtract XK_Substract #define NUX_VK_Decimal XK_Decimal #define NUX_VK_Divide XK_Divide*/ #define NUX_VK_0 XK_0 // 0 key #define NUX_VK_1 XK_1 // 1 key #define NUX_VK_2 XK_2 // 2 key #define NUX_VK_3 XK_3 // 3 key #define NUX_VK_4 XK_4 // 4 key #define NUX_VK_5 XK_5 // 5 key #define NUX_VK_6 XK_6 // 6 key #define NUX_VK_7 XK_7 // 7 key #define NUX_VK_8 XK_8 // 8 key #define NUX_VK_9 XK_9 // 9 key #define NUX_VK_A XK_A // A key #define NUX_VK_B XK_B // B key #define NUX_VK_C XK_C // C key #define NUX_VK_D XK_D // D key #define NUX_VK_E XK_E // E key #define NUX_VK_F XK_F // F key #define NUX_VK_G XK_G // G key #define NUX_VK_H XK_H // H key #define NUX_VK_I XK_I // I key #define NUX_VK_J XK_J // J key #define NUX_VK_K XK_K // K key #define NUX_VK_L XK_L // L key #define NUX_VK_M XK_M // M key #define NUX_VK_N XK_N // N key #define NUX_VK_O XK_O // O key #define NUX_VK_P XK_P // P key #define NUX_VK_Q XK_Q // Q key #define NUX_VK_R XK_R // R key #define NUX_VK_S XK_S // S key #define NUX_VK_T XK_T // T key #define NUX_VK_U XK_U // U key #define NUX_VK_V XK_V // V key #define NUX_VK_W XK_W // W key #define NUX_VK_X XK_X // X key #define NUX_VK_Y XK_Y // Y key #define NUX_VK_Z XK_Z // Z key #define NUX_VK_a XK_a #define NUX_VK_b XK_b #define NUX_VK_c XK_c #define NUX_VK_d XK_d #define NUX_VK_e XK_e #define NUX_VK_f XK_f #define NUX_VK_g XK_g #define NUX_VK_h XK_h #define NUX_VK_i XK_i #define NUX_VK_j XK_j #define NUX_VK_k XK_k #define NUX_VK_l XK_l #define NUX_VK_m XK_m #define NUX_VK_n XK_n #define NUX_VK_o XK_o #define NUX_VK_p XK_p #define NUX_VK_q XK_q #define NUX_VK_r XK_r #define NUX_VK_s XK_s #define NUX_VK_t XK_t #define NUX_VK_u XK_u #define NUX_VK_v XK_v #define NUX_VK_w XK_w #define NUX_VK_x XK_x #define NUX_VK_y XK_y #define NUX_VK_z XK_z #define NUX_VK_LWIN XK_Super_L // Left Windows key (Microsoft Natural Keyboard) #define NUX_VK_RWIN XK_Super_R // Right Windows key (Microsoft Natural Keyboard) #define NUX_VK_NUMPAD0 XK_KP_0 // Numeric keypad 0 key #define NUX_VK_NUMPAD1 XK_KP_1 // Numeric keypad 1 key #define NUX_VK_NUMPAD2 XK_KP_2 // Numeric keypad 2 key #define NUX_VK_NUMPAD3 XK_KP_3 // Numeric keypad 3 key #define NUX_VK_NUMPAD4 XK_KP_4 // Numeric keypad 4 key #define NUX_VK_NUMPAD5 XK_KP_5 // Numeric keypad 5 key #define NUX_VK_NUMPAD6 XK_KP_6 // Numeric keypad 6 key #define NUX_VK_NUMPAD7 XK_KP_7 // Numeric keypad 7 key #define NUX_VK_NUMPAD8 XK_KP_8 // Numeric keypad 8 key #define NUX_VK_NUMPAD9 XK_KP_9 // Numeric keypad 9 key #define NUX_KP_MULTIPLY XK_KP_Multiply // Multiply key #define NUX_KP_ADD XK_KP_Add // Add key #define NUX_KP_SEPARATOR XK_KP_Separator // Separator key #define NUX_KP_SUBTRACT XK_KP_Subtract // Subtract key #define NUX_KP_DECIMAL XK_KP_Decimal // Decimal key #define NUX_KP_DIVIDE XK_KP_Divide // Divide key #define NUX_KP_ENTER XK_KP_Enter #define NUX_VK_F1 XK_F1 // F1 key #define NUX_VK_F2 XK_F2 // F2 key #define NUX_VK_F3 XK_F3 // F3 key #define NUX_VK_F4 XK_F4 // F4 key #define NUX_VK_F5 XK_F5 // F5 key #define NUX_VK_F6 XK_F6 // F6 key #define NUX_VK_F7 XK_F7 // F7 key #define NUX_VK_F8 XK_F8 // F8 key #define NUX_VK_F9 XK_F9 // F9 key #define NUX_VK_F10 XK_F10 // F10 key #define NUX_VK_F11 XK_F11 // F11 key #define NUX_VK_F12 XK_F12 // F12 key #define NUX_VK_F13 XK_F13 // F13 key #define NUX_VK_F14 XK_F14 // F14 key #define NUX_VK_F15 XK_F15 // F15 key #define NUX_VK_F16 XK_F16 // F16 key #define NUX_VK_F17 XK_F17 // F17 key #define NUX_VK_F18 XK_F18 // F18 key #define NUX_VK_F19 XK_F19 // F19 key #define NUX_VK_F20 XK_F20 // F20 key #define NUX_VK_F21 XK_F21 // F21 key #define NUX_VK_F22 XK_F22 // F22 key #define NUX_VK_F23 XK_F23 // F23 key #define NUX_VK_F24 XK_F24 // F24 key #define NUX_VK_NUMLOCK XK_Num_Lock // NUM LOCK key #define NUX_VK_SCROLL XK_Scroll_Lock // SCROLL LOCK key #define NUX_VK_LSHIFT XK_Shift_L // Left SHIFT key #define NUX_VK_RSHIFT XK_Shift_R // Right SHIFT key #define NUX_VK_LCONTROL XK_Control_L // Left CONTROL key #define NUX_VK_RCONTROL XK_Control_R // Right CONTROL key #define NUX_VK_LMENU XK_Alt_L // Left MENU key #define NUX_VK_RMENU XK_Alt_R // Right MENU key #define NUX_VK_FF /*0xFF*/ // Multimedia keys. See ScanCode keys. #define NUX_MAX_VK 256 } #endif // VIRTUALKEYCODESX11_H nux-4.0.6+14.04.20140409/NuxGraphics/RenderingPipe.h0000644000015301777760000001025112321344237022073 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RENDERINGPIPE_H #define RENDERINGPIPE_H #include "GLResource.h" namespace nux { //! Graphics wraping modes /*! Defines the wraping modes of TexCoordXForm. The values are matched to OpenGL wraping modes. @sa TexCoordXForm. */ typedef enum { TEXWRAP_UNKNOWN = 0, TEXWRAP_REPEAT, TEXWRAP_CLAMP, TEXWRAP_CLAMP_TO_EDGE, TEXWRAP_CLAMP_TO_BORDER, TEXWRAP_MIRRORED_REPEAT, TEXWRAP_MIRROR_CLAMP_EXT, TEXWRAP_MIRROR_CLAMP_TO_EDGE_EXT, TEXWRAP_MIRROR_CLAMP_TO_BORDER_EXT, } TexWrap; //! Graphics filtering modes /*! Defines the filtering modes of TexCoordXForm. The values are matched to openGL filtering modes. @sa TexCoordXForm. */ typedef enum { TEXFILTER_UNKNOWN = 0, TEXFILTER_LINEAR, TEXFILTER_NEAREST, TEXFILTER_NEAREST_MIPMAP_NEAREST, TEXFILTER_LINEAR_MIPMAP_NEAREST, TEXFILTER_NEAREST_MIPMAP_LINEAR, TEXFILTER_LINEAR_MIPMAP_LINEAR, } TexFilter; //! Graphics blend modes /*! Defines the blending modes. The values are matched to openGL blending modes. */ typedef enum { ROPBLEND_UNKNOWN = 0, ROPBLEND_ZERO, ROPBLEND_ONE, ROPBLEND_SRC_COLOR, ROPBLEND_ONE_MINUS_SRC_COLOR, ROPBLEND_DST_COLOR, ROPBLEND_ONE_MINUS_DST_COLOR, ROPBLEND_SRC_ALPHA, ROPBLEND_ONE_MINUS_SRC_ALPHA, ROPBLEND_DST_ALPHA, ROPBLEND_ONE_MINUS_DST_ALPHA, ROPBLEND_CONSTANT_COLOR, ROPBLEND_ONE_MINUS_CONSTANT_COLOR, ROPBLEND_CONSTANT_ALPHA, ROPBLEND_ONE_MINUS_CONSTANT_ALPHA, ROPBLEND_SRC_ALPHA_SATURATE, } RopBlend; //! Texture parameter and coordinate computation class. /*! Defines the texture coordinate computation, wrapping and filtering modes */ class TexCoordXForm { public: //! Texture coordinates computation mode typedef enum { OFFSET_SCALE_COORD, //!< Texture coordinates are scaled and offset. OFFSET_COORD, //!< Textures coordinates are offset. The scaling factor between the texture size and the quad size is preserved. NORMALIZED_COORD, //!< Provided normalized texture coordinates in u0, v0, u1, v1 UNNORMALIZED_COORD, //!< Provided un-normalized texture coordinates in u0, v0, u1, v1 FIXED_COORD, //!< Provided fix coordinates in u0, v0, u1, v1 } TexCoordType; TexCoordXForm(); void SetTexCoordType(TexCoordType tex_coord_type); void FlipUCoord(bool b); void FlipVCoord(bool b); void FlipUVCoord(bool flip_u, bool flip_v); void SetFilter(TexFilter min_fliter, TexFilter mag_filter); void SetWrap(TexWrap u_wrap, TexWrap v_wrap); //! Texture coordinates are computed automatically by following the TexCoordType policy or provided by the user float u0, v0, u1, v1; float uscale; float vscale; float uoffset; float voffset; TexWrap uwrap; TexWrap vwrap; TexFilter min_filter; TexFilter mag_filter; bool flip_u_coord; bool flip_v_coord; TexCoordType m_tex_coord_type; }; //! Compute texture coordinates and wrapping mode according to TexCoordXForm /*! @param quad_width Quad width. @param quad_height Quad height. @param tex Device texture. @param texxform Texture coordinates computation mode. */ void QRP_Compute_Texture_Coord(int quad_width, int quad_height, ObjectPtr tex, TexCoordXForm &texxform); } #endif // RENDERINGPIPE_H nux-4.0.6+14.04.20140409/NuxGraphics/FontTexture.h0000644000015301777760000001575212321344237021642 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef FONTTEXTURE_H #define FONTTEXTURE_H class IOpenGLPixelShader; namespace nux { typedef enum _TextAlignment { eAlignTextNone = 0, eAlignTextLeft = 1, eAlignTextRight = 2, eAlignTextCenter = 3, } TextAlignment; class StringBBox { public: StringBBox() { x = 0; y = 0; width = 0; height = 0; ybearing = 0; downline = 0; }; ~StringBBox() {}; int x; int y; int width; int height; int ybearing; // max ybearing of the string int downline; // max downline of the string(max space below the baseline) }; class PageBBox { public: PageBBox() { xmin = 0; ymin = 0; xmax = 0; ymax = 0; x_margin = 0; y_margin = 0; }; ~PageBBox() {}; INT xmin; INT ymin; INT xmax; INT ymax; INT x_margin; INT y_margin; }; /////////////////////////////////////////////////////////////////////////////////////////////////////// struct CharDescriptor { //clean 16 bytes unsigned short x; unsigned short y; unsigned short Width; unsigned short Height; short XOffset; short YOffset; unsigned short page; short XAdvance; short abcA; short abcB; short abcC; CharDescriptor() : x( 0 ) , y( 0 ) , Width( 0 ) , Height( 0 ) , XOffset( 0 ) , YOffset( 0 ) , page( 0 ) , XAdvance( 0 ) , abcA( 0 ) , abcB( 0 ) , abcC( 0 ) { } }; struct KerningPair { unsigned short first; unsigned short second; short amount; KerningPair() : first(0), second(0), amount(0) {} }; struct Charset { bool italic; bool bold; unsigned short LineHeight; unsigned short Base; unsigned short Width, Height; unsigned short Pages; unsigned short FontHeight; unsigned short Ascent; unsigned short Descent; int AvgCharWidth; int MaxCharWidth; int InternalLeading; int ExternalLeading; unsigned short NumChar; CharDescriptor Chars[256]; unsigned short NumKerningPairs; KerningPair *Kerning; Charset() : italic(false), bold(false), LineHeight(0), Base(0), Width(0), Height(0) , Pages(0), FontHeight(0), Ascent(0), Descent(0), AvgCharWidth(0) , MaxCharWidth(0), InternalLeading(0), ExternalLeading(0) , NumChar(0), NumKerningPairs(0), Kerning(NULL) {} ~Charset() { delete [] Kerning; } }; // Information about a glyph. Tex_y2 can be calculated from tex_y1 // and _tex_line_height(see below). Advance is the width of the // glyph in screen space. struct Glyph { float tex_x1, tex_y1, tex_x2; int advance; }; class FontRenderer; //////////////////////////////////////////////////////////////////////////////////////////////////// // This font system loads in a custom file containing a gray scale // texture(used as alpha texture) with all the letters on it, and // information about what glyph is where. class FontTexture: public Object { public: NUX_DECLARE_OBJECT_TYPE(FontTexture, Object); FontTexture(const char *FontFile, NUX_FILE_LINE_PROTO); FontTexture(INT width, INT height, BYTE *Texture); ~FontTexture(); // The line height is a constant; int GetLineHeight() const { return m_Charset.FontHeight; } // Knowing the width of a character or a string can be useful if you // want your UI to look good at all. int GetCharWidth(const char &c) const; int GetStringWidth(const std::string &str) const; int GetCharStringWidth(const char *str) const; int GetStringWidth(const std::string &str, int num_char_to_compute) const; int GetCharStringWidth(const char *str, int num_char_to_compute) const; int GetFontHeight(); // CursorPosToX(similar to ScriptStringCPtoX from microsoft UniScript) // The CursorPosToX function returns the x-coordinate for the leading or trailing edge of a character position. // Parameters // icp // [in] Character position in the string. // fTrailing // [in] Indicates the edge of the icp that corresponds to the x coordinate. If TRUE, it indicates the trailing edge. If FALSE, it indicates the leading edge. // pX // [out] Pointer to a variable that receives the corresponding x coordinate for the icp. // // Return Values // If the function succeeds, it returns S_OK. // If the function fails, it returns an HRESULT. // The return value can be tested with the SUCCEEDED and FAILED macros. bool CursorPosToX(const std::string &Str, int icp, bool fTrailing, int *pX); // XToCursorPosition(similar to ScriptStringXtoCP from microsoft UniScript) // The XToCursorPosition function converts an x-coordinate to a character position. // // Parameters // iX // [in] Specifies the x coordinate. // FirstVisibleCharIndex, // [in] Index of the first visible character in the text box // piCh // [out] Pointer to a variable that receives the character position corresponding to iX. // piTrailing // [out] Pointer to a variable that receives an indicator whether the position is the leading or trailing edge of the character. // // Return Values // If the function is successful, it returns S_OK. // If the function fails, it returns an HRESULT. // The return value can be tested with the SUCCEEDED and FAILED macros. bool XToCursorPosition(const std::string &Str, int iX, unsigned int FirstVisibleCharIndex, int *piCh, int *piTrailing); bool BMFontParseFNT( std::istream &Stream); const Charset &GetFontInfo() const; std::vector TextureArray; private: INT _RefCount; INT _textureBMF; std::vector m_gl_texture_id; Charset m_Charset; friend class FontRenderer; }; } #endif //FONTTEXTURE_H nux-4.0.6+14.04.20140409/NuxGraphics/GLTemplatePrimitiveBuffer.h0000644000015301777760000000502512321344237024364 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef TEMPLATEPRIMITIVEBUFFER_H #define TEMPLATEPRIMITIVEBUFFER_H namespace nux { class IOpenGLVertexBuffer; class IOpenGLIndexBuffer; class GpuDevice; typedef struct { Vector4 v0; Vector4 v1; Vector4 v2; Vector4 v3; } QuadAttributeParam; class TemplateQuadBuffer { public: TemplateQuadBuffer(GpuDevice *, ShaderType Type = SHADER_TYPE_GLSL, int NumQuads = 256); ~TemplateQuadBuffer(); //! Bind GLSL parameter void BindAttribute(INT AttributeLocation, UINT AttributeIndex); //! Bind NVidia CG parameter #if (NUX_ENABLE_CG_SHADERS) void BindCGAttribute(CGparameter AttributeLocation, UINT AttributeIndex); void UnBindCGAttribute(CGparameter AttributeLocation); #endif void UnBindAttribute(INT AttributeLocation); void UnBind(); void Render(INT NumPrimitives); //! Set the Vertices's attribute on a per quad basis. /*! Set the Vertices's attribute on a per quad basis. All vertex of the quad will have the same value for the attribute index. */ void SetPerQuadAttribute(UINT AttributeIndex, INT Num, Vector4 *); //! Set the Vertices's attribute on a per vertex basis. /*! Set the vertex attribute on a per vertex basis. */ void SetPerVertexAttribute(UINT AttributeIndex, INT Num, Vector4 *pVector); void UnSetQuadAttribute(UINT AttributeIndex); void SetNumQuads(int NumQuads); int GetNumQuads() const; protected: //IOpenGLVertexBuffer* m_VB; ObjectPtr m_IB; void FormatQuads(); private: ShaderType m_ShaderType; ObjectPtr VertexAttributeBuffer[16]; GpuDevice *m_pDeviceFactory; INT m_NumVertex; INT m_NumQuad; }; } #endif //TEMPLATEPRIMITIVEBUFFER_H nux-4.0.6+14.04.20140409/NuxGraphics/GpuDevice.cpp0000755000015301777760000011675012321344237021564 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "NuxGraphics.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLDeviceFrameBufferObject.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" #include #include #include #include #include namespace nux { #if (NUX_ENABLE_CG_SHADERS) extern void cgErrorCallback(void); #endif typedef struct { int major; int minor; } OpenGLVersion; static OpenGLVersion OpenGLVersionTable [] = { {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 0}, {2, 1}, {3, 0}, {3, 1}, {3, 2}, {3, 3}, {4, 0}, {4, 1}, {0, 0} }; extern PixelFormatInfo GPixelFormats[]; static void InitTextureFormats() { #ifndef NUX_OPENGLES_20 GPixelFormats[ BITFMT_UNKNOWN ].PlatformFormat = GL_NONE; // Not supported for rendering. // Data in PC system memory: R(LSB) G B A(MSB) ---> GL Format:GL_RGBA - GL Type:GL_UNSIGNED_INT_8_8_8_8_REV GPixelFormats[BITFMT_R8G8B8A8].PlatformFormat = GL_RGBA8; GPixelFormats[BITFMT_R8G8B8A8].Format = GL_RGBA; GPixelFormats[BITFMT_R8G8B8A8].type = GL_UNSIGNED_INT_8_8_8_8_REV; // Data in PC system memory: A(LSB) B G R(MSB) ---> GL Format:GL_RGBA - GL Type:GL_UNSIGNED_INT_8_8_8_8 GPixelFormats[BITFMT_A8B8G8R8].PlatformFormat = GL_RGBA8; GPixelFormats[BITFMT_A8B8G8R8].Format = GL_RGBA; GPixelFormats[BITFMT_A8B8G8R8].type = GL_UNSIGNED_INT_8_8_8_8; // Data in PC system memory: B(LSB) G R A(MSB) ---> GL Format:GL_BGRA - GL Type:GL_UNSIGNED_INT_8_8_8_8_REV GPixelFormats[BITFMT_B8G8R8A8].PlatformFormat = GL_RGBA8; GPixelFormats[BITFMT_B8G8R8A8].Format = GL_BGRA; GPixelFormats[BITFMT_B8G8R8A8].type = GL_UNSIGNED_INT_8_8_8_8_REV; // Data in PC system memory: A(LSB) R G B(MSB) ---> GL Format:GL_BGRA - GL Type:GL_UNSIGNED_INT_8_8_8_8 GPixelFormats[BITFMT_A8R8G8B8].PlatformFormat = GL_RGBA8; GPixelFormats[BITFMT_A8R8G8B8].Format = GL_BGRA; GPixelFormats[BITFMT_A8R8G8B8].type = GL_UNSIGNED_INT_8_8_8_8; // Data in PC system memory: R(LSB) G B(MSB) ---> GL Format:GL_RGB - GL Type:GL_UNSIGNED GPixelFormats[BITFMT_R8G8B8].PlatformFormat = GL_RGB8; GPixelFormats[BITFMT_R8G8B8].Format = GL_RGB; GPixelFormats[BITFMT_R8G8B8].type = GL_UNSIGNED_BYTE; GPixelFormats[BITFMT_B8G8R8].PlatformFormat = GL_RGB8; GPixelFormats[BITFMT_B8G8R8].Format = GL_BGR; GPixelFormats[BITFMT_B8G8R8].type = GL_UNSIGNED_BYTE; GPixelFormats[BITFMT_R5G6B5].PlatformFormat = GL_RGB5; GPixelFormats[BITFMT_R5G6B5].Format = GL_RGB; GPixelFormats[BITFMT_R5G6B5].type = GL_UNSIGNED_SHORT_5_6_5; GPixelFormats[BITFMT_RGBA16F].PlatformFormat = GL_RGBA16F_ARB; GPixelFormats[BITFMT_RGBA16F].Format = GL_RGBA; GPixelFormats[BITFMT_RGBA16F].type = GL_HALF_FLOAT_ARB; GPixelFormats[BITFMT_RGB32F].PlatformFormat = GL_RGB; GPixelFormats[BITFMT_RGB32F].Format = GL_RGB; GPixelFormats[BITFMT_RGB32F].type = GL_FLOAT; GPixelFormats[BITFMT_RGBA32F].PlatformFormat = GL_RGBA32F_ARB; GPixelFormats[BITFMT_RGBA32F].Format = GL_RGBA; GPixelFormats[BITFMT_RGBA32F].type = GL_FLOAT; // Note: Using GL_DEPTH_COMPONENT24 or GL_DEPTH_COMPONENT for PlatformFormat generate error GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT. GPixelFormats[BITFMT_D24S8].PlatformFormat = GL_DEPTH24_STENCIL8_EXT; GPixelFormats[BITFMT_D24S8].Format = GL_DEPTH_STENCIL_EXT; // or GL_DEPTH_STENCIL_NV; GPixelFormats[BITFMT_D24S8].type = GL_UNSIGNED_INT_24_8_EXT; // or GL_UNSIGNED_INT_24_8_NV; GPixelFormats[BITFMT_DXT1].PlatformFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; GPixelFormats[BITFMT_DXT2].PlatformFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; GPixelFormats[BITFMT_DXT3].PlatformFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; GPixelFormats[BITFMT_DXT4].PlatformFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; GPixelFormats[BITFMT_DXT5].PlatformFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; GPixelFormats[BITFMT_R10G10B10A2].PlatformFormat = GL_RGB10_A2; GPixelFormats[BITFMT_R10G10B10A2].Format = GL_RGBA; GPixelFormats[BITFMT_R10G10B10A2].type = GL_UNSIGNED_INT_10_10_10_2; GPixelFormats[BITFMT_A2B10G10R10].PlatformFormat = GL_RGB10_A2; GPixelFormats[BITFMT_A2B10G10R10].Format = GL_RGBA; GPixelFormats[BITFMT_A2B10G10R10].type = GL_UNSIGNED_INT_2_10_10_10_REV; GPixelFormats[BITFMT_B10G10R10A2].PlatformFormat = GL_RGB10_A2; GPixelFormats[BITFMT_B10G10R10A2].Format = GL_BGRA; GPixelFormats[BITFMT_B10G10R10A2].type = GL_UNSIGNED_INT_10_10_10_2; GPixelFormats[BITFMT_A2R10G10B10].PlatformFormat = GL_RGB10_A2; GPixelFormats[BITFMT_A2R10G10B10].Format = GL_BGRA; GPixelFormats[BITFMT_A2R10G10B10].type = GL_UNSIGNED_INT_2_10_10_10_REV; GPixelFormats[BITFMT_A8].PlatformFormat = GL_RGBA8; GPixelFormats[BITFMT_A8].Format = GL_LUMINANCE; GPixelFormats[BITFMT_A8].type = GL_UNSIGNED_BYTE; #else GPixelFormats[ BITFMT_UNKNOWN ].PlatformFormat = GL_NONE; // Not supported for rendering. // Data in PC system memory: R(LSB) G B A(MSB) ---> GL Format:GL_RGBA - GL Type:GL_UNSIGNED_INT_8_8_8_8_REV GPixelFormats[BITFMT_R8G8B8A8].PlatformFormat = GL_RGBA; GPixelFormats[BITFMT_R8G8B8A8].Format = GL_RGBA; GPixelFormats[BITFMT_R8G8B8A8].type = GL_UNSIGNED_BYTE; // Data in PC system memory: B(LSB) G R A(MSB) ---> GL Format:GL_BGRA - GL Type:GL_UNSIGNED_INT_8_8_8_8_REV GPixelFormats[BITFMT_B8G8R8A8].PlatformFormat = GL_BGRA_EXT; GPixelFormats[BITFMT_B8G8R8A8].Format = GL_BGRA_EXT; GPixelFormats[BITFMT_B8G8R8A8].type = GL_UNSIGNED_BYTE; // Data in PC system memory: R(LSB) G B(MSB) ---> GL Format:GL_RGB - GL Type:GL_UNSIGNED GPixelFormats[BITFMT_R8G8B8].PlatformFormat = GL_RGB; GPixelFormats[BITFMT_R8G8B8].Format = GL_RGB; GPixelFormats[BITFMT_R8G8B8].type = GL_UNSIGNED_BYTE; GPixelFormats[BITFMT_R5G6B5].PlatformFormat = GL_RGB; GPixelFormats[BITFMT_R5G6B5].Format = GL_RGB; GPixelFormats[BITFMT_R5G6B5].type = GL_UNSIGNED_SHORT_5_6_5; // Note: Using GL_DEPTH_COMPONENT24 or GL_DEPTH_COMPONENT for PlatformFormat generate error GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT. GPixelFormats[BITFMT_D24S8].PlatformFormat = GL_DEPTH_STENCIL_OES; GPixelFormats[BITFMT_D24S8].Format = GL_DEPTH_STENCIL_OES; GPixelFormats[BITFMT_D24S8].type = GL_UNSIGNED_INT_24_8_OES; GPixelFormats[BITFMT_A8].PlatformFormat = GL_ALPHA; GPixelFormats[BITFMT_A8].Format = GL_ALPHA; GPixelFormats[BITFMT_A8].type = GL_UNSIGNED_BYTE; #endif } STREAMSOURCE GpuDevice::_StreamSource[MAX_NUM_STREAM]; GpuInfo::GpuInfo() : _support_opengl_version_11(false) , _support_opengl_version_12(false) , _support_opengl_version_13(false) , _support_opengl_version_14(false) , _support_opengl_version_15(false) , _support_opengl_version_20(false) , _support_opengl_version_21(false) , _support_opengl_version_30(false) , _support_opengl_version_31(false) , _support_opengl_version_32(false) , _support_opengl_version_33(false) , _support_opengl_version_40(false) , _support_opengl_version_41(false) , _opengl_max_texture_size(0) , _opengl_max_texture_units(0) , _opengl_max_texture_coords(0) , _opengl_max_texture_image_units(0) , _opengl_max_fb_attachment(0) , _opengl_max_vertex_attributes(0) , _support_ext_swap_control(false) , _support_arb_vertex_program(false) , _support_arb_fragment_program(false) , _support_arb_shader_objects(false) , _support_arb_vertex_shader(false) , _support_arb_fragment_shader(false) , _support_arb_vertex_buffer_object(false) , _support_arb_texture_non_power_of_two(false) , _support_ext_framebuffer_object(false) , _support_ext_draw_range_elements(false) , _support_ext_stencil_two_side(false) , _support_ext_texture_rectangle(false) , _support_arb_texture_rectangle(false) , _support_nv_texture_rectangle(false) , _support_arb_pixel_buffer_object(false) , _support_ext_blend_equation_separate(false) , _support_depth_buffer(false) #ifndef NUX_OPENGLES_20 , _support_ext_texture_srgb(false) , _support_ext_texture_srgb_decode(false) , _support_ext_framebuffer_srgb(false) , _support_arb_framebuffer_srgb(false) #endif { } void GpuInfo::Setup() { #ifndef NUX_OPENGLES_20 _support_opengl_version_11 = GLEW_VERSION_1_1; _support_opengl_version_12 = GLEW_VERSION_1_2; _support_opengl_version_13 = GLEW_VERSION_1_3; _support_opengl_version_14 = GLEW_VERSION_1_4; _support_opengl_version_15 = GLEW_VERSION_1_5; _support_opengl_version_20 = GLEW_VERSION_2_0; _support_opengl_version_21 = GLEW_VERSION_2_1; _support_opengl_version_30 = GLEW_VERSION_3_0; _support_opengl_version_31 = GLEW_VERSION_3_1; _support_opengl_version_32 = GLEW_VERSION_3_2; // _support_opengl_version_33 = GLEW_VERSION_3_3; // _support_opengl_version_40 = GLEW_VERSION_4_0; // _support_opengl_version_41 = GLEW_VERSION_4_1; // See: http://developer.nvidia.com/object/General_FAQ.html // The value of GL_MAX_TEXTURE_UNITS is 4 for GeForce FX and GeForce 6 Series GPUs. Why is that, since those GPUs have 16 texture units? CHECKGL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_opengl_max_texture_size)); CHECKGL(glGetIntegerv(GL_MAX_TEXTURE_UNITS, &_opengl_max_texture_units)); CHECKGL(glGetIntegerv(GL_MAX_TEXTURE_COORDS, &_opengl_max_texture_coords)); CHECKGL(glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &_opengl_max_texture_image_units)); CHECKGL(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &_opengl_max_vertex_attributes)); CHECKGL(glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &_opengl_max_fb_attachment)); _support_depth_buffer = true; #else // By opengl es 2.0 standard, GL_MAX_TEXTURE_SIZE should return a minimum of 64. CHECKGL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_opengl_max_texture_size)); // GL_MAX_TEXTURE_UNITS is not supported under opengl es 2.0. // GL_MAX_TEXTURE_IMAGE_UNITS is supported under opengl es 2.0. CHECKGL(glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &_opengl_max_texture_image_units)); // GL_MAX_COLOR_ATTACHMENTS_EXT is not supported under opengl es 2.0. _opengl_max_fb_attachment = 1; if (glGetString(GL_OES_depth_texture)) { _support_depth_buffer = true; } #endif #if defined(NUX_OS_WINDOWS) _support_ext_swap_control = WGLEW_EXT_swap_control; #elif defined(NUX_OS_LINUX) && !defined(NUX_OPENGLES_20) _support_ext_swap_control = GLXEW_SGI_swap_control; #endif #ifndef NUX_OPENGLES_20 _support_arb_vertex_program = GLEW_ARB_vertex_program; _support_arb_fragment_program = GLEW_ARB_fragment_program; _support_ext_framebuffer_object = GLEW_EXT_framebuffer_object; _support_arb_shader_objects = GLEW_ARB_shader_objects; _support_arb_vertex_shader = GLEW_ARB_vertex_shader; _support_arb_fragment_shader = GLEW_ARB_fragment_shader; _support_arb_vertex_buffer_object = GLEW_ARB_vertex_buffer_object; _support_arb_texture_non_power_of_two = GLEW_ARB_texture_non_power_of_two; _support_ext_draw_range_elements = GLEW_EXT_draw_range_elements; _support_ext_stencil_two_side = GLEW_EXT_stencil_two_side; _support_ext_texture_rectangle = GLEW_EXT_texture_rectangle; _support_arb_texture_rectangle = GLEW_ARB_texture_rectangle; _support_nv_texture_rectangle = GLEW_NV_texture_rectangle; _support_arb_pixel_buffer_object = GLEW_ARB_pixel_buffer_object; _support_ext_blend_equation_separate = GLEW_EXT_blend_equation_separate; _support_ext_texture_srgb = GLEW_EXT_texture_sRGB; _support_ext_texture_srgb_decode = false; //GLEW_EXT_texture_sRGB_decode; _support_ext_framebuffer_srgb = GLEW_EXT_framebuffer_sRGB; _support_arb_framebuffer_srgb = GLEW_ARB_framebuffer_sRGB; #else _support_arb_vertex_program = false; _support_arb_fragment_program = false; _support_arb_shader_objects = true; _support_arb_vertex_shader = true; _support_arb_fragment_shader = true; _support_arb_vertex_buffer_object = true; _support_arb_texture_non_power_of_two = true; _support_ext_framebuffer_object = true; _support_ext_draw_range_elements = false; _support_ext_stencil_two_side = false; _support_ext_texture_rectangle = false; _support_arb_texture_rectangle = false; _support_nv_texture_rectangle = false; _support_arb_pixel_buffer_object = false; _support_ext_blend_equation_separate = true; #endif } #if defined(NUX_OS_WINDOWS) GpuDevice::GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat, HDC device_context, HGLRC &opengl_rendering_context, int req_opengl_major, int req_opengl_minor, bool opengl_es_20) #elif defined(USE_X11) # ifdef NUX_OPENGLES_20 GpuDevice::GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat, Display *display, Window window, bool has_glx_13_support, EGLConfig fb_config, EGLContext &opengl_rendering_context, int req_opengl_major, int req_opengl_minor, bool opengl_es_20) # else GpuDevice::GpuDevice(unsigned int /* DeviceWidth */, unsigned int /* DeviceHeight */, BitmapFormat /* DeviceFormat */, Display *display, Window window, bool has_glx_13_support, GLXFBConfig fb_config, GLXContext &opengl_rendering_context, int req_opengl_major, int req_opengl_minor, bool opengl_es_20) # endif #elif defined(NO_X11) GpuDevice::GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat, EGLDisplay display, EGLConfig fb_config, EGLContext &opengl_rendering_context, int req_opengl_major, int req_opengl_minor) #endif : opengl_major_(0) , opengl_minor_(0) , use_pixel_buffer_object_(false) , pixel_store_alignment_(4) , gpu_render_states_(NULL) , gpu_info_(NULL) { gpu_brand_ = GPU_VENDOR_UNKNOWN; #ifndef NUX_OPENGLES_20 // OpenGL extension initialization GLenum Glew_Ok = 0; Glew_Ok = Glew_Ok + (1 - 1); // Suppress compiler warning about set but not used variable. #ifdef GLEW_MX Glew_Ok = glewContextInit(glewGetContext()); nuxAssertMsg(Glew_Ok == GLEW_OK, "[GpuDevice::GpuDevice] GL Extensions failed to initialize."); #if defined(NUX_OS_WINDOWS) Glew_Ok = wglewContextInit(wglewGetContext()); #elif defined(NUX_OS_LINUX) Glew_Ok = glxewContextInit(glxewGetContext()); #elif defined(NUX_OS_MACOSX) Glew_Ok = glxewContextInit(glxewGetContext()); #endif nuxAssertMsg(Glew_Ok == GLEW_OK, "[GpuDevice::GpuDevice] OpenGL Extensions failed to initialize."); #else glewInit(); #endif #endif #ifndef NUX_OPENGLES_20 _openGL_version_string = ANSI_TO_TCHAR(NUX_REINTERPRET_CAST(const char *, glGetString(GL_VERSION))); CHECKGL_MSG(glGetString(GL_VERSION)); if (0) { // We need OpenGL minor and major version. Before OpenGL 3.0, the version number was reported as a string of format // "major.minor". That string has to be parsed to extract the major and minor version numbers. This is not really safe as // we have no guaranty that the version string is has we think it is. Some drivers report a version string like "xx.xx.xx". // Begin string parsing to extract the major and minor version numbers. std::string opengl_major; std::string opengl_minor; std::string split = "."; size_t pos = 0; pos = _openGL_version_string.find(split, pos); if (pos != tstring::npos) { size_t split_string_size = split.length(); opengl_major = _openGL_version_string.substr(0, pos); opengl_minor = _openGL_version_string.substr(pos + split_string_size, _openGL_version_string.length() - (pos + split_string_size) ); } int major_length = opengl_major.length(); opengl_major_ = 0; int digit_position = 1; while (major_length && (opengl_major.c_str()[major_length-1] >= '0') && (opengl_major.c_str()[major_length-1] <= '9')) { opengl_major_ += (opengl_major.c_str()[major_length-1] - '0') * digit_position; digit_position *= 10; --major_length; } int minor_length = opengl_minor.length(); opengl_minor_ = 0; digit_position = 0; while (minor_length && (opengl_minor.c_str()[digit_position] >= '0') && (opengl_minor.c_str()[digit_position] <= '9')) { opengl_minor_ += opengl_minor_ * 10 + (opengl_minor.c_str()[digit_position] - '0'); ++digit_position; --minor_length; } // End string parsing if (opengl_major_ >= 3) { CHECKGL(glGetIntegerv(GL_MAJOR_VERSION, &opengl_major_)); CHECKGL(glGetIntegerv(GL_MINOR_VERSION, &opengl_minor_)); } } else { std::vector versions; boost::split(versions, _openGL_version_string, boost::algorithm::is_any_of(".")); opengl_major_ = std::stoi(versions[0]); opengl_minor_ = std::stoi(versions[1]); if (opengl_major_ >= 3) { CHECKGL(glGetIntegerv(GL_MAJOR_VERSION, &opengl_major_)); CHECKGL(glGetIntegerv(GL_MINOR_VERSION, &opengl_minor_)); } } #else opengl_major_ = 2; opengl_minor_ = 0; #endif #if defined(NUX_OS_WINDOWS) bool opengl_es_context_created = false; if (((opengl_major_ >= 3) && (req_opengl_major >= 3)) || (opengl_major_ >= 3) || opengl_es_20) #elif defined(USE_X11) // Should this be GLES check? //bool opengl_es_context_created = false; if (has_glx_13_support && (((opengl_major_ >= 3) && (req_opengl_major >= 3)) || ((opengl_major_ >= 3) && opengl_es_20))) #elif defined(NO_X11) if (((opengl_major_ >= 3) && (req_opengl_major >= 3)) || (opengl_major_ >= 3)) #endif { // Create a new Opengl Rendering Context bool requested_profile_is_supported = false; int index = 0; for (index = 0; OpenGLVersionTable [index].major != 0; index++) { if ((OpenGLVersionTable[index].major == req_opengl_major) && (OpenGLVersionTable[index].minor == req_opengl_minor)) { if (opengl_major_ == 1) { if ((req_opengl_major == 1) && (req_opengl_minor >= 0) && (req_opengl_minor <= 5)) requested_profile_is_supported = true; } else if (opengl_major_ == 2) { if ((req_opengl_major == 2) && (req_opengl_minor >= 0) && (req_opengl_minor <= 1)) requested_profile_is_supported = true; } else if (opengl_major_ == 3) { if ((req_opengl_major == 3) && (req_opengl_minor >= 0) && (req_opengl_minor <= 3)) requested_profile_is_supported = true; } else if (opengl_major_ == 4) { if ((req_opengl_major == 4) && (req_opengl_minor >= 0) && (req_opengl_minor <= 1)) requested_profile_is_supported = true; } break; } } #if !defined(NO_X11) if (opengl_es_20) { #if defined(NUX_OS_WINDOWS) int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 2, WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_PROFILE_MASK_ARB, //WGL_CONTEXT_ES2_PROFILE_BIT_EXT, 0 }; HGLRC new_opengl_rendering_context = wglCreateContextAttribsARB(device_context,0, attribs); if (new_opengl_rendering_context == 0) { nuxDebugMsg("[GpuDevice::GpuDevice] OpenGL ES 2.0 context creation has failed."); } else { wglMakeCurrent(NULL, NULL); wglDeleteContext(opengl_rendering_context); opengl_rendering_context = new_opengl_rendering_context; wglMakeCurrent(device_context, opengl_rendering_context); opengl_es_context_created = true; } #elif defined(NUX_OS_LINUX) /* int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 2, GLX_CONTEXT_MINOR_VERSION_ARB, 0, //GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 0 }; GLXContext new_opengl_rendering_context = glXCreateContextAttribsARB(display, fb_config, 0, true, attribs); if (new_opengl_rendering_context == 0) { nuxDebugMsg("[GpuDevice::GpuDevice] OpenGL ES 2.0 context creation has failed."); } else { opengl_rendering_context = new_opengl_rendering_context; glXMakeCurrent(display, window, opengl_rendering_context); opengl_es_context_created = true; }*/ #endif } else #endif if (requested_profile_is_supported) { #if defined(NUX_OS_WINDOWS) int profile_mask = 0; int profile_value = 0; int flag_mask = 0; int flag_value = 0; if (((req_opengl_major == 3) && (req_opengl_minor >= 3)) || (req_opengl_major >= 4)) { profile_mask = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; profile_value = WGL_CONTEXT_PROFILE_MASK_ARB; flag_mask = WGL_CONTEXT_FLAGS_ARB; flag_value = 0; } int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, req_opengl_major, WGL_CONTEXT_MINOR_VERSION_ARB, req_opengl_minor, profile_mask, profile_value, flag_mask, flag_value, 0 }; HGLRC new_opengl_rendering_context = wglCreateContextAttribsARB(device_context,0, attribs); if (new_opengl_rendering_context == 0) { nuxDebugMsg("[GpuDevice::GpuDevice] OpenGL version %d.%d context creation has failed.", req_opengl_major, req_opengl_minor); } else { wglMakeCurrent(NULL, NULL); wglDeleteContext(opengl_rendering_context); opengl_rendering_context = new_opengl_rendering_context; wglMakeCurrent(device_context, opengl_rendering_context); } #elif defined(NUX_OS_LINUX) && !defined(NUX_OPENGLES_20) int profile_mask = 0; int profile_value = 0; int flag_mask = 0; int flag_value = 0; if (((req_opengl_major == 3) && (req_opengl_minor >= 3)) || (req_opengl_major >= 4)) { profile_mask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; profile_value = GLX_CONTEXT_PROFILE_MASK_ARB; flag_mask = GLX_CONTEXT_FLAGS_ARB; flag_value = 0; } int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, req_opengl_major, GLX_CONTEXT_MINOR_VERSION_ARB, req_opengl_minor, profile_mask, profile_value, flag_mask, flag_value, 0 }; GLXContext new_opengl_rendering_context = glXCreateContextAttribsARB(display, fb_config, 0, true, attribs); if (new_opengl_rendering_context == 0) { nuxDebugMsg("[GpuDevice::GpuDevice] OpenGL version %d.%d context creation has failed.", req_opengl_major, req_opengl_minor); attribs[0] = 1; // major version attribs[1] = 0; // minor version attribs[2] = 0; new_opengl_rendering_context = glXCreateContextAttribsARB(display, fb_config, 0, true, attribs); opengl_rendering_context = new_opengl_rendering_context; glXMakeCurrent(display, window, opengl_rendering_context); } else { opengl_rendering_context = new_opengl_rendering_context; glXMakeCurrent(display, window, opengl_rendering_context); } #endif } else { nuxDebugMsg("[GpuDevice::GpuDevice] Using highest default OpenGL version."); } } _board_vendor_string = ANSI_TO_TCHAR(NUX_REINTERPRET_CAST(const char *, glGetString(GL_VENDOR))); CHECKGL_MSG(glGetString(GL_VENDOR)); _board_renderer_string = ANSI_TO_TCHAR(NUX_REINTERPRET_CAST(const char *, glGetString(GL_RENDERER))); CHECKGL_MSG(glGetString(GL_RENDERER)); _openGL_version_string = ANSI_TO_TCHAR(NUX_REINTERPRET_CAST(const char *, glGetString(GL_VERSION))); CHECKGL_MSG(glGetString(GL_VERSION)); nuxDebugMsg("Gpu Vendor: %s", _board_vendor_string.c_str()); nuxDebugMsg("Gpu Renderer: %s", _board_renderer_string.c_str()); nuxDebugMsg("Gpu OpenGL Version: %s", _openGL_version_string.c_str()); nuxDebugMsg("Gpu OpenGL Major Version: %d", opengl_major_); nuxDebugMsg("Gpu OpenGL Minor Version: %d", opengl_minor_); std::transform(_board_vendor_string.begin(), _board_vendor_string.end(), _board_vendor_string.begin(), ::toupper); if (_board_vendor_string.find("NVIDIA", 0) != tstring::npos) { gpu_brand_ = GPU_BRAND_NVIDIA; } else if (_board_vendor_string.find("ATI", 0) != tstring::npos) { gpu_brand_ = GPU_BRAND_AMD; } else if (_board_vendor_string.find("TUNGSTEN", 0) != tstring::npos) { gpu_brand_ = GPU_BRAND_INTEL; } use_pixel_buffer_object_ = false; gpu_info_ = new GpuInfo(); gpu_info_->Setup(); gpu_render_states_ = new GpuRenderStates(gpu_brand_, gpu_info_); #if defined(NUX_OS_WINDOWS) OGL_EXT_SWAP_CONTROL = WGLEW_EXT_swap_control; #elif defined(NUX_OS_LINUX) && !defined(NUX_OPENGLES_20) OGL_EXT_SWAP_CONTROL = GLXEW_SGI_swap_control; #endif InitTextureFormats(); // See Avoiding 16 Common OpenGL Pitfalls // 7. Watch Your Pixel Store Alignment // http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ // We use a pack /unpack alignment to 1 so we don't have any padding at the end of row. CHECKGL(glPixelStorei(GL_UNPACK_ALIGNMENT, pixel_store_alignment_)); CHECKGL(glPixelStorei(GL_PACK_ALIGNMENT, pixel_store_alignment_)); // _DeviceWidth = DeviceWidth; // _DeviceHeight = DeviceHeight; // // _ViewportX = 0; // _ViewportY = 0; // _ViewportWidth = DeviceWidth; // _ViewportHeight = DeviceHeight; for (int i = 0; i < MAX_NUM_STREAM; i++) { _StreamSource[i].ResetStreamSource(); } // Configure NVidia CG #if (NUX_ENABLE_CG_SHADERS) { m_Cgcontext = 0; // Create Cg context and set profile. CHECKGL(cgSetErrorCallback( cgErrorCallback )); m_Cgcontext = cgCreateContext(); nuxAssert(m_Cgcontext); //CHECKGL(cgGLEnableProfile( CG_PROFILE_VP40 )); //CHECKGL(cgGLEnableProfile( CG_PROFILE_FP40 )); CHECKGL(cgGLSetManageTextureParameters( m_Cgcontext, CG_FALSE )); } #endif if (GetGpuInfo().Support_EXT_Framebuffer_Object()) { _FrameBufferObject = CreateFrameBufferObject(); _FrameBufferObject->Deactivate(); } } GpuDevice::~GpuDevice() { NUX_SAFE_DELETE(gpu_info_); NUX_SAFE_DELETE(gpu_render_states_); _FrameBufferObject.Release(); active_framebuffer_object_.Release(); _PixelBufferArray.clear(); for (int i = 0; i < MAX_NUM_STREAM; i++) { _StreamSource[i].ResetStreamSource(); } // NVidia CG #if (NUX_ENABLE_CG_SHADERS) cgDestroyContext(m_Cgcontext); #endif } ObjectPtr GpuDevice::CreateFrameBufferObject() { ObjectPtr result; result.Adopt(new IOpenGLFrameBufferObject(NUX_TRACKER_LOCATION)); return result; } int GpuDevice::GetOpenGLMajorVersion() const { return opengl_major_; } int GpuDevice::GetOpenGLMinorVersion() const { return opengl_minor_; } unsigned int GpuDevice::GetPixelStoreAlignment() const { return pixel_store_alignment_; } bool GpuDevice::UsePixelBufferObjects() const { return use_pixel_buffer_object_; } GpuBrand GpuDevice::GetGPUBrand() const { return gpu_brand_; } GpuRenderStates &GpuDevice::GetRenderStates() { return *gpu_render_states_; } const GpuInfo& GpuDevice::GetGpuInfo() const { return *gpu_info_; } void GpuDevice::ResetRenderStates() { gpu_render_states_->ResetStateChangeToDefault(); } void GpuDevice::VerifyRenderStates() { gpu_render_states_->CheckStateChange(); } void GpuDevice::InvalidateTextureUnit(int TextureUnitIndex) { CHECKGL(glActiveTextureARB(TextureUnitIndex)); CHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); #ifndef NUX_OPENGLES_20 CHECKGL(glBindTexture(GL_TEXTURE_1D, 0)); CHECKGL(glBindTexture(GL_TEXTURE_CUBE_MAP, 0)); CHECKGL(glBindTexture(GL_TEXTURE_3D, 0)); CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0)); #endif // From lowest priority to highest priority: // GL_TEXTURE_1D, // GL_TEXTURE_2D, // GL_TEXTURE_RECTANGLE_ARB, // GL_TEXTURE_3D, // GL_TEXTURE_CUBE_MAP. #ifndef NUX_OPENGLES_20 CHECKGL(glDisable(GL_TEXTURE_2D)); CHECKGL(glDisable(GL_TEXTURE_1D)); CHECKGL(glDisable(GL_TEXTURE_RECTANGLE_ARB)); CHECKGL(glDisable(GL_TEXTURE_3D)); CHECKGL(glDisable(GL_TEXTURE_CUBE_MAP)); #endif } int GpuDevice::AllocateUnpackPixelBufferIndex(int *index) { unsigned int num = (unsigned int) _PixelBufferArray.size(); for (unsigned int i = 0; i < num; i++) { if (_PixelBufferArray[i].IsReserved == FALSE) { _PixelBufferArray[i].IsReserved = TRUE; *index = i; return OGL_OK; } } // Not enough free pbo PixelBufferObject pbo; pbo.PBO = CreatePixelBufferObject(4, (VBO_USAGE) GL_STATIC_DRAW); pbo.IsReserved = TRUE; _PixelBufferArray.push_back(pbo); *index = (int) _PixelBufferArray.size() - 1; return OGL_OK; } int GpuDevice::FreeUnpackPixelBufferIndex(const int index) { int num = (int) _PixelBufferArray.size(); nuxAssertMsg((index >= 0) && (index < num), "[GpuDevice::FreeUnpackPixelBufferIndex] Trying to Free a pixel buffer index that does not exist."); if ((index < 0) || (index >= num)) { return OGL_ERROR; } _PixelBufferArray[index].IsReserved = false; // // if (0) // // { // // // Can we realloc the memory used by the buffer with much less memory(4x4bytes)??? // // CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, OpenGLID)); // // CHECKGL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 4*4, NULL, GL_STREAM_DRAW_ARB)); // // } return OGL_OK; } void *GpuDevice::LockUnpackPixelBufferIndex(const int index, int Size) { #ifndef NUX_OPENGLES_20 BindUnpackPixelBufferIndex(index); CHECKGL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, Size, NULL, GL_STREAM_DRAW)); void *pBits = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); CHECKGL_MSG(glMapBufferARB ); CHECKGL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); return pBits; #else return NULL; #endif } void* GpuDevice::LockPackPixelBufferIndex(const int index, int Size) { #ifndef NUX_OPENGLES_20 BindPackPixelBufferIndex(index); CHECKGL(glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, Size, NULL, GL_STREAM_DRAW)); void *pBits = glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); CHECKGL_MSG(glMapBufferARB ); CHECKGL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); return pBits; #else return NULL; #endif } void GpuDevice::UnlockUnpackPixelBufferIndex(const int index) { #ifndef NUX_OPENGLES_20 BindUnpackPixelBufferIndex(index); CHECKGL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); CHECKGL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); #endif } void GpuDevice::UnlockPackPixelBufferIndex(const int index) { #ifndef NUX_OPENGLES_20 BindPackPixelBufferIndex(index); CHECKGL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); CHECKGL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); #endif } int GpuDevice::BindUnpackPixelBufferIndex(const int index) { int num = (int) _PixelBufferArray.size(); nuxAssertMsg((index >= 0) && (index < num), "[GpuDevice::BindUnpackPixelBufferIndex] Trying to bind an invalid pixel buffer index."); if ((index < 0) || (index >= num)) { return OGL_ERROR; } nuxAssertMsg(_PixelBufferArray[index].IsReserved == true, "[GpuDevice::BindUnpackPixelBufferIndex] Trying to reserved pixel buffer index."); if (_PixelBufferArray[index].IsReserved == false) { return OGL_ERROR; } _PixelBufferArray[index].PBO->BindUnpackPixelBufferObject(); return OGL_OK; } int GpuDevice::BindPackPixelBufferIndex(const int index) { int num = (int) _PixelBufferArray.size(); nuxAssertMsg((index >= 0) && (index < num), "[GpuDevice::BindPackPixelBufferIndex] Trying to bind an invalid pixel buffer index."); if ((index < 0) || (index >= num)) { return OGL_ERROR; } nuxAssertMsg(_PixelBufferArray[index].IsReserved == true, "[GpuDevice::BindPackPixelBufferIndex] Trying to reserved pixel buffer index."); if (_PixelBufferArray[index].IsReserved == false) { return OGL_ERROR; } _PixelBufferArray[index].PBO->BindPackPixelBufferObject(); return OGL_OK; } int GpuDevice::FormatFrameBufferObject(unsigned int Width, unsigned int Height, BitmapFormat PixelFormat) { if (!GetGpuInfo().Support_EXT_Framebuffer_Object()) { nuxDebugMsg("[GpuDevice::FormatFrameBufferObject] No support for OpenGL framebuffer extension."); return 0; } return _FrameBufferObject->FormatFrameBufferObject(Width, Height, PixelFormat); } int GpuDevice::SetColorRenderTargetSurface(unsigned int ColorAttachmentIndex, ObjectPtr pRenderTargetSurface) { if (!GetGpuInfo().Support_EXT_Framebuffer_Object()) { nuxDebugMsg("[GpuDevice::SetColorRenderTargetSurface] No support for OpenGL framebuffer extension."); return 0; } return _FrameBufferObject->SetRenderTarget(ColorAttachmentIndex, pRenderTargetSurface); } int GpuDevice::SetDepthRenderTargetSurface(ObjectPtr pDepthSurface) { if (!GetGpuInfo().Support_EXT_Framebuffer_Object()) { nuxDebugMsg("[GpuDevice::SetDepthRenderTargetSurface] No support for OpenGL framebuffer extension."); return 0; } return _FrameBufferObject->SetDepthSurface(pDepthSurface); } ObjectPtr GpuDevice::GetColorRenderTargetSurface(unsigned int ColorAttachmentIndex) { if (!GetGpuInfo().Support_EXT_Framebuffer_Object()) { nuxDebugMsg("[GpuDevice::GetColorRenderTargetSurface] No support for OpenGL framebuffer extension."); return ObjectPtr (0); } return _FrameBufferObject->GetRenderTarget(ColorAttachmentIndex); } ObjectPtr GpuDevice::GetDepthRenderTargetSurface() { if (!GetGpuInfo().Support_EXT_Framebuffer_Object()) { nuxDebugMsg("[GpuDevice::GetDepthRenderTargetSurface] No support for OpenGL framebuffer extension."); return ObjectPtr (0); } return _FrameBufferObject->GetDepthRenderTarget(); } void GpuDevice::ActivateFrameBuffer() { if (!GetGpuInfo().Support_EXT_Framebuffer_Object()) { nuxDebugMsg("[GpuDevice::ActivateFrameBuffer] No support for OpenGL framebuffer extension."); return; } _FrameBufferObject->Activate(); } void GpuDevice::SetCurrentFrameBufferObject(ObjectPtr fbo) { active_framebuffer_object_ = fbo; } ObjectPtr GpuDevice::GetFrameBufferObject() const { return _FrameBufferObject; } ObjectPtr GpuDevice::GetCurrentFrameBufferObject() { return active_framebuffer_object_; } ObjectPtr GpuDevice::ActiveFboTextureAttachment(int color_attachment_index) { if (active_framebuffer_object_.IsValid()) { return active_framebuffer_object_->TextureAttachment(color_attachment_index); } return ObjectPtr(0); } ObjectPtr GpuDevice::ActiveFboDepthTextureAttachment() { if (active_framebuffer_object_.IsValid()) { return active_framebuffer_object_->DepthTextureAttachment(); } return ObjectPtr(0); } void GpuDevice::DeactivateFrameBuffer() { if (!GetGpuInfo().Support_EXT_Framebuffer_Object()) { nuxDebugMsg("[GpuDevice::DeactivateFrameBuffer] No support for OpenGL framebuffer extension."); return; } #ifdef NUX_OPENGLES_20 GLenum binding = GL_FRAMEBUFFER; #else GLenum binding = GL_DRAW_FRAMEBUFFER_EXT; #endif active_framebuffer_object_.Release(); CHECKGL(glBindFramebufferEXT(binding, 0)); CHECKGL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0)); } ObjectPtr GpuDevice::CreateSystemCapableDeviceTexture( int Width , int Height , int Levels , BitmapFormat PixelFormat , NUX_FILE_LINE_DECL) { if ((Width <= 0) || (Height <= 0)) { return ObjectPtr(0); } if (GetGpuInfo().Support_ARB_Texture_Non_Power_Of_Two()) { return CreateTexture(Width, Height, Levels, PixelFormat, NUX_FILE_LINE_PARAM); } if (GetGpuInfo().Support_EXT_Texture_Rectangle() || GetGpuInfo().Support_ARB_Texture_Rectangle()) { return CreateRectangleTexture(Width, Height, Levels, PixelFormat, NUX_FILE_LINE_PARAM); } nuxAssertMsg(0, "[NuxGraphicsResources::CreateSystemCapableDeviceTexture] No support for non power of two textures or rectangle textures"); return ObjectPtr(); } BaseTexture* GpuDevice::CreateSystemCapableTexture(NUX_FILE_LINE_DECL) { if (GetGpuInfo().Support_ARB_Texture_Non_Power_Of_Two()) { return new Texture2D(NUX_FILE_LINE_PARAM); // Why are we creating a texture without a texture here? } if (GetGpuInfo().Support_EXT_Texture_Rectangle() || GetGpuInfo().Support_ARB_Texture_Rectangle()) { return new TextureRectangle(NUX_FILE_LINE_PARAM); // Why are we creating a texture without a texture here? } nuxAssertMsg(0, "[NuxGraphicsResources::CreateSystemCapableTexture] No support for non power of two textures or rectangle textures"); return 0; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLVolumeTexture.h0000644000015301777760000000521212321344237023347 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLVOLUMETEXTURE_H #define IOPENGLVOLUMETEXTURE_H namespace nux { class IOpenGLBaseTexture; class IOpenGLVolumeTexture: public IOpenGLBaseTexture { NUX_DECLARE_OBJECT_TYPE(IOpenGLVolumeTexture, IOpenGLBaseTexture); public: virtual ~IOpenGLVolumeTexture(); int GetVolumeLevel( int Level, IOpenGLVolume **ppVolumeLevel ); int VolumeLockRect( int Slice, int Level, SURFACE_LOCKED_RECT *pLockedRect, const SURFACE_RECT *pRect); int VolumeUnlockRect( int Slice, int Level ); int LockBox( int Level, VOLUME_LOCKED_BOX *pLockedVolume, const VOLUME_BOX *pBox); int UnlockBox( int Level ); int GetLevelDepth(int MipLevel) const { return ImageSurface::GetLevelDim(_PixelFormat, _Depth, MipLevel); } int GetLevelDesc( int Level, VOLUME_DESC *pDesc ) { nuxAssert(Level >= 0 ); nuxAssert(Level < _NumMipLevel); if ((Level < 0) || (Level > _NumMipLevel)) { pDesc->Width = 0; pDesc->Height = 0; pDesc->Depth = 0; pDesc->PixelFormat = BITFMT_UNKNOWN; pDesc->Type = _ResourceType; } else { pDesc->Width = Max (1, _Width >> Level); pDesc->Height = Max (1, _Height >> Level); pDesc->Depth = _Depth; pDesc->PixelFormat = _PixelFormat; pDesc->Type = _ResourceType; } return OGL_OK; } private: IOpenGLVolumeTexture( int Width , int Height , int Depth , int Levels , BitmapFormat PixelFormat); std::vector< ObjectPtr > *_VolumeSurfaceArray; std::vector< ObjectPtr > _VolumeArray; friend class GpuDevice; friend class IOpenGLSurface; }; } #endif // IOPENGLVOLUMETEXTURE_H nux-4.0.6+14.04.20140409/NuxGraphics/XInputWindow.h0000644000015301777760000000504112321344237021760 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef XINPUTWINDOW_H #define XINPUTWINDOW_H /* Xlib.h is the default header that is included and has the core functionallity */ #include /* Xatom.h includes functionallity for creating new protocol messages */ #include /* keysym.h contains keysymbols which we use to resolv what keys that are being pressed */ #include #include #include #include "NuxCore/NuxCore.h" #include "NuxCore/Rect.h" namespace nux { class XInputWindow { public: XInputWindow(const char* title, bool take_focus = False, int override_redirect = 0); ~XInputWindow(); static std::vector const& NativeHandleList(); void EnableStruts(bool enable); bool StrutsEnabled(); void EnableOverlayStruts(bool enable); bool OverlayStrutsEnabled(); void EnsureInputs(); void EnableTakeFocus (); //! Set the position and size of the window void SetGeometry(const Rect& geo); //! Set the position and size of the window void SetGeometry(int x, int y, int width, int height); //! Get the window geometry. Rect const& GetGeometry() const; //! Get X11 the Window. Window GetWindow (); void SetInputFocus (); void Hide (); void Show (); private: std::vector GetStrutsData(); void SetStruts (); void UnsetStruts (); void SetOverlayStruts (); void UnsetOverlayStruts (); void EnableDnd (); void DisableDnd (); static std::vector native_windows_; bool strutsEnabled_; bool overlayStrutsEnabled_; Window window_; Display *display_; Rect geometry_; bool shown_; bool mapped_; }; } #endif // XINPUTWINDOW_H nux-4.0.6+14.04.20140409/NuxGraphics/GLTextureResourceManager.cpp0000644000015301777760000010640212321344237024565 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GLResourceManager.h" #include "GpuDevice.h" #include "GraphicsEngine.h" #include "GLTextureResourceManager.h" #include "NuxCore/Logger.h" namespace nux { DECLARE_LOGGER(logger, "nux.gltexture.resource.manager"); NUX_IMPLEMENT_OBJECT_TYPE(BaseTexture); NUX_IMPLEMENT_OBJECT_TYPE(Texture2D); NUX_IMPLEMENT_OBJECT_TYPE(TextureRectangle); NUX_IMPLEMENT_OBJECT_TYPE(TextureCube); NUX_IMPLEMENT_OBJECT_TYPE(TextureVolume); NUX_IMPLEMENT_OBJECT_TYPE(TextureFrameAnimation); NUX_IMPLEMENT_OBJECT_TYPE(CachedBaseTexture); NUX_IMPLEMENT_OBJECT_TYPE(CachedTexture2D); NUX_IMPLEMENT_OBJECT_TYPE(CachedTextureRectangle); NUX_IMPLEMENT_OBJECT_TYPE(CachedTextureCube); NUX_IMPLEMENT_OBJECT_TYPE(CachedTextureVolume); NUX_IMPLEMENT_OBJECT_TYPE(CachedTextureFrameAnimation); namespace { nux::BaseTexture* get_null_texture(std::string const& extra_msg = "") { if (!g_getenv("NUX_FALLBACK_TEXTURE")) { LOG_ERROR(logger) << "Invalid target, impossible to generate a new texture." << " " << extra_msg; return nullptr; } LOG_WARN(logger) << "Invalid target, impossible to generate a new valid texture." << " " << extra_msg << ". Using fallback mode..."; return GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); } } /*! Up cast a Resource. The source must be derived from the destination type @param T Destination type. @param U Source type. @return The casted to the destination type */ template < class T, class U > static T* UpCastResource(U* Src) { if (!Src || !Src->Type().IsDerivedFromType(T::StaticObjectType)) nuxError("[UpCastResource] Cast of %s to %s failed", U::StaticObjectType.name, T::StaticObjectType.name); return(T*) Src; } BaseTexture* CreateTexture2DFromPixbuf(GdkPixbuf* pixbuf, bool premultiply) { NUX_RETURN_VALUE_IF_NULL(pixbuf, get_null_texture("Null Pixbuf")); const unsigned int rowstride = gdk_pixbuf_get_rowstride(pixbuf); const unsigned int width = gdk_pixbuf_get_width(pixbuf); const unsigned int height = gdk_pixbuf_get_height(pixbuf); // Put the RGB or RGBA pixels in a RGBA texture data object taking care // of alpha premultiplication if requested. // FIXME(loicm) Implies a useless copy. NTextureData should be able to // take ownership of pre-allocated memory. // FIXME(loicm) Add support for big-endian systems. For performance // reasons, pixels are loaded by block of 4 bytes with the color // components bit-shifted considering little-endian ordering. Nux // doesn't seem to be big-endian aware anyway. // FIXME(loicm) Surface::Write32b does branching, splits the 32-bit value // as four 8-bit values(using bit-shifts) that are then stored // separately, that's slow considering it's meant to be used a lot in // deep loops. NTextureData* data = new NTextureData(BITFMT_R8G8B8A8, width, height, 1); ImageSurface& surface = data->GetSurface(0); if (gdk_pixbuf_get_has_alpha(pixbuf) == TRUE) { unsigned char* pixels_u8 = gdk_pixbuf_get_pixels(pixbuf); unsigned int* pixels_u32 = reinterpret_cast (pixels_u8); unsigned char* dest_u8 = surface.GetPtrRawData (); const int pitch = surface.GetPitch (); if (premultiply == true) { // Copy from pixbuf(RGBA) to surface(premultiplied RGBA). for (unsigned int i = 0; i < height; i++) { unsigned int* dest_u32 = reinterpret_cast(dest_u8); for (unsigned int j = 0; j < width; j++) { const unsigned int pixel = pixels_u32[j]; const unsigned int a = pixel >> 24; if (a == 0) { dest_u32[j] = 0; } else { const unsigned int b = (((pixel >> 16) & 0xff) * a) / 255; const unsigned int g = (((pixel >> 8) & 0xff) * a) / 255; const unsigned int r = ((pixel & 0xff) * a) / 255; const unsigned int p = a << 24 | b << 16 | g << 8 | r; dest_u32[j] = p; } } pixels_u8 += rowstride; pixels_u32 = reinterpret_cast (pixels_u8); dest_u8 += pitch; } } else { // Copy from pixbuf(RGBA) to surface(RGBA). for (unsigned int i = 0; i < height; i++) { Memcpy (dest_u8, pixels_u8, width * 4); pixels_u8 += rowstride; dest_u8 += pitch; } } } else { // Copy from pixbuf(RGB) to surface(RGBA). unsigned char* pixels = gdk_pixbuf_get_pixels(pixbuf); unsigned char* dest_u8 = surface.GetPtrRawData(); const int pitch = surface.GetPitch(); for (unsigned int i = 0; i < height; i++) { unsigned int* dest_u32 = reinterpret_cast(dest_u8); for (unsigned int j = 0; j < width; j++) { const unsigned char r = pixels[j*3]; const unsigned char g = pixels[j*3+1]; const unsigned char b = pixels[j*3+2]; const unsigned int p = 0xff000000 | b << 16 | g << 8 | r; dest_u32[j] = p; } pixels += rowstride; dest_u8 += pitch; } } // Create a 2D texture and upload the pixels. BaseTexture* texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); texture->Update(data); delete data; // data is deleted as texture->Update() copies it. return texture; } BaseTexture* CreateTexture2DFromFile(const char* filename, int max_size, bool premultiply) { NUX_RETURN_VALUE_IF_NULL(filename, get_null_texture("Empty filename")); GError* error = NULL; GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_size(filename, max_size, max_size, &error); if (error == NULL) { BaseTexture* texture = CreateTexture2DFromPixbuf(pixbuf, premultiply); g_object_unref(pixbuf); return texture; } else { std::string error_msg = (error->message ? error->message : "Unknown error"); g_error_free(error); return get_null_texture("Impossible to generate a pixbuf: "+error_msg); } } BaseTexture* CreateTextureFromPixbuf(GdkPixbuf* pixbuf) { NBitmapData* BitmapData = LoadGdkPixbuf(pixbuf); NUX_RETURN_VALUE_IF_NULL(BitmapData, get_null_texture("Invalid Pixbuf")); if (BitmapData->IsTextureData()) { BaseTexture* texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); texture->Update(BitmapData); return texture; } delete BitmapData; return get_null_texture("Invalid Pixbuf"); } BaseTexture* CreateTextureFromFile(const char* TextureFilename) { BaseTexture* texture = NULL; NBitmapData* BitmapData = LoadImageFile(TextureFilename); NUX_RETURN_VALUE_IF_NULL(BitmapData, get_null_texture("No data for '"+(TextureFilename ? std::string(TextureFilename) : "")+"'")); if (BitmapData->IsTextureData()) { texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); } else if (BitmapData->IsCubemapTextureData()) { texture = new TextureCube(); } else if (BitmapData->IsVolumeTextureData()) { texture = new TextureVolume(); } else if (BitmapData->IsAnimatedTextureData()) { texture = new TextureFrameAnimation(); } if (texture) { texture->Update(BitmapData); } else { nuxDebugMsg("[CreateTextureFromFile] Invalid texture format type for file(%s)", TextureFilename); texture = get_null_texture(); } delete BitmapData; return texture; } BaseTexture* CreateTextureFromBitmapData(const NBitmapData* BitmapData) { NUX_RETURN_VALUE_IF_NULL(BitmapData, get_null_texture("Invalid BitmapData")); if (BitmapData->IsTextureData()) { BaseTexture* texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture(); texture->Update(BitmapData); return texture; } else if (BitmapData->IsCubemapTextureData()) { TextureCube* texture = new TextureCube(); texture->Update(BitmapData); return texture; } else if (BitmapData->IsVolumeTextureData()) { TextureVolume* texture = new TextureVolume(); texture->Update(BitmapData); return texture; } else if (BitmapData->IsAnimatedTextureData()) { TextureFrameAnimation* texture = new TextureFrameAnimation(); texture->Update(BitmapData); return texture; } return get_null_texture(); } BaseTexture* LoadTextureFromFile(const std::string& filename) { NBitmapData* bitmap = LoadImageFile(filename.c_str()); NUX_RETURN_VALUE_IF_NULL(bitmap, get_null_texture("No Data for '"+filename+"'")); BaseTexture* texture = CreateTextureFromBitmapData(bitmap); delete bitmap; return texture; } BaseTexture::BaseTexture(NUX_FILE_LINE_DECL) : ResourceData(NUX_FILE_LINE_PARAM) { } BaseTexture::~BaseTexture() { } ObjectPtr < IOpenGLBaseTexture > BaseTexture::GetDeviceTexture() { ObjectPtr CachedTexture = GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(this); return CachedTexture->m_Texture; } ObjectPtr BaseTexture::GetCachedTexture() { return GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(this); } Texture2D::Texture2D(NUX_FILE_LINE_DECL) // TODO: Why can we create a texture without a texture? : BaseTexture(NUX_FILE_LINE_PARAM) { } Texture2D::Texture2D(const NTextureData& texture_data, NUX_FILE_LINE_DECL) : BaseTexture(NUX_FILE_LINE_PARAM), _image(texture_data) { } Texture2D::~Texture2D() { } bool Texture2D::Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource) { nuxAssertMsg(BitmapData, "[Texture2D::Update] Argument BitmapData is NULL."); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); if (!BitmapData->IsTextureData()) { nuxAssertMsg(0, "[Texture2D::Update] Argument BitmapData is not a 2D texture"); return false; } _image = *static_cast (BitmapData); if (UpdateAndCacheResource) { // call the texture manager and recreate the texture(CachedTexture2D) associated with this object if any. GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource(this); } return true; } bool Texture2D::Update(const char* filename, bool UpdateAndCacheResource) { NBitmapData* BitmapData = LoadImageFile(filename); nuxAssertMsg(BitmapData, "[Texture2D::Update] Bitmap for file(%s) is NULL.", filename); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); bool ret = Update(BitmapData, UpdateAndCacheResource); NUX_SAFE_DELETE(BitmapData); return ret; } void Texture2D::GetData(void* Buffer, int MipIndex, int StrideY, int /* face */) { BYTE *Dest = (BYTE*) Buffer; const BYTE *Src = _image.GetSurface(MipIndex).GetPtrRawData(); int RowByteSize = _image.GetSurface(MipIndex).GetPitch(); int NumRows = _image.GetSurface(MipIndex).GetBlockHeight(); for ( int Y = 0; Y < NumRows; Y++ ) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. Memcpy(Dest + Y * StrideY, &Src[Y * RowByteSize], Min(RowByteSize, StrideY)); } } Texture2D* Texture2D::Clone() const { return new Texture2D(_image); } CachedBaseTexture::CachedBaseTexture(NResourceSet* ResourceManager) : CachedResourceData(ResourceManager), SourceWidth(0), SourceHeight(0), SourceDepth(0), SourceFormat(BITFMT_UNKNOWN) { } CachedBaseTexture::~CachedBaseTexture() { m_Texture.Release(); } bool CachedBaseTexture::UpdateResource(ResourceData* Resource) { UpdateTexture((BaseTexture*) Resource); return TRUE; } bool CachedBaseTexture::RecreateTexture(BaseTexture* Source) { if (!m_Texture) return false; int CurrentWidth = m_Texture->GetWidth(); int CurrentHeight = m_Texture->GetHeight(); int CurrentDepth = m_Texture->GetDepth(); int CurrentNumMipmap = m_Texture->GetNumMipLevel(); BitmapFormat CurrentFormat = m_Texture->GetPixelFormat(); bool Recreate = (CurrentWidth != Source->GetWidth()) || (CurrentHeight != Source->GetHeight()) || (CurrentDepth != Source->GetDepth()) || (CurrentNumMipmap != Source->GetNumMipLevel()) || (CurrentFormat != Source->GetFormat()); return Recreate; } CachedTexture2D::CachedTexture2D(NResourceSet* ResourceManager, Texture2D* SourceTexture) : CachedBaseTexture(ResourceManager) { if (SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat(), NUX_TRACKER_LOCATION); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } CachedTexture2D::~CachedTexture2D() { } void CachedTexture2D::UpdateTexture( BaseTexture* SourceTexture ) { if ((SourceTexture == 0) || SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } if (!SourceTexture->Type().IsObjectType(Texture2D::StaticObjectType)) { nuxAssertMsg(0, "[Texture2D::UpdateTexture] Source texture is not of type Texture2D."); return; } if ( RecreateTexture(SourceTexture)) { m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat(), NUX_TRACKER_LOCATION); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } else { for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } } void CachedTexture2D::LoadMipLevel(BaseTexture* SourceTexture, int MipLevel) { SURFACE_LOCKED_RECT LockedRect; ObjectPtr < IOpenGLTexture2D > Texture2D = m_Texture; //m_Texture.CastRef(); if (!Texture2D) return; OGL_CALL(Texture2D->LockRect(MipLevel, &LockedRect, NULL)); SourceTexture->GetData(LockedRect.pBits, MipLevel, LockedRect.Pitch); OGL_CALL(Texture2D->UnlockRect(MipLevel)); } TextureRectangle::TextureRectangle(NUX_FILE_LINE_DECL) : BaseTexture(NUX_FILE_LINE_PARAM) { } TextureRectangle::TextureRectangle(const NTextureData& texture, NUX_FILE_LINE_DECL) : BaseTexture(NUX_FILE_LINE_PARAM), _image(texture) { } TextureRectangle::~TextureRectangle() { } bool TextureRectangle::Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource) { nuxAssertMsg(BitmapData, "[TextureRectangle::Update] Argument BitmapData is NULL."); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); if (!BitmapData->IsTextureData()) { nuxAssertMsg(0, "[TextureRectangle::Update] Argument BitmapData is not a 2D texture"); return false; } _image = *static_cast (BitmapData); if (UpdateAndCacheResource) { // call the texture manager and recreate the texture(CachedTexture2D) associated with this object if any. GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource(this); } return true; } bool TextureRectangle::Update(const char* filename, bool /* UpdateAndCacheResource */) { bool b = false; NBitmapData* BitmapData = LoadImageFile(filename); nuxAssertMsg(BitmapData, "[TextureRectangle::Update] Bitmap for file(%s) is NULL.", filename); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); b = Update(BitmapData); NUX_SAFE_DELETE(BitmapData); return b; } void TextureRectangle::GetData(void* Buffer, int MipIndex, int StrideY, int /* face */) { BYTE *Dest = (BYTE *) Buffer; const BYTE *Src = _image.GetSurface(MipIndex).GetPtrRawData(); int RowByteSize = _image.GetSurface(MipIndex).GetPitch(); int NumRows = _image.GetSurface(MipIndex).GetBlockHeight(); for ( int Y = 0; Y < NumRows; Y++ ) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. Memcpy(Dest + Y * StrideY, &Src[Y * RowByteSize], Min(RowByteSize, StrideY)); } } TextureRectangle* TextureRectangle::Clone() const { return new TextureRectangle(_image); } CachedTextureRectangle::CachedTextureRectangle(NResourceSet* ResourceManager, TextureRectangle* SourceTexture) : CachedBaseTexture(ResourceManager) { if (SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateRectangleTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat(), NUX_TRACKER_LOCATION); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } CachedTextureRectangle::~CachedTextureRectangle() { } void CachedTextureRectangle::UpdateTexture( BaseTexture* SourceTexture ) { if ((SourceTexture == 0) || SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } if (!SourceTexture->Type().IsObjectType(TextureRectangle::StaticObjectType)) { nuxAssertMsg(0, "[CachedTextureRectangle::UpdateTexture] Source texture is not of type TextureRectangle."); return; } if ( RecreateTexture(SourceTexture)) { m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateRectangleTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat(), NUX_TRACKER_LOCATION); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } else { for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } } void CachedTextureRectangle::LoadMipLevel(BaseTexture* SourceTexture, int MipLevel) { SURFACE_LOCKED_RECT LockedRect; ObjectPtr TextureRectangle = m_Texture; //m_Texture.CastRef(); if (!TextureRectangle) return; OGL_CALL(TextureRectangle->LockRect( MipLevel, &LockedRect, NULL)); SourceTexture->GetData( LockedRect.pBits, MipLevel, LockedRect.Pitch ); OGL_CALL(TextureRectangle->UnlockRect( MipLevel )); } TextureCube::TextureCube(NUX_FILE_LINE_DECL) // TODO: why can we have a texture without a texture? : BaseTexture(NUX_FILE_LINE_PARAM) { } TextureCube::TextureCube(const NCubemapData& Image) : _image(Image) { } TextureCube::~TextureCube() { } bool TextureCube::Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource) { nuxAssertMsg(BitmapData, "[TextureCube::Update] Argument BitmapData is NULL."); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); if (!BitmapData->IsCubemapTextureData()) { nuxAssertMsg(0, "[TextureCube::Update] Argument BitmapData is not a Cube texture"); return false; } _image = *static_cast (BitmapData); if (UpdateAndCacheResource) { // call the texture manager and recreate the texture(CachedTexture2D) associated with this object if any. GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource(this); } return true; } bool TextureCube::Update(const char* filename, bool /* UpdateAndCacheResource */) { NBitmapData* BitmapData = LoadImageFile(filename); nuxAssertMsg(BitmapData, "[TextureCube::Update] Bitmap for file(%s) is NULL.", filename); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); bool ret = Update(BitmapData); NUX_SAFE_DELETE(BitmapData); return ret; } void TextureCube::GetData(void* Buffer, int MipIndex, int StrideY, int face) { BYTE *Dest = (BYTE *) Buffer; const BYTE *Src = _image.GetSurface(face, MipIndex).GetPtrRawData(); int RowByteSize = _image.GetSurface(face, MipIndex).GetPitch(); int NumRows = _image.GetSurface(face, MipIndex).GetBlockHeight(); for ( int Y = 0; Y < NumRows; Y++ ) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. Memcpy(Dest + Y * StrideY, &Src[Y * RowByteSize], Min(RowByteSize, StrideY)); } } TextureCube* TextureCube::Clone() const { return new TextureCube(_image); } CachedTextureCube::CachedTextureCube(NResourceSet* ResourceManager, TextureCube* SourceTexture) : CachedBaseTexture(ResourceManager) { if (SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateCubeTexture(SourceTexture->GetWidth(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat()); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } CachedTextureCube::~CachedTextureCube() { } void CachedTextureCube::UpdateTexture( BaseTexture* SourceTexture ) { if ((SourceTexture == 0) || SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } if (!SourceTexture->Type().IsObjectType(TextureCube::StaticObjectType)) { nuxAssertMsg(0, "[CachedTextureCube::UpdateTexture] Source texture is not of type TextureCube."); return; } if ( RecreateTexture(SourceTexture)) { m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateCubeTexture(SourceTexture->GetWidth(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat()); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } else { for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } } void CachedTextureCube::LoadMipLevel(BaseTexture* SourceTexture, int MipLevel) { SURFACE_LOCKED_RECT LockedRect; ObjectPtr CubemapTexture = m_Texture; //m_Texture.CastRef(); if (!CubemapTexture) return; for (int face = CUBEMAP_FACE_POSITIVE_X; face < GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + 1; face++) { OGL_CALL( CubemapTexture->CubeLockRect(eCUBEMAP_FACES(face), MipLevel, &LockedRect, NULL)); SourceTexture->GetData(LockedRect.pBits, MipLevel, LockedRect.Pitch, face - CUBEMAP_FACE_POSITIVE_X); OGL_CALL( CubemapTexture->CubeUnlockRect(eCUBEMAP_FACES(face), MipLevel )); } } TextureVolume::TextureVolume(NUX_FILE_LINE_DECL) // TODO: why can we have a texture without a texture? : BaseTexture(NUX_FILE_LINE_PARAM) { } TextureVolume::TextureVolume(const NVolumeData& Image) : _image(Image) { } TextureVolume::~TextureVolume() { } bool TextureVolume::Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource) { nuxAssertMsg(BitmapData, "[TextureVolume::Update] Argument BitmapData is NULL."); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); if (!BitmapData->IsVolumeTextureData()) { nuxAssertMsg(0, "[TextureVolume::Update] Argument BitmapData is not a Volume texture"); return false; } _image = *static_cast (BitmapData); if (UpdateAndCacheResource) { // call the texture manager and recreate the texture(CachedTexture2D) associated with this object if any. GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource(this); } return true; } bool TextureVolume::Update(const char* filename, bool /* UpdateAndCacheResource */) { NBitmapData* BitmapData = LoadImageFile(filename); nuxAssertMsg(BitmapData, "[TextureVolume::Update] Bitmap for file(%s) is NULL.", filename); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); bool ret = Update(filename); NUX_SAFE_DELETE(BitmapData); return ret; } void TextureVolume::GetData(void* Buffer, int MipIndex, int StrideY, int /* face */) { BYTE *Dest = (BYTE *) Buffer; // const BYTE* Src = _image.GetSurface(MipIndex, slice).GetPtrRawData(); // int RowByteSize = _image.GetSurface(MipIndex, slice).GetPitch(); // int NumRows = _image.GetSurface(MipIndex, slice).GetBlockHeight(); for (int slice = 0; slice < ImageSurface::GetLevelDim(_image.GetFormat(), _image.GetDepth(), MipIndex); slice++) { const BYTE *Src = _image.GetSurface(slice, MipIndex).GetPtrRawData(); int RowByteSize = _image.GetSurface(slice, MipIndex).GetPitch(); int NumRows = _image.GetSurface(slice, MipIndex).GetBlockHeight(); for ( int Y = 0; Y < NumRows; Y++ ) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. Memcpy(Dest + Y * StrideY, &Src[Y * RowByteSize], Min(RowByteSize, StrideY)); } Dest += NumRows * StrideY; } // BYTE* Dest = (BYTE*)Buffer; // const BYTE* Src = _image.GetSurface(MipIndex, slice).GetPtrRawData(); // int RowByteSize = _image.GetSurface(MipIndex, slice).GetPitch(); // int NumRows = _image.GetSurface(MipIndex, slice).GetBlockHeight(); // // for ( int Y = 0; Y < NumRows; Y++ ) // { // // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // // they contain the same amount of valid data since they have the same width, height and format. // Memcpy(Dest + Y * StrideY,&Src[Y * RowByteSize], Min(RowByteSize, StrideY)); // } } TextureVolume* TextureVolume::Clone() const { return new TextureVolume(_image); } CachedTextureVolume::CachedTextureVolume(NResourceSet* ResourceManager, TextureVolume* SourceTexture) : CachedBaseTexture(ResourceManager) { if (SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateVolumeTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetDepth(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat()); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } CachedTextureVolume::~CachedTextureVolume() { } void CachedTextureVolume::UpdateTexture( BaseTexture* SourceTexture ) { if ((SourceTexture == 0) || SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } if (!SourceTexture->Type().IsObjectType(TextureVolume::StaticObjectType)) { nuxAssertMsg(0, "[CachedTextureVolume::UpdateTexture] Source texture is not of type TextureVolume."); return; } if ( RecreateTexture(SourceTexture)) { m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateVolumeTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetDepth(), SourceTexture->GetNumMipLevel(), SourceTexture->GetFormat()); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } else { for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } } void CachedTextureVolume::LoadMipLevel(BaseTexture* SourceTexture, int MipLevel) { VOLUME_LOCKED_BOX LockedBox; ObjectPtr VolumeTexture = m_Texture; //m_Texture.CastRef(); if (!VolumeTexture) return; //TextureVolume* Source = UpCastResource(SourceTexture); //for(int slice = 0; slice < ImageSurface::GetLevelDim(Source->GetFormat(), Source->GetDepth(), MipLevel); slice++) { OGL_CALL( VolumeTexture->LockBox(MipLevel, &LockedBox, NULL)); SourceTexture->GetData(LockedBox.pBits, MipLevel, LockedBox.RowPitch, 0); OGL_CALL( VolumeTexture->UnlockBox(MipLevel)); } // for (int slice = 0; slice < depth; slice++) // { // OGL_CALL( VolumeTexture->LockRect(slice, MipLevel, &LockedRect, NULL)); // SourceTexture->GetData(LockedRect.pBits, MipLevel, LockedRect.Pitch, slice); // OGL_CALL( VolumeTexture->UnlockRect(slice, MipLevel )); // } } TextureFrameAnimation::TextureFrameAnimation(NUX_FILE_LINE_DECL) // TODO: why can we have a texture without a texture? : BaseTexture(NUX_FILE_LINE_PARAM) { } TextureFrameAnimation::TextureFrameAnimation(const NAnimatedTextureData& Image) : _image(Image) { } TextureFrameAnimation::~TextureFrameAnimation() { } bool TextureFrameAnimation::Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource) { nuxAssertMsg(BitmapData, "[TextureFrameAnimation::Update] Argument BitmapData is NULL."); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); if (!BitmapData->IsAnimatedTextureData()) { nuxAssertMsg(0, "[TextureFrameAnimation::Update] Argument BitmapData is not a Animated texture"); return false; } _image = *static_cast (BitmapData); if (UpdateAndCacheResource) { // call the texture manager and recreate the texture(CachedTexture2D) associated with this object if any. GetGraphicsDisplay()->GetGraphicsEngine()->UpdateResource(this); } return true; } bool TextureFrameAnimation::Update(const char* filename, bool /* UpdateAndCacheResource */) { NBitmapData* BitmapData = LoadImageFile(filename); nuxAssertMsg(BitmapData, "[TextureFrameAnimation::Update] Bitmap for file(%s) is NULL.", filename); NUX_RETURN_VALUE_IF_NULL(BitmapData, false); bool ret = Update(BitmapData); NUX_SAFE_DELETE(BitmapData); return ret; } void TextureFrameAnimation::GetData(void* Buffer, int /* MipIndex */, int StrideY, int slice) { BYTE *Dest = (BYTE *) Buffer; //for(int slice = 0; slice < ImageSurface::GetLevelDim(_image.GetFormat(), _image.GetDepth(), MipIndex); slice++) { const BYTE *Src = _image.GetSurface(slice).GetPtrRawData(); int RowByteSize = _image.GetSurface(slice).GetPitch(); int NumRows = _image.GetSurface(slice).GetBlockHeight(); for (int Y = 0; Y < NumRows; Y++) { // Take Min(RowByteSize, StrideY): the source and the destination may not have the same Pitch but // they contain the same amount of valid data since they have the same width, height and format. Memcpy(Dest + Y * StrideY, &Src[Y * RowByteSize], Min(RowByteSize, StrideY)); } //Dest += NumRows * StrideY; } } int TextureFrameAnimation::GetFrameTime(int Frame) { return _image.GetFrameTime(Frame); } TextureFrameAnimation* TextureFrameAnimation::Clone() const { return new TextureFrameAnimation(_image); } CachedTextureFrameAnimation::CachedTextureFrameAnimation(NResourceSet* ResourceManager, TextureFrameAnimation* SourceTexture) : CachedBaseTexture(ResourceManager) { if (SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateAnimatedTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetDepth(), SourceTexture->GetFormat()); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } CachedTextureFrameAnimation::~CachedTextureFrameAnimation() { } void CachedTextureFrameAnimation::UpdateTexture( BaseTexture* SourceTexture ) { if ((SourceTexture == 0) || SourceTexture->IsNull()) { m_Texture = ObjectPtr (0); return; } if (!SourceTexture->Type().IsObjectType(TextureFrameAnimation::StaticObjectType)) { nuxAssertMsg(0, "[CachedTextureFrameAnimation::UpdateTexture] Source texture is not of type TextureFrameAnimation."); return; } if (RecreateTexture(SourceTexture)) { m_Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateAnimatedTexture(SourceTexture->GetWidth(), SourceTexture->GetHeight(), SourceTexture->GetDepth(), SourceTexture->GetFormat()); for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } else { for (int i = 0; i < SourceTexture->GetNumMipLevel(); i++) { LoadMipLevel(SourceTexture, i); } } } void CachedTextureFrameAnimation::LoadMipLevel(BaseTexture* SourceTexture, int /* MipLevel */) { SURFACE_LOCKED_RECT LockedRect; ObjectPtr AnimatedTexture = m_Texture; //m_Texture.CastRef(); if (!AnimatedTexture) return; TextureFrameAnimation* Source = UpCastResource (SourceTexture); for (int frame = 0; frame < Source->GetDepth(); frame++) { OGL_CALL( AnimatedTexture->LockRect(frame, &LockedRect, NULL)); SourceTexture->GetData(LockedRect.pBits, 0, LockedRect.Pitch, frame); OGL_CALL( AnimatedTexture->UnlockRect(frame)); AnimatedTexture->SetFrameTime(frame, Source->GetFrameTime(frame)); } } } nux-4.0.6+14.04.20140409/NuxGraphics/GLPBuffer.cpp0000644000015301777760000007101712321344237021456 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUX_OPENGLES_20 #include "NuxCore/NuxCore.h" #include "GLResource.h" #include "GLPBuffer.h" namespace nux { #if defined(NUX_OS_WINDOWS) PBuffer::PBuffer (const char *strMode, bool managed) : m_hDC (0), m_hGLRC (0), m_hPBuffer (0), m_hOldGLRC (0), m_hOldDC (0), m_bIsTexture (false), m_iWidth (0), m_iHeight (0), m_strMode (strMode), m_bSharedContext (false), m_bShareObjects (false), m_bIsBound (false), m_bIsActive (false), m_bManaged (managed) { m_pfAttribList.push_back (WGL_DRAW_TO_PBUFFER_ARB); m_pfAttribList.push_back (true); m_pfAttribList.push_back (WGL_SUPPORT_OPENGL_ARB); m_pfAttribList.push_back (true); m_pbAttribList.push_back (WGL_PBUFFER_LARGEST_ARB); m_pbAttribList.push_back (true); nuxDebugMsg (TEXT ("Declare a Pbuffer with \"%s\" parameters\n"), strMode); m_strMode = strMode; parseModeString (m_strMode, &m_pfAttribList, &m_pbAttribList); m_pfAttribList.push_back (0); m_pbAttribList.push_back (0); } PBuffer::~PBuffer() { if (m_bManaged) Destroy(); } // This function actually does the creation of the p-buffer. // It can only be called once a window has already been created. bool PBuffer::Initialize (int iWidth, int iHeight, bool bShareContexts, bool bShareObjects) { HDC hdc = wglGetCurrentDC(); HGLRC hglrc = wglGetCurrentContext(); int format = 0; int nfattribs = 0; int niattribs = 0; m_iWidth = iWidth; m_iHeight = iHeight; m_bSharedContext = bShareContexts; m_bShareObjects = bShareObjects; if (m_bSharedContext) { // Get the pixel format for the on-screen window. format = GetPixelFormat (hdc); if (format == 0) { nuxDebugMsg (TEXT ("pbuffer creation error: GetPixelFormat() failed") ); return false; } } else { unsigned int nformats; wglChoosePixelFormatARB (hdc, &m_pfAttribList[0], NULL, 1, &format, &nformats); if (nformats == 0) { nuxDebugMsg (TEXT ("pbuffer creation error: Couldn't find a suitable pixel format.") ); return false; } } m_hPBuffer = wglCreatePbufferARB (hdc, format, m_iWidth, m_iHeight, &m_pbAttribList[0]); if (!m_hPBuffer) { DWORD err = GetLastError(); nuxDebugMsg (TEXT ("pbuffer creation error: wglCreatePbufferARB() failed") ); if (err == ERROR_INVALID_PIXEL_FORMAT) { nuxDebugMsg (TEXT ("error: ERROR_INVALID_PIXEL_FORMAT") ); } else if (err == ERROR_NO_SYSTEM_RESOURCES) { nuxDebugMsg (TEXT ("error: ERROR_NO_SYSTEM_RESOURCES") ); } else if (err == ERROR_INVALID_DATA) { nuxDebugMsg (TEXT ("error: ERROR_INVALID_DATA") ); } return false; } // Get the device context. m_hDC = wglGetPbufferDCARB (m_hPBuffer); if (!m_hDC) { nuxDebugMsg (TEXT ("pbuffer creation error: wglGetPbufferDCARB() failed") ); return false; } if (m_bSharedContext) { // Let's use the same gl context.. // Since the device contexts are compatible (i.e. same pixelformat), // we should be able to use the same gl rendering context. m_hGLRC = hglrc; } else { // Create a new gl context for the p-buffer. m_hGLRC = wglCreateContext (m_hDC); if (!m_hGLRC) { nuxDebugMsg (TEXT ("pbuffer creation error: wglCreateContext() failed") ); return false; } if (m_bShareObjects) { if (!wglShareLists (hglrc, m_hGLRC) ) { nuxDebugMsg (TEXT ("pbuffer: wglShareLists() failed") ); return false; } } } GLint texFormat = WGL_NO_TEXTURE_ARB; wglQueryPbufferARB (m_hPBuffer, WGL_TEXTURE_FORMAT_ARB, &texFormat); if (texFormat != WGL_NO_TEXTURE_ARB) m_bIsTexture = true; // Determine the actual width and height we were able to create. wglQueryPbufferARB (m_hPBuffer, WGL_PBUFFER_WIDTH_ARB, &m_iWidth); wglQueryPbufferARB (m_hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &m_iHeight); nuxDebugMsg ("Created a %d x %d pbuffer\n", m_iWidth, m_iHeight); #ifdef _DEBUG // query pixel format int iattributes[] = { WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB, WGL_FLOAT_COMPONENTS_NV, WGL_DEPTH_BITS_ARB, WGL_SAMPLES_EXT, WGL_AUX_BUFFERS_ARB }; int ivalues[sizeof (iattributes) / sizeof (int) ]; if (wglGetPixelFormatAttribivARB (m_hDC, format, 0, sizeof (iattributes) / sizeof (int), iattributes, ivalues) ) { nuxDebugMsg ("r:%d g:%d b:%d a:%d float:%d depth:%d samples:%d aux:%d\n", ivalues[0], ivalues[1], ivalues[2], ivalues[3], ivalues[4], ivalues[5], ivalues[6], ivalues[7]); } #endif return true; } void PBuffer::Destroy() { if (m_hPBuffer) { if (!m_bSharedContext) wglDeleteContext (m_hGLRC); wglReleasePbufferDCARB (m_hPBuffer, m_hDC); wglDestroyPbufferARB (m_hPBuffer); } } void PBuffer::parseModeString (const char *modeString, std::vector *pfAttribList, std::vector *pbAttribList) { if (!modeString || strcmp (modeString, "") == 0) return; m_iBitsPerComponent = 8; m_iNComponents = 0; bool bIsFloatBuffer = false; bool bIsATIFloatBuffer = false; bool bIsTexture = false; bool bNeedAlpha = false; char *mode = _strdup (modeString); std::vector tokens; char *next_token = NULL; #ifdef WIN32_SECURE char *buf = strtok_s (mode, " ", &next_token); #else char *buf = strtok (mode, " "); #endif while (buf != NULL) { if (strstr (buf, "ati_float") != NULL) bIsATIFloatBuffer = true; else if (strstr (buf, "float") != NULL) bIsFloatBuffer = true; if (strstr (buf, "texture") != NULL) bIsTexture = true; if (strstr (buf, "alpha") != NULL) bNeedAlpha = true; tokens.push_back (buf); #ifdef WIN32_SECURE buf = strtok_s (NULL, " ", &next_token); #else buf = strtok (NULL, " "); #endif } pfAttribList->push_back (WGL_PIXEL_TYPE_ARB); #ifdef WGL_ATI_pixel_format_float if (bIsATIFloatBuffer) { pfAttribList->push_back (WGL_TYPE_RGBA_FLOAT_ATI); } else #endif { pfAttribList->push_back (WGL_TYPE_RGBA_ARB); } for (unsigned int i = 0; i < tokens.size(); i++) { std::string token = tokens[i]; if (token == "rgb" && (m_iNComponents <= 1) ) { /* pfAttribList->push_back(WGL_RED_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent); pfAttribList->push_back(WGL_GREEN_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent); pfAttribList->push_back(WGL_BLUE_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent);*/ m_iNComponents += 3; continue; } else if (token == "rgb") nuxDebugMsg ("warning : mistake in components definition (rgb + %d)\n", m_iNComponents); if (token == "rgba" && (m_iNComponents == 0) ) { /*pfAttribList->push_back(WGL_RED_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent); pfAttribList->push_back(WGL_GREEN_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent); pfAttribList->push_back(WGL_BLUE_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent); pfAttribList->push_back(WGL_ALPHA_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent);*/ m_iNComponents = 4; continue; } else if (token == "rgba") nuxDebugMsg ("warning : mistake in components definition (rgba + %d)\n", m_iNComponents); if (token == "alpha" && (m_iNComponents <= 3) ) { /*pfAttribList->push_back(WGL_ALPHA_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent);*/ m_iNComponents++; continue; } else if (token == "alpha") nuxDebugMsg ("warning : mistake in components definition (alpha + %d)\n", m_iNComponents); if (token == "r" && (m_iNComponents <= 1) ) // && bIsFloatBuffer) { /*pfAttribList->push_back(WGL_RED_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent);*/ m_iNComponents++; continue; } else if (token == "r") nuxDebugMsg ("warning : mistake in components definition (r + %d)\n", m_iNComponents); if (token == "rg" && (m_iNComponents <= 1) ) // && bIsFloatBuffer) { /*pfAttribList->push_back(WGL_RED_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent); pfAttribList->push_back(WGL_GREEN_BITS_ARB); pfAttribList->push_back(m_iBitsPerComponent);*/ m_iNComponents += 2; continue; } else if (token == "r") nuxDebugMsg ("warning : mistake in components definition (rg + %d)\n", m_iNComponents); if (token.find ("depth") == 0) { pfAttribList->push_back (WGL_DEPTH_BITS_ARB); pfAttribList->push_back (getIntegerValue (token) ); continue; } if (token.find ("stencil") == 0) { pfAttribList->push_back (WGL_STENCIL_BITS_ARB); pfAttribList->push_back (8); continue; } if (token.find ("samples") == 0) { pfAttribList->push_back (WGL_SAMPLE_BUFFERS_ARB); pfAttribList->push_back (1); pfAttribList->push_back (WGL_SAMPLES_ARB); pfAttribList->push_back (getIntegerValue (token) ); continue; } if (token.find ("aux") == 0) { pfAttribList->push_back (WGL_AUX_BUFFERS_ARB); pfAttribList->push_back (getIntegerValue (token) ); continue; } if (token == "double") { pfAttribList->push_back (WGL_DOUBLE_BUFFER_ARB); pfAttribList->push_back (true); continue; } if (token.find ("ati_float") == 0) { m_iBitsPerComponent = getIntegerValue (token); // type already set above continue; } else if (token.find ("float") == 0) { m_iBitsPerComponent = getIntegerValue (token); //bIsFloatBuffer = true; done previously pfAttribList->push_back (WGL_FLOAT_COMPONENTS_NV); pfAttribList->push_back (true); continue; } if (token.find ("texture") == 0) { if (token.find ("textureRECT") == 0 || bIsFloatBuffer) { pbAttribList->push_back (WGL_TEXTURE_TARGET_ARB); pbAttribList->push_back (WGL_TEXTURE_RECTANGLE_NV); } else if (token.find ("textureCUBE") == 0) { pbAttribList->push_back (WGL_TEXTURE_TARGET_ARB); pbAttribList->push_back (WGL_TEXTURE_CUBE_MAP_ARB); } else { pbAttribList->push_back (WGL_TEXTURE_TARGET_ARB); pbAttribList->push_back (WGL_TEXTURE_2D_ARB); } if (bIsFloatBuffer || bIsATIFloatBuffer) { if (m_iNComponents == 0) { nuxDebugMsg ("components not specified. assuming rgba...\n"); pfAttribList->push_back (WGL_RED_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (WGL_GREEN_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (WGL_BLUE_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (WGL_ALPHA_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); m_iNComponents = 4; } } if (bIsFloatBuffer) { switch (m_iNComponents) { case 1: pfAttribList->push_back (WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV); pfAttribList->push_back (true); pbAttribList->push_back (WGL_TEXTURE_FORMAT_ARB); pbAttribList->push_back (WGL_TEXTURE_FLOAT_R_NV); break; case 2: pfAttribList->push_back (WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV); pfAttribList->push_back (true); pbAttribList->push_back (WGL_TEXTURE_FORMAT_ARB); pbAttribList->push_back (WGL_TEXTURE_FLOAT_RG_NV); break; case 3: pfAttribList->push_back (WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV); pfAttribList->push_back (true); pbAttribList->push_back (WGL_TEXTURE_FORMAT_ARB); pbAttribList->push_back (WGL_TEXTURE_FLOAT_RGB_NV); break; case 4: pfAttribList->push_back (WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV); pfAttribList->push_back (true); pbAttribList->push_back (WGL_TEXTURE_FORMAT_ARB); pbAttribList->push_back (WGL_TEXTURE_FLOAT_RGBA_NV); break; default: nuxDebugMsg ("Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", m_iNComponents); break; } } else { switch (m_iNComponents) { case 3: pfAttribList->push_back (WGL_BIND_TO_TEXTURE_RGB_ARB); pfAttribList->push_back (true); pbAttribList->push_back (WGL_TEXTURE_FORMAT_ARB); pbAttribList->push_back (WGL_TEXTURE_RGB_ARB); break; case 4: pfAttribList->push_back (WGL_BIND_TO_TEXTURE_RGBA_ARB); pfAttribList->push_back (true); pbAttribList->push_back (WGL_TEXTURE_FORMAT_ARB); pbAttribList->push_back (WGL_TEXTURE_RGBA_ARB); break; default: nuxDebugMsg ("Bad number of components (r=1,rg=2,rgb=3,rgba=4): %d\n", m_iNComponents); break; } } std::string option = getStringValue (token); if (option == "depth") { pfAttribList->push_back (WGL_BIND_TO_TEXTURE_DEPTH_NV); pfAttribList->push_back (true); pbAttribList->push_back (WGL_DEPTH_TEXTURE_FORMAT_NV); pbAttribList->push_back (WGL_TEXTURE_DEPTH_COMPONENT_NV); } continue; } if (token.find ("mipmap") == 0 && bIsTexture) { pbAttribList->push_back (WGL_MIPMAP_TEXTURE_ARB); pbAttribList->push_back (true); continue; } nuxDebugMsg ("unknown pbuffer attribute: %s\n", token.c_str() ); } if (m_iNComponents > 0) { pfAttribList->push_back (WGL_RED_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); } if (m_iNComponents > 1) { pfAttribList->push_back (WGL_GREEN_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); } if (m_iNComponents > 2) { pfAttribList->push_back (WGL_BLUE_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); } if (m_iNComponents > 3) { pfAttribList->push_back (WGL_ALPHA_BITS_ARB); pfAttribList->push_back (m_iBitsPerComponent); } } // Check to see if the pbuffer was lost. // If it was lost, destroy it and then recreate it. void PBuffer::HandleModeSwitch() { int lost = 0; wglQueryPbufferARB (m_hPBuffer, WGL_PBUFFER_LOST_ARB, &lost); if (lost) { this->~PBuffer(); Initialize (m_iWidth, m_iHeight, m_bSharedContext, m_bShareObjects); } } int PBuffer::Bind (int iBuffer) { if (!m_bIsTexture) { nuxDebugMsg ("PBuffer::Bind() failed - pbuffer format does not support render to texture!\n"); return 0; } #if 0 // SGG - with MRT it is legal to bind different buffers of a pbuffer simultaneously if (m_bIsBound) { nuxDebugMsg ("PBuffer::Bind() failed - pbuffer is already bound.\n"); return 0; } #endif int ret = wglBindTexImageARB (m_hPBuffer, iBuffer); if (!ret) nuxDebugMsg ("PBuffer::Bind() failed.\n"); m_bIsBound = true; return ret; } int PBuffer::Release (int iBuffer) { if (!m_bIsTexture) { nuxDebugMsg ("PBuffer::Release() failed - pbuffer format does not support render to texture!\n"); return 0; } #if 0 // SGG - with MRT it is legal to bind different buffers of a pbuffer simultaneously if (!m_bIsBound) { nuxDebugMsg ("PBuffer::Release() failed - pbuffer is not bound.\n"); return 0; } #endif int ret = wglReleaseTexImageARB (m_hPBuffer, iBuffer); if (!ret) nuxDebugMsg ("PBuffer::Release() failed.\n"); m_bIsBound = false; return ret; } void PBuffer::Activate (PBuffer *current /* = NULL */) { if (current == this) { return; // no switch necessary } if (NULL == current || !current->m_bIsActive) { if (m_bIsActive) return; m_hOldGLRC = wglGetCurrentContext(); m_hOldDC = wglGetCurrentDC(); } else { m_hOldGLRC = current->m_hOldGLRC; m_hOldDC = current->m_hOldDC; current->m_hOldGLRC = 0; current->m_hOldDC = 0; current->m_bIsActive = false; } if (!wglMakeCurrent (m_hDC, m_hGLRC) ) nuxDebugMsg ("PBuffer::Activate() failed.\n"); m_bIsActive = true; } void PBuffer::Deactivate() { if (!m_bIsActive) return; if (!wglMakeCurrent (m_hOldDC, m_hOldGLRC) ) nuxDebugMsg ("PBuffer::Deactivate() failed.\n"); m_hOldGLRC = 0; m_hOldDC = 0; m_bIsActive = false; } #elif defined(NUX_OS_LINUX) PBuffer::PBuffer (const char *strMode, bool managed) : m_pDisplay (0), m_glxPbuffer (0), m_glxContext (0), m_pOldDisplay (0), m_glxOldDrawable (0), m_glxOldContext (0), m_iWidth (0), m_iHeight (0), m_strMode (strMode), m_bSharedContext (false), m_bShareObjects (false), m_bManaged (managed) { m_pfAttribList.push_back (GLX_DRAWABLE_TYPE); m_pfAttribList.push_back (GLX_PBUFFER_BIT); m_pfAttribList.push_back (GLX_RENDER_TYPE); m_pfAttribList.push_back (GLX_RGBA_BIT); m_pbAttribList.push_back (GLX_LARGEST_PBUFFER); m_pbAttribList.push_back (true); m_pbAttribList.push_back (GLX_PRESERVED_CONTENTS); m_pbAttribList.push_back (true); m_strMode = strMode; parseModeString (m_strMode, &m_pfAttribList, &m_pbAttribList); m_pfAttribList.push_back (0); m_pbAttribList.push_back (0); } PBuffer::~PBuffer() { if (m_bManaged) Destroy(); } bool PBuffer::Initialize (int iWidth, int iHeight, bool bShareContexts, bool bShareObjects) { Display *pDisplay = glXGetCurrentDisplay(); int iScreen = DefaultScreen (pDisplay); GLXContext glxContext = glXGetCurrentContext(); GLXFBConfig *glxConfig; int iConfigCount; m_bSharedContext = bShareContexts; m_bShareObjects = bShareObjects; m_iWidth = iWidth; m_iHeight = iHeight; if (m_bSharedContext) { glxConfig = glXGetFBConfigs (pDisplay, iScreen, &iConfigCount); if (!glxConfig) { nuxDebugMsg ("pbuffer creation error: glXGetFBConfigs() failed\n"); return false; } } else { glxConfig = glXChooseFBConfigSGIX (pDisplay, iScreen, &m_pfAttribList[0], &iConfigCount); if (!glxConfig) { nuxDebugMsg ("pbuffer creation error: glXChooseFBConfig() failed\n"); return false; } } m_glxPbuffer = glXCreateGLXPbufferSGIX (pDisplay, glxConfig[0], m_iWidth, m_iHeight, &m_pbAttribList[0]); if (!m_glxPbuffer) { nuxDebugMsg ("pbuffer creation error: glXCreatePbuffer() failed\n"); return false; } if (m_bSharedContext) { m_glxContext = glxContext; } else { if (m_bShareObjects) m_glxContext = glXCreateContextWithConfigSGIX (pDisplay, glxConfig[0], GLX_RGBA_TYPE, glxContext, true); else m_glxContext = glXCreateContextWithConfigSGIX (pDisplay, glxConfig[0], GLX_RGBA_TYPE, NULL, true); if (!glxConfig) { nuxDebugMsg ("pbuffer creation error: glXCreateNewContext() failed\n"); return false; } } m_pDisplay = pDisplay; unsigned int w, h; w = h = 0; glXQueryGLXPbufferSGIX (m_pDisplay, m_glxPbuffer, GLX_WIDTH, &w); glXQueryGLXPbufferSGIX (m_pDisplay, m_glxPbuffer, GLX_HEIGHT, &h); m_iWidth = w; m_iHeight = h; nuxDebugMsg ("Created a %d x %d pbuffer\n", m_iWidth, m_iHeight); return true; } void PBuffer::Destroy() { if (m_glxContext && !m_bSharedContext) glXDestroyContext (m_pDisplay, m_glxContext); if (m_glxPbuffer) glXDestroyGLXPbufferSGIX (m_pDisplay, m_glxPbuffer); m_glxContext = 0; m_glxPbuffer = 0; m_pDisplay = 0; } void PBuffer::parseModeString (const char *modeString, std::vector *pfAttribList, std::vector * /* pbAttribList */) { if (!modeString || strcmp (modeString, "") == 0) return; m_iBitsPerComponent = 8; m_iNComponents = 0; bool bIsFloatBuffer = false; char *mode = strdup (modeString); std::vector tokens; char *buf = strtok (mode, " "); while (buf != NULL) { if (strstr (buf, "float") != NULL) bIsFloatBuffer = true; tokens.push_back (buf); buf = strtok (NULL, " "); } for (unsigned int i = 0; i < tokens.size(); i++) { std::string token = tokens[i]; if (token == "rgb" && !bIsFloatBuffer) { pfAttribList->push_back (GLX_RED_SIZE); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (GLX_GREEN_SIZE); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (GLX_BLUE_SIZE); pfAttribList->push_back (m_iBitsPerComponent); m_iNComponents += 3; continue; } else if (token == "rgb") { nuxDebugMsg ("warning : mistake in components definition (rgb + %d)\n", m_iNComponents); } if (token == "rgba" && (m_iNComponents == 0) ) { pfAttribList->push_back (GLX_RED_SIZE); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (GLX_GREEN_SIZE); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (GLX_BLUE_SIZE); pfAttribList->push_back (m_iBitsPerComponent); pfAttribList->push_back (GLX_ALPHA_SIZE); pfAttribList->push_back (m_iBitsPerComponent); m_iNComponents = 4; continue; } else if (token == "rgba") { nuxDebugMsg ("warning : mistake in components definition (rgba + %d)\n", m_iNComponents); } if (token.find ("alpha") != token.npos) { pfAttribList->push_back (GLX_ALPHA_SIZE); pfAttribList->push_back (m_iBitsPerComponent); m_iNComponents++; continue; } else if (token == "alpha") { nuxDebugMsg ("warning : mistake in components definition (alpha + %d)\n", m_iNComponents); } if (token.find ("depth") != token.npos) { pfAttribList->push_back (GLX_DEPTH_SIZE); pfAttribList->push_back (getIntegerValue (token) ); continue; } if (token.find ("stencil") != token.npos) { pfAttribList->push_back (GLX_STENCIL_SIZE); pfAttribList->push_back (getIntegerValue (token) ); continue; } if (token.find ("samples") != token.npos) { pfAttribList->push_back (GLX_SAMPLE_BUFFERS_ARB); pfAttribList->push_back (1); pfAttribList->push_back (GLX_SAMPLES_ARB); pfAttribList->push_back (getIntegerValue (token) ); continue; } if (token == "double") { pfAttribList->push_back (GLX_DOUBLEBUFFER); pfAttribList->push_back (true); continue; } if (token.find ("float") == 0) { m_iBitsPerComponent = getIntegerValue (token); pfAttribList->push_back (GLX_FLOAT_COMPONENTS_NV); pfAttribList->push_back (true); continue; } nuxDebugMsg ("unknown pbuffer attribute: %s\n", token.c_str() ); } } void PBuffer::Activate (PBuffer *current /* = NULL */) { if (current == this) { return; // no switch necessary } if (NULL == current || !current->m_bIsActive) { m_pOldDisplay = glXGetCurrentDisplay(); m_glxOldDrawable = glXGetCurrentDrawable(); m_glxOldContext = glXGetCurrentContext(); } else { m_pOldDisplay = current->m_pOldDisplay; m_glxOldDrawable = current->m_glxOldDrawable; m_glxOldContext = current->m_glxOldContext; current->m_pOldDisplay = 0; current->m_glxOldDrawable = 0; current->m_glxOldContext = 0; } if (!glXMakeCurrent (m_pDisplay, m_glxPbuffer, m_glxContext) ) { nuxDebugMsg ("PBuffer::Activate() failed.\n"); } } void PBuffer::Deactivate() { if (!glXMakeCurrent (m_pOldDisplay, m_glxOldDrawable, m_glxOldContext) ) { nuxDebugMsg ("PBuffer::Deactivate() failed.\n"); } m_pOldDisplay = 0; m_glxOldDrawable = 0; m_glxOldContext = 0; } #elif defined(NUX_OS_MACOSX) PBuffer::PBuffer (const char *strMode) : m_iWidth (0), m_iHeight (0), m_strMode (strMode), m_bSharedContext (false), m_bShareObjects (false) { nuxDebugMsg ("pbuffer not implemented under Mac OS X yet\n"); } PBuffer::~PBuffer() { nuxDebugMsg ("pbuffer not implemented under Mac OS X yet\n"); } bool PBuffer::Initialize (int iWidth, int iHeight, bool bShareContexts, bool bShareObjects) { nuxDebugMsg ("pbuffer not implemented under Mac OS X yet\n"); return false; } void PBuffer::Activate() { nuxDebugMsg ("pbuffer not implemented under Mac OS X yet\n"); } void PBuffer::Deactivate() { nuxDebugMsg ("pbuffer not implemented under Mac OS X yet\n"); } #endif std::string PBuffer::getStringValue (std::string token) { size_t pos; if ( (pos = token.find ("=") ) != token.npos) { std::string value = token.substr (pos + 1, token.length() - pos + 1); return value; } else return ""; } int PBuffer::getIntegerValue (std::string token) { size_t pos; if ( (pos = token.find ("=") ) != token.npos) { std::string value = token.substr (pos + 1, token.length() - pos + 1); if (value.empty() ) return 1; return atoi (value.c_str() ); } else return 1; } //---------------------------------------------------------------------------------- // /// return the total size in bytes of the PBuffer // //---------------------------------------------------------------------------------- unsigned int PBuffer::GetSizeInBytes() { return m_iWidth * m_iHeight * (m_iNComponents / 8); } /*************************************************************************/ /** make a copy the entire PBuffer in the memory. You have to allocate this area (ptr). if ever you want to read a smaller size : specify it through w,h. otherwise w=h=-1 */ /*********************************************************************/ unsigned int PBuffer::CopyToBuffer (void *ptr, int w, int h) { GLenum format = 0; GLenum type = 0; switch (m_iNComponents) { case 1: // format = GL_LUMINANCE; // is it right to ask for Red only component ? break; case 2: format = GL_LUMINANCE_ALPHA; //How to ask for GL_RG ?? break; case 3: format = GL_RGB; break; case 4: format = GL_RGBA; break; } switch (m_iBitsPerComponent) { case 8: type = GL_UNSIGNED_BYTE; break; case 32: type = GL_FLOAT; break; #ifdef GL_NV_half_float case 16: type = GL_HALF_FLOAT_NV; break; #endif default: nuxDebugMsg ("unknown m_iBitsPerComponent\n"); # if defined(WIN32) __debugbreak(); # endif } Activate(); if ( (w < 0) || (w > m_iWidth) ) w = m_iWidth; if ( (h < 0) || (h > m_iHeight) ) h = m_iHeight; glReadPixels (0, 0, w, h, format, type, ptr); Deactivate(); return w * h * (m_iNComponents / 8); } } #endif // NUX_OPENGLES_20 nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLGLSLShader.cpp0000644000015301777760000011126512321344237022750 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GraphicsDisplay.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "IOpenGLGLSLShader.h" namespace nux { namespace local { namespace { GLuint last_loaded_shader = 0; bool enable_tracking = false; } } NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLShader); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLVertexShader); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLPixelShader); //NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLGeometryShader); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLShaderProgram); bool ExtractShaderString3(const std::string &ShaderToken, const std::string &ShaderSource, std::string &RetSource, std::string ShaderPreprocessorDefines) { //Loop for all characters in the string if (ShaderToken != "") { size_t lineStart = 0; size_t lineCount = 1; bool startTokenFound = false; size_t shaderStringStart = 0; size_t shaderStartLine = 1; size_t i; for (i = 0; i < ShaderSource.length(); i++) { //Check if the starting character '[' (open bracket) is found at the beginning of the line // i counts the characters in the file. lineStart is equal to i at the beginning of the line. std::string sub_string = ShaderSource.substr(i, std::string::npos); if ((TCharStringNCompare(sub_string.c_str(), "[", 1) == 0) && (lineStart == i)) { if (!startTokenFound) { //Test for the start token if (ShaderSource.find(ShaderToken, 0) == i) { // Found the shader token shaderStringStart = i + ShaderToken.length(); startTokenFound = true; //Set what line the shader was found on shaderStartLine = lineCount; } } else { //Break where the end token was found break; } } //If the character is equal to the new line character, // The next character must be on the new line sub_string = ShaderSource.substr(i, std::string::npos); if ((TCharStringNCompare(sub_string.c_str(), "\r", 1) == 0) || (TCharStringNCompare(sub_string.c_str(), "\n", 1) == 0)) { lineStart = i + 1; } //Count the new lines if (TCharStringNCompare(sub_string.c_str(), "\n", 1) == 0) { lineCount++; } } //If the string was not found, return false if (!startTokenFound || shaderStringStart >= i) { return false; } //Assign the return string RetSource = ShaderSource.substr(shaderStringStart, i - shaderStringStart); //Add the line directive to the shader source. See the documentation for GLSL #line directive. // GLSL spec: The #version directive must occur in a shader before anything else, except for comments and white space. size_t Pos = RetSource.find("#version", 0); while (Pos != std::string::npos && RetSource[Pos] != '\n') { if (RetSource[Pos] == 0) break; ++Pos; } if (RetSource[Pos] != 0) ++Pos; size_t EndOfLinePosition = 0; size_t LinePosition = 0; while ((EndOfLinePosition = RetSource.find('\n', EndOfLinePosition)) < Pos - 1) { ++EndOfLinePosition; ++LinePosition; } std::string s = "#line "; s += std::to_string((unsigned long long)(LinePosition + shaderStartLine)) + "\n"; RetSource.insert(Pos, s); // Insert the preprocessor definitions before the #line directive if (ShaderPreprocessorDefines.length()) RetSource.insert(Pos, ShaderPreprocessorDefines + std::string("\n")); return true; } else { // We are not searching for a start token. Return the whole source. RetSource = ShaderSource; return true; } } static void InsertPreProcessorDefinitions(const std::string &ShaderSource, std::string &RetSource, std::string &ShaderPreprocessorDefines) { RetSource = ShaderSource; if (ShaderPreprocessorDefines.length() == 0) return; // GLSL spec: The #version directive must occur in a shader before anything else, except for comments and white space. size_t Pos = RetSource.find("#version", 0); if (Pos != tstring::npos) { Pos = RetSource.find('\n', Pos); if (Pos == std::string::npos) { // this is most likely an incorrect shader Pos = RetSource.size(); RetSource.insert(Pos, std::string("\n")); Pos = RetSource.size(); } else { // Skip character \n Pos++; } } else { Pos = 0; } if (ShaderPreprocessorDefines.length()) RetSource.insert(Pos, ShaderPreprocessorDefines + std::string("\n")); } IOpenGLShader::IOpenGLShader(std::string ShaderName, OpenGLResourceType ResourceType) : IOpenGLResource(ResourceType) , _ShaderName(ShaderName) { } IOpenGLShader::~IOpenGLShader() { } IOpenGLVertexShader::IOpenGLVertexShader(std::string ShaderName) : IOpenGLShader(ShaderName, RT_GLSL_VERTEXSHADER) , m_CompiledAndReady(false) { _OpenGLID = glCreateShader(GL_VERTEX_SHADER_ARB); CHECKGL_MSG( glCreateShader(GL_VERTEX_SHADER_ARB)); } IOpenGLVertexShader::~IOpenGLVertexShader() { CHECKGL(glDeleteShader(_OpenGLID)); _OpenGLID = 0; m_CompiledAndReady = false; } void IOpenGLVertexShader::SetShaderCode(const char *ShaderCode, const char *VtxShaderPreprocessorDefines) { nuxAssertMsg(ShaderCode, "[IOpenGLVertexShader::SetShaderCode] Invalid shader code."); NUX_RETURN_IF_NULL(ShaderCode); std::string ProcessedShaderSource; std::string Defines(VtxShaderPreprocessorDefines); InsertPreProcessorDefinitions(ShaderCode, ProcessedShaderSource, Defines); m_CompiledAndReady = false; _ShaderCode = ProcessedShaderSource; } bool IOpenGLVertexShader::Compile() { size_t CodeSize = _ShaderCode.size(); if (CodeSize == 0) { nuxDebugMsg("[IOpenGLVertexShader::Compile] Vertex shader source code is empty."); } char *ShaderSource = new char[CodeSize+1]; Memset(ShaderSource, 0, CodeSize + 1); Memcpy(ShaderSource, _ShaderCode.c_str(), CodeSize); CHECKGL(glShaderSource(_OpenGLID, 1, (const GLcharARB **) &ShaderSource, NULL)); delete [] ShaderSource; // compile vertex shader object CHECKGL(glCompileShader(_OpenGLID)); // check if shader compiled m_CompiledAndReady = false; CHECKGL(glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady)); if (!m_CompiledAndReady) { ANSICHAR *InfoLogBuffer = 0; GLint InfoLogBufferSize = 0; GLint InfoLogReturnSize = 0; GLint iLog = 0; glGetShaderiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog); InfoLogBuffer = new ANSICHAR[iLog+1]; InfoLogBufferSize = iLog + 1; glGetShaderInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer); if (InfoLogReturnSize != 0) { nuxError("[IOpenGLVertexShader::Compile] glCompileShader: %s", InfoLogBuffer); } delete[] InfoLogBuffer; } return m_CompiledAndReady; } bool IOpenGLVertexShader::IsValid() { return m_CompiledAndReady; } IOpenGLPixelShader::IOpenGLPixelShader(std::string ShaderName) : IOpenGLShader(ShaderName, RT_GLSL_PIXELSHADER) , m_CompiledAndReady(false) { _OpenGLID = glCreateShader(GL_FRAGMENT_SHADER_ARB); CHECKGL_MSG( glCreateShader(GL_FRAGMENT_SHADER_ARB)); } IOpenGLPixelShader::~IOpenGLPixelShader() { CHECKGL(glDeleteShader(_OpenGLID)); _OpenGLID = 0; m_CompiledAndReady = false; } void IOpenGLPixelShader::SetShaderCode(const char *ShaderCode, const char *FrgShaderPreprocessorDefines) { nuxAssertMsg(ShaderCode, "[IOpenGLPixelShader::SetShaderCode] Invalid shader code."); NUX_RETURN_IF_NULL(ShaderCode); std::string ProcessedShaderSource; std::string Defines(FrgShaderPreprocessorDefines); InsertPreProcessorDefinitions(ShaderCode, ProcessedShaderSource, Defines); m_CompiledAndReady = false; _ShaderCode = ProcessedShaderSource; } bool IOpenGLPixelShader::Compile() { GLint CodeSize = (GLint) _ShaderCode.size(); if (CodeSize == 0) { nuxDebugMsg("[IOpenGLPixelShader::Compile] Pixel shader source code is empty."); } char *ShaderSource = new char[CodeSize+1]; Memset(ShaderSource, 0, CodeSize + 1); Memcpy(ShaderSource, _ShaderCode.c_str(), CodeSize); CHECKGL(glShaderSource(_OpenGLID, 1, (const GLcharARB **) &ShaderSource, &CodeSize)); delete [] ShaderSource; // compile pixel shader object CHECKGL(glCompileShader(_OpenGLID)); // check if shader compiled m_CompiledAndReady = false; CHECKGL(glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady)); if (!m_CompiledAndReady) { ANSICHAR *InfoLogBuffer = 0; GLint InfoLogBufferSize = 0; GLint InfoLogReturnSize = 0; GLint iLog = 0; glGetShaderiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog); InfoLogBuffer = new ANSICHAR[iLog+1]; InfoLogBufferSize = iLog + 1; glGetShaderInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer); if (InfoLogReturnSize != 0) { nuxError("[IOpenGLPixelShader::Compile] glCompileShader: %s", InfoLogBuffer); } printf("Error: %s \n COMPILE \n", InfoLogBuffer); delete[] InfoLogBuffer; } return m_CompiledAndReady; } bool IOpenGLPixelShader::IsValid() { return m_CompiledAndReady; } #if 0 IOpenGLGeometryShader::IOpenGLGeometryShader(std::string ShaderName) : IOpenGLShader(ShaderName, RT_GLSL_GEOMETRYSHADER) , m_CompiledAndReady(false) { _OpenGLID = glCreateShader(GL_GEOMETRY_SHADER); CHECKGL_MSG(glCreateShader(GL_GEOMETRY_SHADER)); } IOpenGLGeometryShader::~IOpenGLGeometryShader() { CHECKGL(glDeleteShader(_OpenGLID)); _OpenGLID = 0; m_CompiledAndReady = false; } void IOpenGLGeometryShader::SetShaderCode(const char *ShaderCode, const char *GeometryShaderPreprocessorDefines) { nuxAssertMsg(ShaderCode, "[IOpenGLGeometryShader::SetShaderCode] Invalid shader code."); NUX_RETURN_IF_NULL(ShaderCode); std::string ProcessedShaderSource; std::string Defines(GeometryShaderPreprocessorDefines); InsertPreProcessorDefinitions(ShaderCode, ProcessedShaderSource, Defines); m_CompiledAndReady = false; _ShaderCode = ProcessedShaderSource; } bool IOpenGLGeometryShader::Compile() { GLint CodeSize = (GLint) _ShaderCode.Size(); if (CodeSize == 0) { nuxDebugMsg("[IOpenGLGeometryShader::Compile] Pixel shader source code is empty."); } char *ShaderSource = new char[CodeSize+1]; Memset(ShaderSource, 0, CodeSize + 1); Memcpy(ShaderSource, _ShaderCode.m_string.c_str(), CodeSize); CHECKGL(glShaderSource(_OpenGLID, 1, (const GLcharARB **) &ShaderSource, &CodeSize)); delete [] ShaderSource; // compile pixel shader object CHECKGL(glCompileShader(_OpenGLID)); // check if shader compiled m_CompiledAndReady = false; CHECKGL(glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady)); if (!m_CompiledAndReady) { ANSICHAR *InfoLogBuffer = 0; GLint InfoLogBufferSize = 0; GLint InfoLogReturnSize = 0; GLint iLog = 0; glGetShaderiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog); InfoLogBuffer = new ANSICHAR[iLog+1]; InfoLogBufferSize = iLog + 1; glGetShaderInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer); if (InfoLogReturnSize != 0) { nuxError("[IOpenGLGeometryShader::Compile] glCompileShader: %s", InfoLogBuffer); } delete InfoLogBuffer; } return m_CompiledAndReady; } bool IOpenGLGeometryShader::IsValid() { return m_CompiledAndReady; } void IOpenGLGeometryShader::SetInputPrimitiveType(GLenum type) { CHECKGL(glProgramParameteri(_OpenGLID, GL_GEOMETRY_INPUT_TYPE_EXT, type)); } void IOpenGLGeometryShader::SetOutputPrimitiveType(GLenum type) { CHECKGL(glProgramParameteri(_OpenGLID, GL_GEOMETRY_OUTPUT_TYPE_EXT, type)); } void IOpenGLGeometryShader::SetMaxVertexOutput(int max_vertex_output) { CHECKGL(glProgramParameteri(_OpenGLID, GL_GEOMETRY_VERTICES_OUT_EXT, max_vertex_output)); } #endif IOpenGLShaderProgram::IOpenGLShaderProgram(std::string ShaderProgramName) : IOpenGLResource(RT_GLSL_SHADERPROGRAM) , _FirstParameter(0) , m_CompiledAndReady(false) , _ShaderProgramName(ShaderProgramName) { _OpenGLID = glCreateProgram(); CHECKGL_MSG( glCreateProgram()); } IOpenGLShaderProgram::~IOpenGLShaderProgram() { if (local::last_loaded_shader == _OpenGLID) { CHECKGL(glUseProgramObjectARB(0)); local::last_loaded_shader = 0; } CHECKGL(glDeleteProgram(_OpenGLID)); _OpenGLID = 0; m_CompiledAndReady = false; } void IOpenGLShaderProgram::LoadIShaderFile(const char *ShaderFileName, const char *VtxShaderPreprocessorDefines, const char *FrgShaderPreprocessorDefines) { nuxAssertMsg(ShaderFileName, "[IOpenGLShaderProgram::LoadIShaderFile] Invalid shader file name."); NUX_RETURN_IF_NULL(ShaderFileName); std::string SourceCode; LoadFileToString(SourceCode, ShaderFileName); LoadIShader(&SourceCode[0], VtxShaderPreprocessorDefines, FrgShaderPreprocessorDefines); } void IOpenGLShaderProgram::LoadIShader(const char *ShaderCode, const char *VtxShaderPreprocessorDefines, const char *FrgShaderPreprocessorDefines) { nuxAssertMsg(ShaderCode, "[IOpenGLShaderProgram::LoadIShader] Invalid shader code."); NUX_RETURN_IF_NULL(ShaderCode); std::string VertexShaderSource; ExtractShaderString3("[Vertex Shader]", ShaderCode, VertexShaderSource, std::string(VtxShaderPreprocessorDefines)); std::string PixelShaderSource; ExtractShaderString3("[Fragment Shader]", ShaderCode, PixelShaderSource, std::string(FrgShaderPreprocessorDefines)); ObjectPtr vs = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); //new IOpenGLVertexShader; ObjectPtr ps = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); //new IOpenGLPixelShader; vs->SetShaderCode(VertexShaderSource.c_str()); ps->SetShaderCode(PixelShaderSource.c_str()); vs->Compile(); ps->Compile(); ShaderObjectList.clear(); AddShaderObject(vs); AddShaderObject(ps); } void IOpenGLShaderProgram::LoadVertexShader(const char *glslshader, const char *VtxShaderPreprocessorDefines) { nuxAssertMsg(glslshader, "[IOpenGLShaderProgram::LoadVertexShader] Invalid shader code."); NUX_RETURN_IF_NULL(glslshader); ObjectPtr vs = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); //new IOpenGLVertexShader; std::string ProcessedShaderSource; if(!VtxShaderPreprocessorDefines) { VtxShaderPreprocessorDefines = ""; } std::string Defines(VtxShaderPreprocessorDefines); InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines); vs->SetShaderCode(glslshader); vs->Compile(); AddShaderObject(vs); } void IOpenGLShaderProgram::LoadPixelShader(const char *glslshader, const char *FrgShaderPreprocessorDefines) { nuxAssertMsg(glslshader, "[IOpenGLShaderProgram::LoadPixelShader] Invalid shader code."); NUX_RETURN_IF_NULL(glslshader); ObjectPtr ps = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); //new IOpenGLPixelShader; std::string ProcessedShaderSource; if (!FrgShaderPreprocessorDefines) { FrgShaderPreprocessorDefines = ""; } std::string Defines(FrgShaderPreprocessorDefines); InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines); ps->SetShaderCode(glslshader); ps->Compile(); AddShaderObject(ps); } void IOpenGLShaderProgram::AddShaderObject(ObjectPtr ShaderObject) { ShaderObjectList.push_back(ShaderObject); } void IOpenGLShaderProgram::AddShaderParameter(GLShaderParameter* parameter) { GLShaderParameter* temp = _FirstParameter; while (temp) { if (temp == parameter) { // Parameter already added return; } temp = temp->m_NextParameter; } parameter->m_NextParameter = _FirstParameter; _FirstParameter = parameter; // If we add shader parameters after the program is linked, we need to call CheckUniformLocation(). CheckUniformLocation(); } void IOpenGLShaderProgram::RemoveShaderObject(ObjectPtr ShaderObject) { std::vector< ObjectPtr >::iterator it = find(ShaderObjectList.begin(), ShaderObjectList.end(), ShaderObject); if (it != ShaderObjectList.end()) { ShaderObjectList.erase(it); } } void IOpenGLShaderProgram::ClearShaderObjects() { ShaderObjectList.clear(); } bool IOpenGLShaderProgram::Link() { // Get the number of attached shaders. GLint NumAttachedShaders; CHECKGL(glGetProgramiv(_OpenGLID, GL_ATTACHED_SHADERS, &NumAttachedShaders)); GLuint *ShaderObjects = 0; if (NumAttachedShaders) { ShaderObjects = new GLuint[NumAttachedShaders]; } CHECKGL(glGetAttachedShaders(_OpenGLID, NumAttachedShaders, NULL, ShaderObjects)); // Detach everything first for (int i = 0; i < (int) NumAttachedShaders; i++) { unsigned int obj = ShaderObjects[i]; CHECKGL(glDetachShader(_OpenGLID, obj)); } if (NumAttachedShaders) { delete[] ShaderObjects; } for (int i = 0; i < (int) ShaderObjectList.size(); i++) { if (!ShaderObjectList[i]->IsValid()) { if (ShaderObjectList[i]->Compile() == false) { nuxDebugMsg("[IOpenGLShaderProgram::Link] Attached shader %s does not compile with program: %s.", ShaderObjectList[i]->_ShaderName.c_str(), _ShaderProgramName.c_str()); } } unsigned int obj = ShaderObjectList[i]->GetOpenGLID(); CHECKGL(glAttachShader(_OpenGLID, obj)); } GLint linked; CHECKGL(glLinkProgram(_OpenGLID)); CHECKGL(glGetProgramiv(_OpenGLID, GL_LINK_STATUS, &linked)); if (linked == GL_FALSE) { ANSICHAR *InfoLogBuffer = 0; GLint InfoLogBufferSize = 0; GLint InfoLogReturnSize = 0; GLint iLog = 0; glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog); InfoLogBuffer = new ANSICHAR[iLog+1]; InfoLogBufferSize = iLog + 1; glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer); if (InfoLogReturnSize != 0) { nuxError("[IOpenGLShaderProgram::Link] glLinkProgram: %s", InfoLogBuffer); } delete[] InfoLogBuffer; m_CompiledAndReady = false; return m_CompiledAndReady; } GLint validated; // glValidateProgram checks to see whether the executables contained in program can execute given the current OpenGL state. CHECKGL(glValidateProgram(_OpenGLID)); CHECKGL(glGetProgramiv(_OpenGLID, GL_VALIDATE_STATUS, &validated)); if (validated == GL_FALSE) { ANSICHAR *InfoLogBuffer = 0; GLint InfoLogBufferSize = 0; GLint InfoLogReturnSize = 0; GLint iLog = 0; glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog); InfoLogBuffer = new ANSICHAR[iLog+1]; InfoLogBufferSize = iLog + 1; glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer); if (InfoLogReturnSize != 0) { nuxError("[IOpenGLShaderProgram::Link] glValidateProgram: %s", InfoLogBuffer); } delete [] InfoLogBuffer; } m_CompiledAndReady = true; Begin(); CheckUniformLocation(); CheckAttributeLocation(); End(); return m_CompiledAndReady; } void IOpenGLShaderProgram::SetShaderTracking(bool enabled) { local::enable_tracking = enabled; local::last_loaded_shader = 0; CHECKGL(glUseProgramObjectARB(0)); } void IOpenGLShaderProgram::Begin(void) { if (local::last_loaded_shader == _OpenGLID && local::enable_tracking) return; local::last_loaded_shader = _OpenGLID; CHECKGL(glUseProgramObjectARB(_OpenGLID)); } void IOpenGLShaderProgram::End(void) { if (!local::enable_tracking) CHECKGL(glUseProgramObjectARB(0)); } void IOpenGLShaderProgram::CheckAttributeLocation() { //ResetAttributeVariable(m_ProgramAttributeDefinition); for (int i = 0; i < NUM_VERTEX_SHADER_INPUT_ATTRIBUTE; i++) { m_ProgramAttributeDefinition[i].attribute_index = -1; m_ProgramAttributeDefinition[i].attribute_name = ""; m_ProgramAttributeDefinition[i].type = VAT_UNDEFINED; m_ProgramAttributeDefinition[i].valid = false; } char active_attribute_name[256]; GLsizei length; GLint size; GLenum type; GLint num_active_attributes; CHECKGL(glGetObjectParameterivARB(_OpenGLID, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &num_active_attributes)); // Vertex Attribute Aliasing // GLSL attempts to eliminate aliasing of vertex attributes but this is integral to NVIDIA's hardware // approach and necessary for maintaining compatibility with existing OpenGL applications that NVIDIA customers rely on. // NVIDIA's GLSL implementation therefore does not allow built-in vertex attributes to collide with a // generic vertex attributes that is assigned to a particular vertex attribute index with glBindAttribLocation. // For example, you should not use gl_Normal(a built-in vertex attribute) and also use glBindAttribLocation to // bind a generic vertex attribute named "whatever" to vertex attribute index 2 because gl_Normal aliases to index 2. // // Built-in vertex attribute name Incompatible aliased vertex attribute index // gl_Vertex 0 // gl_Normal 2 // gl_Color 3 // gl_SecondaryColor 4 // gl_FogCoord 5 // gl_MultiTexCoord0 8 // gl_MultiTexCoord1 9 // gl_MultiTexCoord2 10 // gl_MultiTexCoord3 11 // gl_MultiTexCoord4 12 // gl_MultiTexCoord5 13 // gl_MultiTexCoord6 14 // gl_MultiTexCoord7 15 // The compiler will automatically assign vertex shader attribute variables not pre-assigned // by glBindAttribLocation to locations that do not collide with any built-in attribute variables // used by the vertex shader. The assigned locations can be queries with glGetAttribLocation. // This means that a developer only needs to worry about collisions when they are explicitly requesting // an attribute to be bound to a specific location. for (int index = 0; index < num_active_attributes; index++) { glGetActiveAttribARB(_OpenGLID, index, 256, &length, &size, &type, active_attribute_name); CHECKGL_MSG( glGetActiveAttribARB ); m_ProgramAttributeDefinition[index].attribute_index = glGetAttribLocationARB(_OpenGLID, active_attribute_name); CHECKGL_MSG( glGetAttribLocationARB ); m_ProgramAttributeDefinition[index].attribute_name = active_attribute_name; m_ProgramAttributeDefinition[index].valid = true; switch(type) { case GL_FLOAT: m_ProgramAttributeDefinition[index].type = VAT_FLOAT; break; case GL_FLOAT_VEC2: m_ProgramAttributeDefinition[index].type = VAT_FLOAT2; break; case GL_FLOAT_VEC3: m_ProgramAttributeDefinition[index].type = VAT_FLOAT3; break; case GL_FLOAT_VEC4: m_ProgramAttributeDefinition[index].type = VAT_FLOAT4; break; case GL_FLOAT_MAT2: case GL_FLOAT_MAT3: case GL_FLOAT_MAT4: default: //todo nuxAssert(0); } } } void IOpenGLShaderProgram::CheckUniformLocation() { GLShaderParameter *parameter = _FirstParameter; while (m_CompiledAndReady && parameter) { int location = glGetUniformLocationARB(_OpenGLID, parameter->m_Name.c_str()); CHECKGL_MSG(glGetUniformLocationARB(_OpenGLID, parameter->m_Name.c_str())); //nuxDebugMsg("[IOpenGLShaderProgram::CheckUniformLocation] prog: %d, name: %s, location index: %d", _OpenGLID, parameter->m_Name.c_str(), location); if ((location == -1) && (!parameter->m_bIsOptional)) { nuxDebugMsg("[IOpenGLShaderProgram::CheckUniformLocation] Couldn't find shader program parameter %s \n", parameter->m_Name.c_str()); nuxAssert(0); } parameter->m_Index = location; parameter = parameter->m_NextParameter; } } int IOpenGLShaderProgram::GetAttributeLocation(const char *AttributeName) { for (int i = 0; i < 16 /*NUM_VERTEX_SHADER_INPUT_ATTRIBUTE*/; i++) { if (m_ProgramAttributeDefinition[i].attribute_name == AttributeName) return m_ProgramAttributeDefinition[i].attribute_index; } return -1; } bool IOpenGLShaderProgram::SetUniform1f(char *varname, GLfloat v0) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform1fARB(loc, v0); return true; } bool IOpenGLShaderProgram::SetUniform1f(GLint loc, GLfloat v0) { if (loc == -1) return false; // can't find variable glUniform1fARB(loc, v0); return true; } bool IOpenGLShaderProgram::SetUniform2f(char *varname, GLfloat v0, GLfloat v1) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform2fARB(loc, v0, v1); return true; } bool IOpenGLShaderProgram::SetUniform2f(GLint loc, GLfloat v0, GLfloat v1) { if (loc == -1) return false; // can't find variable glUniform2fARB(loc, v0, v1); return true; } bool IOpenGLShaderProgram::SetUniform3f(char *varname, GLfloat v0, GLfloat v1, GLfloat v2) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform3fARB(loc, v0, v1, v2); return true; } bool IOpenGLShaderProgram::SetUniform3f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2) { if (loc == -1) return false; // can't find variable glUniform3fARB(loc, v0, v1, v2); return true; } bool IOpenGLShaderProgram::SetUniform4f(char *varname, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform4fARB(loc, v0, v1, v2, v3); return true; } bool IOpenGLShaderProgram::SetUniform4f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { if (loc == -1) return false; // can't find variable glUniform4fARB(loc, v0, v1, v2, v3); return true; } bool IOpenGLShaderProgram::SetUniform1i(char *varname, GLint v0) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform1iARB(loc, v0); return true; } bool IOpenGLShaderProgram::SetUniform1i(GLint loc, GLint v0) { if (loc == -1) return false; // can't find variable glUniform1iARB(loc, v0); return true; } bool IOpenGLShaderProgram::SetUniform2i(char *varname, GLint v0, GLint v1) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform2iARB(loc, v0, v1); return true; } bool IOpenGLShaderProgram::SetUniform2i(GLint loc, GLint v0, GLint v1) { if (loc == -1) return false; // can't find variable glUniform2iARB(loc, v0, v1); return true; } bool IOpenGLShaderProgram::SetUniform3i(char *varname, GLint v0, GLint v1, GLint v2) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform3iARB(loc, v0, v1, v2); return true; } bool IOpenGLShaderProgram::SetUniform3i(GLint loc, GLint v0, GLint v1, GLint v2) { if (loc == -1) return false; // can't find variable glUniform3iARB(loc, v0, v1, v2); return true; } bool IOpenGLShaderProgram::SetUniform4i(char *varname, GLint v0, GLint v1, GLint v2, GLint v3) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform4iARB(loc, v0, v1, v2, v3); return true; } bool IOpenGLShaderProgram::SetUniform4i(GLint loc, GLint v0, GLint v1, GLint v2, GLint v3) { if (loc == -1) return false; // can't find variable glUniform4iARB(loc, v0, v1, v2, v3); return true; } bool IOpenGLShaderProgram::SetUniform1fv(char *varname, GLsizei count, GLfloat *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform1fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform1fv(GLint loc, GLsizei count, GLfloat *value) { if (loc == -1) return false; // can't find variable glUniform1fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform2fv(char *varname, GLsizei count, GLfloat *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform2fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform2fv(GLint loc, GLsizei count, GLfloat *value) { if (loc == -1) return false; // can't find variable glUniform2fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform3fv(char *varname, GLsizei count, GLfloat *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform3fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform3fv(GLint loc, GLsizei count, GLfloat *value) { if (loc == -1) return false; // can't find variable glUniform3fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform4fv(char *varname, GLsizei count, GLfloat *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform4fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform4fv(GLint loc, GLsizei count, GLfloat *value) { if (loc == -1) return false; // can't find variable glUniform4fvARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform1iv(char *varname, GLsizei count, GLint *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform1ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform1iv(GLint loc, GLsizei count, GLint *value) { if (loc == -1) return false; // can't find variable glUniform1ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform2iv(char *varname, GLsizei count, GLint *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform2ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform2iv(GLint loc, GLsizei count, GLint *value) { if (loc == -1) return false; // can't find variable glUniform2ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform3iv(char *varname, GLsizei count, GLint *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform3ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform3iv(GLint loc, GLsizei count, GLint *value) { if (loc == -1) return false; // can't find variable glUniform3ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform4iv(char *varname, GLsizei count, GLint *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniform4ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniform4iv(GLint loc, GLsizei count, GLint *value) { if (loc == -1) return false; // can't find variable glUniform4ivARB(loc, count, value); return true; } bool IOpenGLShaderProgram::SetUniformMatrix2fv(char *varname, GLsizei count, GLboolean transpose, GLfloat *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniformMatrix2fvARB(loc, count, transpose, value); return true; } bool IOpenGLShaderProgram::SetUniformLocMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value) { if (loc == -1) return false; // can't find variable glUniformMatrix2fvARB(loc, count, transpose, value); return true; } bool IOpenGLShaderProgram::SetUniformMatrix3fv(char *varname, GLsizei count, GLboolean transpose, GLfloat *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniformMatrix3fvARB(loc, count, transpose, value); return true; } bool IOpenGLShaderProgram::SetUniformLocMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value) { if (loc == -1) return false; // can't find variable glUniformMatrix3fvARB(loc, count, transpose, value); return true; } bool IOpenGLShaderProgram::SetUniformMatrix4fv(char *varname, GLsizei count, GLboolean transpose, GLfloat *value) { GLint loc = GetUniformLocationARB(varname); if (loc == -1) return false; // can't find variable glUniformMatrix4fvARB(loc, count, transpose, value); return true; } bool IOpenGLShaderProgram::SetUniformLocMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value) { if (loc == -1) return false; // can't find variable glUniformMatrix4fvARB(loc, count, transpose, value); return true; } void IOpenGLShaderProgram::GetUniformfv(char *name, GLfloat *values) { GLint loc; loc = glGetUniformLocationARB(_OpenGLID, name); CHECKGL_MSG( glGetUniformLocationARB ); if (loc == -1) { std::cout << "Error: can't find uniform variable \"" << name << "\"\n"; } CHECKGL(glGetUniformfvARB(_OpenGLID, loc, values)); } void IOpenGLShaderProgram::GetUniformiv(char *name, GLint *values) { GLint loc; loc = glGetUniformLocationARB(_OpenGLID, name); CHECKGL_MSG( glGetUniformLocationARB ); if (loc == -1) { std::cout << "Error: can't find uniform variable \"" << name << "\"\n"; } CHECKGL(glGetUniformivARB(_OpenGLID, loc, values)); } int IOpenGLShaderProgram::GetUniformLocationARB(const GLcharARB *name) { GLint loc; loc = glGetUniformLocationARB(_OpenGLID, name); CHECKGL_MSG( glGetUniformLocationARB ); return loc; } void IOpenGLShaderProgram::GetActiveUniformARB( GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name) { glGetActiveUniformARB(_OpenGLID, index, maxLength, length, size, type, name); CHECKGL_MSG(glGetActiveUniformARB); } void IOpenGLShaderProgram::GetObjectParameterfvARB(GLenum pname, GLfloat *params) { #ifndef NUX_OPENGLES_20 glGetObjectParameterfvARB(_OpenGLID, pname, params); CHECKGL_MSG(glGetObjectParameterfvARB); #endif } bool IOpenGLShaderProgram::SetSampler(char *name, int texture_unit) { GLint loc = GetUniformLocationARB(name); if (loc == -1) return false; // can't find variable glUniform1iARB(loc, texture_unit); return true; } } nux-4.0.6+14.04.20140409/NuxGraphics/MeshFileLoader-OBJ.h0000644000015301777760000000025112321344237022572 0ustar pbusernogroup00000000000000#ifndef MESHFILELOADER_H #define MESHFILELOADER_H namespace nux { class MeshData; MeshData* LoadMeshFile_OBJ(const char* filename); } #endif // MESHFILELOADER_H nux-4.0.6+14.04.20140409/NuxGraphics/GLShaderParameter.h0000644000015301777760000001073612321344237022642 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLSHADERPARAMETER_H #define GLSHADERPARAMETER_H #include "GLError.h" #include "GLResource.h" namespace nux { //! Type of shader in a shader enum eShaderParameterType { eVERTEXUNIFORMTYPE, eFRAGMENTUNIFORMTYPE, eSAMPLERUNIFORMTYPE, }; //! Type of shader enum eShaderType { eVERTEXSHADERTYPE, eFRAGMENTSHADERTYPE }; class GLProgramObject; class IOpenGLShaderProgram; class GLShaderParameter { public: int m_Index; // Register m_Index / Attribute m_Index eShaderParameterType m_ShaderParameterType; std::string m_Name; bool m_bIsOptional; bool m_bIsStatic; bool bStaticSet; GLProgramObject *m_ShaderProgram; IOpenGLShaderProgram *m_ShaderProgram2; GLShaderParameter *m_NextParameter; UINT m_Size; UINT m_Type; GLShaderParameter(GLProgramObject *Shader, const char *ParamName, eShaderParameterType InType, bool InbIsOptional = FALSE, bool InbIsStatic = FALSE); inline void SetUniform1f( FLOAT FloatA ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform1fARB( m_Index, FloatA )); } inline void SetUniform1i( INT i ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform1iARB( m_Index, i )); } inline void SetUniform2f( FLOAT FloatA, FLOAT FloatB ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform2fARB( m_Index, FloatA, FloatB )); } inline void SetUniform3f( FLOAT FloatA, FLOAT FloatB, FLOAT FloatC ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform3fARB( m_Index, FloatA, FloatB, FloatC )); } inline void SetUniform4f( FLOAT FloatA, FLOAT FloatB, FLOAT FloatC, FLOAT FloatD ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform4fARB( m_Index, FloatA, FloatB, FloatC, FloatD )); } inline void SetUniform1fv( GLsizei count, GLfloat *value ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform1fvARB( m_Index, count, value )); } inline void SetUniform2fv( GLsizei count, GLfloat *value ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform2fvARB( m_Index, count, value )); } inline void SetUniform3fv( GLsizei count, GLfloat *value ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform3fvARB( m_Index, count, value )); } inline void SetUniform4fv( GLsizei count, GLfloat *value ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniform4fvARB( m_Index, count, value )); } inline void SetUniformMatrix2fv( GLsizei count, GLfloat *value, GLboolean transpose = GL_FALSE ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniformMatrix2fvARB( m_Index, count, transpose, value )); } inline void SetUniformMatrix3fv( GLsizei count, GLfloat *value, GLboolean transpose = GL_FALSE ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniformMatrix3fvARB( m_Index, count, transpose, value )); } inline void SetUniformMatrix4fv( GLsizei count, GLfloat *value, GLboolean transpose = GL_FALSE ) { NUX_RETURN_IF_TRUE(m_Index == -1); CHECKGL(glUniformMatrix4fvARB( m_Index, count, transpose, value )); } inline void SetTexture( const GLuint /* textureId */) { //CHECKGL(glUniform1iARB( m_Index, textureId )); //CHECKGL(cgGLEnableTextureParameter( CgParameter )); } void MapTo( GLProgramObject *Shader ); private: }; } #endif // GLSHADERPARAMETER_H nux-4.0.6+14.04.20140409/NuxGraphics/GLError.h0000644000015301777760000000362412321344237020662 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLERROR_H #define GLERROR_H // WARNING: Never call glGetError between glBegin and glEnd. // WARNING: Never use CHECKGL between glBegin() and glEnd(). #ifdef NUX_DEBUG #define CHECKGL(GLcall ) \ { \ GLcall; \ if (1) \ nux::CheckGLError( ANSI_TO_TCHAR(#GLcall), __FILE__, __LINE__ ); \ } #define CHECKGL_MSG( msg ) \ { \ if (1) \ nux::CheckGLError( ANSI_TO_TCHAR(#msg), __FILE__, __LINE__ ); \ } #else #define CHECKGL(GLcall) \ { \ GLcall; \ } #define CHECKGL_MSG( msg ) \ { \ } #endif namespace nux { void CheckGLError(const char *GLcall, const char *file, int line); } #endif // GLERROR_H nux-4.0.6+14.04.20140409/NuxGraphics/GestureEvent.h0000644000015301777760000001302312321344237021760 0ustar pbusernogroup00000000000000/* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Daniel d'Andrada * */ #ifndef NUX_GESTURE_EVENT_H #define NUX_GESTURE_EVENT_H #include "Nux/Features.h" #ifdef NUX_GESTURES_SUPPORT #include #include #include "Events.h" #include "NuxCore/Math/Point2D.h" namespace nux { //! Enumerates all possible gesture classes. enum GestureClass { DRAG_GESTURE = 1, //! A drag gesture PINCH_GESTURE = 2, //! A pinch gesture ROTATE_GESTURE = 4, //! A rotation gesture TAP_GESTURE = 8, //! A tap gesture. TOUCH_GESTURE = 16 /*! A touch gesture. It merely groups two or more touch points and send their information, without interpreting what gestures the touch points are performing. */ }; class TouchPoint { public: TouchPoint() : id(-1), x(0.0f), y(0.0f) {} TouchPoint(int id, float x, float y) : id(id), x(x), y(y) {} bool operator ==(const TouchPoint& other) const { return id == other.id; } int id; float x; float y; }; //! Gesture Event class class GestureEvent : public Event { public: //! Constructs a GestureEvent GestureEvent(); //! Accepts the gesture. void Accept(); //! Rejects the gesture. void Reject(); //! The gesture classes that this gesture belongs to. /*! A bitwise "or" of one or more gesture classes from GestureClass enumeration. A single physical gesture can comply/belong to more than one gesture class, such as a rotating pinch. */ int GetGestureClasses() const {return gesture_classes_;} //! Whether all gestures for the related touch points have been presented. /*! This property allows the client to determine if all the possible gestures from the set of touches in this event have already been presented. When this value is true, the client will have received all the information needed to make a gesture accept and reject decision based on potentially overlapping gestures. An example is when both one and two touch gestures are subscribed on the same window with the same gesture classes and thresholds. When this property is true for one touch gesture events, the client can be sure there are no other touches unless a two touch gesture event has already been sent. Another example is when you subscribe for three touches Touch and four touches Drag. As soon as a third finger is detected a three touches Touch gesture will begin, but you cannot be sure a fourth finger isn't coming right after (that can eventually cause a four touches Drag) until this property is true. */ bool IsConstructionFinished() const { return is_construction_finished_;} int GetGestureId() const {return gesture_id_;} bool IsDirectTouch() const {return is_direct_touch_;} int GetTimestamp() const {return timestamp_;} const Point2D &GetFocus() const {return focus_;} const Point2D &GetDelta() const {return delta_;} float GetAngle() const {return angle_;} float GetAngleDelta() const {return angle_delta_;} float GetAngularVelocity() const {return angular_velocity_;} //! Duration of a tap gesture, in milliseconds int GetTapDuration() const {return tap_duration_;} const Point2D &GetVelocity() {return velocity_;} float GetRadius() const {return radius_;} float GetRadiusDelta() const {return radius_delta_;} float GetRadialVelocity() const {return radial_velocity_;} const std::vector &GetTouches() const {return touches_;} virtual void Reset(); private: int gesture_id_; int gesture_classes_; bool is_direct_touch_; int timestamp_; Point2D focus_; Point2D delta_; float angle_; float angle_delta_; float angular_velocity_; int tap_duration_; Point2D velocity_; float radius_; float radius_delta_; float radial_velocity_; std::vector touches_; bool is_construction_finished_; Geis geis_; GeisGroup geis_group_; friend class GeisAdapter; friend class FakeGestureEvent; }; //! Enumerates possible requests regarding delivery of gesture events. enum class GestureDeliveryRequest { NONE, /*!< No request. Continue with current delivery policy. */ EXCLUSIVITY /*!< From this moment onwards, deliver events from the related gesture only to this target. Other targets for this gesture will receive an event of type EVENT_GESTURE_LOST instead of this event. Note that it doesn't affect targets that come before this one in the order of delivery. */ }; } // namespace nux #endif // NUX_GESTURES_SUPPORT #endif // NUX_GESTURE_EVENT_H nux-4.0.6+14.04.20140409/NuxGraphics/GLTimer.cpp0000644000015301777760000000417112321344237021202 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "GLResource.h" #include "GLTimer.h" namespace nux { GLTimer::GLTimer() { #if defined(NUX_OS_WINDOWS) LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&now); res = (float) (1.0f / (double) freq.QuadPart); #elif defined(NUX_OS_LINUX) gettimeofday(&m_last_time, NULL); #endif } GLTimer::~GLTimer() { } void GLTimer::Reset(void) { #if defined(NUX_OS_WINDOWS) QueryPerformanceCounter(&now); #elif defined(NUX_OS_LINUX) gettimeofday(&m_last_time, NULL); #endif } float GLTimer::PassedMilliseconds(void) { #if defined(NUX_OS_WINDOWS) LARGE_INTEGER temp; QueryPerformanceCounter(&temp); double elapsedTime = (temp.QuadPart - now.QuadPart) * res * 1000.0f; //now.QuadPart = temp.QuadPart; return elapsedTime; #elif defined(NUX_OS_LINUX) timeval current_time; float elapsedTime; gettimeofday(¤t_time, NULL); elapsedTime = (current_time.tv_sec - m_last_time.tv_sec) * 1000.0f; // seconds to millisecond elapsedTime += (current_time.tv_usec - m_last_time.tv_usec) / 1000.0f; // micro seconds to millisecond return elapsedTime; #endif } // float GLTimer::PassedFrac(void) // { // LARGE_INTEGER temp; // QueryPerformanceCounter(&temp); // return(temp.QuadPart - now.QuadPart) * res; // } } nux-4.0.6+14.04.20140409/NuxGraphics/GLDeviceObjects.h0000644000015301777760000000321212321344237022273 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLDEVICEOBJECT_H #define GLDEVICEOBJECT_H #include "GLResource.h" #include "NuxGraphics.h" #include "GLDeviceFrameBufferObject.h" #include "GLShaderParameter.h" #include "GLTextureStates.h" #include "IOpenGLResource.h" #include "IOpenGLVertexBuffer.h" #include "IOpenGLIndexBuffer.h" #include "IOpenGLPixelBufferOject.h" #include "IOpenGLBaseTexture.h" #include "IOpenGLSurface.h" #include "IOpenGLVolume.h" #include "IOpenGLVolumeTexture.h" #include "IOpenGLCubeTexture.h" #include "IOpenGLRectangleTexture.h" #include "IOpenGLTexture2D.h" #include "IOpenGLAnimatedTexture.h" #include "IOpenGLGLSLShader.h" #ifndef NUX_OPENGLES_20 #include "IOpenGLAsmShader.h" #endif #include "IOpenGLQuery.h" #include "IOpenGLVertexDeclaration.h" #include "IOpenGLFrameBufferObject.h" #if (NUX_ENABLE_CG_SHADERS) #include "IOpenGLCgShader.h" #endif #endif // GLDEVICEOBJECT_H nux-4.0.6+14.04.20140409/NuxGraphics/GLTextureResourceManager.h0000644000015301777760000004247012321344237024236 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLTEXTURERESOURCEMANAGER_H #define GLTEXTURERESOURCEMANAGER_H #include "GLResourceManager.h" #include "IOpenGLBaseTexture.h" #include namespace nux { class NTextureData; class BaseTexture; class CachedBaseTexture; /*! * Create and load a 2D texture filled with RGBA pixels loaded from the image * file pointed by filename. The loading uses the GdkPixbuf library which * implies that the supported formats depend on the GdkPixbuf loaders * installed on the client system. * * @max_size Specifies the maximal required size for the image to be loaded, * if the width or height exceeds that value, the image is scaled down * respecting the aspect ratio. A value of -1 means that no maximal value is * required. * @premultiply Specifies if the R, G and B color channels must be * premultiplied by the alpha channel before being uploaded to the texture. * Note that if there's no alpha channel, the argument is ignored. * @return The resulting texture. */ BaseTexture* CreateTexture2DFromFile(const char* filename, int max_size, bool premultiply); /*! * Create and load a 2D texture filled with RGBA pixels loaded from the * GdkPixbuf pointed by pixbuf. * * @premultiply Specifies if the R, G and B color channels must be * premultiplied by the alpha channel before being uploaded to the texture. * Note that if there's no alpha channel, the argument is ignored. * @return The resulting texture. */ BaseTexture* CreateTexture2DFromPixbuf(GdkPixbuf* pixbuf, bool premultiply); // FIXME(loicm) Should be deprecated. BaseTexture* CreateTextureFromPixbuf(GdkPixbuf* pixbuf); BaseTexture* CreateTextureFromFile(const char* TextureFilename); BaseTexture* CreateTextureFromBitmapData(const NBitmapData* BitmapData); BaseTexture* LoadTextureFromFile(const std::string& filename); //! Abstract base class for textures. class BaseTexture: public ResourceData { NUX_DECLARE_OBJECT_TYPE(BaseTexture, ResourceData); BaseTexture(NUX_FILE_LINE_PROTO); virtual ~BaseTexture(); /*! Update the texture with the provided Bitmap data. In doing so, if the texture as been cached in the resource manager, then the the DeviceTexture inside the CachedTexture will no longer be returned by GetDeviceTexture(). Instead a new device texture will be returned. @BitmapData Pointer to the bitmap data. @UpdateAndCacheResource If true, then the texture is cached immediately. If false, the texture will be cached the first time GetDeviceTexture() or GetCachedTexture() is called. @return True if there was no error during the update. */ virtual bool Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource = true) = 0; /*! Update the texture with the provided filename. In doing so, if the texture as been cached in the resource manager, then the the DeviceTexture inside the CachedTexture will no longer be returned by GetDeviceTexture(). Instead a new device texture will be returned. @BitmapData Pointer to the bitmap data. @UpdateAndCacheResource If true, then the texture is cached immediately. If false, the texture will be cached the first time GetDeviceTexture() or GetCachedTexture() is called. @return True if there was no error during the update. */ virtual bool Update(const char* filename, bool UpdateAndCacheResource = true) = 0; virtual void GetData(void* Buffer, int MipIndex, int StrideY, int face = 0) = 0; /*! @return The texture width. */ virtual int GetWidth() const = 0; /*! @return The texture height. */ virtual int GetHeight() const = 0; /*! @return The texture depth. Return 1 for Texture2D, TextureCube, TextureRenctangle. TextureVolume and TextureFrameAnimation have a depth equal or greater than 1. For TextureFrameAnimation the depth represents the number of frames. */ virtual int GetDepth() const { return 1; } /*! @return True if the width and height of the texture are powers of two. */ virtual bool IsPowerOfTwo() const = 0; /*! @return The texture data format. */ virtual BitmapFormat GetFormat() const = 0; /*! @return The number of mip maps in the texture. */ virtual int GetNumMipLevel() const = 0; /*! @return True if the texture storage contains valid bitmap data. */ virtual bool IsNull() const = 0; virtual BaseTexture* Clone() const = 0; /*! Cache the texture if it hasn't been been already and return the device texture. \sa IOpenGLBaseTexture; @return The device texture. */ ObjectPtr GetDeviceTexture(); /*! Cache the texture if it hasn't been been already and return the cached texture. \sa CachedBaseTexture; @return The cached texture. */ ObjectPtr GetCachedTexture(); }; //! General Texture /*! The class of texture that cover power-of-two and non-power-of-two dimensions. */ class Texture2D: public BaseTexture { NUX_DECLARE_OBJECT_TYPE(Texture2D, BaseTexture); public: Texture2D(NUX_FILE_LINE_PROTO); // TODO: Why can we create a texture without a texture? Texture2D(const NTextureData& Image, NUX_FILE_LINE_PROTO); ~Texture2D(); /*! Update the hardware resources associated to this with the provided texture data. @param BitmapData The texture data to update into the hardware resource. @param UpdateAndCacheResource if True, then the texture data is loaded into this object, and the caching into hardware data is done right away. If false, the caching is done latter by calling GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(this); @return True is there was not error. */ virtual bool Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource = true); /*! Update the hardware resources associated to this object with the data associated to the file name. @param Filename File name of texture data to update into the hardware resource. @param UpdateAndCacheResource if True, then the texture data is loaded into this object, and the caching into hardware data is done right away. If false, the caching is done latter by calling GetGraphicsDisplay()->GetGraphicsEngine()->CacheResource(this); @return True is there was not error. */ virtual bool Update(const char* Filename, bool UpdateAndCacheResource = true); /*! @return True if the texture storage contains valid bitmap data. */ virtual bool IsNull() const { return _image.IsNull(); } void GetData(void* Buffer, int MipIndex, int StrideY, int face = 0); /*! @return The number of mip maps in the texture. */ int GetNumMipLevel() const { return _image.GetNumMipmap(); } /*! @return The texture width. */ int GetWidth() const { return _image.GetWidth(); } /*! @return The texture height. */ int GetHeight() const { return _image.GetHeight(); } /*! @return The texture data format. */ BitmapFormat GetFormat() const { return _image.GetFormat(); } /*! @return True if the width and height of the texture are powers of two. */ bool IsPowerOfTwo() const { return IsPowerOf2(_image.GetWidth()) && IsPowerOf2(_image.GetHeight()); } virtual Texture2D* Clone() const; private: NTextureData _image; //!< Storage for the texture data }; class TextureRectangle: public BaseTexture { NUX_DECLARE_OBJECT_TYPE(TextureRectangle, BaseTexture); public: TextureRectangle(NUX_FILE_LINE_PROTO); // TODO: Why can we create a texture without a texture? TextureRectangle(const NTextureData& Image, NUX_FILE_LINE_PROTO); ~TextureRectangle(); virtual bool Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource = true); virtual bool Update(const char* filename, bool UpdateAndCacheResource = true); /*! @return True if the texture storage contains valid bitmap data. */ virtual bool IsNull() const { return _image.IsNull(); } void GetData(void* Buffer, int MipIndex, int StrideY, int face = 0); /*! @return The number of mip maps in the texture. */ int GetNumMipLevel() const { return _image.GetNumMipmap(); } /*! @return The texture width. */ int GetWidth() const { return _image.GetWidth(); } /*! @return The texture height. */ int GetHeight() const { return _image.GetHeight(); } /*! @return The texture data format. */ BitmapFormat GetFormat() const { return _image.GetFormat(); } /*! @return True if the width and height of the texture are powers of two. */ bool IsPowerOfTwo() const { return IsPowerOf2(_image.GetWidth()) && IsPowerOf2(_image.GetHeight()); } virtual TextureRectangle* Clone() const; private: NTextureData _image; }; class TextureCube: public BaseTexture { NUX_DECLARE_OBJECT_TYPE(TextureCube, BaseTexture); public: TextureCube(NUX_FILE_LINE_PROTO); // TODO: why can we have a texture without a texture? TextureCube(const NCubemapData& Image); ~TextureCube(); virtual bool Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource = true); virtual bool Update(const char* filename, bool UpdateAndCacheResource = true); /*! @return True if the texture storage contains valid bitmap data. */ virtual bool IsNull() const { return _image.IsNull(); } void GetData(void* Buffer, int MipIndex, int StrideY, int face = 0); /*! @return The number of mip maps in the texture. */ int GetNumMipLevel() const { return _image.GetNumMipmap(); } /*! @return The texture width. */ int GetWidth() const { return _image.GetWidth(); } /*! @return The texture height. */ int GetHeight() const { return _image.GetHeight(); } /*! @return The texture data format. */ BitmapFormat GetFormat() const { return _image.GetFormat(); } /*! @return True if the width and height of the texture are powers of two. */ bool IsPowerOfTwo() const { return IsPowerOf2(_image.GetWidth()) && IsPowerOf2(_image.GetHeight()); } virtual TextureCube* Clone() const; private: NCubemapData _image; }; class TextureVolume: public BaseTexture { NUX_DECLARE_OBJECT_TYPE(TextureVolume, BaseTexture); public: TextureVolume(NUX_FILE_LINE_PROTO); // TODO: why can we have a texture without a texture? TextureVolume(const NVolumeData& Image); ~TextureVolume(); virtual bool Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource = true); virtual bool Update(const char* filename, bool UpdateAndCacheResource = true); /*! @return True if the texture storage contains valid bitmap data. */ virtual bool IsNull() const { return _image.IsNull(); } void GetData(void* Buffer, int MipIndex, int StrideY, int slice = 0); /*! @return The number of mip maps in the texture. */ int GetNumMipLevel() const { return _image.GetNumMipmap(); } /*! @return The texture width. */ int GetWidth() const { return _image.GetWidth(); } /*! @return The texture height. */ int GetHeight() const { return _image.GetHeight(); } /*! @return The texture depth. For TextureFrameAnimation the depth represents the number of frames. */ int GetDepth() const { return _image.GetDepth(); } /*! @return The texture data format. */ BitmapFormat GetFormat() const { return _image.GetFormat(); } /*! @return True if the width and height of the texture are powers of two. */ bool IsPowerOfTwo() const { return IsPowerOf2(_image.GetWidth()) && IsPowerOf2(_image.GetHeight()); } virtual TextureVolume* Clone() const; private: NVolumeData _image; }; class TextureFrameAnimation: public BaseTexture { NUX_DECLARE_OBJECT_TYPE(TextureFrameAnimation, BaseTexture); public: TextureFrameAnimation(NUX_FILE_LINE_PROTO); // TODO: why can we have a texture without a texture? TextureFrameAnimation(const NAnimatedTextureData& Image); ~TextureFrameAnimation(); virtual bool Update(const NBitmapData* BitmapData, bool UpdateAndCacheResource = true); virtual bool Update(const char* filename, bool UpdateAndCacheResource = true); /*! @return True if the texture storage contains valid bitmap data. */ virtual bool IsNull() const { return _image.IsNull(); } void GetData(void* Buffer, int MipIndex, int StrideY, int slice = 0); int GetFrameTime(int Frame); /*! @return The number of mip maps in the texture. */ int GetNumMipLevel() const { return _image.GetNumMipmap(); } /*! @return The texture width. */ int GetWidth() const { return _image.GetWidth(); } /*! @return The texture height. */ int GetHeight() const { return _image.GetHeight(); } /*! @return The number of animation frames in the texture. */ int GetDepth() const { return _image.GetDepth(); } /*! @return The texture data format. */ BitmapFormat GetFormat() const { return _image.GetFormat(); } /*! @return true if the width and heigth of the texture are powers of two. */ bool IsPowerOfTwo() const { return IsPowerOf2(_image.GetWidth()) && IsPowerOf2(_image.GetHeight()); } virtual TextureFrameAnimation* Clone() const; private: NAnimatedTextureData _image; }; class CachedBaseTexture: public CachedResourceData { NUX_DECLARE_OBJECT_TYPE(CachedBaseTexture, CachedResourceData); public: ObjectPtr < IOpenGLBaseTexture > m_Texture; CachedBaseTexture(NResourceSet* ResourceManager); ~CachedBaseTexture(); virtual void LoadMipLevel(BaseTexture* SourceTexture, int MipLevel) = 0; virtual bool UpdateResource(ResourceData* Resource); bool RecreateTexture(BaseTexture* Source); virtual void UpdateTexture(BaseTexture* Source) = 0; unsigned int SourceWidth; unsigned int SourceHeight; unsigned int SourceDepth; BitmapFormat SourceFormat; }; class CachedTexture2D: public CachedBaseTexture { NUX_DECLARE_OBJECT_TYPE(CachedTexture2D, CachedBaseTexture); public: CachedTexture2D(NResourceSet* ResourceManager, Texture2D* SourceTexture); ~CachedTexture2D(); virtual void UpdateTexture(BaseTexture* Source); virtual void LoadMipLevel(BaseTexture* SourceTexture, int MipLevel); }; class CachedTextureRectangle: public CachedBaseTexture { NUX_DECLARE_OBJECT_TYPE(CachedTextureRectangle, CachedBaseTexture); public: CachedTextureRectangle(NResourceSet* ResourceManager, TextureRectangle* SourceTexture); ~CachedTextureRectangle(); virtual void UpdateTexture(BaseTexture* Source); virtual void LoadMipLevel(BaseTexture* SourceTexture, int MipLevel); }; class CachedTextureCube: public CachedBaseTexture { NUX_DECLARE_OBJECT_TYPE(CachedTextureCube, CachedBaseTexture); public: CachedTextureCube(NResourceSet* ResourceManager, TextureCube* SourceTexture); ~CachedTextureCube(); virtual void UpdateTexture(BaseTexture* Source); virtual void LoadMipLevel(BaseTexture* SourceTexture, int MipLevel); }; class CachedTextureVolume: public CachedBaseTexture { NUX_DECLARE_OBJECT_TYPE(CachedTextureVolume, CachedBaseTexture); public: CachedTextureVolume(NResourceSet* ResourceManager, TextureVolume* SourceTexture); ~CachedTextureVolume(); virtual void UpdateTexture(BaseTexture* Source); virtual void LoadMipLevel(BaseTexture* SourceTexture, int MipLevel); }; class CachedTextureFrameAnimation: public CachedBaseTexture { NUX_DECLARE_OBJECT_TYPE(CachedTextureFrameAnimation, CachedBaseTexture); public: CachedTextureFrameAnimation(NResourceSet* ResourceManager, TextureFrameAnimation* SourceTexture); ~CachedTextureFrameAnimation(); virtual void UpdateTexture(BaseTexture* Source); virtual void LoadMipLevel(BaseTexture* SourceTexture, int MipLevel); }; } #endif // GLTEXTURERESOURCEMANAGER_H nux-4.0.6+14.04.20140409/NuxGraphics/Events.h0000644000015301777760000003757012321344237020621 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef EVENTS_H #define EVENTS_H #include "GLResource.h" #if defined(NUX_OS_WINDOWS) #include "VirtualKeyCodes.h" #elif defined(USE_X11) #include "VirtualKeyCodesX11.h" #elif defined(NO_X11) #include "VirtualKeyCodes.h" #else #error VirtualKeyCode file not Implemented. #endif namespace nux { const long I_ExposureMask = (1L << 15); const long I_StructureNotifyMask = (1L << 17); const long I_SubstructureNotifyMask = (1L << 19); #define NUX_BackSpace NUX_VK_BACK #define NUX_Tab NUX_VK_TAB #define NUX_Clear NUX_VK_CLEAR #define NUX_Enter NUX_VK_ENTER #define NUX_Shift_L NUX_VK_SHIFT #define NUX_Control_L NUX_VK_CONTROL #define NUX_Alt_L NUX_VK_MENU #define NUX_Pause NUX_VK_PAUSE #define NUX_Caps_Lock NUX_VK_CAPITAL #define NUX_Escape NUX_VK_ESCAPE #define NUX_SpaceBar NUX_VK_SPACE #define NUX_Page_Up NUX_VK_PAGE_UP #define NUX_Page_Down NUX_VK_PAGE_DOWN #define NUX_End NUX_VK_END #define NUX_Home NUX_VK_HOME #define NUX_Left NUX_VK_LEFT #define NUX_Up NUX_VK_UP #define NUX_Right NUX_VK_RIGHT #define NUX_Down NUX_VK_DOWN #define NUX_Print NUX_VK_SNAPSHOT #define NUX_Insert NUX_VK_INSERT #define NUX_Delete NUX_VK_DELETE #define NUX_LWin NUX_VK_LWIN #define NUX_RWin NUX_VK_RWIN #define NUX_APPS NUX_VK_APPS #define NUX_Multiply NUX_VK_MULTIPLY #define NUX_Add NUX_VK_ADD #define NUX_Subtract NUX_VK_SUBTRACT #define NUX_Decimal NUX_VK_DECIMAL #define NUX_Divide NUX_VK_DIVIDE #define NUX_Numlock NUX_VK_NUMLOCK #define NUX_Scroll NUX_VK_SCROLL #define NUX_EXT_Shift_R (0xff00 | NUX_VK_SHIFT) #define NUX_EXT_Control_R (0xff00 | NUX_VK_CONTROL) #define NUX_EXT_Alt_R (0xff00 | NUX_VK_MENU) #define NUX_KP_DOWN 0xFF99 #define NUX_KP_UP 0xFF97 #define NUX_KP_LEFT 0xFF96 #define NUX_KP_RIGHT 0xFF98 // #define NUX_KP_PAGE_UP (0xff00 | NUX_VK_PAGE_UP) // #define NUX_KP_PAGE_DOWN (0xff00 | NUX_VK_PAGE_DOWN) // #define NUX_KP_END (0xff00 | NUX_VK_END) // #define NUX_KP_HOME (0xff00 | NUX_VK_HOME) // #define NUX_KP_INSERT (0xff00 | NUX_VK_INSERT) // #define NUX_KP_DELETE (0xff00 | NUX_VK_DELETE) #define NUX_F1 NUX_VK_F1 #define NUX_F2 NUX_VK_F2 #define NUX_F3 NUX_VK_F3 #define NUX_F4 NUX_VK_F4 #define NUX_F5 NUX_VK_F5 #define NUX_F6 NUX_VK_F6 #define NUX_F7 NUX_VK_F7 #define NUX_F8 NUX_VK_F8 #define NUX_F9 NUX_VK_F9 #define NUX_F10 NUX_VK_F10 #define NUX_F11 NUX_VK_F11 #define NUX_F12 NUX_VK_F12 #define NUX_F13 NUX_VK_F13 #define NUX_F14 NUX_VK_F14 #define NUX_F15 NUX_VK_F15 #define NUX_F16 NUX_VK_F16 #define NUX_F17 NUX_VK_F17 #define NUX_F18 NUX_VK_F18 #define NUX_F19 NUX_VK_F19 #define NUX_F20 NUX_VK_F20 #define NUX_F21 NUX_VK_F21 #define NUX_F22 NUX_VK_F22 #define NUX_F23 NUX_VK_F23 #define NUX_F24 NUX_VK_F24 // These flags describe the mouse button responsible for the mouse event. // They are valid only for the current frame. // Go in mouse_state. #define NUX_EVENT_BUTTON1_UP 0x00001000 #define NUX_EVENT_BUTTON2_UP 0x00002000 #define NUX_EVENT_BUTTON3_UP 0x00004000 #define NUX_EVENT_BUTTON4_UP 0x00008000 #define NUX_EVENT_BUTTON1_DOWN 0x00010000 #define NUX_EVENT_BUTTON2_DOWN 0x00020000 #define NUX_EVENT_BUTTON3_DOWN 0x00040000 #define NUX_EVENT_BUTTON4_DOWN 0x00080000 #define NUX_EVENT_BUTTON1 0x00010000 #define NUX_EVENT_BUTTON2 0x00020000 #define NUX_EVENT_BUTTON3 0x00040000 #define NUX_EVENT_BUTTON4 0x00080000 #define NUX_EVENT_MOUSEWHEEL 0x00100000 // Describes the event as the first press in the double click event. #define NUX_STATE_FIRST_EVENT 0x00200000 // These flags describe the state of the mouse buttons. // They persist over several frame until the mouse buttons change state. // Go in mouse_state. #define NUX_STATE_BUTTON1_DOWN 0x01000000 #define NUX_STATE_BUTTON2_DOWN 0x02000000 #define NUX_STATE_BUTTON3_DOWN 0x04000000 #define NUX_STATE_BUTTON4_DOWN 0x08000000 // These flags are set if the event is a double click. // They are valid only for the current frame. // Go in mouse_state. #define NUX_EVENT_BUTTON1_DBLCLICK 0x10000000 #define NUX_EVENT_BUTTON2_DBLCLICK 0x20000000 #define NUX_EVENT_BUTTON3_DBLCLICK 0x40000000 #define NUX_MOUSEWHEEL_DELTA 120 // 120 correspond to one notch of the mouse wheel typedef unsigned char uchar; typedef unsigned long ulong; struct EventToNameStruct { int event; const char *EventName; }; enum MouseButton { MOUSE_BUTTON_INVALID = 0, MOUSE_BUTTON1 = 1, MOUSE_BUTTON2 = 2, MOUSE_BUTTON3 = 3, MOUSE_BUTTON4 = 4, MOUSE_BUTTON5 = 5, MOUSE_BUTTON6 = 6, MOUSE_BUTTON7 = 7, // The following values are deprecated. Use the ones above. NUX_INVALID_MOUSE_BUTTON = MOUSE_BUTTON_INVALID, NUX_MOUSE_BUTTON1 = MOUSE_BUTTON1, NUX_MOUSE_BUTTON2 = MOUSE_BUTTON2, NUX_MOUSE_BUTTON3 = MOUSE_BUTTON3, NUX_MOUSE_BUTTON4 = MOUSE_BUTTON4, NUX_MOUSE_BUTTON5 = MOUSE_BUTTON5, NUX_MOUSE_BUTTON6 = MOUSE_BUTTON6, NUX_LEFT_MOUSE = NUX_MOUSE_BUTTON1, // Deprecated NUX_MIDDLE_MOUSE = NUX_MOUSE_BUTTON2, // Deprecated NUX_RIGHT_MOUSE = NUX_MOUSE_BUTTON3, // Deprecated }; enum KeyModifier { KEY_MODIFIER_SHIFT = 0x00010000, KEY_MODIFIER_CAPS_LOCK = 0x00020000, KEY_MODIFIER_CTRL = 0x00040000, KEY_MODIFIER_ALT = 0x00080000, KEY_MODIFIER_NUMLOCK = 0x00100000, KEY_MODIFIER_SUPER = 0x00200000, KEY_MODIFIER_SCROLLLOCK = 0x00400000, // The following values are deprecated. Use the ones above. NUX_STATE_SHIFT = KEY_MODIFIER_SHIFT, NUX_STATE_CAPS_LOCK = KEY_MODIFIER_CAPS_LOCK, NUX_STATE_CTRL = KEY_MODIFIER_CTRL, NUX_STATE_ALT = KEY_MODIFIER_ALT, NUX_STATE_NUMLOCK = KEY_MODIFIER_NUMLOCK, NUX_STATE_SUPER = KEY_MODIFIER_SUPER, NUX_STATE_SCROLLLOCK = KEY_MODIFIER_SCROLLLOCK, }; enum EventType { EVENT_NONE = 0, EVENT_MOUSE_DOWN, EVENT_MOUSE_UP, EVENT_MOUSE_MOVE, EVENT_MOUSE_DOUBLECLICK, EVENT_MOUSE_WHEEL, EVENT_MOUSE_CANCEL, /*!< InputArea lost ownership over a pressed mouse. Any changes caused by the previous EVENT_MOUSE_PRESS should be undone. */ EVENT_KEY_DOWN, EVENT_KEY_UP, EVENT_WINDOW_SIZE_CONFIGURATION, EVENT_WINDOW_MAP, EVENT_WINDOW_UNMAP, EVENT_NC_WINDOW_CONFIGURATION, //!< Non-client event on the window borders. EVENT_WINDOW_ENTER_FOCUS, EVENT_WINDOW_EXIT_FOCUS, EVENT_WINDOW_DIRTY, EVENT_WINDOW_MOUSELEAVE, EVENT_DESTROY_WINDOW, EVENT_TERMINATE_APP, EVENT_TAKE_FOCUS, // ClientMessage for window with WM_TAKE_FOCUS protocol-atom set EVENT_DND_MOVE, EVENT_DND_DROP, EVENT_DND_ENTER, //!< Synthetic event generated when the dnd action enters an InputArea. This is not the event sent when the dnd action enters the window. EVENT_DND_LEAVE, //!< Synthetic event generated when the dnd action leaves an InputArea. This is not the event sent when the dnd action leaves the window. EVENT_DND_ENTER_WINDOW, //!< Emitted when the DND action goes inside(XdndLeave) a window. EVENT_DND_LEAVE_WINDOW, //!< Emitted when the DND action goes outside(XdndEnter) a window. EVENT_GESTURE_BEGIN, //!< Emitted when a gesture begins. Event class is GestureEvent. EVENT_GESTURE_UPDATE, //!< Emitted when a gesture is updated. Event class is GestureEvent. EVENT_GESTURE_END, //!< Emitted when a gesture ends. Event class is GestureEvent. EVENT_GESTURE_LOST, //!< Emitted when a gesture target loses a gesture. Event class is GestureEvent. // The following values are deprecated. Use the ones above. NUX_NO_EVENT = EVENT_NONE, NUX_MOUSE_PRESSED = EVENT_MOUSE_DOWN, NUX_MOUSE_RELEASED = EVENT_MOUSE_UP, NUX_MOUSE_MOVE = EVENT_MOUSE_MOVE, NUX_MOUSE_DOUBLECLICK = EVENT_MOUSE_DOUBLECLICK, NUX_MOUSE_WHEEL = EVENT_MOUSE_WHEEL, NUX_MOUSEWHEEL = EVENT_MOUSE_WHEEL, //!< Deprecated. Use NUX_MOUSE_WHEEL. NUX_KEYDOWN = EVENT_KEY_DOWN, NUX_KEYUP = EVENT_KEY_UP, NUX_SIZE_CONFIGURATION = EVENT_WINDOW_SIZE_CONFIGURATION, NUX_WINDOW_MAP = EVENT_WINDOW_MAP, NUX_WINDOW_UNMAP = EVENT_WINDOW_UNMAP, NUX_NC_WINDOW_CONFIGURATION = EVENT_NC_WINDOW_CONFIGURATION, NUX_WINDOW_ENTER_FOCUS = EVENT_WINDOW_ENTER_FOCUS, NUX_WINDOW_EXIT_FOCUS = EVENT_WINDOW_EXIT_FOCUS, NUX_WINDOW_DIRTY = EVENT_WINDOW_DIRTY, NUX_WINDOW_MOUSELEAVE = EVENT_WINDOW_MOUSELEAVE, NUX_DESTROY_WINDOW = EVENT_DESTROY_WINDOW, NUX_TERMINATE_APP = EVENT_TERMINATE_APP, NUX_TAKE_FOCUS = EVENT_TAKE_FOCUS, // ClientMessage for window with WM_TAKE_FOCUS protocol-atom set NUX_DND_MOVE = EVENT_DND_MOVE, NUX_DND_DROP = EVENT_DND_DROP, NUX_DND_ENTER = EVENT_DND_ENTER, //!< Synthetic event generated when the dnd action enters an InputArea. This is not the event sent when the dnd action enters the window. NUX_DND_LEAVE = EVENT_DND_LEAVE, //!< Synthetic event generated when the dnd action leaves an InputArea. This is not the event sent when the dnd action leaves the window. NUX_DND_ENTER_WINDOW = EVENT_DND_ENTER_WINDOW, //!< Emitted when the DND action goes inside(XdndLeave) a window. NUX_DND_LEAVE_WINDOW = EVENT_DND_LEAVE_WINDOW, //!< Emitted when the DND action goes outside(XdndEnter) a window. }; typedef EventType NuxEventType; // NuxEventType is deprecated. //! Returns index of the mouse button that triggered an event. /*! Given the mouse button states of and event, returns the index of the button that triggered an event. The index of the left mouse button is 1 and the index for the right mouse button is 2. If 0 is returned, then a mouse button didn't triggered the event. @param button_state The mouse button states of an event. @return The button that triggered the event. */ MouseButton GetEventButton(unsigned long button_state); //! Returns the state of a mouse button: pressed or released. /*! Given the mouse button states of and event, returns the state of a mouse button. True is the button is pressed. False otherwise. @param button_state The mouse button states of an event. @param button Button to query(1 for left mouse button). @return True is the button is pressed. False otherwise. */ bool GetButtonState(unsigned long button_state, MouseButton button); //! Returns the state of a special key: CTRL, Shift, Alt, NumLock... /*! Given the key modifiers states of and event, returns the state of a key modifier. True is the key is pressed. False otherwise. @param key_modifiers_state The key modifiers states of an event. @param key_modifier Key modifier be query. @return True is the key is pressed. False otherwise. */ bool GetKeyModifierState(unsigned long key_modifiers_states, KeyModifier key_modifier); #define NUX_EVENT_TEXT_BUFFER_SIZE 16 //! Nux event class. class Event { public: Event(); // Because an event is save in event_type instead of calling immediately the handling function, // we must clear the previous event each time before we test for new event in Gfx_OpenGLImpl::get_event. /*virtual*/ void Reset(); int GetX() const; int GetY() const; int GetRootX() const; int GetRootY() const; int GetDeltaX() const; int GetDeltaY() const; unsigned long GetKeyState() const; unsigned long GetMouseState() const; bool IsShiftDown() const; bool IsControlDown() const; bool IsCapsLockDown() const; bool IsAltDown() const; bool IsNumLockDown() const; bool IsScrollLockDown() const; bool IsSuperKeyDown() const; //! Returns index of the mouse button that triggered this event. /*! Returns the index of the button that triggered this event. The index of the left mouse button is 1 and the index for the right mouse button is 2. If 0 is returned, then a mouse button didn't triggered the event. @return The button that triggered the event. */ MouseButton GetEventButton() const; //! Returns the state of a mouse button: pressed or released. /*! Returns the state of a mouse button. True is the button is pressed. False otherwise. @param button_index Button index to query(1 for left mouse button). @return True is the button is pressed. False otherwise. */ bool GetButtonState(MouseButton button) const; //! Returns the state of a special key: CTRL, Shift, Alt, NumLock... /*! Returns the state of a key modifier. True is the key is pressed. False otherwise. @param key_modifier Key modifier be query. @return True is the key is pressed. False otherwise. */ bool GetKeyModifierState(KeyModifier key_modifier) const; //! Return virtual key code of the key that has triggered the last event. /*! Return virtual key code of the key that has triggered the last event. @return the virtual key code. */ unsigned long GetKeySym() const; unsigned short GetKeyRepeatCount() const; const char* GetText() const; //! Return the state of the Virtual key /*! Return the state of the Virtual key. @param VirtualKey virtual key code. @return 1 if the key is pressed, 0 if the key is released. */ unsigned long GetVirtualKeyState(unsigned long VirtualKey) const; unsigned long VirtualKeycodeState[NUX_MAX_VK]; int width, height; unsigned int ascii_code; int virtual_code; int x; int y; int x_root; int y_root; int dx; int dy; int clicks; int is_click; #if defined(NUX_OS_WINDOWS) int win32_keycode; // Not used. Just a place holder. int win32_keysym; #elif defined(USE_X11) Time x11_timestamp; //!< X11 timestamp. Window x11_window; //!< X11 window. unsigned int x11_key_state; //!< X11 key state (xevent.xkey.state). unsigned int x11_keycode; //!< X11 raw keycode. KeySym x11_keysym; //!< X11 keysym. #endif int wheel_delta; //!< Wheel delta. char text[NUX_EVENT_TEXT_BUFFER_SIZE]; char* dtext; //!< Dynamically allocated unsigned long key_modifiers; //!< Key modifiers. A bitwise inclusive OR of values in KeyModifier. unsigned long mouse_state; unsigned short key_repeat_count; //!< Number of time a key is repeated; EventType type; }; }; #endif // EVENTS_H nux-4.0.6+14.04.20140409/NuxGraphics/GraphicsDisplayX11.cpp0000755000015301777760000025256612321344237023277 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GraphicsEngine.h" #include "GLWindowManager.h" #include "Events.h" #include "GraphicsDisplay.h" #include #include namespace nux { int GraphicsDisplay::double_click_time_delay = 400; // milliseconds namespace atom { namespace { Atom XdndPosition = 0; Atom XdndEnter = 0; Atom XdndStatus = 0; Atom XdndLeave = 0; Atom XdndDrop = 0; Atom XdndAware = 0; Atom XdndFinished = 0; Atom XdndSelection = 0; Atom XdndTypeList = 0; Atom XdndActionMove = 0; Atom XdndActionCopy = 0; Atom XdndActionPrivate = 0; Atom XdndActionLink = 0; Atom XdndActionAsk = 0; Atom WM_DELETE_WINDOW = 0; Atom _NET_WM_STATE_STICKY = 0; Atom _NET_WM_STATE_SKIP_TASKBAR = 0; Atom _NET_WM_STATE_SKIP_PAGER = 0; Atom _NET_WM_STATE_ABOVE = 0; Atom _NET_WM_STATE = 0; Atom _NET_WM_WINDOW_TYPE = 0; Atom _NET_WM_WINDOW_TYPE_UTILITY = 0; Atom _NET_WM_WINDOW_TYPE_DND = 0; void initialize(Display *dpy) { if (XdndPosition) return; XdndPosition = XInternAtom(dpy, "XdndPosition", False); XdndEnter = XInternAtom(dpy, "XdndEnter", False); XdndStatus = XInternAtom(dpy, "XdndStatus", False); XdndLeave = XInternAtom(dpy, "XdndLeave", False); XdndDrop = XInternAtom(dpy, "XdndDrop", False); XdndAware = XInternAtom(dpy, "XdndAware", False); XdndFinished = XInternAtom(dpy, "XdndFinished", False); XdndSelection = XInternAtom(dpy, "XdndSelection", False); XdndTypeList = XInternAtom(dpy, "XdndTypeList", False); XdndActionMove = XInternAtom(dpy, "XdndActionMove", False); XdndActionCopy = XInternAtom(dpy, "XdndActionCopy", False); XdndActionPrivate = XInternAtom(dpy, "XdndActionPrivate", False); XdndActionLink = XInternAtom(dpy, "XdndActionLink", False); XdndActionAsk = XInternAtom(dpy, "XdndActionAsk", False); WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False); _NET_WM_STATE_STICKY = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False); _NET_WM_STATE_SKIP_TASKBAR = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False); _NET_WM_STATE_SKIP_PAGER = XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False); _NET_WM_STATE_ABOVE = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False); _NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False); _NET_WM_WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); _NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_UTILITY", False); _NET_WM_WINDOW_TYPE_DND = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DND", False); } } } GraphicsDisplay::GraphicsDisplay() : m_X11Display(NULL) , m_X11Screen(0) , m_X11Window(0) , m_X11VisualInfo(NULL) , m_current_xic(NULL) , parent_window_(0) , m_GLCtx(NULL) #ifndef NUX_OPENGLES_20 , glx_window_(0) #endif , m_NumVideoModes(0) , m_X11VideoModes(0) , m_BorderPixel(0) , _x11_major(0) , _x11_minor(0) , _glx_major(0) , _glx_minor(0) , _has_glx_13(false) , m_X11RepeatKey(true) , viewport_size_(Size(0,0)) , window_size_(Size(0,0)) , m_WindowPosition(Point(0,0)) , fullscreen_(false) , screen_bit_depth_(32) , gfx_interface_created_(false) , m_CreatedFromForeignWindow(false) , last_click_time_(0) , double_click_counter_(0) , m_pEvent(NULL) , _last_dnd_position(Point(0, 0)) //DND , m_PauseGraphicsRendering(false) , m_FrameTime(0) , m_DeviceFactory(0) , m_GraphicsContext(0) , m_Style(WINDOWSTYLE_NORMAL) , _drag_display(NULL) , _drag_window(0) , _drag_source(0) , _drag_drop_timestamp(0) , _dnd_source_data(NULL) , _dnd_source_window(0) , _global_pointer_grab_data(0) , _global_pointer_grab_active(false) , _global_pointer_grab_callback(0) , _global_keyboard_grab_data(0) , _global_keyboard_grab_active(false) , _global_keyboard_grab_callback(0) , _dnd_is_drag_source(false) , _dnd_source_target_accepts_drop(false) , _dnd_source_grab_active(false) , _dnd_source_drop_sent(false) { inlSetThreadLocalStorage(_TLS_GraphicsDisplay, this); m_X11LastEvent.type = -1; m_pEvent = new Event(); _dnd_source_funcs.get_drag_image = 0; _dnd_source_funcs.get_drag_types = 0; _dnd_source_funcs.get_data_for_type = 0; _dnd_source_funcs.drag_finished = 0; } GraphicsDisplay::~GraphicsDisplay() { NUX_SAFE_DELETE( m_GraphicsContext ); NUX_SAFE_DELETE( m_DeviceFactory ); if (m_CreatedFromForeignWindow == false) { DestroyOpenGLWindow(); } NUX_SAFE_DELETE( m_pEvent ); inlSetThreadLocalStorage(_TLS_GraphicsDisplay, 0); XFree(m_X11VideoModes); XFree(m_X11VisualInfo); } std::string GraphicsDisplay::FindResourceLocation(const char *ResourceFileName, bool ErrorOnFail) { std::string path = m_ResourcePathLocation.GetFile(ResourceFileName); if (path == "" && ErrorOnFail) { nuxCriticalMsg("[GraphicsDisplay::FindResourceLocation] Failed to locate resource file: %s.", ResourceFileName); return ""; } return path; } std::string GraphicsDisplay::FindUITextureLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_UITextureSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[GraphicsDisplay::FindResourceLocation] Failed to locate ui texture file: %s.", ResourceFileName); return std::string(""); } return path; } std::string GraphicsDisplay::FindShaderLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_ShaderSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[GraphicsDisplay::FindResourceLocation] Failed to locate shader file: %s.", ResourceFileName); return std::string(""); } return path; } std::string GraphicsDisplay::FindFontLocation(const char *ResourceFileName, bool ErrorOnFail) { FilePath searchpath; searchpath.AddSearchPath(m_FontSearchPath); std::string path = searchpath.GetFile(ResourceFileName); if ((path == "") && ErrorOnFail) { nuxCriticalMsg("[GraphicsDisplay::FindResourceLocation] Failed to locate font file file: %s.", ResourceFileName); return std::string(""); } return path; } bool GraphicsDisplay::IsGfxInterfaceCreated() { return gfx_interface_created_; } #ifndef NUX_OPENGLES_20 static Bool WaitForNotify( Display * /* dpy */, XEvent *event, XPointer arg ) { return(event->type == MapNotify) && (event->xmap.window == (Window) arg); } #endif // TODO: change windowWidth, windowHeight, to window_size; static NCriticalSection CreateOpenGLWindow_CriticalSection; bool GraphicsDisplay::CreateOpenGLWindow(const char* window_title, unsigned int WindowWidth, unsigned int WindowHeight, WindowStyle /* Style */, const GraphicsDisplay * /* Parent */, bool fullscreen_flag, bool /* create_rendering_data */) { int xinerama_event, xinerama_error; int xinerama_major, xinerama_minor; NScopeLock Scope(&CreateOpenGLWindow_CriticalSection); window_title_ = window_title; gfx_interface_created_ = false; // FIXME : put at the end Size new_size(WindowWidth, WindowHeight); viewport_size_ = new_size; window_size_ = new_size; // end of fixme fullscreen_ = fullscreen_flag; // Set The Global Fullscreen Flag // Open The display. m_X11Display = XOpenDisplay(0); if (m_X11Display == 0) { nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] XOpenDisplay has failed. The window cannot be created."); return false; } m_X11Screen = DefaultScreen(m_X11Display); XF86VidModeQueryVersion(m_X11Display, &_x11_major, &_x11_minor); XineramaQueryVersion(m_X11Display, &xinerama_major, &xinerama_minor); XineramaQueryExtension(m_X11Display, &xinerama_event, &xinerama_error); atom::initialize(m_X11Display); XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &m_NumVideoModes, &m_X11VideoModes); m_X11OriginalVideoMode = *m_X11VideoModes[0]; int best_mode = -1; if (fullscreen_) // Attempt Fullscreen Mode? { // check if resolution is supported bool mode_supported = false; for (int mode = 0 ; mode < m_NumVideoModes; ++mode) { if ((m_X11VideoModes[mode]->hdisplay == viewport_size_.width ) && (m_X11VideoModes[mode]->vdisplay == viewport_size_.height )) { mode_supported = true; best_mode = mode; break; } } if (mode_supported == false) { fullscreen_ = false; } } #ifndef NUX_OPENGLES_20 // Check support for GLX int dummy0, dummy1; if (!glXQueryExtension(m_X11Display, &dummy0, &dummy1)) { nuxCriticalMsg("[GraphicsDisplay::CreateOpenGLWindow] GLX is not supported."); return false; } // Check GLX version glXQueryVersion(m_X11Display, &_glx_major, &_glx_minor); // FBConfigs support added in GLX version 1.3 if (((_glx_major == 1) && (_glx_minor < 3)) || (_glx_major < 1)) { _has_glx_13 = false; } else { _has_glx_13 = true; } _has_glx_13 = false; // force old way. this is temporary... if (_has_glx_13 == false) { // Find an OpenGL capable visual. static int g_DoubleBufferVisual[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, None }; XFree(m_X11VisualInfo); m_X11VisualInfo = glXChooseVisual(m_X11Display, m_X11Screen, g_DoubleBufferVisual); if (m_X11VisualInfo == NULL) { nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] Cannot get appropriate visual."); return false; } // Create OpenGL Context. if (m_GLCtx) glXDestroyContext(m_X11Display, m_GLCtx); m_GLCtx = glXCreateContext(m_X11Display, m_X11VisualInfo, 0, GL_TRUE); m_X11Colormap = XCreateColormap(m_X11Display, RootWindow(m_X11Display, m_X11VisualInfo->screen), m_X11VisualInfo->visual, AllocNone); } else { int DoubleBufferAttributes[] = { //GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_DOUBLEBUFFER, True, GLX_RED_SIZE, 8, /* the maximum number of bits per component */ GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, None }; GLXFBConfig *fbconfigs = NULL; int fbcount; #define GET_PROC(proc_type, proc_name, check) \ do \ { \ proc_name = (proc_type) glXGetProcAddress((const GLubyte *) #proc_name); \ } while (0) /* initialize GLX 1.3 function pointers */ GET_PROC(PFNGLXGETFBCONFIGSPROC, glXGetFBConfigs, false); GET_PROC(PFNGLXGETFBCONFIGATTRIBPROC, glXGetFBConfigAttrib, false); GET_PROC(PFNGLXGETVISUALFROMFBCONFIGPROC, glXGetVisualFromFBConfig, false); GET_PROC(PFNGLXCREATEWINDOWPROC, glXCreateWindow, false); GET_PROC(PFNGLXDESTROYWINDOWPROC, glXDestroyWindow, false); GET_PROC(PFNGLXCREATEPIXMAPPROC, glXCreatePixmap, false); GET_PROC(PFNGLXDESTROYPIXMAPPROC, glXDestroyPixmap, false); GET_PROC(PFNGLXCREATEPBUFFERPROC, glXCreatePbuffer, false); GET_PROC(PFNGLXDESTROYPBUFFERPROC, glXDestroyPbuffer, false); GET_PROC(PFNGLXCREATENEWCONTEXTPROC, glXCreateNewContext, false); GET_PROC(PFNGLXMAKECONTEXTCURRENTPROC, glXMakeContextCurrent, false); GET_PROC(PFNGLXCHOOSEFBCONFIGPROC, glXChooseFBConfig, false); /* GLX_SGIX_pbuffer */ GET_PROC(PFNGLXCREATEGLXPBUFFERSGIXPROC, glXCreateGLXPbufferSGIX, false); GET_PROC(PFNGLXDESTROYGLXPBUFFERSGIXPROC, glXDestroyGLXPbufferSGIX, false); #undef GET_PROC // Request a double buffer configuration fbconfigs = glXChooseFBConfig(m_X11Display, DefaultScreen(m_X11Display), DoubleBufferAttributes, &fbcount); if (fbconfigs == NULL) { nuxCriticalMsg("[GraphicsDisplay::CreateOpenGLWindow] glXChooseFBConfig cannot get a supported configuration."); return false; } // Select best multi-sample config. if ((_glx_major >= 1) && (_glx_minor >= 4)) { int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; for (int i = 0; i < fbcount; i++) { XVisualInfo *vi = glXGetVisualFromFBConfig(m_X11Display, fbconfigs[i]); if (vi) { int sample_buf, samples; glXGetFBConfigAttrib(m_X11Display, fbconfigs[i], GLX_SAMPLE_BUFFERS, &sample_buf); glXGetFBConfigAttrib(m_X11Display, fbconfigs[i], GLX_SAMPLES , &samples); //nuxDebugMsg("Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d SAMPLES = %d\n", i, vi->visualid, sample_buf, samples); if (((best_fbc < 0) || sample_buf) && (samples > best_num_samp)) { best_fbc = i; best_num_samp = samples; } if ((worst_fbc < 0) || (!sample_buf) || (samples < worst_num_samp)) { worst_fbc = i; worst_num_samp = samples; } } XFree(vi); } nuxAssertMsg(best_fbc >= 0, "[GraphicsDisplay::CreateOpenGLWindow] Invalid frame buffer config."); _fb_config = fbconfigs[best_fbc]; } else { // Choose the first one _fb_config = fbconfigs[0]; } XFree(fbconfigs); XFree(m_X11VisualInfo); m_X11VisualInfo = glXGetVisualFromFBConfig(m_X11Display, _fb_config); m_X11Colormap = XCreateColormap(m_X11Display, RootWindow(m_X11Display, m_X11VisualInfo->screen), m_X11VisualInfo->visual, AllocNone); } #else EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)m_X11Display); if (dpy == EGL_NO_DISPLAY) { nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] Cannot get EGL display."); return false; } EGLint major, minor; if (!eglInitialize(dpy, &major, &minor)) { nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] Cannot initialize EGL."); return false; } eglBindAPI(EGL_OPENGL_ES_API); const EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 1, EGL_DEPTH_SIZE, 1, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_CONFIG_CAVEAT, EGL_NONE, EGL_NONE, }; EGLConfig configs[1024]; EGLint count; if (!eglChooseConfig(dpy, config_attribs, configs, 1024, &count)) { nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] Cannot get EGL config."); return false; } EGLConfig config = configs[0]; EGLint visualid = 0; if (!eglGetConfigAttrib(dpy, config, EGL_NATIVE_VISUAL_ID, &visualid)) { nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] Cannot get native visual ID from EGL config."); return false; } XVisualInfo visual_info; memset(&visual_info, 0, sizeof(visual_info)); visual_info.visualid = visualid; XFree(m_X11VisualInfo); m_X11VisualInfo = XGetVisualInfo(m_X11Display, VisualIDMask, &visual_info, &count); if (!m_X11VisualInfo) { nuxCriticalMsg("[GraphicsDisplay::CreateOpenGLWindow] Cannot get appropriate visual."); return false; } m_X11Colormap = XCreateColormap(m_X11Display, RootWindow(m_X11Display, m_X11VisualInfo->screen), m_X11VisualInfo->visual, AllocNone); #endif m_X11Attr.background_pixmap = 0; m_X11Attr.border_pixel = 0; m_X11Attr.colormap = m_X11Colormap; m_X11Attr.override_redirect = fullscreen_; m_X11Attr.event_mask = // Mouse /*Button1MotionMask | Button2MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask | ButtonMotionMask |*/ ButtonPressMask | ButtonReleaseMask | // Mouse motion //-OwnerGrabButtonMask | //PointerMotionHintMask | PointerMotionMask | // Keyboard //--KeymapStateMask | KeyPressMask | KeyReleaseMask | // Window enter/exit LeaveWindowMask | EnterWindowMask | // Exposure Focus ExposureMask | FocusChangeMask | // Structure notify //--ResizeRedirectMask | StructureNotifyMask;// | //--SubstructureNotifyMask | //--SubstructureRedirectMask | // Visibility //--VisibilityChangeMask | // Property //--PropertyChangeMask | // Colormap //--ColormapChangeMask | // No event //--NoEventMask; if (fullscreen_) { XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, m_X11VideoModes[best_mode]); XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0); //Width = m_X11VideoModes[best_mode]->hdisplay; //Height = m_X11VideoModes[best_mode]->vdisplay; XFree(m_X11VideoModes); /* create a fullscreen window */ m_X11Window = XCreateWindow(m_X11Display, RootWindow(m_X11Display, m_X11VisualInfo->screen), 0, 0, // X, Y window_size_.width, window_size_.height, 0, // Border m_X11VisualInfo->depth, // Depth InputOutput, // Class m_X11VisualInfo->visual, // Visual CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &m_X11Attr); XWarpPointer(m_X11Display, None, m_X11Window, 0, 0, 0, 0, 0, 0); //XMapRaised(m_X11Display, m_X11Window); XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime); } else { m_X11Window = XCreateWindow(m_X11Display, RootWindow(m_X11Display, m_X11VisualInfo->screen), 0, 0, window_size_.width, window_size_.height, 0, m_X11VisualInfo->depth, InputOutput, m_X11VisualInfo->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &m_X11Attr); /* only set window title and handle wm_delete_events if in windowed mode */ m_WMDeleteWindow = atom::WM_DELETE_WINDOW; XSetWMProtocols(m_X11Display, m_X11Window, &m_WMDeleteWindow, 1); XSetStandardProperties(m_X11Display, m_X11Window, window_title_.c_str(), window_title_.c_str(), None, NULL, 0, NULL); //XMapRaised(m_X11Display, m_X11Window); } #ifndef NUX_OPENGLES_20 if (_has_glx_13) { XFree(m_X11VisualInfo); m_X11VisualInfo = 0; /* Create a GLX context for OpenGL rendering */ if (m_GLCtx) glXDestroyContext(m_X11Display, m_GLCtx); m_GLCtx = glXCreateNewContext(m_X11Display, _fb_config, GLX_RGBA_TYPE, NULL, True); if (m_GLCtx == 0) { nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] m_GLCtx is null"); } /* Create a GLX window to associate the frame buffer configuration ** with the created X window */ glx_window_ = glXCreateWindow(m_X11Display, _fb_config, m_X11Window, NULL); // Map the window to the screen, and wait for it to appear */ XMapWindow(m_X11Display, m_X11Window); XEvent event; XIfEvent(m_X11Display, &event, WaitForNotify, (XPointer) m_X11Window); /* Bind the GLX context to the Window */ glXMakeContextCurrent(m_X11Display, glx_window_, glx_window_, m_GLCtx); } #else m_GLSurface = eglCreateWindowSurface(dpy, config, (EGLNativeWindowType)m_X11Window, 0); if (!m_GLSurface) { nuxCriticalMsg("[GraphicsDisplay::CreateOpenGLWindow] Failed to create surface."); return false; } const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; m_GLCtx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, context_attribs); if (m_GLCtx == EGL_NO_CONTEXT) { nuxCriticalMsg("[GraphicsDisplay::CreateOpenGLWindow] Failed to create EGL context."); return false; } #endif MakeGLContextCurrent(); gfx_interface_created_ = true; m_DeviceFactory = new GpuDevice(viewport_size_.width, viewport_size_.height, BITFMT_R8G8B8A8, m_X11Display, m_X11Window, _has_glx_13, _fb_config, m_GLCtx, 1, 0, false); if (m_DeviceFactory->GetGpuInfo().Support_EXT_Framebuffer_Object()) m_DeviceFactory->GetFrameBufferObject()->SetupFrameBufferObject(); m_GraphicsContext = new GraphicsEngine(*this); //EnableVSyncSwapControl(); //DisableVSyncSwapControl(); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); SwapBuffer(); InitGlobalGrabWindow(); return TRUE; } #ifdef NUX_OPENGLES_20 bool GraphicsDisplay::CreateFromOpenGLWindow(Display *X11Display, Window X11Window, EGLContext OpenGLContext) #else bool GraphicsDisplay::CreateFromOpenGLWindow(Display *X11Display, Window X11Window, GLXContext OpenGLContext) #endif { // Do not make the opengl context current // Do not swap the framebuffer // Do not clear the depth or color buffer // Do not enable/disbale VSync m_X11Display = X11Display; m_X11Window = X11Window; m_GLCtx = OpenGLContext; m_X11Screen = DefaultScreen(m_X11Display); atom::initialize(m_X11Display); Window root_return; int x_return, y_return; unsigned int width_return, height_return; unsigned int border_width_return; unsigned int depth_return; XGetGeometry(X11Display, X11Window, &root_return, &x_return, &y_return, &width_return, &height_return, &border_width_return, &depth_return); window_size_ = Size(width_return, height_return); m_WindowPosition = Point(x_return, y_return); viewport_size_ = Size(width_return, height_return); gfx_interface_created_ = true; // m_DeviceFactory = new GpuDevice(viewport_size_.GetWidth(), viewport_size_.GetHeight(), BITFMT_R8G8B8A8); m_DeviceFactory = new GpuDevice(viewport_size_.width, viewport_size_.height, BITFMT_R8G8B8A8, m_X11Display, m_X11Window, false, _fb_config, m_GLCtx, 1, 0, false); if (m_DeviceFactory->GetGpuInfo().Support_EXT_Framebuffer_Object()) m_DeviceFactory->GetFrameBufferObject()->SetupFrameBufferObject(); m_GraphicsContext = new GraphicsEngine(*this); InitGlobalGrabWindow(); m_CreatedFromForeignWindow = true; return true; } GraphicsEngine* GraphicsDisplay::GetGraphicsEngine() const { return m_GraphicsContext; } GpuDevice* GraphicsDisplay::GetGpuDevice() const { return m_DeviceFactory; } void GraphicsDisplay::SetCurrentXIC(XIC xic) { m_current_xic = xic; } int GraphicsDisplay::GetGlXMajor() const { return _glx_major; } int GraphicsDisplay::GetGlXMinor() const { return _glx_minor; } bool GraphicsDisplay::HasFrameBufferSupport() { return m_DeviceFactory->GetGpuInfo().Support_EXT_Framebuffer_Object(); } // TODO(thumper): Size const& GraphicsDisplay::GetWindowSize(); void GraphicsDisplay::GetWindowSize(int &w, int &h) { w = window_size_.width; h = window_size_.height; } void GraphicsDisplay::GetDesktopSize(int &w, int &h) { Window root; int x, y; unsigned int width, height, depth, border_width; bool ret = XGetGeometry(m_X11Display, RootWindow(m_X11Display, m_X11Screen), &root, &x, &y, &width, &height, &border_width, &depth); if (ret == false) { nuxAssert("[GetDesktopSize] Failed to get the desktop size"); w = 0; h = 0; } } void GraphicsDisplay::SetWindowSize(int width, int height) { nuxDebugMsg("[GraphicsDisplay::SetWindowSize] Setting window size to %dx%d", width, height); // Resize window client area XResizeWindow(m_X11Display, m_X11Window, width, height); XFlush(m_X11Display); } void GraphicsDisplay::SetWindowPosition(int x, int y) { nuxDebugMsg("[GraphicsDisplay::SetWindowPosition] Setting window position to %dx%d", x, y); // Resize window client area XMoveWindow(m_X11Display, m_X11Window, x, y); XFlush(m_X11Display); } int GraphicsDisplay::GetWindowWidth() { return window_size_.width; } int GraphicsDisplay::GetWindowHeight() { return window_size_.height; } void GraphicsDisplay::SetViewPort(int x, int y, int width, int height) { if (IsGfxInterfaceCreated()) { //do not rely on viewport_size_: glViewport can be called directly viewport_size_ = Size(width, height); m_GraphicsContext->SetViewport(x, y, width, height); m_GraphicsContext->SetScissor(0, 0, width, height); } } void GraphicsDisplay::ResetWindowSize() { Window root_return; int x_return, y_return; unsigned int width_return, height_return; unsigned int border_width_return; unsigned int depth_return; XGetGeometry(m_X11Display, m_X11Window, &root_return, &x_return, &y_return, &width_return, &height_return, &border_width_return, &depth_return); window_size_ = Size(width_return, height_return); m_WindowPosition = Point(x_return, y_return); } Point GraphicsDisplay::GetMouseScreenCoord() { Window root_return; Window child_return; int root_x_return; int root_y_return; int win_x_return; int win_y_return; unsigned int mask_return; XQueryPointer(m_X11Display, RootWindow(m_X11Display, m_X11Screen), &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask_return); XFlush(m_X11Display); return Point(root_x_return, root_y_return); } Point GraphicsDisplay::GetMouseWindowCoord() { Window root_return; Window child_return; int root_x_return; int root_y_return; int win_x_return; int win_y_return; unsigned int mask_return; XQueryPointer(m_X11Display, RootWindow(m_X11Display, m_X11Screen), &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask_return); XFlush(m_X11Display); return Point(win_x_return, win_y_return); } Point GraphicsDisplay::GetWindowCoord() { XWindowAttributes attrib; int status = XGetWindowAttributes(m_X11Display, m_X11Window, &attrib); if (status == 0) { nuxAssert("[GraphicsDisplay::GetWindowCoord] Failed to get the window attributes."); return Point(0, 0); } return Point(attrib.x, attrib.y); } Rect GraphicsDisplay::GetWindowGeometry() { return Rect(m_WindowPosition.x, m_WindowPosition.y, window_size_.width, window_size_.height); } Rect GraphicsDisplay::GetNCWindowGeometry() { return Rect(m_WindowPosition.x, m_WindowPosition.y, window_size_.width, window_size_.height); } void GraphicsDisplay::MakeGLContextCurrent() { #ifndef NUX_OPENGLES_20 if (_has_glx_13) { nuxDebugMsg("Has glx 1.3"); if (!glXMakeContextCurrent(m_X11Display, glx_window_, glx_window_, m_GLCtx)) { nuxDebugMsg("Destroy"); DestroyOpenGLWindow(); } } else if (!glXMakeCurrent(m_X11Display, m_X11Window, m_GLCtx)) { DestroyOpenGLWindow(); } #else EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)m_X11Display); if (!eglMakeCurrent(dpy, m_GLSurface, m_GLSurface, m_GLCtx)) { DestroyOpenGLWindow(); } #endif } void GraphicsDisplay::SwapBuffer(bool glswap) { // There are a lot of mouse motion events coming from X11. The system processes one event at a time and sleeps // if necessary to cap the frame rate to 60 frames per seconds. But while the thread sleeping, there are accumulated // motion events waiting to be processed. This creates an increasing backlog of motion events. It translate into a slow // motion of elements that moves in response to the mouse. // Solution: if the the current event is a motion event, changes are, it is followed many more motion events. // In this case, don't sleep the thread... Swap the framebuffer to see the result of the current single motion event. // It maybe worth investigating how to properly balance event processing and drawing in order to keep the // frame rate and the responsiveness at acceptable levels. // As a consequence, when the mouse is moving, the frame rate goes beyond 60fps. /*bool bsleep = true; if (XPending(m_X11Display) > 0) { XEvent xevent; XPeekEvent(m_X11Display, &xevent); if (xevent.type == MotionNotify) { //nuxDebugMsg("[GraphicsDisplay::SwapBuffer]: MotionNotify event."); bsleep = false; } }*/ if (IsPauseThreadGraphicsRendering()) return; if (glswap) { #ifndef NUX_OPENGLES_20 if (_has_glx_13) glXSwapBuffers(m_X11Display, glx_window_); else glXSwapBuffers(m_X11Display, m_X11Window); #else eglSwapBuffers(eglGetDisplay((EGLNativeDisplayType)m_X11Display), m_GLSurface); #endif } m_FrameTime = m_Timer.PassedMilliseconds(); } void GraphicsDisplay::DestroyOpenGLWindow() { if (gfx_interface_created_ == true) { if (m_GLCtx == 0) { nuxDebugMsg("[GraphicsDisplay::DestroyOpenGLWindow] m_GLCtx is null"); } if (m_GLCtx) { #ifndef NUX_OPENGLES_20 // Release the current context if (_has_glx_13) { if (!glXMakeContextCurrent(m_X11Display, None, None, NULL)) { nuxAssert("[GraphicsDisplay::DestroyOpenGLWindow] glXMakeContextCurrent failed."); } } else { if (!glXMakeCurrent(m_X11Display, None, NULL)) { nuxAssert("[GraphicsDisplay::DestroyOpenGLWindow] glXMakeCurrent failed."); } } glXDestroyContext(m_X11Display, m_GLCtx); if (_has_glx_13) { glXDestroyWindow(m_X11Display, glx_window_); } #else EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)m_X11Display); if (!eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { nuxAssert("[GraphicsDisplay::DestroyOpenGLWindow] eglMakeCurrent failed."); } eglDestroyContext(dpy, m_GLCtx); eglDestroySurface(dpy, m_GLSurface); eglTerminate(dpy); eglReleaseThread(); #endif m_GLCtx = NULL; } /* switch back to original desktop resolution if we were in fs */ if (fullscreen_) { XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, &m_X11OriginalVideoMode); XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0); } XDestroyWindow(m_X11Display, m_X11Window); XFreeColormap(m_X11Display, m_X11Colormap); XCloseDisplay(m_X11Display); } gfx_interface_created_ = false; } int GraphicsDisplay::MouseMove(XEvent xevent, Event *m_pEvent) { // Erase mouse event and mouse doubleclick events. Keep the mouse states. unsigned int _mouse_state = m_pEvent->mouse_state & 0x0F000000; m_pEvent->type = NUX_MOUSE_MOVE; if (xevent.type == MotionNotify) { _mouse_state |= (xevent.xmotion.state & Button1Mask) ? NUX_STATE_BUTTON1_DOWN : 0; _mouse_state |= (xevent.xmotion.state & Button2Mask) ? NUX_STATE_BUTTON2_DOWN : 0; _mouse_state |= (xevent.xmotion.state & Button3Mask) ? NUX_STATE_BUTTON3_DOWN : 0; } else if (xevent.type == LeaveNotify || xevent.type == EnterNotify) { _mouse_state |= (xevent.xcrossing.state & Button1Mask) ? NUX_STATE_BUTTON1_DOWN : 0; _mouse_state |= (xevent.xcrossing.state & Button2Mask) ? NUX_STATE_BUTTON2_DOWN : 0; _mouse_state |= (xevent.xcrossing.state & Button3Mask) ? NUX_STATE_BUTTON3_DOWN : 0; } m_pEvent->mouse_state = _mouse_state; return 0; } int GraphicsDisplay::MousePress(XEvent xevent, Event *m_pEvent) { // Erase mouse event and mouse double-click events. Keep the mouse states. ulong _mouse_state = m_pEvent->mouse_state & 0x0F000000; bool double_click = false; Time current_time = xevent.xbutton.time; if ((double_click_counter_ == 1) && ((int)current_time - (int)last_click_time_ < double_click_time_delay)) { double_click = true; double_click_counter_ = 0; } else { _mouse_state |= NUX_STATE_FIRST_EVENT; double_click_counter_ = 1; } // State of the button before the event _mouse_state |= (xevent.xbutton.state & Button1Mask) ? NUX_STATE_BUTTON1_DOWN : 0; _mouse_state |= (xevent.xbutton.state & Button2Mask) ? NUX_STATE_BUTTON2_DOWN : 0; _mouse_state |= (xevent.xbutton.state & Button3Mask) ? NUX_STATE_BUTTON3_DOWN : 0; if (xevent.xbutton.type == ButtonPress) { if (xevent.xbutton.button == Button1) { if (double_click) m_pEvent->type = NUX_MOUSE_DOUBLECLICK; else m_pEvent->type = NUX_MOUSE_PRESSED; _mouse_state |= NUX_EVENT_BUTTON1_DOWN; _mouse_state |= NUX_STATE_BUTTON1_DOWN; } if (xevent.xbutton.button == Button2) { if (double_click) m_pEvent->type = NUX_MOUSE_DOUBLECLICK; else m_pEvent->type = NUX_MOUSE_PRESSED; _mouse_state |= NUX_EVENT_BUTTON2_DOWN; _mouse_state |= NUX_STATE_BUTTON2_DOWN; } if (xevent.xbutton.button == Button3) { if (double_click) m_pEvent->type = NUX_MOUSE_DOUBLECLICK; else m_pEvent->type = NUX_MOUSE_PRESSED; _mouse_state |= NUX_EVENT_BUTTON3_DOWN; _mouse_state |= NUX_STATE_BUTTON3_DOWN; } if (xevent.xbutton.button == Button4) { _mouse_state |= NUX_EVENT_MOUSEWHEEL; m_pEvent->type = NUX_MOUSE_WHEEL; m_pEvent->wheel_delta = NUX_MOUSEWHEEL_DELTA; return 1; } if (xevent.xbutton.button == Button5) { _mouse_state |= NUX_EVENT_MOUSEWHEEL; m_pEvent->type = NUX_MOUSE_WHEEL; m_pEvent->wheel_delta = -NUX_MOUSEWHEEL_DELTA; return 1; } if (xevent.xbutton.button == 6) { _mouse_state |= NUX_EVENT_MOUSEWHEEL; m_pEvent->type = NUX_MOUSE_WHEEL; m_pEvent->wheel_delta = NUX_MOUSEWHEEL_DELTA; return 1; } if (xevent.xbutton.button == 7) { _mouse_state |= NUX_EVENT_MOUSEWHEEL; m_pEvent->type = NUX_MOUSE_WHEEL; m_pEvent->wheel_delta = -NUX_MOUSEWHEEL_DELTA; return 1; } } m_pEvent->mouse_state = _mouse_state; return 0; } int GraphicsDisplay::MouseRelease(XEvent xevent, Event *m_pEvent) { // Erase mouse event and mouse double-click events. Keep the mouse states. ulong _mouse_state = m_pEvent->mouse_state & 0x0F000000; // State of the button before the event _mouse_state |= (xevent.xbutton.state & Button1Mask) ? NUX_STATE_BUTTON1_DOWN : 0; _mouse_state |= (xevent.xbutton.state & Button2Mask) ? NUX_STATE_BUTTON2_DOWN : 0; _mouse_state |= (xevent.xbutton.state & Button3Mask) ? NUX_STATE_BUTTON3_DOWN : 0; if (double_click_counter_ == 1) { _mouse_state |= NUX_STATE_FIRST_EVENT; } if (xevent.xbutton.type == ButtonRelease) { if (xevent.xbutton.button == Button1) { m_pEvent->type = NUX_MOUSE_RELEASED; _mouse_state |= NUX_EVENT_BUTTON1_UP; _mouse_state &= ~NUX_STATE_BUTTON1_DOWN; } if (xevent.xbutton.button == Button2) { m_pEvent->type = NUX_MOUSE_RELEASED; _mouse_state |= NUX_EVENT_BUTTON2_UP; _mouse_state &= ~NUX_STATE_BUTTON2_DOWN; } if (xevent.xbutton.button == Button3) { m_pEvent->type = NUX_MOUSE_RELEASED; _mouse_state |= NUX_EVENT_BUTTON3_UP; _mouse_state &= ~NUX_STATE_BUTTON3_DOWN; } } m_pEvent->mouse_state = _mouse_state; last_click_time_ = xevent.xbutton.time; return 0; } unsigned int GetModifierKeyState(unsigned int modifier_key_state) { unsigned int state = 0; // For CapsLock, we don't want to know if the key is pressed Down or Up. // We really want to know the state of the the CapsLock: on(keyboard light is on) or off? if (modifier_key_state & LockMask) { state |= KEY_MODIFIER_CAPS_LOCK; } if (modifier_key_state & ControlMask) { state |= KEY_MODIFIER_CTRL; } if (modifier_key_state & ShiftMask) { state |= KEY_MODIFIER_SHIFT; } if (modifier_key_state & Mod1Mask) { state |= KEY_MODIFIER_ALT; } if (modifier_key_state & Mod2Mask) { state |= KEY_MODIFIER_NUMLOCK; } // todo(jaytaoko): find out which key enable mod3mask // if (modifier_key_state & Mod3Mask) // { // } if (modifier_key_state & Mod4Mask) { state |= KEY_MODIFIER_SUPER; } // todo(jaytaoko): find out which key enable mod5mask // if (modifier_key_state & Mod5Mask) // { // } return state; } bool GraphicsDisplay::GetSystemEvent(Event *evt) { m_pEvent->Reset(); // Erase mouse event and mouse doubleclick states. Keep the mouse states. m_pEvent->mouse_state &= 0x0F000000; bool got_event; // Process event matching this window XEvent xevent; if (XPending(m_X11Display)) { bool bProcessEvent = true; XNextEvent(m_X11Display, &xevent); if (XFilterEvent(&xevent, None) == True) { return true; } if (!_event_filters.empty()) { for (auto filter : _event_filters) { bool result = filter.filter(xevent, filter.data); if (result) { memcpy(evt, m_pEvent, sizeof(Event)); return true; } } } // Detect auto repeat keys. X11 sends a combination of KeyRelease/KeyPress(at the same time) when a key auto repeats. // Here, we make sure we process only the keyRelease when the key is effectively released. if ((xevent.type == KeyPress) || (xevent.type == KeyRelease)) { if (xevent.xkey.keycode < 256) { // Detect if a key is repeated char Keys[32]; // The XQueryKeymap function returns a bit vector for the logical state of the keyboard, where each bit set // to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. // Byte N(from 0) contains the bits for keys 8N to 8N + 7 with the least significant bit in the byte representing // key 8N. // Note that the logical state of a device(as seen by client applications) may lag the physical state if device // event processing is frozen. XQueryKeymap(m_X11Display, Keys); if (Keys[xevent.xkey.keycode >> 3] & (1 << (xevent.xkey.keycode % 8))) { // KeyRelease event + KeyDown = discard repeated event if (xevent.type == KeyRelease) { m_X11LastEvent = xevent; bProcessEvent = false; } // KeyPress event + key repeat disabled + matching KeyRelease event = discard repeated event if ((xevent.type == KeyPress) && (!m_X11RepeatKey) && (m_X11LastEvent.xkey.keycode == xevent.xkey.keycode) && (m_X11LastEvent.xkey.time == xevent.xkey.time)) { bProcessEvent = false;; } } } } if (xevent.type == MotionNotify) { while (XCheckTypedEvent(m_X11Display, MotionNotify, &xevent)); } if (bProcessEvent) ProcessXEvent(xevent, false); memcpy(evt, m_pEvent, sizeof(Event)); got_event = true; } else { memcpy(evt, m_pEvent, sizeof(Event)); got_event = false; } return got_event; } #if defined(NUX_OS_LINUX) void GraphicsDisplay::InjectXEvent(Event *evt, XEvent xevent) { m_pEvent->Reset(); // Erase mouse event and mouse doubleclick states. Keep the mouse states. m_pEvent->mouse_state &= 0x0F000000; // We could do some checks here to make sure the xevent is really what it pretends to be. ProcessXEvent(xevent, false); memcpy(evt, m_pEvent, sizeof(Event)); } void GraphicsDisplay::AddEventFilter(EventFilterArg arg) { _event_filters.push_back(arg); } void GraphicsDisplay::RemoveEventFilter(void *owner) { std::list::iterator it; for (it = _event_filters.begin(); it != _event_filters.end(); ++it) { if ((*it).data == owner) { _event_filters.erase(it); break; } } } #endif void GraphicsDisplay::ProcessForeignX11Event(XEvent *xevent, Event *nux_event) { m_pEvent->Reset(); // Erase mouse event and mouse doubleclick states. Keep the mouse states. m_pEvent->mouse_state &= 0x0F000000; // Process event matching this window if (true /*(NUX_REINTERPRET_CAST(XAnyEvent*, xevent))->window == m_X11Window*/) { bool bProcessEvent = true; // Detect auto repeat keys. X11 sends a combination of KeyRelease/KeyPress(at the same time) when a key auto repeats. // Here, we make sure we process only the keyRelease when the key is effectively released. if ((xevent->type == KeyPress) || (xevent->type == KeyRelease)) { if (xevent->xkey.keycode < 256) { // Detect if a key is repeated char Keys[32]; // The XQueryKeymap function returns a bit vector for the logical state of the keyboard, where each bit set // to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. // Byte N(from 0) contains the bits for keys 8N to 8N + 7 with the least significant bit in the byte representing // key 8N. // Note that the logical state of a device(as seen by client applications) may lag the physical state if device // event processing is frozen. XQueryKeymap(xevent->xany.display, Keys); if (Keys[xevent->xkey.keycode >> 3] & (1 << (xevent->xkey.keycode % 8))) { // KeyRelease event + KeyDown = discard repeated event if (xevent->type == KeyRelease) { m_X11LastEvent = *xevent; bProcessEvent = false; } // KeyPress event + key repeat disabled + matching KeyRelease event = discard repeated event if ((xevent->type == KeyPress) && (!m_X11RepeatKey) && (m_X11LastEvent.xkey.keycode == xevent->xkey.keycode) && (m_X11LastEvent.xkey.time == xevent->xkey.time)) { bProcessEvent = false;; } } } } if (xevent->type == MotionNotify) { while (XCheckTypedEvent(m_X11Display, MotionNotify, xevent)); } if (bProcessEvent) ProcessXEvent(*xevent, true); memcpy(nux_event, m_pEvent, sizeof(Event)); } else { memcpy(nux_event, m_pEvent, sizeof(Event)); } } Event &GraphicsDisplay::GetCurrentEvent() { return *m_pEvent; } bool GraphicsDisplay::HasXPendingEvent() const { return XPending(m_X11Display); } void GraphicsDisplay::RecalcXYPosition(int x_root, int y_root, int &x_recalc, int &y_recalc) { int main_window_x = m_WindowPosition.x; int main_window_y = m_WindowPosition.y; x_recalc = x_root - main_window_x; y_recalc = y_root - main_window_y; } void GraphicsDisplay::RecalcXYPosition(Window TheMainWindow, XEvent xevent, int &x_recalc, int &y_recalc) { x_recalc = y_recalc = 0; int main_window_x = m_WindowPosition.x; int main_window_y = m_WindowPosition.y; bool same = (TheMainWindow == xevent.xany.window); switch(xevent.type) { case ButtonPress: case ButtonRelease: { if (same) { x_recalc = xevent.xbutton.x; y_recalc = xevent.xbutton.y; } else { x_recalc = xevent.xbutton.x_root - main_window_x; y_recalc = xevent.xbutton.y_root - main_window_y; } break; } case MotionNotify: { if (same) { x_recalc = xevent.xmotion.x; y_recalc = xevent.xmotion.y; } else { x_recalc = xevent.xmotion.x_root - main_window_x; y_recalc = xevent.xmotion.y_root - main_window_y; } break; } case LeaveNotify: case EnterNotify: { if (same) { x_recalc = xevent.xcrossing.x; y_recalc = xevent.xcrossing.y; } else { x_recalc = xevent.xcrossing.x_root - main_window_x; y_recalc = xevent.xcrossing.y_root - main_window_y; } break; } } } void GetDefaultSizeLookupString(XEvent event, Event* nux_event) { nux_event->dtext = new char[NUX_EVENT_TEXT_BUFFER_SIZE]; int num_char_stored = XLookupString(&event.xkey, nux_event->dtext, NUX_EVENT_TEXT_BUFFER_SIZE, (KeySym*)&nux_event->x11_keysym, nullptr); nux_event->dtext[num_char_stored] = 0; } void GraphicsDisplay::ProcessXEvent(XEvent xevent, bool foreign) { int x_recalc = 0; int y_recalc = 0; RecalcXYPosition(m_X11Window, xevent, x_recalc, y_recalc); bool local_from_server = !foreign; foreign = foreign || xevent.xany.window != m_X11Window; m_pEvent->type = NUX_NO_EVENT; m_pEvent->x11_window = xevent.xany.window; switch(xevent.type) { case DestroyNotify: { if (foreign) break; m_pEvent->type = NUX_DESTROY_WINDOW; //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: DestroyNotify event."); break; } case Expose: { if (foreign) break; m_pEvent->type = NUX_WINDOW_DIRTY; //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: Expose event."); break; } case ConfigureNotify: { if (foreign) break; m_pEvent->type = NUX_SIZE_CONFIGURATION; m_pEvent->width = xevent.xconfigure.width; m_pEvent->height = xevent.xconfigure.height; window_size_ = Size(xevent.xconfigure.width, xevent.xconfigure.height); int x, y; Window child_return; XTranslateCoordinates(m_X11Display, m_X11Window, RootWindow(m_X11Display, 0), 0, 0, &x, &y, &child_return); m_WindowPosition = Point(x, y); //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: ConfigureNotify event. %d %d", x, y); break; } case FocusIn: { if (!local_from_server) break; m_pEvent->type = NUX_WINDOW_ENTER_FOCUS; m_pEvent->mouse_state = 0; m_pEvent->dx = 0; m_pEvent->dy = 0; m_pEvent->virtual_code = 0; //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: FocusIn event."); break; } case FocusOut: { if (!local_from_server) break; m_pEvent->type = NUX_WINDOW_EXIT_FOCUS; m_pEvent->mouse_state = 0; m_pEvent->dx = 0; m_pEvent->dy = 0; m_pEvent->virtual_code = 0; //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: FocusOut event."); break; } case KeyPress: { //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: KeyPress event."); KeyCode keycode = xevent.xkey.keycode; KeySym keysym = NoSymbol; keysym = XkbKeycodeToKeysym(xevent.xany.display, keycode, 0, 0); m_pEvent->key_modifiers = GetModifierKeyState(xevent.xkey.state); m_pEvent->key_repeat_count = 0; m_pEvent->x11_keysym = keysym; m_pEvent->x11_keycode = xevent.xkey.keycode; m_pEvent->type = NUX_KEYDOWN; m_pEvent->x11_timestamp = xevent.xkey.time; m_pEvent->x11_key_state = xevent.xkey.state; Memset(m_pEvent->text, 0, NUX_EVENT_TEXT_BUFFER_SIZE); bool skip = false; if ((keysym == NUX_VK_BACKSPACE) || (keysym == NUX_VK_DELETE) || (keysym == NUX_VK_ESCAPE)) { //temporary fix for TextEntry widget: filter some keys skip = true; } if (!skip) { int num_char_stored = 0; if (m_current_xic) { delete[] m_pEvent->dtext; m_pEvent->dtext = nullptr; Status status; num_char_stored = XmbLookupString(m_current_xic, &xevent.xkey, nullptr, 0, (KeySym*) &m_pEvent->x11_keysym, &status); if (status == XLookupKeySym) { GetDefaultSizeLookupString(xevent, m_pEvent); } else if (num_char_stored > 0) { int buf_len = num_char_stored + 1; m_pEvent->dtext = new char[buf_len]; num_char_stored = XmbLookupString(m_current_xic, &xevent.xkey, m_pEvent->dtext, buf_len, (KeySym*) &m_pEvent->x11_keysym, nullptr); m_pEvent->dtext[num_char_stored] = 0; } } else { GetDefaultSizeLookupString(xevent, m_pEvent); } } if (m_pEvent->dtext == nullptr) { m_pEvent->dtext = new char[NUX_EVENT_TEXT_BUFFER_SIZE]; m_pEvent->dtext[0] = 0; } break; } case KeyRelease: { //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: KeyRelease event."); KeyCode keycode = xevent.xkey.keycode; KeySym keysym = NoSymbol; keysym = XkbKeycodeToKeysym(xevent.xany.display, keycode, 0, 0); m_pEvent->key_modifiers = GetModifierKeyState(xevent.xkey.state); m_pEvent->key_repeat_count = 0; m_pEvent->x11_keysym = keysym; m_pEvent->x11_keycode = xevent.xkey.keycode; m_pEvent->type = NUX_KEYUP; m_pEvent->x11_timestamp = xevent.xkey.time; m_pEvent->x11_key_state = xevent.xkey.state; break; } case ButtonPress: { if (_dnd_is_drag_source) { HandleDndDragSourceEvent(xevent); break; } m_pEvent->x = x_recalc; m_pEvent->y = y_recalc; m_pEvent->x_root = 0; m_pEvent->y_root = 0; m_pEvent->key_modifiers = GetModifierKeyState(xevent.xkey.state); m_pEvent->x11_timestamp = xevent.xbutton.time; MousePress(xevent, m_pEvent); //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: ButtonPress event."); break; } case ButtonRelease: { if (_dnd_is_drag_source) { HandleDndDragSourceEvent(xevent); // fall through on purpose } m_pEvent->x = x_recalc; m_pEvent->y = y_recalc; m_pEvent->x_root = 0; m_pEvent->y_root = 0; m_pEvent->key_modifiers = GetModifierKeyState(xevent.xkey.state); m_pEvent->x11_timestamp = xevent.xbutton.time; MouseRelease(xevent, m_pEvent); //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: ButtonRelease event."); break; } case MotionNotify: { if (_dnd_is_drag_source) { HandleDndDragSourceEvent(xevent); break; } m_pEvent->x = x_recalc; m_pEvent->y = y_recalc; m_pEvent->x_root = 0; m_pEvent->y_root = 0; m_pEvent->key_modifiers = GetModifierKeyState(xevent.xkey.state); m_pEvent->x11_timestamp = xevent.xmotion.time; MouseMove(xevent, m_pEvent); //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: MotionNotify event."); break; } // Note: there is no WM_MOUSEENTER. WM_MOUSEENTER is equivalent to WM_MOUSEMOVE after a WM_MOUSELEAVE. case LeaveNotify: { if (xevent.xcrossing.mode != NotifyNormal || !local_from_server) break; m_pEvent->x = -1; m_pEvent->y = -1; m_pEvent->x_root = 0; m_pEvent->y_root = 0; m_pEvent->key_modifiers = GetModifierKeyState(xevent.xkey.state); m_pEvent->x11_timestamp = xevent.xcrossing.time; m_pEvent->type = NUX_WINDOW_MOUSELEAVE; //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: LeaveNotify event."); break; } case EnterNotify: { if (xevent.xcrossing.mode != NotifyNormal || !local_from_server) break; m_pEvent->x = x_recalc; m_pEvent->y = y_recalc; m_pEvent->x_root = 0; m_pEvent->y_root = 0; m_pEvent->key_modifiers = GetModifierKeyState(xevent.xkey.state); m_pEvent->x11_timestamp = xevent.xcrossing.time; MouseMove(xevent, m_pEvent); //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: EnterNotify event."); break; } case SelectionRequest: { if (xevent.xselectionrequest.selection == atom::XdndSelection) HandleDndSelectionRequest(xevent); break; } case MapNotify: { if (xevent.xmap.window == _dnd_source_window) { DrawDndSourceWindow(); } else { //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: MapNotify event."); m_pEvent->type = NUX_WINDOW_MAP; } break; } case UnmapNotify: { //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: UnmapNotify event."); m_pEvent->type = NUX_WINDOW_UNMAP; break; } case ClientMessage: { //if(foreign) // break; if ((xevent.xclient.format == 32) && ((xevent.xclient.data.l[0]) == static_cast (m_WMDeleteWindow))) { m_pEvent->type = NUX_TERMINATE_APP; //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: ClientMessage event: Close Application."); } if (xevent.xclient.message_type == atom::XdndPosition) { HandleXDndPosition(xevent, m_pEvent); } else if (xevent.xclient.message_type == atom::XdndEnter) { HandleXDndEnter(xevent); m_pEvent->type = NUX_DND_ENTER_WINDOW; } else if (xevent.xclient.message_type == atom::XdndStatus) { HandleXDndStatus(xevent); m_pEvent->type = NUX_NO_EVENT; } else if (xevent.xclient.message_type == atom::XdndLeave) { HandleXDndLeave(xevent); m_pEvent->type = NUX_DND_LEAVE_WINDOW; } else if (xevent.xclient.message_type == atom::XdndDrop) { HandleXDndDrop(xevent, m_pEvent); } else if (xevent.xclient.message_type == atom::XdndFinished) { HandleXDndFinished(xevent); m_pEvent->type = NUX_NO_EVENT; } break; } } } void GraphicsDisplay::HandleDndSelectionRequest(XEvent xevent) { XEvent result; if (!_dnd_source_funcs.get_data_for_type) return; result.xselection.type = SelectionNotify; result.xselection.display = xevent.xany.display; result.xselection.requestor = xevent.xselectionrequest.requestor; result.xselection.selection = xevent.xselectionrequest.selection; result.xselection.target = xevent.xselectionrequest.target; result.xselection.property = xevent.xselectionrequest.property; result.xselection.time = xevent.xselectionrequest.time; int format, size; char *type = XGetAtomName(xevent.xany.display, xevent.xselectionrequest.target); const unsigned char *data = (const unsigned char *) (*(_dnd_source_funcs.get_data_for_type)) (type, &size, &format, _dnd_source_data); XFree(type); XChangeProperty(xevent.xany.display, xevent.xselectionrequest.requestor, xevent.xselectionrequest.property, xevent.xselectionrequest.target, format, PropModeReplace, data, size); XSendEvent(xevent.xany.display, xevent.xselectionrequest.requestor, False, 0, &result); } gboolean GraphicsDisplay::OnDragEndTimeout(gpointer data) { static_cast (data)->EndDndDrag(DNDACTION_NONE); return false; } void GraphicsDisplay::HandleDndDragSourceEvent(XEvent xevent) { if (_dnd_source_drop_sent) return; switch(xevent.type) { case ButtonPress: break; case ButtonRelease: if (!_dnd_source_target_window || !_dnd_source_target_accepts_drop) { SetDndSourceTargetWindow(None); EndDndDrag(DNDACTION_NONE); } else { SendDndSourceDrop(_dnd_source_target_window, xevent.xbutton.time); _dnd_source_drop_sent = true; UngrabPointer(this); _dnd_source_grab_active = false; g_timeout_add(1000, &GraphicsDisplay::OnDragEndTimeout, this); } break; case MotionNotify: Window target = GetDndTargetWindowForPos(xevent.xmotion.x_root, xevent.xmotion.y_root); if (_dnd_source_window) { Window rw; int x, y; unsigned int w, h, b, d; XGetGeometry(GetX11Display(), _dnd_source_window, &rw, &x, &y, &w, &h, &b, &d); XMoveWindow(GetX11Display(), _dnd_source_window, xevent.xmotion.x_root - (w / 2), xevent.xmotion.y_root - (h / 2)); } if (target != _dnd_source_target_window) SetDndSourceTargetWindow(target); if (_dnd_source_target_window) SendDndSourcePosition(_dnd_source_target_window, xevent.xmotion.x_root, xevent.xmotion.y_root, xevent.xmotion.time); break; } } void GraphicsDisplay::SendDndSourceDrop(Window target, Time time) { XClientMessageEvent drop_message; drop_message.window = target; drop_message.format = 32; drop_message.type = ClientMessage; drop_message.message_type = atom::XdndDrop; drop_message.data.l[0] = _dnd_source_window; drop_message.data.l[1] = 0; drop_message.data.l[2] = time; XSendEvent(GetX11Display(), target, False, NoEventMask, (XEvent *) &drop_message); } void GraphicsDisplay::SendDndSourcePosition(Window target, int x, int y, Time time) { XClientMessageEvent position_message; position_message.window = target; position_message.format = 32; position_message.type = ClientMessage; position_message.message_type = atom::XdndPosition; position_message.data.l[0] = _dnd_source_window; position_message.data.l[1] = 0; position_message.data.l[2] = (x << 16) + y; position_message.data.l[3] = time; position_message.data.l[4] = atom::XdndActionCopy; //fixme XSendEvent(GetX11Display(), target, False, NoEventMask, (XEvent *) &position_message); } void GraphicsDisplay::SendDndSourceEnter(Window target) { XClientMessageEvent enter_message; enter_message.window = target; enter_message.format = 32; enter_message.type = ClientMessage; enter_message.message_type = atom::XdndEnter; enter_message.data.l[0] = _dnd_source_window; enter_message.data.l[1] = (((unsigned long) xdnd_version) << 24) + 1; // mark that we have set the atom list enter_message.data.l[2] = None; // fixme, these should contain the first 3 atoms enter_message.data.l[3] = None; enter_message.data.l[4] = None; XSendEvent(GetX11Display(), target, False, NoEventMask, (XEvent *) &enter_message); } void GraphicsDisplay::SendDndSourceLeave(Window target) { XClientMessageEvent leave_message; leave_message.window = target; leave_message.format = 32; leave_message.type = ClientMessage; leave_message.message_type = atom::XdndLeave; leave_message.data.l[0] = _dnd_source_window; leave_message.data.l[1] = 0; // flags XSendEvent(GetX11Display(), target, False, NoEventMask, (XEvent *) &leave_message); } void GraphicsDisplay::SetDndSourceTargetWindow(Window target) { if (target == _dnd_source_target_window || !_dnd_source_grab_active) return; if (_dnd_source_target_window) SendDndSourceLeave(_dnd_source_target_window); if (target) SendDndSourceEnter(target); _dnd_source_target_accepts_drop = false; _dnd_source_target_window = target; } // This function hilariously inefficient Window GraphicsDisplay::GetDndTargetWindowForPos(int pos_x, int pos_y) { Window result = 0; Window root_window = DefaultRootWindow(GetX11Display()); int cur_x, cur_y; XTranslateCoordinates(GetX11Display(), root_window, root_window, pos_x, pos_y, &cur_x, &cur_y, &result); if (!result) return result; Window src = root_window; while (true) { // translate into result space Window child; int new_x, new_y; XTranslateCoordinates(GetX11Display(), src, result, cur_x, cur_y, &new_x, &new_y, &child); cur_x = new_x; cur_y = new_y; // Check if our current window is XdndAware Atom type = 0; int format; unsigned long n, a; unsigned char *data = 0; if (XGetWindowProperty(GetX11Display(), result, atom::XdndAware, 0, 1, False, XA_ATOM, &type, &format, &n, &a, &data) == Success) { if (data) { long dnd_version = 0; dnd_version = ((Atom *)data)[0]; if (dnd_version < 5) result = 0; // dont have v5? go away until I implement this :) XFree(data); break; // result is the winner } } // Find child window if any and ignore translation XTranslateCoordinates(GetX11Display(), result, result, cur_x, cur_y, &new_x, &new_y, &child); // there is no child window, stop if (!child) { result = 0; break; } src = result; result = child; } return result; } void GraphicsDisplay::EndDndDrag(DndAction action) { Display *display = GetX11Display(); if (_dnd_source_funcs.drag_finished) (*(_dnd_source_funcs.drag_finished)) (action, _dnd_source_data); _dnd_is_drag_source = false; if (_dnd_source_window) XDestroyWindow(display, _dnd_source_window); _dnd_source_window = 0; GrabDndSelection(display, None, CurrentTime); UngrabPointer(this); _dnd_source_grab_active = false; _dnd_source_funcs.get_drag_image = 0; _dnd_source_funcs.get_drag_types = 0; _dnd_source_funcs.get_data_for_type = 0; _dnd_source_funcs.drag_finished = 0; _dnd_source_data = 0; } void GraphicsDisplay::DrawDndSourceWindow() { if (!_dnd_source_funcs.get_drag_image || !_dnd_source_data || !_dnd_source_window) return; Display *display = GetX11Display(); NBitmapData *data = (*(_dnd_source_funcs.get_drag_image)) (_dnd_source_data); XImage *image; image = XGetImage(display, _dnd_source_window, 0, 0, data->GetWidth(), data->GetHeight(), AllPlanes, ZPixmap); GC gc = XCreateGC(display, _dnd_source_window, 0, NULL); BitmapFormat format = data->GetFormat(); /* draw some shit */ if (data->IsTextureData()) { ImageSurface surface = data->GetSurface(0); int x, y; for (y = 0; y < data->GetHeight(); y++) { for (x = 0; x < data->GetWidth(); x++) { long pixel = (long) surface.Read(x, y); long a; if (format == BITFMT_R8G8B8) a = 255; else a = ((pixel >> 24) & 0xff); long r = (((pixel >> 16) & 0xff) * a) / 255; long g = (((pixel >> 8) & 0xff) * a) / 255; long b = (((pixel >> 0) & 0xff) * a) / 255; long result_pixel = (a << 24) | (b << 16) | (g << 8) | (r << 0); XPutPixel(image, x, y, result_pixel); } } } /* upload */ XPutImage(display, _dnd_source_window, gc, image, 0, 0, 0, 0, data->GetWidth(), data->GetHeight()); XDestroyImage(image); } void GraphicsDisplay::StartDndDrag(const DndSourceFuncs &funcs, void *user_data) { Display *display = GetX11Display(); if (!display || !GrabPointer(NULL, this, true)) { if (funcs.drag_finished) (*(funcs.drag_finished)) (DNDACTION_NONE, user_data); return; } _dnd_source_funcs = funcs; _dnd_source_data = user_data; _dnd_source_grab_active = true; _dnd_source_drop_sent = false; int width = 100, height = 100; if (_dnd_source_funcs.get_drag_image) { NBitmapData *data = (*(_dnd_source_funcs.get_drag_image)) (_dnd_source_data); width = data->GetWidth(); height = data->GetHeight(); delete data; } Window root = DefaultRootWindow(display); XVisualInfo vinfo; if (!XMatchVisualInfo(display, XDefaultScreen(display), 32, TrueColor, &vinfo)) { printf("Could not match visual info\n"); EndDndDrag(DNDACTION_NONE); return; } XSetWindowAttributes attribs; attribs.override_redirect = true; attribs.background_pixel = 0; attribs.border_pixel = 0; attribs.colormap = XCreateColormap(display, root, vinfo.visual, AllocNone); unsigned long attrib_mask = CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap; // make a window which will serve two purposes: // First this window will be used to display feedback to the user // Second this window will grab and own the XdndSelection Selection _dnd_source_window = XCreateWindow(display, root, -1000, -1000, width, height, 0, vinfo.depth, InputOutput, vinfo.visual, attrib_mask, &attribs); XSelectInput(display, _dnd_source_window, StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask); XMapRaised(display, _dnd_source_window); Atom atom_type[1]; atom_type[0] = atom::_NET_WM_WINDOW_TYPE_DND; XChangeProperty(display, _dnd_source_window, atom::_NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char*) atom_type, 1); Atom data[32]; int i = 0; data[i++] = atom::_NET_WM_STATE_STICKY; data[i++] = atom::_NET_WM_STATE_SKIP_TASKBAR; data[i++] = atom::_NET_WM_STATE_SKIP_PAGER; data[i++] = atom::_NET_WM_STATE_ABOVE; XChangeProperty(display, _dnd_source_window, atom::_NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) data, i); Region region = XCreateRegion(); if (region) { XShapeCombineRegion(display, _dnd_source_window, ShapeInput, 0, 0, region, ShapeSet); XDestroyRegion(region); } XFlush(display); _dnd_is_drag_source = true; _dnd_source_target_window = 0; std::list types = _dnd_source_funcs.get_drag_types(_dnd_source_data); std::list::iterator it; Atom type_atoms[types.size()]; i = 0; for (it = types.begin(); it != types.end(); ++it) { type_atoms[i] = XInternAtom(display, *it, false); i++; } XChangeProperty(display, _dnd_source_window, atom::XdndTypeList, XA_ATOM, 32, PropModeReplace, (unsigned char *)type_atoms, i); GrabDndSelection(display, _dnd_source_window, CurrentTime); } bool GraphicsDisplay::GrabDndSelection(Display *display, Window window, Time time) { XSetSelectionOwner(GetX11Display(), atom::XdndSelection, window, time); Window owner = XGetSelectionOwner(display, atom::XdndSelection); return owner == window; } void GraphicsDisplay::SendDndStatus(bool accept, DndAction action, Rect region) { if (!_drag_window || !_drag_display || !_drag_source) return; Atom a; switch(action) { case DNDACTION_MOVE: a = atom::XdndActionMove; break; case DNDACTION_COPY: a = atom::XdndActionCopy; break; case DNDACTION_PRIVATE: a = atom::XdndActionPrivate; break; case DNDACTION_LINK: a = atom::XdndActionLink; break; case DNDACTION_ASK: a = atom::XdndActionAsk; break; default: a = None; break; } SendXDndStatus(_drag_display, _drag_window, _drag_source, accept, a, region); } void GraphicsDisplay::SendDndFinished(bool accepted, DndAction performed_action) { if (!_drag_window || !_drag_display || !_drag_source) return; Atom a; switch(performed_action) { case DNDACTION_MOVE: a = atom::XdndActionMove; break; case DNDACTION_COPY: a = atom::XdndActionCopy; break; case DNDACTION_PRIVATE: a = atom::XdndActionPrivate; break; case DNDACTION_LINK: a = atom::XdndActionLink; break; case DNDACTION_ASK: a = atom::XdndActionAsk; break; default: a = None; break; } SendXDndFinished(_drag_display, _drag_window, _drag_source, accepted, a); } std::list GraphicsDisplay::GetDndMimeTypes() { std::list result; if (!_drag_display) return result; Atom a; int i; for (i = 0; i <= _xdnd_max_type; i++) { a = _xdnd_types[i]; if (!a) break; char *name = XGetAtomName(_drag_display, a); result.push_back(g_strdup(name)); XFree(name); } return result; } char * GraphicsDisplay::GetDndData(char *property) { if (!_drag_display) return NULL; if (_dnd_is_drag_source) { int size, format; return g_strdup((*(_dnd_source_funcs.get_data_for_type)) (property, &size, &format, _dnd_source_data)); } else { Atom a = XInternAtom(_drag_display, property, false); return GetXDndData(_drag_display, _drag_window, a, _drag_drop_timestamp); } } void GraphicsDisplay::SendXDndStatus(Display *display, Window source, Window target, bool accept, Atom action, Rect box) { XClientMessageEvent response; response.window = target; response.format = 32; response.type = ClientMessage; response.message_type = atom::XdndStatus; response.data.l[0] = source; response.data.l[1] = 0; // flags response.data.l[2] = (box.x << 16) | box.y; // x, y response.data.l[3] = (box.width << 16) | box.height; // w, h if (accept) { response.data.l[4] = action; response.data.l[1] |= 1 << 0; } else { response.data.l[4] = None; } XSendEvent(display, target, False, NoEventMask, (XEvent *) &response); } void GraphicsDisplay::HandleXDndPosition(XEvent event, Event* nux_event) { const unsigned long *l = (const unsigned long *)event.xclient.data.l; int x = (l[2] & 0xffff0000) >> 16; int y = l[2] & 0x0000ffff; int x_recalc = 0; int y_recalc = 0; RecalcXYPosition(x, y, x_recalc, y_recalc); nux_event->type = NUX_DND_MOVE; nux_event->x = x_recalc; nux_event->y = y_recalc; // Store the last DND position; _last_dnd_position = Point(x_recalc, y_recalc); } void GraphicsDisplay::HandleXDndEnter(XEvent event) { const long *l = event.xclient.data.l; int version = (int)(((unsigned long)(l[1])) >> 24); if (version > xdnd_version) return; _drag_source = l[0]; _drag_window = event.xany.window; _drag_display = event.xany.display; int j = 0; if (l[1] & 1) { unsigned char *retval = 0; unsigned long n, a; int f; Atom type = None; XGetWindowProperty(_drag_display, _drag_source, atom::XdndTypeList, 0, _xdnd_max_type, False, XA_ATOM, &type, &f, &n, &a, &retval); if (retval) { Atom *data = (Atom *)retval; for (; j < _xdnd_max_type && j < (int)n; j++) _xdnd_types[j] = data[j]; XFree((uchar*)data); } } else { // xdnd supports up to 3 types without using XdndTypelist int i; for (i = 2; i < 5; i++) _xdnd_types[j++] = l[i]; } _xdnd_types[j] = 0; } void GraphicsDisplay::HandleXDndStatus(XEvent event) { const unsigned long *l = (const unsigned long *)event.xclient.data.l; // should protect against stray messages if (l[1] & 1) _dnd_source_target_accepts_drop = true; else _dnd_source_target_accepts_drop = false; } void GraphicsDisplay::HandleXDndLeave(XEvent /* event */) { // reset the key things _xdnd_types[0] = 0; _drag_source = 0; _drag_window = 0; _drag_drop_timestamp = 0; } bool GraphicsDisplay::GetXDndSelectionEvent(Display *display, Window target, Atom property, long time, XEvent *result, int attempts) { // request the selection XConvertSelection(display, atom::XdndSelection, property, atom::XdndSelection, target, time); XFlush(display); int i; for (i = 0; i < attempts; i++) { if (XCheckTypedWindowEvent(display, target, SelectionNotify, result)) { return true; } XFlush(display); struct timeval usleep_tv; usleep_tv.tv_sec = 0; usleep_tv.tv_usec = 50000; select(0, 0, 0, 0, &usleep_tv); } return false; } void GraphicsDisplay::SendXDndFinished(Display *display, Window source, Window target, bool result, Atom action) { XClientMessageEvent response; response.window = target; response.format = 32; response.type = ClientMessage; response.message_type = atom::XdndFinished; response.data.l[0] = source; response.data.l[1] = result ? 1 : 0; // flags response.data.l[2] = action; // action XSendEvent(display, target, False, NoEventMask, (XEvent *) &response); } char * GraphicsDisplay::GetXDndData(Display *display, Window requestor, Atom property, long time) { char *result = 0; XEvent xevent; if (GetXDndSelectionEvent(display, requestor, property, time, &xevent, 50)) { unsigned char *buffer = NULL; Atom type; unsigned long bytes_left; // bytes_after unsigned long length; // nitems int format; if (XGetWindowProperty(display, requestor, atom::XdndSelection, 0, 10000, False, AnyPropertyType, &type, &format, &length, &bytes_left, &buffer) == Success) { result = g_strdup((char *) buffer); XFree(buffer); } } return result; } void GraphicsDisplay::HandleXDndDrop(XEvent event, Event *nux_event) { const long *l = event.xclient.data.l; _drag_drop_timestamp = l[2]; nux_event->type = NUX_DND_DROP; // The drop does not provide(x, y) coordinates of the location of the drop. Use the last DND position. nux_event->x = _last_dnd_position.x; nux_event->y = _last_dnd_position.y; nux_event->x11_timestamp = _drag_drop_timestamp; } void GraphicsDisplay::HandleXDndFinished(XEvent event) { const unsigned long *l = (const unsigned long *)event.xclient.data.l; if (l[0] != _dnd_source_target_window) return; bool accepted = l[1] & 1; DndAction result = DNDACTION_NONE; if (accepted) { if (l[2] == atom::XdndActionCopy) result = DNDACTION_COPY; else if (l[2] == atom::XdndActionAsk) result = DNDACTION_ASK; else if (l[2] == atom::XdndActionLink) result = DNDACTION_LINK; else if (l[2] == atom::XdndActionMove) result = DNDACTION_MOVE; else if (l[2] == atom::XdndActionPrivate) result = DNDACTION_PRIVATE; } EndDndDrag(result); } void GraphicsDisplay::InitGlobalGrabWindow() { Display *display = GetX11Display(); XSetWindowAttributes attribs; attribs.override_redirect = True; _global_grab_window = XCreateWindow(display, DefaultRootWindow(display), -100, -100, // X, Y 1, 1, // Width, Height 0, // Border 0, // Depth InputOnly, // Class CopyFromParent, // Visual CWOverrideRedirect, &attribs); XSelectInput(display, _global_grab_window, StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask); XMapRaised(display, _global_grab_window); Atom atom_type[1]; atom_type[0] = atom::_NET_WM_WINDOW_TYPE_UTILITY; XChangeProperty(display, _global_grab_window, atom::_NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char*) atom_type, 1); Atom data[32]; int i = 0; data[i++] = atom::_NET_WM_STATE_STICKY; data[i++] = atom::_NET_WM_STATE_SKIP_TASKBAR; data[i++] = atom::_NET_WM_STATE_SKIP_PAGER; data[i++] = atom::_NET_WM_STATE_ABOVE; XChangeProperty(display, _global_grab_window, atom::_NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) data, i); } bool GraphicsDisplay::GrabPointer(GrabReleaseCallback callback, void *data, bool replace_existing) { if (_global_pointer_grab_active) { if (!replace_existing || _dnd_source_grab_active) // prevent grabbing over DND grabs return false; if (_global_pointer_grab_callback) (*_global_pointer_grab_callback) (true, _global_pointer_grab_data); } if (!_global_pointer_grab_active) { int result = XGrabPointer(GetX11Display(), _global_grab_window, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ButtonMotionMask , GrabModeAsync, GrabModeAsync, None, None, CurrentTime); if (result == GrabSuccess) _global_pointer_grab_active = true; } if (_global_pointer_grab_active) { _global_pointer_grab_callback = callback; _global_pointer_grab_data = data; } return _global_pointer_grab_active; } bool GraphicsDisplay::UngrabPointer(void *data) { if (data != _global_pointer_grab_data || !_global_pointer_grab_active) return false; _global_pointer_grab_active = false; XUngrabPointer(GetX11Display(), CurrentTime); if (_global_pointer_grab_callback) (*_global_pointer_grab_callback) (false, data); _global_pointer_grab_data = 0; _global_pointer_grab_callback = 0; return true; } bool GraphicsDisplay::PointerIsGrabbed() { return _global_pointer_grab_active; } bool GraphicsDisplay::GrabKeyboard(GrabReleaseCallback callback, void *data, bool replace_existing) { if (_global_keyboard_grab_active) { if (!replace_existing) return false; // fail case if (_global_keyboard_grab_callback) (*_global_keyboard_grab_callback) (true, _global_keyboard_grab_data); } if (!_global_keyboard_grab_active) { int result = XGrabKeyboard(GetX11Display(), _global_grab_window, True, GrabModeAsync, GrabModeAsync, CurrentTime); if (result == GrabSuccess) _global_keyboard_grab_active = true; } if (_global_keyboard_grab_active) { _global_keyboard_grab_callback = callback; _global_keyboard_grab_data = data; } return _global_keyboard_grab_active; } bool GraphicsDisplay::UngrabKeyboard(void *data) { if (data != _global_keyboard_grab_data || !_global_keyboard_grab_active) return false; _global_keyboard_grab_active = false; XUngrabKeyboard(GetX11Display(), CurrentTime); if (_global_keyboard_grab_callback) (*_global_keyboard_grab_callback) (false, data); _global_keyboard_grab_data = 0; _global_keyboard_grab_callback = 0; return true; } bool GraphicsDisplay::KeyboardIsGrabbed() { return _global_keyboard_grab_active; } void GraphicsDisplay::ShowWindow() { XMapRaised(m_X11Display, m_X11Window); } void GraphicsDisplay::HideWindow() { XUnmapWindow(m_X11Display, m_X11Window); } bool GraphicsDisplay::IsWindowVisible() { XWindowAttributes window_attributes_return; XGetWindowAttributes(m_X11Display, m_X11Window, &window_attributes_return); if (window_attributes_return.map_state == IsViewable) { return true; } return false; } void GraphicsDisplay::EnterMaximizeWindow() { } void GraphicsDisplay::ExitMaximizeWindow() { } void GraphicsDisplay::SetWindowTitle(const char *Title) { window_title_ = Title; XStoreName(m_X11Display, m_X11Window, window_title_.c_str()); } bool GraphicsDisplay::HasVSyncSwapControl() const { return GetGpuDevice()->GetGpuInfo().Support_EXT_Swap_Control(); } void GraphicsDisplay::EnableVSyncSwapControl() { #ifndef NUX_OPENGLES_20 if (GetGpuDevice()->GetGpuInfo().Support_EXT_Swap_Control()) { GLXDrawable drawable = glXGetCurrentDrawable(); glXSwapIntervalEXT(m_X11Display, drawable, 1); } #endif } void GraphicsDisplay::DisableVSyncSwapControl() { #ifndef NUX_OPENGLES_20 if (GetGpuDevice()->GetGpuInfo().Support_EXT_Swap_Control()) { GLXDrawable drawable = glXGetCurrentDrawable(); if (drawable != None) { glXSwapIntervalEXT(m_X11Display, drawable, 0); } } #endif } float GraphicsDisplay::GetFrameTime() const { return m_FrameTime; } void GraphicsDisplay::ResetFrameTime() { m_Timer.Reset(); } void GraphicsDisplay::PauseThreadGraphicsRendering() { m_PauseGraphicsRendering = true; MakeGLContextCurrent(); } bool GraphicsDisplay::IsPauseThreadGraphicsRendering() const { return m_PauseGraphicsRendering; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLPixelBufferOject.h0000644000015301777760000000332212321344237023717 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IOPENGLPIXELBUFFEROBJECT_H #define IOPENGLPIXELBUFFEROBJECT_H namespace nux { class IOpenGLPixelBufferObject: public IOpenGLResource { NUX_DECLARE_OBJECT_TYPE(IOpenGLPixelBufferObject, IOpenGLResource); public: virtual ~IOpenGLPixelBufferObject(); int Lock( unsigned int OffsetToLock, unsigned int SizeToLock, void **ppbData); int Unlock(); int GetDescription(INDEXBUFFER_DESC *desc) const { desc->Usage = _Usage; desc->Size = _Length; return OGL_OK; } void BindPackPixelBufferObject(); void BindUnpackPixelBufferObject(); unsigned int GetSize(); private: IOpenGLPixelBufferObject(unsigned int Size, VBO_USAGE Usage, NUX_FILE_LINE_PROTO); unsigned int _Length; VBO_USAGE _Usage; BYTE *_MemMap; unsigned int _OffsetToLock; unsigned int _SizeToLock; friend class GpuDevice; }; } #endif // IOPENGLPIXELBUFFEROJECT_H nux-4.0.6+14.04.20140409/NuxGraphics/GLDeviceObjects.cpp0000644000015301777760000001565112321344237022640 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLDeviceFrameBufferObject.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" namespace nux { extern PixelFormatInfo GPixelFormats[]; //NObjectType IOpenGLResource::StaticObjectType("IOpenGLResource", 0); NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLResource); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* GLSL Built-in vertex attribute(Deprecated in GLSL 1.30) ------------------------------- Built-in vertex attribute name Incompatible aliased vertex attribute index gl_Vertex 0 gl_Normal 2 gl_Color 3 gl_SecondaryColor 4 gl_FogCoord 5 gl_MultiTexCoord0 8 gl_MultiTexCoord1 9 gl_MultiTexCoord2 10 gl_MultiTexCoord3 11 gl_MultiTexCoord4 12 gl_MultiTexCoord5 13 gl_MultiTexCoord6 14 gl_MultiTexCoord7 15 gl_Vertex: - glVertex{234sifd} - glEnableClientState/glDisableClientState(GL_VERTEX_ARRAY); glVertexPointer(...); gl_Normal: - glNormal{3sifd} - glEnableClientState/glDisableClientState(GL_NORMAL_ARRAY); glNormalPointer(...); gl_Color: - glColor{34sifd} - glEnableClientState/glDisableClientState(GL_COLOR_ARRAY); glColorPointer(...); gl_SecondaryColor(requires GL_EXT_secondary_color) - glSecondaryColor3{bsifd}; - glEnableClientState/glDisableClientState(SECONDARY_COLOR_ARRAY_EXT); glSecondaryColorPointerEXT(...); gl_FogCoord(requires GL_EXT_fog_coord) - glFogCoord{fd}; - glEnableClientState/glDisableClientState(FOG_COORDINATE_ARRAY_EXT); glFogCoordPointerEXT(...); gl_MultiTexCoordXXX - glMultiTexCoord{234fd} - glClientActiveTextureARB(GL_TEXTUREXXX_ARB); glEnableClientState/glDisableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(...); GLSL Vertex Shader Special output variables(write) ---------------------------------------------------- gl_Position (must be written to) gl_PointSize (may be written to) gl_ClipVertex (may be written to) GLSL Vertex Shader Built-in varying(write) GLSL Fragment Shader Built-in varying(read) ------------------------------------------- ------------------------------------------- varying vec4 gl_FrontColor; ----> gl_Color varying vec4 gl_BackColor; ----> gl_Color varying vec4 gl_FrontSecondaryColor; ----> gl_SecondaryColor varying vec4 gl_BackSecondaryColor; ----> gl_SecondaryColor varying vec4 gl_TexCoord[]; ----> gl_TexCoord[] varying float gl_FogFragCoord; ----> gl_FogFragCoord GLSL Fragment Built-in variables -------------------------------- vec4 gl_FragCoord (read only) bool gl_FrontFacing (read only) vec2 gl_PointCoord (read only) GLSL Fragment Shader Special output variables --------------------------------------------- vec4 gl_FragColor (may be written to) vec4 gl_FragData[gl_MaxDrawBuffers] (may be written to) float gl_FragDepth (may be written to) vec2 gl_PointCoord (read only) Binding Semantics for Cg programs Binding Semantics for Varying Input/Output Data ----------------------------------------------- Table 23 summarizes the valid binding semantics for varying input parameters in the vp30 profile. One can also use TANGENT and BINORMAL instead of TEXCOORD6 and TEXCOORD7. These binding semantics map to NV_vertex_program2 input attribute parameters. The two sets act as aliases to each other. Table 23 vp30 Varying Input Binding Semantics Binding Semantics Name Corresponding Data POSITION, ATTR0 Input Vertex, Generic Attribute 0 BLENDWEIGHT, ATTR1 Input vertex weight, Generic Attribute 1 NORMAL, ATTR2 Input normal, Generic Attribute 2 COLOR0, DIFFUSE, ATTR3 Input primary color, Generic Attribute 3 COLOR1, SPECULAR, ATTR4 Input secondary color, Generic Attribute 4 TESSFACTOR, FOGCOORD, ATTR5 Input fog coordinate, Generic Attribute 5 PSIZE, ATTR6 Input point size, Generic Attribute 6 BLENDINDICES, ATTR7 Generic Attribute 7 TEXCOORD0-TEXCOORD7, ATTR8-ATTR15 Input texture coordinates(texcoord0-texcoord7), Generic Attributes 815 TANGENT, ATTR14 Generic Attribute 14 BINORMAL, ATTR15 Generic Attribute 15 Table 24 summarizes the valid binding semantics for varying output parameters in the vp30 profile. These binding semantics map to NV_vertex_program2 output registers. The two sets act as aliases to each other. Table 24 vp30 Varying Output Binding Semantics Binding Semantics Name Corresponding Data POSITION, HPOS Output position PSIZE, PSIZ Output point size FOG, FOGC Output fog coordinate COLOR0, COL0 Output primary color COLOR1, COL1 Output secondary color BCOL0 Output backface primary color BCOL1 Output backface secondary color TEXCOORD0-TEXCOORD7, TEX0-TEX7 Output texture coordinates CLP0-CL5 Output Clip distances */ } nux-4.0.6+14.04.20140409/NuxGraphics/GraphicsDisplayX11.h0000755000015301777760000003401212321344237022724 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GRAPHICSDISPLAYX11_H #define GRAPHICSDISPLAYX11_H #include "Gfx_Interface.h" #include "GLTimer.h" #include "GLDeviceObjects.h" #include "GLRenderStates.h" /* Xlib.h is the default header that is included and has the core functionallity */ #include /* Xatom.h includes functionallity for creating new protocol messages */ #include /* keysym.h contains keysymbols which we use to resolv what keys that are being pressed */ #include #include #include namespace nux { class Event; class MainFBO; class GpuDevice; class GraphicsEngine; class IOpenGLFrameBufferObject; enum WindowStyle { WINDOWSTYLE_NORMAL, WINDOWSTYLE_PANEL, WINDOWSTYLE_DIALOG, WINDOWSTYLE_TOOL, WINDOWSTYLE_NOBORDER, }; enum DndAction { DNDACTION_COPY, DNDACTION_MOVE, DNDACTION_LINK, DNDACTION_ASK, DNDACTION_PRIVATE, DNDACTION_NONE, }; #define NUX_THREADMSG (WM_APP+0) #define NUX_THREADMSG_START_RENDERING (WM_APP+1) // Connection established // start at WM_APP #define NUX_THREADMSG_CHILD_WINDOW_TERMINATED (WM_APP+2) // General failure - Wait Connection failed #define NUX_THREADMSG_THREAD_TERMINATED (WM_APP+3) // Set wParam = Thread ID, lParam = 0 #define _xdnd_max_type 100 #define xdnd_version 5 // This will become GLWindow class GraphicsDisplay : public GraphicSystem { private: Display *m_X11Display; int m_X11Screen; Window m_X11Window; XVisualInfo *m_X11VisualInfo; XIC m_current_xic; int parent_window_; #ifndef NUX_OPENGLES_20 GLXContext m_GLCtx; GLXFBConfig _fb_config; GLXWindow glx_window_; #else EGLContext m_GLCtx; EGLSurface m_GLSurface; EGLConfig _fb_config; #endif XSetWindowAttributes m_X11Attr; int m_NumVideoModes; XF86VidModeModeInfo **m_X11VideoModes; /* original desktop mode which we save so we can restore it later */ XF86VidModeModeInfo m_X11OriginalVideoMode; Atom m_WMDeleteWindow; Colormap m_X11Colormap; int m_BorderPixel; int _x11_major; int _x11_minor; int _glx_major; int _glx_minor; bool _has_glx_13; XEvent m_X11LastEvent; Bool m_X11RepeatKey; char m_WindowClassName[256]; GLuint m_PixelFormat; // Holds The Results After Searching For A Match std::string window_title_; // size, position Size viewport_size_; Size window_size_; Point m_WindowPosition; //! Full screen mode. bool fullscreen_; //! Screen bit depth unsigned int screen_bit_depth_; //! State of the graphics interface. bool gfx_interface_created_; // Device information void GetDisplayInfo(); bool m_CreatedFromForeignWindow; Time last_click_time_; /*! Maximum time allowed between the end of the last click (mouse up) and the next mouse down to be considered as a double click event. */ static int double_click_time_delay; int double_click_counter_; public: typedef void(*GrabReleaseCallback) (bool replaced, void *user_data); typedef struct _DndSourceFuncs { nux::NBitmapData * (*get_drag_image) (void * data); std::list (*get_drag_types) (void * data); const char * (*get_data_for_type) (const char * type, int *size, int *format, void * data); void (*drag_finished) (DndAction result, void * data); } DndSourceFuncs; bool HasXPendingEvent() const; Display *GetX11Display() { return m_X11Display; } // Event object Event *m_pEvent; bool IsGfxInterfaceCreated(); //! Create a window with and OpenGL context. /*! @param WindowTitle The window title. @param WindowWidth Initial window width. @param WindowHeight Initial window height. @param Style The window style. @param ParentWindow The parent window. @param fullscreen_flag Full screen flag. */ bool CreateOpenGLWindow( const char *WindowTitle, unsigned int WindowWidth, unsigned int WindowHeight, WindowStyle Style, const GraphicsDisplay *Parent, bool fullscreen_flag = false, bool create_rendering_data = true); //! Create a GLWindow from a display and window created externally. /*! @param X11Display Provided display. @param X11Window Provided window. */ #ifdef NUX_OPENGLES_20 bool CreateFromOpenGLWindow(Display *X11Display, Window X11Window, EGLContext OpenGLContext); #else bool CreateFromOpenGLWindow(Display *X11Display, Window X11Window, GLXContext OpenGLContext); #endif void DestroyOpenGLWindow(); void SetWindowTitle(const char *Title); //! Set the window size. /*! Actively set the window size to the provided parameters. \sa ResetWindowSize */ void SetWindowSize(int width, int height); //! Set the window position. void SetWindowPosition(int width, int height); //! Set the OpenGL Viewport. void SetViewPort(int x, int y, int width, int height); Point GetMouseScreenCoord(); Point GetMouseWindowCoord(); Point GetWindowCoord(); Rect GetWindowGeometry(); Rect GetNCWindowGeometry(); void MakeGLContextCurrent(); void SwapBuffer(bool glswap = true); // Event methods /*! Returns true if there was a pending event to be fetched and false otherwise */ bool GetSystemEvent(Event *evt); // Os specific int GetGlXMajor() const; int GetGlXMinor() const; #if defined(NUX_OS_LINUX) void InjectXEvent(Event *evt, XEvent xevent); typedef struct _EventFilterArg { bool (*filter) (XEvent event, void * data); void * data; } EventFilterArg; void AddEventFilter (EventFilterArg arg); void RemoveEventFilter (void *owner); std::list _event_filters; #endif Event &GetCurrentEvent(); // That method is deprecated, it always returns false and still here in // order to maintain API compatibility. bool isWindowMinimized() const { return false; } void ShowWindow(); void HideWindow(); bool IsWindowVisible(); void EnterMaximizeWindow(); void ExitMaximizeWindow(); Window GetWindowHandle() const { return m_X11Window; } bool IsChildWindow() const { return parent_window_ != 0; } // Return true if VSync swap control is available bool HasVSyncSwapControl() const; void EnableVSyncSwapControl(); void DisableVSyncSwapControl(); // m_FrameRate float GetFrameTime() const; void ResetFrameTime(); GraphicsEngine* GetGraphicsEngine() const; GpuDevice* GetGpuDevice() const; void SetCurrentXIC(XIC xic); // Dialog /*bool StartOpenFileDialog(FileDialogOption& fdo); bool StartSaveFileDialog(FileDialogOption& fdo); bool StartColorDialog(ColorDialogOption& cdo);*/ void GetDesktopSize(int &w, int &h); void GetWindowSize(int &w, int &h); int GetWindowWidth(); int GetWindowHeight(); //! Get the window size and reset the GraphicsEngine and GpuDevice accordingly. /*! This is a passive way to set the window size through out the NuxGraphics system. This call gets the current window size and sets its accordingly to all sub-system. \sa SetWindowSize */ void ResetWindowSize(); bool HasFrameBufferSupport(); /*void SetWindowCursor(HCURSOR cursor); HCURSOR GetWindowCursor() const;*/ //! Pause graphics rendering. /*! Pause graphics rendering. This function also sets the current openGL context to 0 for this window. This is useful while a child window is being created and is sharing openGL objects with this context. For wglShareLists to work, both OpenGL context must be set to 0 in their respective thread. Send NUX_THREADMSG_START_RENDERING(PostThreadMessage) to this window to reactivate rendering. Never call this function while doing rendering. Call it only when processing events. */ void PauseThreadGraphicsRendering(); bool IsPauseThreadGraphicsRendering() const; void ProcessForeignX11Event(XEvent *xevent, Event *nux_event); void ProcessXEvent(XEvent xevent, bool foreign); void RecalcXYPosition(Window TheMainWindow, XEvent xevent, int &x, int &y); void RecalcXYPosition(int x_root, int y_root, int &x_recalc, int &y_recalc); void SendDndStatus (bool accept, DndAction action, Rect region); void SendDndFinished(bool accepted, DndAction performed_action); std::list GetDndMimeTypes(); char * GetDndData (char *property); void StartDndDrag(const DndSourceFuncs &funcs, void *user_data); bool GrabPointer (GrabReleaseCallback callback, void *data, bool replace_existing); bool UngrabPointer(void *data); bool PointerIsGrabbed(); bool GrabKeyboard (GrabReleaseCallback callback, void *data, bool replace_existing); bool UngrabKeyboard(void *data); bool KeyboardIsGrabbed(); void * KeyboardGrabData() { return _global_keyboard_grab_data; } void * PointerGrabData() { return _global_pointer_grab_data; } private: void InitGlobalGrabWindow(); void HandleXDndPosition(XEvent event, Event* nux_event); void HandleXDndEnter (XEvent event); void HandleXDndStatus (XEvent event); void HandleXDndLeave (XEvent event); void HandleXDndDrop (XEvent event, Event* nux_event); void HandleXDndFinished(XEvent event); void SendXDndStatus(Display *display, Window source, Window target, bool accept, Atom action, Rect box); bool GetXDndSelectionEvent(Display *display, Window target, Atom property, long time, XEvent *result, int attempts); void SendXDndFinished(Display *display, Window source, Window target, bool result, Atom action); char * GetXDndData(Display *display, Window requestor, Atom property, long time); void EndDndDrag(DndAction action); bool GrabDndSelection(Display *display, Window window, Time time); void HandleDndDragSourceEvent(XEvent event); void HandleDndSelectionRequest(XEvent event); Window GetDndTargetWindowForPos(int x, int y); void DrawDndSourceWindow(); void SendDndSourcePosition(Window target, int x, int y, Time time); void SendDndSourceEnter(Window target); void SendDndSourceLeave(Window target); void SendDndSourceDrop(Window target, Time time); void SetDndSourceTargetWindow(Window target); static gboolean OnDragEndTimeout(gpointer data); Point _last_dnd_position; bool m_PauseGraphicsRendering; GLTimer m_Timer; float m_FrameTime; GpuDevice *m_DeviceFactory; GraphicsEngine *m_GraphicsContext; WindowStyle m_Style; Atom _xdnd_types[_xdnd_max_type + 1]; Display *_drag_display; Window _drag_window; Window _drag_source; long _drag_drop_timestamp; void * _dnd_source_data; DndSourceFuncs _dnd_source_funcs; Window _dnd_source_window; Window _dnd_source_target_window; Window _global_grab_window; void *_global_pointer_grab_data; bool _global_pointer_grab_active; GrabReleaseCallback _global_pointer_grab_callback; void *_global_keyboard_grab_data; bool _global_keyboard_grab_active; GrabReleaseCallback _global_keyboard_grab_callback; bool _dnd_is_drag_source; bool _dnd_source_target_accepts_drop; bool _dnd_source_grab_active; bool _dnd_source_drop_sent; public: ~GraphicsDisplay(); #ifndef NUX_OPENGLES_20 GLEWContext *GetGLEWContext() { return &m_GLEWContext; } GLXEWContext *GetGLXEWContext() { return &m_GLXEWContext; } #endif std::string FindResourceLocation(const char *ResourceFileName, bool ErrorOnFail = false); std::string FindUITextureLocation(const char *ResourceFileName, bool ErrorOnFail = false); std::string FindShaderLocation(const char *ResourceFileName, bool ErrorOnFail = false); std::string FindFontLocation(const char *ResourceFileName, bool ErrorOnFail = false); const std::vector& GetFontSearchPath() const { return m_FontSearchPath; } const std::vector& GetShaderSearchPath() const { return m_ShaderSearchPath; } const std::vector& GetUITextureSearchPath() const { return m_UITextureSearchPath; } private: std::vector m_FontSearchPath; std::vector m_ShaderSearchPath; std::vector m_UITextureSearchPath; FilePath m_ResourcePathLocation; GraphicsDisplay(); GraphicsDisplay(const GraphicsDisplay &); // Does not make sense for a singleton. This is a self assignment. GraphicsDisplay &operator= (const GraphicsDisplay &); #ifndef NUX_OPENGLES_20 GLEWContext m_GLEWContext; GLXEWContext m_GLXEWContext; #endif int MouseMove(XEvent xevent, Event *event); int MousePress(XEvent xevent, Event *event); int MouseRelease(XEvent xevent, Event *event); friend class DisplayAccessController; friend class GraphicsEngine; }; } #endif //GRAPHICSDISPLAYX11_H nux-4.0.6+14.04.20140409/NuxGraphics/GLResource.h0000644000015301777760000004104212321344237021354 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLRESOURCE_H #define GLRESOURCE_H #include "NuxCore/NuxCore.h" #include "NuxCore/Error.h" #include "NuxCore/FilePath.h" #include "NuxCore/Color.h" #include "NuxCore/Rect.h" #include "NuxCore/Point.h" #include "NuxCore/Size.h" #include "BitmapFormats.h" #include "NuxCore/Parsing.h" #include "NuxCore/Object.h" #include "NuxCore/ObjectPtr.h" #include "NuxCore/Math/MathUtility.h" #include "NuxCore/Math/Constants.h" #include "NuxCore/Math/Vector3.h" #include "NuxCore/Math/Vector4.h" #include "NuxCore/Math/Matrix3.h" #include "NuxCore/Math/Matrix4.h" #include "NuxCore/Math/Spline.h" #include "NuxCore/Math/MathFunctions.h" #include "ImageSurface.h" namespace nux { class IOpenGLResource; class BaseTexture; class Texture2D; class TextureRectangle; class TextureCube; class TextureVolume; class TextureFrameAnimation; class BaseMeshBuffer; class NIndexBuffer; class CachedTexture2D; class CachedTextureRectangle; class CachedTextureCube; class CachedTextureVolume; class CachedTextureFrameAnimation; class FontTexture; } #define NUX_ENABLE_CG_SHADERS 0 #if defined(NUX_OS_WINDOWS) #include "GL/glew.h" #include "GL/wglew.h" GLEWContext *glewGetContext(); WGLEWContext *wglewGetContext(); #if (NUX_ENABLE_CG_SHADERS) #include "CG/cg.h" #include "CG/cgGL.h" #pragma comment( lib, "cg.lib" ) #pragma comment( lib, "cgGL.lib" ) #endif #elif defined(NUX_OS_LINUX) #ifdef NUX_OPENGLES_20 #include "NuxGraphics/OpenGLMapping.h" #include "EGL/egl.h" #include "GLES2/gl2.h" #include "GLES2/gl2ext.h" #else #ifndef GLEW_MX #define GLEW_MX #endif #include "GL/glew.h" #include "GL/glxew.h" GLEWContext *glewGetContext(); GLXEWContext *glxewGetContext(); #if (NUX_ENABLE_CG_SHADERS) #include "Cg/cg.h" #include "Cg/cgGL.h" #endif #endif #ifdef USE_X11 // Explicitly include X11 headers as many EGL implementations don't // do it for us. #include #include #endif #endif #include "RunTimeStats.h" #include "NuxGraphicsResources.h" #include "FontTexture.h" #include "GlobalGraphicsInitializer.h" #include "GLError.h" #define CG_FRAGMENT_PROFILE CG_PROFILE_FP30 #define CG_VERTEX_PROFILE CG_PROFILE_VP30 #define NUX_BUFFER_OFFSET(i) ((BYTE *)NULL + (i)) namespace nux { enum { OGL_OK = 0, OGL_ERROR, OGL_ERROR_UNKNOWN, OGL_INVALID_SURFACE_LEVEL, OGL_INVALID_CALL, OGL_INVALID_LOCK, OGL_INVALID_UNLOCK, OGL_INVALID_TEXTURE, OGL_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ }; extern const char *OGLDeviceErrorMessages[]; #define OGL_OK 0 #define OGL_CALL(call) \ { \ int Result = call; \ if (Result != OGL_OK) \ {nuxError("OGL Object Error: Error # %d - (%s) ", Result, *OGLDeviceErrorMessages[Result] );} \ } //if(Result!=OGL_OK) {nuxError("OGL Object Error: Error # %d - %s", Result, OGLDeviceErrorMessages[Result]);} #ifndef NUX_OPENGLES_20 enum TEXTURE_FORMAT { TEXTURE_FMT_UNKNOWN = 0, TEXTURE_FMT_ALPHA = GL_ALPHA, TEXTURE_FMT_ALPHA8 = GL_ALPHA8, TEXTURE_FMT_ALPHA16 = GL_ALPHA16, TEXTURE_FMT_LUMINANCE = GL_LUMINANCE, TEXTURE_FMT_LUMINANCE8 = GL_LUMINANCE8, TEXTURE_FMT_LUMINANCE16 = GL_LUMINANCE16, TEXTURE_FMT_LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA, TEXTURE_FMT_LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8, TEXTURE_FMT_LUMINANCE16_ALPHA16 = GL_LUMINANCE16_ALPHA16, TEXTURE_FMT_INTENSITY = GL_INTENSITY, TEXTURE_FMT_INTENSITY8 = GL_INTENSITY8, TEXTURE_FMT_INTENSITY16 = GL_INTENSITY16, TEXTURE_FMT_GL_DEPTH_COMPONENT = GL_DEPTH_COMPONENT, TEXTURE_FMT_GL_DEPTH_COMPONENT24 = GL_DEPTH_COMPONENT24, TEXTURE_FMT_RGBA = GL_RGBA, TEXTURE_FMT_RGBA8 = GL_RGBA8, TEXTURE_FMT_RGBA16 = GL_RGBA16, TEXTURE_FMT_RGBA16F_ARB = GL_RGBA16F_ARB, TEXTURE_FMT_RGBA32F_ARB = GL_RGBA32F_ARB, TEXTURE_FMT_RGB = GL_RGB, TEXTURE_FMT_RGB8 = GL_RGB8, TEXTURE_FMT_RGB16 = GL_RGB16, TEXTURE_FMT_RGB16F_ARB = GL_RGB16F_ARB, TEXTURE_FMT_RGB32F_ARB = GL_RGB32F_ARB, TEXTURE_FMT_COMPRESSED_RGB_S3TC_DXT1_EXT = GL_COMPRESSED_RGB_S3TC_DXT1_EXT, TEXTURE_FMT_COMPRESSED_RGBA_S3TC_DXT1_EXT = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, TEXTURE_FMT_COMPRESSED_RGBA_S3TC_DXT3_EXT = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, TEXTURE_FMT_COMPRESSED_RGBA_S3TC_DXT5_EXT = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, TEXTURE_FMT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ }; #else enum TEXTURE_FORMAT { TEXTURE_FMT_UNKNOWN = 0, TEXTURE_FMT_ALPHA = GL_ALPHA, TEXTURE_FMT_LUMINANCE = GL_LUMINANCE, TEXTURE_FMT_LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA, TEXTURE_FMT_GL_DEPTH_COMPONENT = GL_DEPTH_COMPONENT, TEXTURE_FMT_RGBA = GL_RGBA, TEXTURE_FMT_RGB = GL_RGB, TEXTURE_FMT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ }; #endif struct PixelFormatReadInfo { const char *Name; GLenum Format; // format use for glReadPixels GLenum type; // type use for glReadPixels // Format specific internal flags, e.g. whether SRGB is supported with this format DWORD Flags; bool Supported; }; enum eCUBEMAP_FACES { CUBEMAP_FACE_POSITIVE_X = GL_TEXTURE_CUBE_MAP_POSITIVE_X, CUBEMAP_FACE_NEGATIVE_X = GL_TEXTURE_CUBE_MAP_NEGATIVE_X, CUBEMAP_FACE_POSITIVE_Y = GL_TEXTURE_CUBE_MAP_POSITIVE_Y, CUBEMAP_FACE_NEGATIVE_Y = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, CUBEMAP_FACE_POSITIVE_Z = GL_TEXTURE_CUBE_MAP_POSITIVE_Z, CUBEMAP_FACE_NEGATIVE_Z = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, CUBEMAP_FACE_FORCE_DWORD = 0x7fffffff }; enum VBO_USAGE { VBO_USAGE_UNKNOWN = 0, VBO_USAGE_STATIC = GL_STATIC_DRAW, VBO_USAGE_DYNAMIC = GL_DYNAMIC_DRAW, VBO_USAGE_STREAM = GL_STREAM_DRAW, VBO_USAGE_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ }; enum INDEX_FORMAT { INDEX_FORMAT_UNKNOWN = 0, INDEX_FORMAT_USHORT = GL_UNSIGNED_SHORT, INDEX_FORMAT_UINT = GL_UNSIGNED_INT, INDEX_FORMAT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ }; // Primitives supported by draw-primitive API typedef enum { PRIMITIVE_TYPE_POINTLIST = GL_POINTS, PRIMITIVE_TYPE_LINELIST = GL_LINES, PRIMITIVE_TYPE_LINESTRIP = GL_LINE_STRIP, PRIMITIVE_TYPE_TRIANGLELIST = GL_TRIANGLES, PRIMITIVE_TYPE_TRIANGLESTRIP = GL_TRIANGLE_STRIP, PRIMITIVE_TYPE_TRIANGLEFAN = GL_TRIANGLE_FAN, #ifndef NUX_OPENGLES_20 PRIMITIVE_TYPE_QUADLIST = GL_QUADS, PRIMITIVE_TYPE_QUADSTRIP = GL_QUAD_STRIP, #endif PRIMITIVE_TYPE_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ } PRIMITIVE_TYPE; enum OpenGLResourceType { RTINDEXBUFFER, RTVERTEXBUFFER, RTSURFACE, RTVOLUME, RTBASETEXTURE, RTTEXTURE, RTTEXTURERECTANGLE, RTCUBETEXTURE, RTVOLUMETEXTURE, RTANIMATEDTEXTURE, RTVERTEXDECLARATION, RTQUERY, RTFRAMEBUFFEROBJECT, RT_GLSL_VERTEXSHADER, RT_GLSL_PIXELSHADER, RT_GLSL_GEOMETRYSHADER, RT_GLSL_SHADERPROGRAM, RT_CG_VERTEXSHADER, RT_CG_PIXELSHADER, RT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ }; /* Multi-Sample buffer types */ typedef enum { MULTISAMPLE_TYPE_NONE = 0, MULTISAMPLE_TYPE_NONMASKABLE = 1, MULTISAMPLE_TYPE_2_SAMPLES = 2, MULTISAMPLE_TYPE_3_SAMPLES = 3, MULTISAMPLE_TYPE_4_SAMPLES = 4, MULTISAMPLE_TYPE_5_SAMPLES = 5, MULTISAMPLE_TYPE_6_SAMPLES = 6, MULTISAMPLE_TYPE_7_SAMPLES = 7, MULTISAMPLE_TYPE_8_SAMPLES = 8, MULTISAMPLE_TYPE_9_SAMPLES = 9, MULTISAMPLE_TYPE_10_SAMPLES = 10, MULTISAMPLE_TYPE_11_SAMPLES = 11, MULTISAMPLE_TYPE_12_SAMPLES = 12, MULTISAMPLE_TYPE_13_SAMPLES = 13, MULTISAMPLE_TYPE_14_SAMPLES = 14, MULTISAMPLE_TYPE_15_SAMPLES = 15, MULTISAMPLE_TYPE_16_SAMPLES = 16, MULTISAMPLE_TYPE_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ } MULTISAMPLE_TYPE; typedef enum { MEM_POOL_DEFAULT = 0, MEM_POOL_MANAGED = 1, MEM_POOL_SYSTEMMEM = 2, MEM_POOL_SCRATCH = 3, MEM_POOL_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ } MEM_POOL; typedef struct { OpenGLResourceType ResourceType; unsigned int Width; unsigned int Height; unsigned int Depth; BitmapFormat PixelFormat; unsigned int RowPitch; unsigned int SlicePitch; unsigned int BitsPerPixel; unsigned int WidthInBlocks; unsigned int HeightInBlocks; unsigned int DepthInBlocks; unsigned int BytesPerBlock; int ExpBias; DWORD Flags; MULTISAMPLE_TYPE MultiSampleType; } TEXTURE_DESC; typedef struct _SURFACE_DESC { BitmapFormat PixelFormat; OpenGLResourceType Type; DWORD Usage; MEM_POOL Pool; MULTISAMPLE_TYPE MultiSampleType; DWORD MultiSampleQuality; unsigned int Width; unsigned int Height; } SURFACE_DESC; typedef struct _VOLUME_DESC { BitmapFormat PixelFormat; OpenGLResourceType Type; DWORD Usage; MEM_POOL Pool; unsigned int Width; unsigned int Height; unsigned int Depth; } VOLUME_DESC; typedef struct _ANIMATEDTEXTURE_DESC { BitmapFormat PixelFormat; OpenGLResourceType Type; DWORD Usage; MEM_POOL Pool; unsigned int Width; unsigned int Height; unsigned int Depth; } ANIMATEDTEXTURE_DESC; typedef struct _VERTEXBUFFER_DESC { VBO_USAGE Usage; unsigned int Size; } VERTEXBUFFER_DESC; typedef struct _INDEXBUFFER_DESC { INDEX_FORMAT Format; VBO_USAGE Usage; unsigned int Size; } INDEXBUFFER_DESC; typedef struct _LOCKED_RECT { int Pitch; void *pBits; } SURFACE_LOCKED_RECT; typedef struct _SURFACE_RECT { long left; //Specifies the x-coordinate of the lower-left corner of the rectangle. long top; //Specifies the y-coordinate of the lower-left corner of the rectangle. long right; //Specifies the x-coordinate of the upper-right corner of the rectangle. long bottom; //Specifies the y-coordinate of the upper-right corner of the rectangle. } SURFACE_RECT; /* Structures for LockBox */ typedef struct _VOLUME_BOX { int Left; int Top; int Right; int Bottom; int Front; int Back; } VOLUME_BOX; typedef struct _VOLUME_LOCKED_BOX { int RowPitch; int SlicePitch; void *pBits; } VOLUME_LOCKED_BOX; typedef enum _ATTRIB_DECL_TYPE { ATTRIB_DECLTYPE_UNKNOWN = 0, ATTRIB_DECLTYPE_FLOAT1, ATTRIB_DECLTYPE_FLOAT2, ATTRIB_DECLTYPE_FLOAT3, ATTRIB_DECLTYPE_FLOAT4, ATTRIB_DECLTYPE_COLOR, ATTRIB_DECLTYPE_UBYTE4, ATTRIB_DECLTYPE_SHORT2, ATTRIB_DECLTYPE_SHORT4, ATTRIB_DECLTYPE_UBYTE4N, ATTRIB_DECLTYPE_SHORT2N, ATTRIB_DECLTYPE_SHORT4N, ATTRIB_DECLTYPE_USHORT2N, ATTRIB_DECLTYPE_USHORT4N, ATTRIB_DECLTYPE_UDEC3, ATTRIB_DECLTYPE_DEC3N, ATTRIB_DECLTYPE_FLOAT16_2, ATTRIB_DECLTYPE_FLOAT16_4, ATTRIB_DECLTYPE_UNUSED, ATTRIB_DECLTYPE_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ } ATTRIB_DECL_TYPE; typedef enum _ATTRIB_COMPONENT_TYPE { ATTRIB_CT_UNKNOWN = 0, ATTRIB_CT_BYTE = GL_BYTE, ATTRIB_CT_UNSIGNED_BYTE = GL_UNSIGNED_BYTE, ATTRIB_CT_SHORT = GL_SHORT, ATTRIB_CT_UNSIGNED_SHORT = GL_UNSIGNED_SHORT, ATTRIB_CT_INT = GL_INT, ATTRIB_CT_UNSIGNED_INT = GL_UNSIGNED_INT, ATTRIB_CT_FLOAT = GL_FLOAT, #ifndef NUX_OPENGLES_20 ATTRIB_CT_HALF_FLOAT = GL_HALF_FLOAT_ARB, // ATTRIB_CT_2_BYTES = GL_2_BYTES, // ATTRIB_CT_3_BYTES = GL_3_BYTES, // ATTRIB_CT_4_BYTES = GL_4_BYTES, ATTRIB_CT_DOUBLE = GL_DOUBLE, #endif // Type can be GL_UNSIGNED_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE ATTRIB_CT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ } ATTRIB_COMPONENT_TYPE; // Binding Semantics typedef enum { ATTRIB_USAGE_DECL_POSITION = 0, ATTRIB_USAGE_DECL_BLENDWEIGHT = 1, ATTRIB_USAGE_DECL_NORMAL = 2, ATTRIB_USAGE_DECL_COLOR = 3, ATTRIB_USAGE_DECL_COLOR1 = 4, ATTRIB_USAGE_DECL_FOGCOORD = 5, ATTRIB_USAGE_DECL_PSIZE = 6, ATTRIB_USAGE_DECL_BLENDINDICES = 7, ATTRIB_USAGE_DECL_TEXCOORD = 8, ATTRIB_USAGE_DECL_TEXCOORD0 = 8, ATTRIB_USAGE_DECL_TEXCOORD1 = 9, ATTRIB_USAGE_DECL_TEXCOORD2 = 10, ATTRIB_USAGE_DECL_TEXCOORD3 = 11, ATTRIB_USAGE_DECL_TEXCOORD4 = 12, ATTRIB_USAGE_DECL_TEXCOORD5 = 13, ATTRIB_USAGE_DECL_TEXCOORD6 = 14, ATTRIB_USAGE_DECL_TEXCOORD7 = 15, ATTRIB_USAGE_DECL_TANGENT = 14, ATTRIB_USAGE_DECL_BINORMAL = 15, ATTRIB_USAGE_DECL_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ } ATTRIB_USAGE_DECL; typedef enum { QUERY_TYPE_VCACHE = 4, QUERY_TYPE_RESOURCEMANAGER = 5, QUERY_TYPE_VERTEXSTATS = 6, QUERY_TYPE_EVENT = 8, QUERY_TYPE_OCCLUSION = 9, QUERY_TYPE_SCREENEXTENT = 10, QUERY_TYPE_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ } QUERY_TYPE; // Flags field for Issue #define ISSUE_END (1 << 0) // Tells the runtime to issue the end of a query, changing it's state to "non-signaled". #define ISSUE_BEGIN (1 << 1) // Tells the runtime to issue the beginning of a query. struct VERTEXELEMENT { VERTEXELEMENT() { Stream = 0; Offset = 0; Type = ATTRIB_CT_UNKNOWN; NumComponent = 0; stride_ = 0; } VERTEXELEMENT( int stream, int offset, ATTRIB_COMPONENT_TYPE type, BYTE numcomponents, int stride) { Stream = stream; Offset = offset; Type = type; NumComponent = numcomponents; stride_ = stride; } int Stream; intptr_t Offset; // Type can be GL_UNSIGNED_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE ... ATTRIB_COMPONENT_TYPE Type; // This can be 1, 2, 3 or 4; For a position(xyzw), it will be 4. For a texture coordinate(uv) it will be 2. int NumComponent; int stride_; }; #define DECL_END VERTEXELEMENT( \ 0xFF, \ 0, \ ATTRIB_CT_UNKNOWN, \ 0, 0) unsigned int GetVertexElementSize(VERTEXELEMENT vtxelement); #define MAXDECLLENGTH 64 #define MAX_NUM_STREAM 8 void DecomposeTypeDeclaraction(ATTRIB_DECL_TYPE Type, BYTE &NumComponent, ATTRIB_COMPONENT_TYPE &ComponentType); // void AddVertexElement(std::vector& Elements, // WORD Stream, // WORD Offset, // //ubiS16 Stride, // ATTRIB_DECL_TYPE Type, // ATTRIB_USAGE_DECL Usage, // BYTE UsageIndex); GLenum GetGLPrimitiveType(PRIMITIVE_TYPE InPrimitiveType); unsigned int GetGLElementCount(PRIMITIVE_TYPE InPrimitiveType, unsigned int InPrimitiveCount); } #endif // GLRESOURCE_H nux-4.0.6+14.04.20140409/NuxGraphics/GLTimer.h0000644000015301777760000000221212321344237020641 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLTIMER_H #define GLTIMER_H namespace nux { class GLTimer { public: GLTimer(); ~GLTimer(); void Reset(); float PassedMilliseconds(); //float PassedFrac(); protected: #if defined(NUX_OS_WINDOWS) LARGE_INTEGER now; float res; #elif defined(NUX_OS_LINUX) timeval m_last_time; #endif }; } #endif // GLTIMER_H nux-4.0.6+14.04.20140409/NuxGraphics/FontTexture.cpp0000644000015301777760000002441612321344237022172 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GraphicsEngine.h" #include "FontTexture.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(FontTexture); const int CURSOR_OFFSET = 0; FontTexture::FontTexture(const char *FontFile, NUX_FILE_LINE_DECL) : Object(true, NUX_FILE_LINE_PARAM) { std::string FontPath = GNuxGraphicsResources.FindResourceLocation(FontFile); std::filebuf fb; fb.open(FontPath.c_str(), std::ios::in); std::istream is(&fb); BMFontParseFNT(is); } FontTexture::FontTexture(int /* width */, int /* height */, BYTE * /* Texture */) { } FontTexture::~FontTexture() { std::vector::iterator it; for (it = TextureArray.begin(); it != TextureArray.end(); ++it) { (*it)->UnReference(); } TextureArray.clear(); } int FontTexture::GetCharWidth(const char &c) const { int ascii = c & 0xff; nuxAssert(ascii < m_Charset.NumChar); if (ascii >= m_Charset.NumChar) return 0; // XAdvance = abcA + abcB + abcC return m_Charset.Chars[ascii].XAdvance; } int FontTexture::GetStringWidth(const std::string &str) const { // unsigned int total = 0; // for (unsigned int i = 0; i != (unsigned int)str.size(); ++i) // { // total += GetCharWidth(str[i]); // } // return total; return GetCharStringWidth(str.c_str()); } int FontTexture::GetCharStringWidth(const char *str) const { if (str == 0 || *str == '\0') return 0; unsigned int total = 0; for (int i = 0; ; ++i) { if (str[i] == 0) return total; total += GetCharWidth(str[i]); } return total; } int FontTexture::GetStringWidth(const std::string &str, int num_char_to_compute) const { return GetCharStringWidth(str.c_str(), num_char_to_compute); } int FontTexture::GetCharStringWidth(const char *str, int num_char_to_compute) const { if (str == 0 || *str == '\0') return 0; int num_chars = num_char_to_compute; if (num_chars <= 0) { return 0; } int total = 0; for (int i = 0; i < num_chars; ++i) { if (str[i] == 0) return total; total += GetCharWidth(str[i]); } return total; } int FontTexture::GetFontHeight() { return m_Charset.FontHeight; } bool FontTexture::BMFontParseFNT( std::istream &Stream ) { std::string Line; int KerningIndex = 0; while ( !Stream.eof()) { std::getline( Stream, Line ); unsigned int line_size = (unsigned int) Line.length(); char *tc = new char[line_size+1]; const char *stream = tc; Memcpy(tc, Line.c_str(), line_size + 1); tc[line_size] = 0; if ( ParseCommand(&stream, "common") /*Read == "common"*/) { Parse_bool(tc, "Bold=", m_Charset.bold); Parse_bool(tc, "Italic=", m_Charset.italic); Parse_u16(tc, "base=", m_Charset.Base); Parse_u16(tc, "scaleW=", m_Charset.Width); Parse_u16(tc, "scaleH=", m_Charset.Height); Parse_u16(tc, "NumPages=", m_Charset.Pages); Parse_u16(tc, "FontHeight=", m_Charset.FontHeight); Parse_u16(tc, "Ascent=", m_Charset.Ascent); Parse_u16(tc, "Descent=", m_Charset.Descent); Parse_int(tc, "AvgCharWidth=", m_Charset.AvgCharWidth); Parse_int(tc, "MaxCharWidth=", m_Charset.MaxCharWidth); Parse_int(tc, "InternalLeading=", m_Charset.InternalLeading); Parse_int(tc, "ExternalLeading=", m_Charset.ExternalLeading); // Constant for now... Should be read from the font file m_Charset.NumChar = 256; } else if (ParseCommand(&stream, "char")) { unsigned short CharID = 0; Parse_u16(tc, "id=", CharID); Parse_u16(tc, "x=", m_Charset.Chars[CharID].x); Parse_u16(tc, "y=", m_Charset.Chars[CharID].y); Parse_u16(tc, "width=", m_Charset.Chars[CharID].Width); Parse_u16(tc, "height=", m_Charset.Chars[CharID].Height); Parse_s16(tc, "xoffset=", m_Charset.Chars[CharID].XOffset); Parse_s16(tc, "yoffset=", m_Charset.Chars[CharID].YOffset); Parse_s16(tc, "xadvance=", m_Charset.Chars[CharID].XAdvance); Parse_s16(tc, "abcA=", m_Charset.Chars[CharID].abcA); Parse_s16(tc, "abcB=", m_Charset.Chars[CharID].abcB); Parse_s16(tc, "abcC=", m_Charset.Chars[CharID].abcC); Parse_u16(tc, "page=", m_Charset.Chars[CharID].page); } else if ( ParseCommand(&stream, "Kerning")) { Parse_u16(tc, "count=", m_Charset.NumKerningPairs); if (m_Charset.NumKerningPairs > 0) m_Charset.Kerning = new KerningPair[m_Charset.NumKerningPairs]; } else if ( ParseCommand(&stream, "KerningPair")) { if (KerningIndex < m_Charset.NumKerningPairs) { Parse_u16(tc, "first=", m_Charset.Kerning[KerningIndex].first); Parse_u16(tc, "second=", m_Charset.Kerning[KerningIndex].second); Parse_s16(tc, "amount=", m_Charset.Kerning[KerningIndex].amount); KerningIndex++; } } else if ( ParseCommand(&stream, "Texture")) { char texture[256]; if (ParseLine(&stream, texture, 256)) { // FilePath FontPath; // FontPath.AddSearchPath(""); // for case where fully qualified path is given // FontPath.AddSearchPath("."); // FontPath.AddSearchPath("../Fonts"); std::string font_texture_file = GNuxGraphicsResources.FindResourceLocation(texture); #ifdef NUX_OPENGLES_20 Texture2D *Texture = new Texture2D(NUX_TRACKER_LOCATION); #else TextureRectangle *Texture = new TextureRectangle(NUX_TRACKER_LOCATION); #endif NBitmapData* bitmap_data = LoadImageFile(font_texture_file.c_str()); if (bitmap_data) Texture->Update(bitmap_data, false); delete bitmap_data; TextureArray.push_back(Texture); } } delete [] tc; } return true; } // CursorPosToX(similar to ScriptStringCPtoX from Microsoft UniScript) // The CursorPosToX function returns the x-coordinate for the leading or trailing edge of a character position. // Parameters // icp // [in] Character position in the string. // fTrailing // [in] Indicates the edge of the icp that corresponds to the x coordinate. If TRUE, it indicates the trailing edge. If FALSE, it indicates the leading edge. // pX // [out] Pointer to a variable that receives the corresponding x coordinate for the icp. // // Return Values // If the function succeeds, it returns S_OK. // If the function fails, it returns an HRESULT. // The return value can be tested with the SUCCEEDED and FAILED macros. bool FontTexture::CursorPosToX(const std::string &Str, int icp, bool fTrailing, int *pX) { if (icp > (int) Str.size()) return false; if (fTrailing) // get pX at the right of the character at position icp *pX = GetStringWidth(Str, icp + 1); else // get pX at the left of the character at position icp *pX = GetStringWidth(Str, icp); return true; } // XToCursorPosition(similar to ScriptStringXtoCP from Microsoft UniScript) // The XToCursorPosition function converts an x-coordinate to a character position. // // Parameters // iX // [in] Specifies the x coordinate. // FirstVisibleCharIndex, // [in] Index of the first visible character in the text box // piCh // [out] Pointer to a variable that receives the character position corresponding to iX. // piTrailing // [out] Pointer to a variable that receives an indicator whether the position is the leading or trailing edge of the character. // // Return Values // If the function is successful, it returns S_OK. // If the function fails, it returns an HRESULT. // The return value can be tested with the SUCCEEDED and FAILED macros. bool FontTexture::XToCursorPosition(const std::string &Str, int iX, unsigned int FirstVisibleCharIndex, int *piCh, int *piTrailing) { unsigned int num_chars; num_chars = (unsigned int) Str.size(); nuxAssert(FirstVisibleCharIndex < num_chars); *piCh = 0; *piTrailing = 0; unsigned int total = 0; if (iX == 0) { *piCh = 0; *piTrailing = 0; return true; } unsigned int X = iX; for (unsigned int i = 0; i < FirstVisibleCharIndex; ++i) { X += GetCharWidth(Str[i]); } for (unsigned int i = 0; i < num_chars; ++i) { unsigned int s = GetCharWidth(Str[i]); if (i >= FirstVisibleCharIndex) { if (total == X) { *piCh = i; *piTrailing = 0; return true; } else if (total + s / 2 > X) { *piCh = i; *piTrailing = 0; return true; } else if (total + GetCharWidth(Str[i+1]) / 2 > X) { *piCh = i + 1; *piTrailing = 0; return true; } } total += s; } return false; } const Charset &FontTexture::GetFontInfo() const { return m_Charset; } } nux-4.0.6+14.04.20140409/NuxGraphics/FreetypeFont.h0000644000015301777760000001201612321344237021753 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef DBM_FONTMGR #define DBM_FONTMGR #if defined WIN32 #include // Header File For Windows #include #include #include // #include // Header File For The OpenGL32 Library // #include // Header File For The GLu32 Library // #include using namespace std; #else #include #include // #include // #include // #include #endif /*#include "fmt_image.h" #include "fmt_tga.h" #include "fmt_bmp.h" #include "dbm_texturemgr.h"*/ #include #include #include #include #include FT_FREETYPE_H typedef int FontID; typedef enum _TextAlignment { eAlignTextNone = 0, eAlignTextLeft = 1, eAlignTextRight = 2, eAlignTextCenter = 3, } TextAlignment; class StringBBox { public: StringBBox() { x = 0; y = 0; width = 0; height = 0; ybearing = 0; downline = 0; }; ~StringBBox() {}; int x; int y; int width; int height; int ybearing; // max ybearing of the string int downline; // max downline of the string (max space below the baseline) }; class PageBBox { public: PageBBox() { xmin = 0; ymin = 0; xmax = 0; ymax = 0; x_margin = 0; y_margin = 0; }; ~PageBBox() {}; int xmin; int ymin; int xmax; int ymax; int x_margin; int y_margin; }; typedef struct _CharData { int hbearingX; int hbearingY; int vbearingX; int vbearingY; int vadvance; int hadvance; int gwidth; int gheight; struct { int xmin, xmax, ymin, ymax; } bbox; int bitmap_left_bearing; int bitmap_top_bearing; int bitmap_width; int bitmap_height; int glyph_index; int gltexid; int glTexWidth; int glTexHeight; } CharData; typedef struct _FontStyle { char *style_name; CharData *charmap; int num_glyph; int ascent; int descent; int texture_width; int texture_height; int line_spacing; } FontStyle; typedef struct _FontFamily { char *font_name; FT_Face m_face; //int num_glyph; list *style_list; } FontFamily; class FontMgr { private: char *current_font; char *current_style; FontMgr(); static FontMgr *pinstance; public: list *m_font_list; static FontMgr *Instance(); int nombre; ~FontMgr(); bool load_font (const char *font_name); int get_character_texture_id (const char *font_name, int encoding, CharData *cd); int get_character_texture_id (int encoding, CharData *cd); void get_style_texture_size (const char *font_name, int *width, int *height); void get_style_texture_size (int *width, int *height); void get_style_line_spacing (const char *font_name, int *line_spacing); void get_style_line_spacing (int *line_spacing); unsigned int get_null_character_texture_id (const char *font_name); unsigned int get_null_character_texture_id(); bool find_font (const char *font_name, const char *style_name); FontFamily *get_font_family (const char *font_name); FontStyle *get_font_style (char *font_name, char *style_name); void set_current_font (char *font_name, char *style_name); void draw_text (int rect_xmin, int rect_ymin, int rect_xmax, int rect_ymax, const char *text, const char *sh_name); void ComputeGlyphString (int x, int y, const char *text); //unsigned int GetStringWidth(const char* text); //unsigned int GetStringHeight(const char* text); unsigned int GetStringWidth (const std::string &text); unsigned int GetStringHeight (const std::string &text); void ComputeStringBBox (StringBBox &stringBBox, const char *text); void PositionString (const PageBBox &, StringBBox &, TextAlignment align = eAlignTextCenter); //void RenderGlyph(int targer_width, int target_height); void RenderGlyph (const PageBBox &pageSize, const char *text, TextAlignment align = eAlignTextCenter); void RenderString (const PageBBox &pageSize, const std::string &Str, TextAlignment alignment, unsigned int CursorPosition, int offset = 0); void RenderTextLineEdit (const PageBBox &pageSize, const std::string &Str, unsigned int CursorPosition, int offset = 0); void RenderTextLineStatic (const PageBBox &pageSize, const std::string &Str, TextAlignment alignment, char trailingchar = 0); }; #endif nux-4.0.6+14.04.20140409/NuxGraphics/Events.cpp0000644000015301777760000001425612321344237021150 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "Events.h" namespace nux { MouseButton GetEventButton(unsigned long button_state) { if ((button_state & NUX_EVENT_BUTTON1_DOWN) || (button_state & NUX_EVENT_BUTTON1_UP)) return NUX_MOUSE_BUTTON1; else if ((button_state & NUX_EVENT_BUTTON2_DOWN) || (button_state & NUX_EVENT_BUTTON2_UP)) return NUX_MOUSE_BUTTON2; else if ((button_state & NUX_EVENT_BUTTON3_DOWN) || (button_state & NUX_EVENT_BUTTON3_UP)) return NUX_MOUSE_BUTTON3; else if ((button_state & NUX_EVENT_BUTTON4_DOWN) || (button_state & NUX_EVENT_BUTTON4_UP)) return NUX_MOUSE_BUTTON4; return NUX_INVALID_MOUSE_BUTTON; } bool GetButtonState(unsigned long button_state, MouseButton button) { if (button == NUX_MOUSE_BUTTON1) return (button_state & NUX_STATE_BUTTON1_DOWN); else if (button == NUX_MOUSE_BUTTON2) return (button_state & NUX_STATE_BUTTON2_DOWN); else if (button == NUX_MOUSE_BUTTON3) return (button_state & NUX_STATE_BUTTON3_DOWN); else if (button == NUX_MOUSE_BUTTON4) return (button_state & NUX_STATE_BUTTON4_DOWN); return false; } bool GetKeyModifierState(unsigned long key_modifiers_states, KeyModifier key_modifier) { return((key_modifiers_states & key_modifier) != 0); } Event::Event() { Memset(text, 0, sizeof(text)); dtext = nullptr; for (int i = 0; i < NUX_MAX_VK; i++) { VirtualKeycodeState[i] = 0; } ascii_code = 0; virtual_code = 0; key_modifiers = 0; key_repeat_count = 0; mouse_state = 0; x = -1; y = -1; x_root = 0; y_root = 0; dx = 0; dy = 0; clicks = 0; is_click = 0; wheel_delta = 0; #if defined(NUX_OS_WINDOWS) win32_keycode = 0; win32_keysym = 0; #endif #if defined(USE_X11) x11_keycode = 0; x11_keysym = 0; x11_timestamp = 0; x11_window = 0; x11_key_state = 0; #endif //Application = 0; } void Event::Reset() { type = NUX_NO_EVENT; Memset(text, 0, sizeof(text)); #if defined(NUX_OS_WINDOWS) win32_keycode = 0; win32_keysym = 0; #endif #if defined(USE_X11) x11_keycode = 0; x11_keysym = 0; x11_key_state = 0; #endif delete[] dtext; dtext = nullptr; key_repeat_count = 0; key_modifiers = 0; wheel_delta = 0; } int Event::GetX() const { return x; } int Event::GetY() const { return y; } int Event::GetRootX() const { return x_root; } int Event::GetRootY() const { return y_root; } int Event::GetDeltaX() const { return dx; } int Event::GetDeltaY() const { return dy; } unsigned long Event::GetKeyState() const { return key_modifiers; } unsigned long Event::GetMouseState() const { return mouse_state; } MouseButton Event::GetEventButton() const { if ((mouse_state & NUX_EVENT_BUTTON1_DOWN) || (mouse_state & NUX_EVENT_BUTTON1_UP)) return NUX_MOUSE_BUTTON1; else if ((mouse_state & NUX_EVENT_BUTTON2_DOWN) || (mouse_state & NUX_EVENT_BUTTON2_UP)) return NUX_MOUSE_BUTTON2; else if ((mouse_state & NUX_EVENT_BUTTON3_DOWN) || (mouse_state & NUX_EVENT_BUTTON3_UP)) return NUX_MOUSE_BUTTON3; else if ((mouse_state & NUX_EVENT_BUTTON4_DOWN) || (mouse_state & NUX_EVENT_BUTTON4_UP)) return NUX_MOUSE_BUTTON4; return NUX_INVALID_MOUSE_BUTTON; } bool Event::GetButtonState(MouseButton button) const { if (button == 1) return (mouse_state & NUX_STATE_BUTTON1_DOWN); else if (button == 2) return (mouse_state & NUX_STATE_BUTTON2_DOWN); else if (button == 3) return (mouse_state & NUX_STATE_BUTTON3_DOWN); else if (button == 4) return (mouse_state & NUX_STATE_BUTTON4_DOWN); return false; } bool Event::GetKeyModifierState(KeyModifier key_modifier) const { return((key_modifiers & key_modifier) != 0); } //! Return virtual key code of the key that has triggered the last event. /*! Return virtual key code of the key that has triggered the last event. @return the virtual key code. */ unsigned long Event::GetKeySym() const { #if defined(NUX_OS_WINDOWS) return win32_keysym; #elif defined(USE_X11) return x11_keysym; #else return 0; #endif } unsigned short Event::GetKeyRepeatCount() const { return key_repeat_count; } const char* Event::GetText() const { return dtext; } //! Return the state of the Virtual key /*! Return the state of the Virtual key. @param VirtualKey virtual key code. @return 1 if the key is pressed, 0 if the key is released. */ unsigned long Event::GetVirtualKeyState(unsigned long VirtualKey) const { if (VirtualKey >= NUX_MAX_VK) return 0; if (VirtualKey <= 0) return 0; return VirtualKeycodeState[VirtualKey]; } bool Event::IsShiftDown() const { return (key_modifiers & NUX_STATE_SHIFT); } bool Event::IsControlDown() const { return (key_modifiers & NUX_STATE_CTRL); } bool Event::IsCapsLockDown() const { return (key_modifiers & NUX_STATE_CAPS_LOCK); } bool Event::IsAltDown() const { return (key_modifiers & NUX_STATE_ALT); } bool Event::IsNumLockDown() const { return (key_modifiers & NUX_STATE_NUMLOCK); } bool Event::IsScrollLockDown() const { return (key_modifiers & NUX_STATE_SCROLLLOCK); } bool Event::IsSuperKeyDown() const { return (key_modifiers & NUX_STATE_SCROLLLOCK); } } nux-4.0.6+14.04.20140409/NuxGraphics/MeshFileLoader-OBJ.cpp0000644000015301777760000001063712321344237023136 0ustar pbusernogroup00000000000000 #include "GLResource.h" #include "MeshFileLoader-OBJ.h" #include "MeshData.h" #include "NuxCore/Math/Vector3.h" #include "NuxCore/Math/Vector2.h" namespace nux { #define TOKEN_VERTEX_POS "v" #define TOKEN_VERTEX_NOR "vn" #define TOKEN_VERTEX_TEX "vt" #define TOKEN_FACE "f" struct ObjMeshVertex { nux::Vector3 pos; nux::Vector2 texcoord; nux::Vector3 normal; }; /* This is a triangle, that we can render */ struct ObjMeshFace { ObjMeshVertex vertices[3]; }; /* This contains a list of triangles */ struct ObjMesh { std::vector faces; }; /* Internal structure */ struct _ObjMeshFaceIndex { int pos_index[3]; int tex_index[3]; int nor_index[3]; }; MeshData* LoadMeshFile_OBJ(const char* filename) { std::vector positions; std::vector texcoords; std::vector normals; std::vector<_ObjMeshFaceIndex> faces; /** * Load file, parse it * Lines beginning with: * '#' are comments can be ignored * 'v' are vertices positions(3 floats that can be positive or negative) * 'vt' are vertices texcoords(2 floats that can be positive or negative) * 'vn' are vertices normals (3 floats that can be positive or negative) * 'f' are faces, 3 values that contain 3 values which are separated by / and */ std::ifstream filestream; filestream.open(filename); std::string line_stream; // No longer depending on char arrays thanks to: Dale Weiler while (std::getline(filestream, line_stream)) { std::stringstream str_stream(line_stream); std::string type_str; str_stream >> type_str; if (type_str == TOKEN_VERTEX_POS) { nux::Vector4 pos; str_stream >> pos.x >> pos.y >> pos.z; pos.w = 1.0f; positions.push_back(pos); } else if (type_str == TOKEN_VERTEX_TEX) { nux::Vector2 tex; str_stream >> tex.x >> tex.y; texcoords.push_back(tex); } else if (type_str == TOKEN_VERTEX_NOR) { nux::Vector3 nor; str_stream >> nor.x >> nor.y >> nor.z; normals.push_back(nor); } else if (type_str == TOKEN_FACE) { _ObjMeshFaceIndex face_index; char interupt; for (int i = 0; i < 3; ++i) { str_stream >> face_index.pos_index[i] >> interupt >> face_index.tex_index[i] >> interupt >> face_index.nor_index[i]; } faces.push_back(face_index); } } // Explicit closing of the file filestream.close(); nux::MeshData* md = new nux::MeshData; md->Allocate(faces.size(), nux::NUX_MESH_TRIANGLE, 3*faces.size(), 16 + 12 + 8); //md->_mesh_primitive_type = nux::NuxMeshPrimitiveType::NUX_MESH_TRIANGLE; size_t i = 0; float* vertex_buffer = (float*)md->_vertex_data; // for (i = 0; i < positions.size(); i++) // { // vertex_buffer[9*i + 0] = positions[i].x; // vertex_buffer[9*i + 1] = positions[i].y; // vertex_buffer[9*i + 2] = positions[i].z; // vertex_buffer[9*i + 3] = positions[i].w; // // vertex_buffer[9*i + 4] = normals[i].x; // vertex_buffer[9*i + 5] = normals[i].y; // vertex_buffer[9*i + 6] = normals[i].z; // // vertex_buffer[9*i + 7] = texcoords[i].x; // vertex_buffer[9*i + 8] = texcoords[i].y; // } int* index_buffer = (int*)md->_index_data; for (i = 0; i < faces.size(); i++) { index_buffer[3*i + 0] = 3*i + 0; //faces[i].pos_index[0]-1; index_buffer[3*i + 1] = 3*i + 1; //faces[i].pos_index[1]-1; index_buffer[3*i + 2] = 3*i + 2; //faces[i].pos_index[2]-1; for (int j = 0; j < 3; j++) { int vi = faces[i].pos_index[j]-1; int ni = faces[i].nor_index[j]-1; int ti = faces[i].tex_index[j]-1; vertex_buffer[27*i + 9*j + 0] = positions[vi].x; vertex_buffer[27*i + 9*j + 1] = positions[vi].y; vertex_buffer[27*i + 9*j + 2] = positions[vi].z; vertex_buffer[27*i + 9*j + 3] = positions[vi].w; vertex_buffer[27*i + 9*j + 4] = normals[ni].x; vertex_buffer[27*i + 9*j + 5] = normals[ni].y; vertex_buffer[27*i + 9*j + 6] = normals[ni].z; vertex_buffer[27*i + 9*j + 7] = texcoords[ti].x; vertex_buffer[27*i + 9*j + 8] = texcoords[ti].y; } } return md; } } nux-4.0.6+14.04.20140409/NuxGraphics/GLError.cpp0000644000015301777760000000556412321344237021222 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "FontTexture.h" #include "GLError.h" #include "NuxCore/Logger.h" namespace nux { DECLARE_LOGGER(logger, "nux.gl"); namespace { #ifdef NUX_DEBUG bool BreakOnGLErrors = false; #endif bool debug_glerror_stack() { // If the extra log environment variable is set the stack trace for failing // GLError checks will also get a backtrace. static bool extra_debugging(::getenv("NUX_DEBUG_GLERROR_STACK")); return extra_debugging; } } // WARNING: never call glGetError between glBegin and glEnd. void CheckGLError(const char * /* GLcall */, const char *file, int line) { GLenum glErr; std::string error_msg; while ((glErr = glGetError()) != GL_NO_ERROR) { switch(glErr) { case GL_INVALID_ENUM: error_msg += "[CheckGLError] GL_INVALID_ENUM"; break; case GL_INVALID_VALUE: error_msg += "[CheckGLError] GL_INVALID_VALUE"; break; case GL_INVALID_OPERATION: error_msg += "[CheckGLError] GL_INVALID_OPERATION"; break; #ifndef NUX_OPENGLES_20 case GL_STACK_OVERFLOW: error_msg += "[CheckGLError] GL_STACK_OVERFLOW"; break; case GL_STACK_UNDERFLOW: error_msg += "[CheckGLError] GL_STACK_UNDERFLOW"; break; #endif case GL_OUT_OF_MEMORY: error_msg += "[CheckGLError] GL_OUT_OF_MEMORY"; break; default: error_msg += "[CheckGLError] UNKNOWN ERROR, "; } if (Unwrap(logger).IsWarningEnabled() && !error_msg.empty()) { std::string stacktrace; #if defined(NUX_OS_LINUX) if (debug_glerror_stack()) stacktrace = "\n" + logging::Backtrace(); #endif logging::LogStream(logging::Warning, Unwrap(logger).module(), file, line).stream() #ifndef NUX_OPENGLES_20 << "[CheckGLError] OpenGL Error " << glErr << " (" << gluErrorString(glErr) << ")" #else << error_msg #endif << stacktrace; } #ifdef NUX_DEBUG // break on errors if asked to if (BreakOnGLErrors) inlDebugBreak(); #endif } } } nux-4.0.6+14.04.20140409/NuxGraphics/GdkGraphics.cpp0000644000015301777760000000537512321344237022074 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "ImageSurface.h" #include "GdkGraphics.h" #include "NuxCore/Logger.h" namespace nux { DECLARE_LOGGER(logger, "nux.image"); GdkGraphics::GdkGraphics() : pixbuf_(0) { } GdkGraphics::GdkGraphics(GdkPixbuf* pixbuf) : pixbuf_(pixbuf) { } GdkGraphics::GdkGraphics(const char* filename) : pixbuf_(0) { LoadImage(filename); } GdkGraphics::~GdkGraphics() { if (pixbuf_) g_object_unref(pixbuf_); } bool GdkGraphics::LoadImage(const char* filename) { if (pixbuf_) g_object_unref(pixbuf_); GError* error = 0; pixbuf_ = gdk_pixbuf_new_from_file(filename, &error); if (error) { LOG_ERROR(logger) << error->message; g_error_free(error); return false; } return true; } NBitmapData* GdkGraphics::GetBitmap() const { if (!pixbuf_) { LOG_WARN(logger) << "No pixbuf loaded"; return 0; } unsigned int width = gdk_pixbuf_get_width(pixbuf_); unsigned int height = gdk_pixbuf_get_height(pixbuf_); int channels = gdk_pixbuf_get_n_channels(pixbuf_); int src_pitch = gdk_pixbuf_get_rowstride(pixbuf_); NTextureData* texture = NULL; if (channels == 4) { texture = new NTextureData(BITFMT_R8G8B8A8, width, height, 1); } else if (channels == 3) { texture = new NTextureData(BITFMT_R8G8B8, width, height, 1); } else if (channels == 1) { texture = new NTextureData(BITFMT_A8, width, height, 1); } else { LOG_ERROR(logger) << __func__ << ": Invalid number of channels"; return 0; } ImageSurface& image_surface = texture->GetSurface(0); unsigned char* dest = image_surface.GetPtrRawData(); int dest_pitch = image_surface.GetPitch(); guchar* src = gdk_pixbuf_get_pixels(pixbuf_); for (unsigned int i = 0; i < height; ++i) { Memcpy(dest, src + i*src_pitch, width*channels); dest += dest_pitch; } return texture; } } nux-4.0.6+14.04.20140409/NuxGraphics/GLSh_Fill.h0000644000015301777760000000315112321344237021104 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef GLSH_FILL_H #define GLSH_FILL_H #include "IOpenGLGLSLShader.h" #include "GLShaderParameter.h" #include "GLDeviceObjects.h" namespace nux { class TemplateQuadBuffer; class GLSh_Fill { public: GLShaderParameter *Color; GLShaderParameter *ViewProjectionMatrix; GLShaderParameter *Scale; GLShaderParameter *Offset; GLSh_Fill(); ~GLSh_Fill(); void CacheShader(); void SetColor(FLOAT R, FLOAT G, FLOAT B, FLOAT A); void Render(INT x, INT y, INT z, INT width, INT height); void SetTransformMatrix(const Matrix4 &TransformMatrix); private: FLOAT _R, _G, _B, _A; ObjectPtr vs; ObjectPtr ps; ObjectPtr sprog; Matrix4 m_TransformMatrix; TemplateQuadBuffer *m_QuadBuffer; }; } #endif // GLSH_FILL_H nux-4.0.6+14.04.20140409/NuxGraphics/GLDeviceFrameBufferObject.cpp0000644000015301777760000003010712321344237024553 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "GLResource.h" #include "GpuDevice.h" #include "GLDeviceObjects.h" #include "GLResourceManager.h" #include "GLTextureResourceManager.h" #include "GLVertexResourceManager.h" #include "GLDeviceFrameBufferObject.h" #include "GLTemplatePrimitiveBuffer.h" #include "GraphicsEngine.h" namespace nux { GLenum AttachmentBuffer[] = { GL_COLOR_ATTACHMENT0_EXT #ifndef NUX_OPENGLES_20 // GLES 2.0 only supports one color attachment , GL_COLOR_ATTACHMENT1_EXT , GL_COLOR_ATTACHMENT2_EXT , GL_COLOR_ATTACHMENT3_EXT #endif }; ////////////////////////////////////////////////////////////////////////// // GLFramebufferObject ////////////////////////////////////////////////////////////////////////// GLFramebufferObject::GLFramebufferObject() : m_fboId(0) , m_savedFboId(0) { m_fboId = _GenerateFboId(); // Bind this FBO so that it actually gets created now _GuardedBind(); _GuardedUnbind(); } GLFramebufferObject::~GLFramebufferObject() { CHECKGL(glDeleteFramebuffersEXT(1, (const GLuint *) &m_fboId)); } void GLFramebufferObject::Bind() { #ifdef NUX_OPENGLES_20 GLenum binding = GL_FRAMEBUFFER; #else GLenum binding = GL_DRAW_FRAMEBUFFER_EXT; #endif CHECKGL(glBindFramebufferEXT(binding, m_fboId)); } void GLFramebufferObject::Disable() { #ifdef NUX_OPENGLES_20 GLenum binding = GL_FRAMEBUFFER; #else GLenum binding = GL_DRAW_FRAMEBUFFER_EXT; #endif CHECKGL(glBindFramebufferEXT(binding, 0)); } void GLFramebufferObject::AttachTexture( GLenum attachment, GLenum texType, GLuint texId, int mipLevel, int zSlice) { _GuardedBind(); if ( GetAttachedId(attachment) != texId ) { _FramebufferTextureND( attachment, texType, texId, mipLevel, zSlice ); } else { // nuxError("GLFramebufferObject::AttachTexture PERFORMANCE WARNING:\n // \tRedundant bind of texture(id = %d).\n"), texId); } _GuardedUnbind(); } void GLFramebufferObject::AttachTextures( int numTextures, GLenum texTarget[], GLuint texId[], GLenum attachment[], int mipLevel[], int zSlice[] ) { for (int i = 0; i < numTextures; ++i) { AttachTexture( texTarget[i], texId[i], attachment ? attachment[i] : (GL_COLOR_ATTACHMENT0_EXT + i), mipLevel ? mipLevel[i] : 0, zSlice ? zSlice[i] : 0 ); } } void GLFramebufferObject::AttachRenderBuffer( GLenum attachment, GLuint buffId ) { _GuardedBind(); if ( GetAttachedId(attachment) != buffId ) { CHECKGL(glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, buffId)); } else { // nuxError(TEXT("GLFramebufferObject::AttachRenderBuffer PERFORMANCE WARNING:\n // \tRedundant bind of GLRenderbuffer(id = %d).\n"), buffId); } _GuardedUnbind(); } void GLFramebufferObject::Unattach( GLenum attachment ) { _GuardedBind(); GLenum type = GetAttachedType(attachment); switch(type) { case GL_NONE: break; case GL_RENDERBUFFER_EXT: AttachRenderBuffer( attachment, 0 ); break; case GL_TEXTURE: AttachTexture( attachment, GL_TEXTURE_2D, 0 ); break; default: std::cout << "GLFramebufferObject::unbind_attachment ERROR: Unknown attached resource type\n"; } _GuardedUnbind(); } GLint GLFramebufferObject::GetMaxColorAttachments() { #ifndef NUX_OPENGLES_20 GLint maxAttach = 0; CHECKGL(glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &maxAttach )); return maxAttach; #else return 1; #endif } GLuint GLFramebufferObject::_GenerateFboId() { GLuint id = 0; CHECKGL(glGenFramebuffersEXT(1, &id)); return id; } void GLFramebufferObject::_GuardedBind() { #ifndef NUX_OPENGLES_20 // Only binds if m_fboId is different than the currently bound FBO CHECKGL(glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING_EXT, &m_savedFboId )); if (m_fboId != m_savedFboId) { CHECKGL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fboId)); } #else // Only binds if m_fboId is different than the currently bound FBO CHECKGL(glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &m_savedFboId )); if (m_fboId != m_savedFboId) { CHECKGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId)); } #endif } void GLFramebufferObject::_GuardedUnbind() { #ifdef NUX_OPENGLES_20 GLenum binding = GL_FRAMEBUFFER; #else GLenum binding = GL_DRAW_FRAMEBUFFER_EXT; #endif // Returns FBO binding to the previously enabled FBO if (m_savedFboId != m_fboId) { CHECKGL(glBindFramebufferEXT(binding, (GLuint) m_savedFboId)); } } void GLFramebufferObject::_FramebufferTextureND( GLenum attachment, GLenum texType, GLuint texId, int mipLevel, int zSlice ) { if (texType == GL_TEXTURE_2D) { // Default is GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, or cube faces CHECKGL(glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment, texType, texId, mipLevel )); } #ifndef NUX_OPENGLES_20 else if (texType == GL_TEXTURE_1D) { CHECKGL(glFramebufferTexture1DEXT( GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_1D, texId, mipLevel )); } else if (texType == GL_TEXTURE_3D) { CHECKGL(glFramebufferTexture3DEXT( GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_3D, texId, mipLevel, zSlice )); } #endif } bool GLFramebufferObject::IsValid() { _GuardedBind(); bool isOK = false; GLenum status; status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); CHECKGL_MSG(glCheckFramebufferStatusEXT); switch(status) { case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK isOK = true; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT"); isOK = false; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT"); isOK = false; break; // See issue(87) of http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt // case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: // nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT"); // isOK = false; // break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT"); isOK = false; break; #ifndef NUX_OPENGLES_20 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT"); isOK = false; break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT"); isOK = false; break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT"); isOK = false; break; #endif // case GL_FRAMEBUFFER_STATUS_ERROR_EXT: // nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_STATUS_ERROR_EXT"); // isOK = false; // break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: nuxError("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_UNSUPPORTED_EXT"); isOK = false; break; default: nuxError("[GLFramebufferObject::IsValid] Unknown ERROR"); isOK = false; } _GuardedUnbind(); return isOK; } /// Accessors GLenum GLFramebufferObject::GetAttachedType( GLenum attachment ) { // Returns GL_RENDERBUFFER_EXT or GL_TEXTURE _GuardedBind(); GLint type = 0; CHECKGL(glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT, &type)); _GuardedUnbind(); return GLenum(type); } GLuint GLFramebufferObject::GetAttachedId( GLenum attachment ) { _GuardedBind(); GLint id = 0; CHECKGL(glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &id)); _GuardedUnbind(); return GLuint(id); } GLint GLFramebufferObject::GetAttachedMipLevel( GLenum attachment ) { _GuardedBind(); GLint level = 0; CHECKGL(glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &level)); _GuardedUnbind(); return level; } GLint GLFramebufferObject::GetAttachedCubeFace( GLenum attachment ) { _GuardedBind(); GLint level = 0; #ifndef NUX_OPENGLES_20 CHECKGL(glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT, &level)); #endif _GuardedUnbind(); return level; } GLint GLFramebufferObject::GetAttachedZSlice( GLenum attachment ) { _GuardedBind(); GLint slice = 0; #ifndef NUX_OPENGLES_20 CHECKGL(glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT, &slice)); #endif _GuardedUnbind(); return slice; } ////////////////////////////////////////////////////////////////////////// // GLRenderbuffer ////////////////////////////////////////////////////////////////////////// GLRenderbuffer::GLRenderbuffer() : m_bufId(0) { m_bufId = _CreateBufferId(); } GLRenderbuffer::GLRenderbuffer(GLenum internalFormat, int width, int height) : m_bufId(_CreateBufferId()) { Set(internalFormat, width, height); } GLRenderbuffer::~GLRenderbuffer() { CHECKGL(glDeleteRenderbuffersEXT(1, &m_bufId)); } void GLRenderbuffer::Bind() { CHECKGL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_bufId)); } void GLRenderbuffer::Unbind() { CHECKGL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0)); } void GLRenderbuffer::Set(GLenum internalFormat, int width, int height) { int maxSize = GLRenderbuffer::GetMaxSize(); if (width > maxSize || height > maxSize ) { std::cout << "GLRenderbuffer::GLRenderbuffer() ERROR: Size too big width=" << width << "height=" << height << "\n"; return; } // Guarded bind GLint savedId = 0; CHECKGL(glGetIntegerv( GL_RENDERBUFFER_BINDING_EXT, &savedId )); if (savedId != (GLint) m_bufId) { Bind(); } // Allocate memory for renderBuffer CHECKGL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalFormat, width, height )); // Guarded unbind if (savedId != (GLint) m_bufId) { Unbind(); } } GLuint GLRenderbuffer::GetId() const { return m_bufId; } GLint GLRenderbuffer::GetMaxSize() { GLint maxAttach = 0; CHECKGL(glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE_EXT, &maxAttach )); return maxAttach; } GLuint GLRenderbuffer::_CreateBufferId() { GLuint id = 0; CHECKGL(glGenRenderbuffersEXT(1, &id)); return id; } } nux-4.0.6+14.04.20140409/NuxGraphics/IOpenGLBaseTexture.cpp0000644000015301777760000003533012321344237023311 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore/NuxCore.h" #include "GLResource.h" #include "IOpenGLResource.h" #include "GLShaderParameter.h" #include "GLTextureStates.h" #include "IOpenGLBaseTexture.h" #include "IOpenGLSurface.h" namespace nux { NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLBaseTexture); IOpenGLBaseTexture::IOpenGLBaseTexture(OpenGLResourceType ResourceType, unsigned int Width, unsigned int Height, unsigned int Depth, unsigned int NumMipLevel, BitmapFormat PixelFormat, NUX_FILE_LINE_DECL) : IOpenGLResource(ResourceType, NUX_FILE_LINE_PARAM) , _IsPOT(false) , _NumMipLevel(NumMipLevel) , _PixelFormat(PixelFormat) , _Width(Width) , _Height(Height) , _Depth(Depth) , _RowMemoryAlignment(1) { // if ((GPixelFormats[PixelFormat].BlockBytes == 1) || // (GPixelFormats[PixelFormat].BlockBytes == 2) || // (GPixelFormats[PixelFormat].BlockBytes == 3)) // _RowMemoryAlignment = 1; // else // _RowMemoryAlignment = 4; if (_ResourceType == RTTEXTURE) _TextureStates.SetType(GL_TEXTURE_2D); #ifndef NUX_OPENGLES_20 if (_ResourceType == RTTEXTURERECTANGLE) _TextureStates.SetType(GL_TEXTURE_RECTANGLE_ARB); if (_ResourceType == RTCUBETEXTURE) _TextureStates.SetType(GL_TEXTURE_CUBE_MAP_ARB); if (_ResourceType == RTVOLUMETEXTURE) _TextureStates.SetType(GL_TEXTURE_3D); if (_ResourceType == RTANIMATEDTEXTURE) _TextureStates.SetType(GL_TEXTURE_RECTANGLE_ARB); #endif _RowMemoryAlignment = ImageSurface::GetMemAlignment(PixelFormat); if (IsPowerOf2(Width) && IsPowerOf2(Height)) { _IsPOT = true; } } IOpenGLBaseTexture::~IOpenGLBaseTexture() { } void IOpenGLBaseTexture::SetRenderStates() { if (_ResourceType == RTTEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_2D, _OpenGLID)); } #ifndef NUX_OPENGLES_20 else if (_ResourceType == RTTEXTURERECTANGLE) { CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _OpenGLID)); } else if (_ResourceType == RTCUBETEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_CUBE_MAP, _OpenGLID)); } else if (_ResourceType == RTVOLUMETEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_3D, _OpenGLID)); } else if (_ResourceType == RTANIMATEDTEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _OpenGLID)); } #endif else { nuxError("[IOpenGLBaseTexture::SetRenderStates] Incorrect texture resource type."); } _TextureStates.SetRenderStates(); } void IOpenGLBaseTexture::SetFiltering(unsigned int MinFilter, unsigned int MagFilter/*, unsigned int MIP = GL_NEAREST*/) { _TextureStates.SetFiltering(MinFilter, MagFilter); } void IOpenGLBaseTexture::SetWrap(unsigned int U, unsigned int V, unsigned int W) { _TextureStates.SetWrap(U, V, W); } void IOpenGLBaseTexture::SetLOD(float MinLod, float MaxLod) { _TextureStates.SetLOD(MinLod, MaxLod); } void IOpenGLBaseTexture::SetMipLevel(unsigned int MinMip, unsigned int MaxMip) { _TextureStates.SetMipLevel(MinMip, MaxMip); } void IOpenGLBaseTexture::SetBorderColor(float R, float G, float B, float A) { _TextureStates.SetBorderColor(R, G, B, A); } int IOpenGLBaseTexture::BindTexture() { if (_OpenGLID == 0) { CHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); } else if (_ResourceType == RTTEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_2D, _OpenGLID)); } #ifndef NUX_OPENGLES_20 else if (_ResourceType == RTTEXTURERECTANGLE) { CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _OpenGLID)); } else if (_ResourceType == RTCUBETEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_CUBE_MAP, _OpenGLID)); } else if (_ResourceType == RTVOLUMETEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_3D, _OpenGLID)); } else if (_ResourceType == RTANIMATEDTEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _OpenGLID)); } #endif else { nuxError("[GpuDevice::BindTexture] Unknown texture type."); return OGL_INVALID_TEXTURE; } _TextureStates.SetRenderStates(); return OGL_OK; } int IOpenGLBaseTexture::BindTextureToUnit(int TextureUnitIndex) { CHECKGL(glActiveTextureARB(TextureUnitIndex)); CHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); #ifndef NUX_OPENGLES_20 CHECKGL(glBindTexture(GL_TEXTURE_3D, 0)); CHECKGL(glBindTexture(GL_TEXTURE_CUBE_MAP, 0)); CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0)); CHECKGL(glDisable(GL_TEXTURE_2D)); CHECKGL(glDisable(GL_TEXTURE_3D)); CHECKGL(glDisable(GL_TEXTURE_RECTANGLE_ARB)); CHECKGL(glDisable(GL_TEXTURE_CUBE_MAP)); #endif if (_ResourceType == RTTEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_2D, _OpenGLID)); #ifndef NUX_OPENGLES_20 CHECKGL(glEnable(GL_TEXTURE_2D)); #endif } #ifndef NUX_OPENGLES_20 else if (_ResourceType == RTTEXTURERECTANGLE) { CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _OpenGLID)); CHECKGL(glEnable(GL_TEXTURE_RECTANGLE_ARB)); } else if (_ResourceType == RTCUBETEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_CUBE_MAP, _OpenGLID)); CHECKGL(glEnable(GL_TEXTURE_CUBE_MAP)); } else if (_ResourceType == RTVOLUMETEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_3D, _OpenGLID)); CHECKGL(glEnable(GL_TEXTURE_3D)); } else if (_ResourceType == RTANIMATEDTEXTURE) { CHECKGL(glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _OpenGLID)); CHECKGL(glEnable(GL_TEXTURE_RECTANGLE_ARB)); } #endif else { nuxError("[IOpenGLBaseTexture::BindTexture] unknown texture type."); return OGL_ERROR; } _TextureStates.SetRenderStates(); return OGL_OK; } void IOpenGLBaseTexture::GetSurfaceLevel(int /* Level */, ObjectPtr& /* surface */) { } ObjectPtr IOpenGLBaseTexture::GetSurfaceLevel(int /* Level */) { return ObjectPtr (0); } int IOpenGLBaseTexture::LockRect(int /* Level */, SURFACE_LOCKED_RECT * /* pLockedRect */, const SURFACE_RECT * /* pRect */) { return 0; } int IOpenGLBaseTexture::UnlockRect(int /* Level */) { return 0; } unsigned char* IOpenGLBaseTexture::GetSurfaceData(int /* level */, int &width, int &height, int &stride) { // Make this call a pure virtual once it has been implemented for IOpenGLCubeTexture, // IOpenGLVolumeTexture and IOpenGLAnimatedTexture. width = 0; height = 0; stride = 0; return 0; } void IOpenGLBaseTexture::Save(const char* filename) { GLuint tex_id = GetOpenGLID(); glBindTexture(GL_TEXTURE_2D, tex_id); int width, height; #ifndef NUX_OPENGLES_20 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); #else width = GetWidth(); height = GetHeight(); #endif if(!width || !height) return; uint32_t* pixels = new uint32_t[width * height]; uint32_t* tmp = pixels; #ifndef NUX_OPENGLES_20 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); #else GLuint fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fbo); #endif FILE* fp; if(!(fp = fopen(filename, "wb"))) { fprintf(stderr, "Cannot open file: %s\n", filename); return; } fprintf(fp, "P6\n%d %d\n255\n", width, height); int sz = width * height; for(int i=0; i> 16) & 0xff; int g = (pix >> 8) & 0xff; int b = pix & 0xff; fputc(r, fp); fputc(g, fp); fputc(b, fp); } fclose(fp); delete [] pixels; } int GetTextureSize(IOpenGLBaseTexture *pTexture) { GLint unpack_alignment = GPixelFormats[pTexture->_PixelFormat].RowMemoryAlignment; unsigned int halfUnpack = Log2(unpack_alignment); unsigned int TextureSize = 0; if ( pTexture->_PixelFormat == BITFMT_DXT1 || pTexture->_PixelFormat == BITFMT_DXT2 || pTexture->_PixelFormat == BITFMT_DXT3 || pTexture->_PixelFormat == BITFMT_DXT4 || pTexture->_PixelFormat == BITFMT_DXT5) { for (int Level = 0; Level < pTexture->GetNumMipLevel(); Level++) { unsigned int Width = Max (1, pTexture->_Width >> Level); unsigned int Height = Max (1, pTexture->_Height >> Level); unsigned int WidthInBlocks = Max ((Width + 3) / 4, 1); // round the width to the upper multiple of 4. DXT blocks are 4x4 texels. unsigned int HeightInBlocks = Max ((Height + 3) / 4, 1); // round the height to the upper multiple of 4. DXT blocks are 4x4 texels. if (pTexture->_PixelFormat == BITFMT_DXT1) { TextureSize += WidthInBlocks * HeightInBlocks * 8;; } else { TextureSize += WidthInBlocks * HeightInBlocks * 16; } } } else { for (int Level = 0; Level < pTexture->GetNumMipLevel(); Level++) { unsigned int Width = Max (1, pTexture->_Width >> Level); unsigned int Height = Max (1, pTexture->_Height >> Level); unsigned int BytePerPixel = GPixelFormats[pTexture->_PixelFormat].BlockBytes; unsigned int SlicePitch = (((Width * BytePerPixel + (unpack_alignment - 1)) >> (halfUnpack)) << (halfUnpack)) * Height; TextureSize += SlicePitch; } } if (pTexture->GetResourceType() == RTANIMATEDTEXTURE) { return TextureSize * pTexture->GetDepth(); } return TextureSize; } void GetTextureDesc(IOpenGLBaseTexture *pTexture, unsigned int Level, TEXTURE_DESC *pDesc) { GLint unpack_alignment = GPixelFormats[pTexture->_PixelFormat].RowMemoryAlignment; unsigned int halfUnpack = Log2(unpack_alignment); pDesc->PixelFormat = pTexture->_PixelFormat; if ( /*pTexture->_Format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||*/ pTexture->_PixelFormat == BITFMT_DXT1 || pTexture->_PixelFormat == BITFMT_DXT2 || pTexture->_PixelFormat == BITFMT_DXT3 || pTexture->_PixelFormat == BITFMT_DXT4 || pTexture->_PixelFormat == BITFMT_DXT5) { pDesc->Width = Max (1, pTexture->_Width >> Level); pDesc->Height = Max (1, pTexture->_Height >> Level); pDesc->WidthInBlocks = Max ((pDesc->Width + 3) / 4, 1); // round the width to the upper multiple of 4. DXT blocks are 4x4 texels. pDesc->HeightInBlocks = Max ((pDesc->Height + 3) / 4, 1); // round the height to the upper multiple of 4. DXT blocks are 4x4 texels. if ( /*pTexture->_Format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||*/ pTexture->_PixelFormat == BITFMT_DXT1) { // We can conceive a 4x4 DXT1 block as if each texel uses 4 bits. // Actually, for DXT, we have 2 16-bits colors(5:6:5), and each texel uses 2 bits to interpolate // between the 2 colors. // --------------------- // | COLOR0 | 16 bits // --------------------- // | COLOR1 | 16 bits // --------------------- // | xx | xx | xx | xx | xx = 2 bits // --------------------- // | xx | xx | xx | xx | // --------------------- // | xx | xx | xx | xx | // --------------------- // | xx | xx | xx | xx | // --------------------- // A line of n texel DXT1 data uses n/2 bytes(4 bits/texel). So the number of bytes used for a // texwidth texel, is texwidth/2 bytes. // Note that texwidth is divisible by 4(to to the upper rounding to 4), therefore, it is also divisible // by 2. // glCompressedTexImage2DARB, glCompressedTexImage3DARB, // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei. pDesc->RowPitch = pDesc->WidthInBlocks * 8; pDesc->SlicePitch = pDesc->WidthInBlocks * pDesc->HeightInBlocks * 8; pDesc->BitsPerPixel = 0; // compressed pDesc->BytesPerBlock = 8; } else { // A line of n texel DXT3/5 data uses n bytes(1 byte/texel). So the number of bytes used for a // texwidth texels, is texwidth bytes. // glCompressedTexImage2DARB, glCompressedTexImage3DARB, // glCompressedTexSubImage2DARB, glCompressedTexSubImage3DARB are not affected by glPixelStorei. pDesc->RowPitch = pDesc->WidthInBlocks * 16; pDesc->SlicePitch = pDesc->WidthInBlocks * pDesc->HeightInBlocks * 16; pDesc->BitsPerPixel = 0; // compressed pDesc->BytesPerBlock = 16; } } else { pDesc->Width = Max (1, pTexture->_Width >> Level); pDesc->Height = Max (1, pTexture->_Height >> Level); pDesc->WidthInBlocks = pDesc->Width; pDesc->HeightInBlocks = pDesc->Height; unsigned int BytePerPixel = GPixelFormats[pTexture->_PixelFormat].BlockBytes; pDesc->BitsPerPixel = BytePerPixel * 8; pDesc->BytesPerBlock = BytePerPixel; // a block is a 1x1 pixel ie. 1 pixel. pDesc->RowPitch = (((pDesc->Width * BytePerPixel + (unpack_alignment - 1)) >> (halfUnpack)) << (halfUnpack)); pDesc->SlicePitch = (((pDesc->Width * BytePerPixel + (unpack_alignment - 1)) >> (halfUnpack)) << (halfUnpack)) * pDesc->Height; } } } nux-4.0.6+14.04.20140409/TODO0000644000015301777760000000001512321344237015421 0ustar pbusernogroup00000000000000Write README nux-4.0.6+14.04.20140409/NuxCore/0000755000015301777760000000000012321344711016315 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxCore/Platform.h0000644000015301777760000000456712321344237020271 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NPLATFORM_H #define NPLATFORM_H namespace nux { void NuxCoreInitialize (const TCHAR *CommandLine); void inlPreInitializePlatform(); void inlInitializePlatform(); void inlPostInitializePlatform(); void inlExitSystem(); void inlInitRandomGenerator(); /*----------------------------------------------------------------------------- Command line. -----------------------------------------------------------------------------*/ //! Get the program command line /*! Get the program command line. @return The program command line. */ std::string GetCmdLine(); //! Get startup directory. /*! Get startup directory. @return The computer name. */ std::string GetProgramDirectory(); //! Get computer name. /*! Get computer name. @return The computer name. */ std::string GetComputerName(); //! Get user name. /*! Get the user name. @return The user name. */ std::string GetUserName(); //! Return the logs directory /*! Returns the directory where logs files are output. This cannot be in a .ini files as the system may start logging before the .ini files are read. @return The logs directory */ std::string GetLogDirectory(); class NGlobalData { NUX_DECLARE_GLOBAL_OBJECT (NGlobalData, GlobalSingletonInitializer); public: void Initialize (const TCHAR *CommandLine); unsigned int m_RandomSeed; std::string m_UserName; std::string m_ComputerName; std::string m_ProgramName; std::string m_ProgramDirectory; std::string m_CommandLine; }; } #endif // NPLATFORM_H nux-4.0.6+14.04.20140409/NuxCore/AnimationController.h0000644000015301777760000000470112321344237022456 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Tim Penhey * */ #ifndef NUX_CORE_ANIMATION_CONTROLLER_H #define NUX_CORE_ANIMATION_CONTROLLER_H #include namespace nux { namespace animation { class Animation; class TickSource { public: virtual ~TickSource(); // tick value is in microseconds sigc::signal tick; }; /** * The Animation Controller is responsible for updating running animations. * * The controller is constructed with a tick source, and operates as a * pseudo-singleton. A controller must be created somewhere, and once it is, * it set as the default controller. It is expected that there is only one * animation controller. */ class Controller { public: static Controller* Instance(); Controller(); virtual ~Controller(); virtual void AddAnimation(Animation* animation) = 0; virtual void RemoveAnimation(Animation* animation) = 0; virtual bool HasRunningAnimations() const = 0; private: #if defined(NUX_OS_WINDOWS) && !defined(NUX_VISUAL_STUDIO_VC11) Controller(Controller const&); Controller& operator = (Controller const&); #else Controller(Controller const&) = delete; Controller& operator = (Controller const&) = delete; #endif }; class AnimationController : public Controller, public sigc::trackable { public: AnimationController(TickSource& tick_source); virtual ~AnimationController(); // tick is expected to be ever increasing virtual void OnTick(long long tick); virtual void AddAnimation(Animation* animation); virtual void RemoveAnimation(Animation* animation); virtual bool HasRunningAnimations() const; private: struct Impl; Impl* pimpl; }; }} // close namespaces #endif nux-4.0.6+14.04.20140409/NuxCore/FileName.h0000644000015301777760000000577512321344237020167 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NFILENAME_H #define NFILENAME_H #include "TextString.h" namespace nux { class NFileName : public std::string { public: NFileName() : std::string() {} NFileName ( const NFileName &Filename ) : std::string ( Filename ) {} NFileName ( const std::string &str ) : std::string ( str ) {} NFileName ( const ANSICHAR *str ) : std::string ( str ) {} //! Replace all slash with backslash. void ConvertSlashToBackslash(); //! Replace all backslash with slash. void ConvertBackslashToSlash(); //! Add slash at the end if there isn't one already. void AddSlashAtEnd(); //! Add backslash at the end if there isn't one already. void AddBackSlashAtEnd(); //! Add slash at the start if there isn't one already. void AddSlashAtStart(); //! Add backslash at the start if there isn't one already. void AddBackSlashAtStart(); //! Remove slash at the end if there is one. void RemoveSlashAtEnd(); //! Remove backslash at the end if there is one. void RemoveBackSlashAtEnd(); //! Remove slash at the start if there is one. void RemoveSlashAtStart(); //! Remove backslash at the start if there is one. void RemoveBackSlashAtStart(); //! Replace all backslash with slash. Replace multiple consecutive slash with one slash. void ConvertToCleanSlash(); //! Replace all slash with backslash. Replace multiple consecutive backslash with one backslash. void ConvertToCleanBackslash(); std::string GetDrive() const; //! Returns the text following the last period. std::string GetExtension() const; //! Returns the base filename, minus any path information. std::string GetCleanFilename() const; //! Returns the base filename, without the extension (keep the path) std::string GetFilenameNoExtension() const; //! Returns the same thing as GetCleanFilename, but without the extension std::string GetBaseFilename() const; //! Returns the path in front of the filename std::string GetDirectoryPath() const; //! Change the file extension. Do not start ext with a dot character '.'. //! ie ext = "com" void ChangeFileExtension (const TCHAR *ext); }; } #endif // NFILENAME_H nux-4.0.6+14.04.20140409/NuxCore/Property-inl.h0000644000015301777760000002131012321344237021072 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Tim Penhey * */ #ifndef NUXCORE_PROPERTY_INL_H #define NUXCORE_PROPERTY_INL_H namespace nux { template PropertyChangedSignal::PropertyChangedSignal() : notify_(true) {} template void PropertyChangedSignal::DisableNotifications() { notify_ = false; } template void PropertyChangedSignal::EnableNotifications() { notify_ = true; } template void PropertyChangedSignal::EmitChanged(VALUE_TYPE const& new_value) { if (notify_) changed.emit(new_value); } template Property::Property() : value_(VALUE_TYPE()) , setter_function_(std::bind(&Property::DefaultSetter, this, std::placeholders::_1, std::placeholders::_2)) {} template Property::Property(VALUE_TYPE const& initial) : value_(initial) , setter_function_(std::bind(&Property::DefaultSetter, this, std::placeholders::_1, std::placeholders::_2)) {} template Property::Property(VALUE_TYPE const& initial, SetterFunction setter_function) : value_(initial) , setter_function_(setter_function) {} template VALUE_TYPE Property::operator=(VALUE_TYPE const& value) { return Set(value); } template Property::operator VALUE_TYPE() const { return value_; } template VALUE_TYPE Property::operator()() const { return value_; } template VALUE_TYPE Property::operator()(VALUE_TYPE const& value) { return Set(value); } template VALUE_TYPE Property::Get() const { return value_; } template VALUE_TYPE Property::Set(VALUE_TYPE const& value) { if (setter_function_(value_, value)) SignalBase::EmitChanged(value_); return value_; } template bool Property::DefaultSetter(VALUE_TYPE& target, VALUE_TYPE const& value) { bool changed = false; if (target != value) { target = value; changed = true; } return changed; } template void Property::SetSetterFunction(SetterFunction setter_function) { setter_function_ = setter_function; } template ROProperty::ROProperty() : getter_function_(std::bind(&ROProperty::DefaultGetter, this)) {} template ROProperty::ROProperty(GetterFunction getter_function) : getter_function_(getter_function) {} template ROProperty::operator VALUE_TYPE() const { return getter_function_(); } template VALUE_TYPE ROProperty::operator()() const { return getter_function_(); } template VALUE_TYPE ROProperty::Get() const { return getter_function_(); } template VALUE_TYPE ROProperty::DefaultGetter() const { return VALUE_TYPE(); } template void ROProperty::SetGetterFunction(GetterFunction getter_function) { getter_function_ = getter_function; } template RWProperty::RWProperty() : getter_function_(std::bind(&RWProperty::DefaultGetter, this)) , setter_function_(std::bind(&RWProperty::DefaultSetter, this, std::placeholders::_1)) {} template RWProperty::RWProperty(GetterFunction getter_function, SetterFunction setter_function) : getter_function_(getter_function) , setter_function_(setter_function) {} template VALUE_TYPE RWProperty::operator=(VALUE_TYPE const& value) { return Set(value); } template RWProperty::operator VALUE_TYPE() const { return getter_function_(); } template VALUE_TYPE RWProperty::operator()() const { return getter_function_(); } template VALUE_TYPE RWProperty::operator()(VALUE_TYPE const& value) { return Set(value); } template VALUE_TYPE RWProperty::Get() const { return getter_function_(); } template VALUE_TYPE RWProperty::Set(VALUE_TYPE const& value) { if (setter_function_(value)) { VALUE_TYPE new_value = getter_function_(); SignalBase::EmitChanged(new_value); return new_value; } return getter_function_(); } template VALUE_TYPE RWProperty::DefaultGetter() const { return VALUE_TYPE(); } template bool RWProperty::DefaultSetter(VALUE_TYPE const& /* value */) { return false; } template void RWProperty::SetSetterFunction(SetterFunction setter_function) { setter_function_ = setter_function; } template void RWProperty::SetGetterFunction(GetterFunction getter_function) { getter_function_ = getter_function; } // We need to provide a default constructor since we hide the copy ctor. inline Introspectable::Introspectable() {} inline void Introspectable::AddProperty(std::string const& name, PropertyBase* property) { // check to see if it exists and if it does barf horribly as we can't // have two properties with the same name; properties_[name] = property; } inline bool Introspectable::SetProperty(std::string const& name, const char* value) { PropertyContainer::iterator i = properties_.find(name); if (i == properties_.end()) return false; else return i->second->SetValue(value); } template bool Introspectable::SetProperty(std::string const& name, T const& value) { PropertyContainer::iterator i = properties_.find(name); if (i == properties_.end()) return false; else { return i->second->SetValue(type::PropertyTrait::to_string(value)); } } template T Introspectable::GetProperty(std::string const& name, T* /* foo */) { PropertyContainer::iterator i = properties_.find(name); if (i == properties_.end()) return T(); std::string s = i->second->GetSerializedValue(); std::pair result = type::PropertyTrait::from_string(s); // If this is called with a template type that the property does not // support nice conversion to, you'll get no error, but will get // a default constructed T. We could use an exception here. return result.first; } template SerializableProperty::SerializableProperty(Introspectable* owner, std::string const& name) : Base() , name_(name) { owner->AddProperty(name, this); } template SerializableProperty::SerializableProperty(Introspectable* owner, std::string const& name, T const& initial) : Base(initial) , name_(name) { owner->AddProperty(name, this); } template bool SerializableProperty::SetValue(std::string const& serialized_form) { std::pair result = TraitType::from_string(serialized_form); if (result.second) { Base::Set(result.first); } return result.second; } template std::string SerializableProperty::GetSerializedValue() const { return TraitType::to_string(Base::Get()); } template T SerializableProperty::operator=(T const& value) { Base::Set(value); // There are no arguments to ‘get’ that depend on a template parameter, // so we explicitly specify Base. return Base::Get(); } } #endif nux-4.0.6+14.04.20140409/NuxCore/Rect.h0000644000015301777760000000612412321344237017371 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef RECT_H #define RECT_H #include "Point.h" #include "Size.h" namespace nux { class Rect { public: Rect(); Rect(int x_, int y_, int width_, int height_); Rect(const Rect &); Rect(Rect&&); Rect &operator = (Rect r); bool operator == (const Rect &p) const; bool operator != (const Rect &p) const; //! Return true is the area of this rectangle is Null. /*! Return true is the area of this rectangle is Null. */ bool IsNull() const; bool IsInside(const Point &p) const; bool IsInside(const Point2D &p) const; bool IsIntersecting(const Rect&) const; Rect Intersect(const Rect &) const; // expand the width by factor_x and the height by factor_y void Expand (int factor_x, int factor_y); int GetWidth() const { return width; } int GetHeight() const { return height; } //! Returns a Point at the center of the Rectangle. Point GetCenter() const { return Point (x + width / 2, y + height / 2); } //! Returns a Point at the center of the Rectangle. Point GetPosition() const { return Point (x, y); } void SetWidth (int w) { width = w; } void SetHeight (int h) { height = h; } void SetX (int px) { x = px; } void SetY (int py) { y = py; } void Set (int px, int py, int w, int h); void SetPosition (int px, int py); void SetSize (int px, int py); void OffsetSize (int dw, int dh) { width += dw; height += dh; if (width < 0) width = 0; if (height < 0) height = 0; } void OffsetPosition (int dx, int dy) { x += dx; y += dy; } bool IsPointInside (int dx, int dy) const; Rect GetExpand (int dx, int dy) const; friend void swap(Rect& lhs, Rect& rhs) { using std::swap; swap(lhs.x, rhs.x); swap(lhs.y, rhs.y); swap(lhs.width, rhs.width); swap(lhs.height, rhs.height); } int x, y; int width, height; }; Rect operator+(Rect const& lhs, Rect const& rhs); Rect operator-(Rect const& lhs, Rect const& rhs); Rect operator*(Rect const& lhs, float scalar); std::ostream& operator<<(std::ostream &os, Rect const&); typedef Rect Geometry; } #endif // RECT_H nux-4.0.6+14.04.20140409/NuxCore/ThreadWin.cpp0000644000015301777760000002653312321344237020722 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "TextString.h" #include "ThreadWin.h" namespace nux { #define NUX_ATOMOP_ITERLOCKED_INCREMENT InterlockedIncrement #define NUX_ATOMOP_ITERLOCKED_DECREMENT InterlockedDecrement #define NUX_ATOMOP_ITERLOCKED_EXCHANGED InterlockedExchange #define NUX_ATOMOP_ITERLOCKED_VALUE long NThreadSafeCounter::Increment() { return NUX_ATOMOP_ITERLOCKED_INCREMENT ( &m_Counter ); } long NThreadSafeCounter::Decrement() { return NUX_ATOMOP_ITERLOCKED_DECREMENT ( &m_Counter ); } long NThreadSafeCounter::Set (long i) { return NUX_ATOMOP_ITERLOCKED_EXCHANGED ( &m_Counter, i ); } long NThreadSafeCounter::GetValue() const { return m_Counter; } long NThreadSafeCounter::operator ++ () { return Increment(); } long NThreadSafeCounter::operator -- () { return Decrement(); } bool NThreadSafeCounter::operator == (long i) { return (m_Counter == i); } unsigned int NThreadLocalStorage::m_TLSIndex[NThreadLocalStorage::NbTLS]; BOOL NThreadLocalStorage::m_TLSUsed[NThreadLocalStorage::NbTLS]; NThreadLocalStorage::TLS_ShutdownCallback NThreadLocalStorage::m_TLSCallbacks[NThreadLocalStorage::NbTLS]; // http://msdn2.microsoft.com/en-us/library/xcb2z8hs(VS.80).aspx // // Usage: SetWin32ThreadName (-1, "MainThread"); // #define MS_VC_EXCEPTION 0x406D1388 typedef struct tagTHREADNAME_INFO { DWORD dwType; // Must be 0x1000. LPCSTR szName; // Pointer to name (in user addr space). DWORD dwThreadID; // Thread ID (-1=caller thread). DWORD dwFlags; // Reserved for future use, must be zero. } THREADNAME_INFO; void SetWin32ThreadName (DWORD dwThreadID, LPCSTR szThreadName) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = szThreadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; __try { RaiseException ( MS_VC_EXCEPTION, 0, sizeof (info) / sizeof (DWORD), (ULONG_PTR *) &info ); } __except (EXCEPTION_CONTINUE_EXECUTION) { } } BOOL NThreadLocalStorage::RegisterTLS(unsigned int index, NThreadLocalStorage::TLS_ShutdownCallback shutdownCallback) { if (m_TLSUsed[index]) { nuxDebugMsg("[NThreadLocalStorage::RegisterTLS] TLS has already been registered."); return TRUE; } if (!m_TLSUsed[index]) { m_TLSIndex[index] = TlsAlloc(); if (m_TLSIndex[index] == TLS_OUT_OF_INDEXES) { nuxAssertMsg (0, TEXT ("[NThreadLocalStorage::RegisterTLS] Out of TLS index.") ); } m_TLSUsed[index] = TRUE; m_TLSCallbacks[index] = shutdownCallback; return TRUE; } else { return FALSE; } } void NThreadLocalStorage::Initialize() { for (unsigned int i = 0; i < NThreadLocalStorage::NbTLS; i++) { m_TLSUsed[i] = FALSE; // Fill the array with invalid values m_TLSIndex[i] = NThreadLocalStorage::InvalidTLS; // invalid index } } void NThreadLocalStorage::Shutdown() { ThreadShutdown(); } void NThreadLocalStorage::ThreadInit() { } void NThreadLocalStorage::ThreadShutdown() { TLS_ShutdownCallback *callback = m_TLSCallbacks; for (unsigned int i = 0; i < NThreadLocalStorage::NbTLS; ++i, ++callback) { if (*callback) { (**callback) (); } } } NUX_IMPLEMENT_ROOT_OBJECT_TYPE (NThread); NThread::NThread() : m_ThreadState (THREADINIT) { m_pThreadFunc = NThread::EntryPoint; // Can call Detach() also. } NThread::NThread (LPTHREAD_START_ROUTINE lpExternalRoutine) { Attach (lpExternalRoutine); } NThread::~NThread() { CloseHandle (m_ThreadCtx.m_hThread); } ThreadState NThread::Start ( void *arg ) { if ( m_ThreadCtx.m_hThread == 0) { m_ThreadCtx.m_pUserData = arg; m_ThreadCtx.m_hThread = CreateThread (NULL, 0, m_pThreadFunc, this, 0 /*CREATE_SUSPENDED*/, (LPDWORD) &m_ThreadCtx.m_dwTID); if (m_ThreadCtx.m_hThread != 0) { //ResumeStart(); m_ThreadState = THREADINIT; m_ThreadCtx.m_dwExitCode = (unsigned int) - 1; return m_ThreadState; } else { nuxDebugMsg (TEXT ("[NThread::Start] Cannot start thread: %s"), inlGetSystemErrorMessage() ); m_ThreadState = THREAD_START_ERROR; return m_ThreadState; } } return m_ThreadState; } ThreadState NThread::Stop(bool bForceKill) { // From MSDN // TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating. // TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems: // If the target thread owns a critical section, the critical section will not be released. // If the target thread is allocating memory from the heap, the heap lock will not be released. // If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent. // If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL. // Attention: Calling Stop from another thread is not going to free the stack of this thread. // the stack is freed only if the thread exits by itself. if (m_ThreadCtx.m_hThread) { BOOL success = GetExitCodeThread(m_ThreadCtx.m_hThread, (LPDWORD) &m_ThreadCtx.m_dwExitCode); if ((m_ThreadCtx.m_dwExitCode == STILL_ACTIVE) && bForceKill) { // This will forcibly kill the thread! Read the doc on TerminateThread to find out about the consequences. TerminateThread(m_ThreadCtx.m_hThread, unsigned int (-1)); CloseHandle(m_ThreadCtx.m_hThread); } m_ThreadCtx.m_hThread = NULL; } m_ThreadState = THREADSTOP; return m_ThreadState; } ThreadState NThread::Suspend() { unsigned int ret = SuspendThread(m_ThreadCtx.m_hThread); if (ret == 0xFFFFFFFF) { nuxDebugMsg(TEXT("[NThread::Suspend] Cannot suspend thread: %s"), inlGetSystemErrorMessage()); return THREAD_SUSPEND_ERROR; } m_ThreadState = THREADSUSPENDED; return m_ThreadState; } ThreadState NThread::Resume() { unsigned int ret = ResumeThread(m_ThreadCtx.m_hThread); if (ret == 0xFFFFFFFF) { nuxDebugMsg(TEXT("[NThread::Suspend] Cannot resume thread: %s"), inlGetSystemErrorMessage()); return THREAD_RESUME_ERROR; } if (ret == 1) { // If the return value is 1, the specified thread was suspended but was restarted. m_ThreadState = THREADRUNNING; } if (ret > 1) { // If the return value is greater than 1, the specified thread is still suspended. m_ThreadState = THREADSUSPENDED; } return m_ThreadState; } // go from suspended to thread start ThreadState NThread::ResumeStart() { m_ThreadState = THREADINIT; unsigned int ret = ResumeThread(m_ThreadCtx.m_hThread); if (ret == 0xFFFFFFFF) { nuxDebugMsg(TEXT("[NThread::ResumeExit] Cannot resume thread: %s"), inlGetSystemErrorMessage()); return THREAD_RESUME_ERROR; } if (ret == 1) { // If the return value is 1, the specified thread was suspended but was restarted. m_ThreadState = THREADINIT; } if (ret > 1) { nuxAssert(0); // should not happen // If the return value is greater than 1, the specified thread is still suspended. m_ThreadState = THREADINIT; } return m_ThreadState; } // go from suspended to thread exit ThreadState NThread::ResumeExit() { m_ThreadState = THREADSTOP; unsigned int ret = ResumeThread(m_ThreadCtx.m_hThread); if (ret == 0xFFFFFFFF) { nuxDebugMsg(TEXT("[NThread::ResumeExit] Cannot resume thread: %s"), inlGetSystemErrorMessage()); return THREAD_RESUME_ERROR; } if (ret == 1) { // If the return value is 1, the specified thread was suspended but was restarted. m_ThreadState = THREADSTOP; } if (ret > 1) { nuxAssert(0); // should not happen // If the return value is greater than 1, the specified thread is still suspended. m_ThreadState = THREADSTOP; } return m_ThreadState; } DWORD WINAPI NThread::EntryPoint(void *pArg) { NThread *pParent = reinterpret_cast (pArg); if (pParent == 0) { nuxDebugMsg(TEXT("[NThread::EntryPoint] Invalid pointer. The thread will exit.")); return 0; } if (!pParent->ThreadCtor()) { // return another message saying the thread could not execute due to error in ThreadCtor; return 0; } pParent->Run(pParent->m_ThreadCtx.m_pUserData); pParent->ThreadDtor(); return 0; } unsigned int NThread::GetExitCode() const { if ( m_ThreadCtx.m_hThread ) GetExitCodeThread (m_ThreadCtx.m_hThread, (LPDWORD) &m_ThreadCtx.m_dwExitCode); return m_ThreadCtx.m_dwExitCode; } HANDLE NThread::GetThreadHandle() { return m_ThreadCtx.m_hThread; } unsigned int NThread::GetThreadId() { return (unsigned int)m_ThreadCtx.m_dwTID; } ThreadState NThread::GetThreadState() const { return m_ThreadState; } void NThread::SetThreadState(ThreadState state) { m_ThreadState = state; } void NThread::SetThreadName(const TCHAR *ThreadName) { SetWin32ThreadName (GetThreadId(), TCHAR_TO_ANSI (ThreadName) ); m_ThreadName = ThreadName; } const std::string& NThread::GetThreadName() const { return m_ThreadName; } ThreadWaitResult NThread::JoinThread(NThread *thread, unsigned int milliseconds) { if (thread == NULL) { return THREAD_WAIT_RESULT_FAILED; } unsigned int result = WaitForSingleObject(thread->GetThreadHandle(), milliseconds); switch(result) { case WAIT_OBJECT_0: return THREAD_WAIT_RESULT_COMPLETED; case WAIT_ABANDONED: return THREAD_WAIT_RESULT_ABANDONED; case WAIT_TIMEOUT: return THREAD_WAIT_RESULT_TIMEOUT; case WAIT_FAILED: default: return THREAD_WAIT_RESULT_FAILED; } } } nux-4.0.6+14.04.20140409/NuxCore/Memory.cpp0000644000015301777760000000465212321344237020303 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" namespace nux { unsigned int Memcmp ( const void *Buf1, const void *Buf2, unsigned int Count ) { return std::memcmp ( Buf1, Buf2, Count ); } bool MemIsZero ( const void *V, size_t Count ) { unsigned char *B = (unsigned char *) V; while ( Count-- > 0 ) if ( *B++ != 0 ) return false; return true; } void *Memmove ( void *Dest, const void *Src, size_t Count ) { if (Count == 0) return Dest; return std::memmove ( Dest, Src, Count ); } void Memset ( void *Dest, int C, size_t Count ) { std::memset ( Dest, C, Count ); } void Memzero ( void *Dest, size_t Count ) { std::memset ( Dest, 0, Count ); } void Memcpy ( void *Dest, const void *Src, size_t Count ) { std::memcpy ( Dest, Src, Count ); } void Memswap ( void *Ptr1, void *Ptr2, size_t Size ) { void *Temp = malloc (Size); Memcpy ( Temp, Ptr1, Size ); Memcpy ( Ptr1, Ptr2, Size ); Memcpy ( Ptr2, Temp, Size ); free (Temp); } bool IsMemoryAligned (void *data, unsigned int alignment) { nuxAssertMsg ( (alignment & (alignment - 1) ) == 0, TEXT ("[IsMemAligned] Argument for memory alignment test is not a power of two: %d"), alignment); return ( ( (uintptr_t) &data) & (alignment - 1) ) == 0; } void *Malloc (size_t Count, unsigned int /* Alignment */) { return std::malloc ( Count ); } void *Realloc (void *Original, size_t Count, unsigned int /* Alignment */) { void *mem = std::realloc ( Original, Count ); if (mem == 0) { nuxCriticalMsg (TEXT ("[Realloc] realloc failed.")); return NULL; } return mem; } } nux-4.0.6+14.04.20140409/NuxCore/Animation.cpp0000644000015301777760000000352012321344237020743 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2012 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Tim Penhey * */ #include "NuxCore.h" #include "Animation.h" #include "AnimationController.h" namespace na = nux::animation; na::Animation::Animation() : state_(Stopped) {} na::Animation::~Animation() { if (state_ != Stopped) { if (Controller* controller = Controller::Instance()) controller->RemoveAnimation(this); } } void na::Animation::Pause() { if (state_ == Running) { state_ = Paused; } } void na::Animation::Resume() { if (state_ == Paused) { state_ = Running; } } void na::Animation::Start() { if (state_ == Stopped) { state_ = Running; Restart(); Controller* controller = Controller::Instance(); if (controller) controller->AddAnimation(this); } } void na::Animation::Stop() { if (state_ != Stopped) { state_ = Stopped; finished.emit(); Controller* controller = Controller::Instance(); if (controller) controller->RemoveAnimation(this); } } na::Animation::State na::Animation::CurrentState() const { return state_; } nux-4.0.6+14.04.20140409/NuxCore/FileManager/0000755000015301777760000000000012321344711020467 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxCore/FileManager/NFileManagerGeneric.cpp0000644000015301777760000001636412321344237024775 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "Math/MathUtility.h" namespace nux { #define COPYBLOCKSIZE 32768 int NFileManagerGeneric::Copy (const TCHAR *InDestFile, const TCHAR *InSrcFile, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor *Monitor) { // Direct file copier. if (Monitor && !Monitor->Progress (0.0) ) { return COPY_CANCELED; } int Result = COPY_OK; std::string SrcFile = InSrcFile; std::string DestFile = InDestFile; NSerializer *Src = CreateFileReader (SrcFile.c_str() ); if (!Src) { Result = COPY_READFAIL; } else { unsigned int Size = Src->GetFileSize(); NSerializer *Dest = CreateFileWriter (DestFile.c_str(), (OverWriteExisting ? 0 : FILEWRITE_NOREPLACEEXISTING) | (OverWriteReadOnly ? FILEWRITE_EVENIFREADONLY : 0) ); if (!Dest) { Result = COPY_WRITEFAIL; } else { unsigned int Percent = 0, NewPercent = 0; BYTE Buffer[COPYBLOCKSIZE]; for (unsigned int Total = 0; Total < Size; Total += sizeof (Buffer) ) { unsigned int Count = Min (Size - Total, (unsigned int) sizeof (Buffer) ); Src->Serialize (Buffer, Count); if (Src->IsError() ) { Result = COPY_READFAIL; break; } Dest->Serialize (Buffer, Count); if (Dest->IsError() ) { Result = COPY_WRITEFAIL; break; } NewPercent = Total * 100 / Size; if (Monitor && Percent != NewPercent && !Monitor->Progress ( (float) NewPercent / 100.f) ) { Result = COPY_CANCELED; break; } Percent = NewPercent; } if (Result == COPY_OK) { if (!Dest->Close() ) { Result = COPY_WRITEFAIL; } } delete Dest; if (Result != COPY_OK) { Delete (DestFile.c_str() ); } } if (Result == COPY_OK) { if (!Src->Close() ) { Result = COPY_READFAIL; } } delete Src; } if (Monitor && Result == COPY_OK && !Monitor->Progress (1.0) ) { Result = COPY_CANCELED; } return Result; } bool NFileManagerGeneric::IsDrive (const TCHAR *Path) { // Does Path refer to a drive letter or UNC path? // A UNC is a naming convention that permits you to use a network resource, // such as a network server, without formally connecting to the network resource // with a mapped drive. A UNC path uses the following syntax: // \\\ // The share is a drive: D:\Folder of ServerA = "\\ServerA\D\Folder" if (Stricmp (Path, TEXT ("") ) == 0) return 1; else if ( (ToUpperCase (Path[0]) != ToLowerCase (Path[0]) ) && (Path[1] == TEXT (':') ) && (Path[2] == 0) ) // look for "a:", "c:", "d:" ... return 1; else if (Stricmp (Path, TEXT ("\\") ) == 0) // look for "\" return 1; else if (Stricmp (Path, TEXT ("\\\\") ) == 0) // look for "\\" return 1; else if (Path[0] == TEXT ('\\') && Path[1] == TEXT ('\\') && !Strchr (Path + 2, TEXT ('\\') ) ) // look for "\\Server" return 1; else if (Path[0] == TEXT ('\\') && Path[1] == TEXT ('\\') && Strchr (Path + 2, TEXT ('\\') ) && !Strchr (Strchr (Path + 2, TEXT ('\\') ) + 1, TEXT ('\\') ) ) // look for "\\Server\share" return 1; else return 0; } bool NFileManagerGeneric::MakeDirectory (const TCHAR *Path, bool /* CreateCompletePath */) { // Support code for making a directory tree. unsigned int SlashCount = 0, CreateCount = 0; for (TCHAR Full[256] = TEXT (""), *Ptr = Full; ; *Ptr++ = *Path++) { if ( (*Path == NUX_BACKSLASH_CHAR) || (*Path == NUX_SLASH_CHAR) || (*Path == 0) ) { if ( (SlashCount++ > 0) && !IsDrive (Full) ) { *Ptr = 0; if (MakeDirectory (Full, 0) != NUX_OK) return 0; CreateCount++; } } if (*Path == 0) break; } return CreateCount != 0; } bool NFileManagerGeneric::DeleteDirectory (const TCHAR *Path, bool /* DeleteContentFirst */) { nuxAssert (Path != NULL); size_t PathLength = StringLength (Path); if (PathLength == 0) return false; std::string WildcardPath = std::string (Path); if ( (WildcardPath[PathLength - 1] != NUX_BACKSLASH_CHAR) && (WildcardPath[PathLength - 1] != NUX_SLASH_CHAR) ) WildcardPath += NUX_BACKSLASH_CHAR; WildcardPath += TEXT ("*"); std::vector List; FindFiles (List, WildcardPath.c_str(), 1, 0); for (unsigned int i = 0; i < List.size(); i++) { if (!Delete ((std::string (Path) + NUX_BACKSLASH_CHAR + List[i]).c_str(), 1) ) return 0; } List.clear(); FindFiles (List, WildcardPath.c_str(), 0, 1); for (unsigned int i = 0; i < List.size(); i++) { if (!DeleteDirectory ((std::string (Path) + NUX_BACKSLASH_CHAR + List[i]).c_str(), true) ) return 0; } List.clear(); return DeleteDirectory (Path, false); } bool NFileManagerGeneric::Move (const TCHAR *Dest, const TCHAR *Src, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor * /* Monitor */) { // Move file manually. if (Copy (Dest, Src, OverWriteExisting, OverWriteReadOnly, NULL) != COPY_OK) return 0; Delete (Src, 1); return 1; } int NFileManagerGeneric::CreateUniqueFileName (const TCHAR *Filename, const TCHAR *Extension, std::string &OutputFilename, unsigned int BaseIndex) { nuxAssert (Filename); nuxAssert (Extension); std::string FullPath (Filename); const size_t IndexMarker = FullPath.length(); // Marks location of the four-digit index. FullPath += TEXT ("0000."); FullPath += Extension; // Iterate over indices, searching for a file that doesn't exist. for (DWORD i = BaseIndex + 1 ; i < 10000 ; ++i) { FullPath[IndexMarker ] = i / 1000 + TEXT ('0'); FullPath[IndexMarker+1] = (i / 100) % 10 + TEXT ('0'); FullPath[IndexMarker+2] = (i / 10) % 10 + TEXT ('0'); FullPath[IndexMarker+3] = i % 10 + TEXT ('0'); if (GFileManager.FileSize (FullPath.c_str() ) == -1) { // The file doesn't exist; output success. OutputFilename = FullPath; return static_cast (i); } } // Can't find an empty filename slot with index in (StartVal, 9999]. return -1; } } nux-4.0.6+14.04.20140409/NuxCore/FileManager/NSerializer.h0000644000015301777760000001536012321344237023077 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NSERIALIZER_H #define NSERIALIZER_H namespace nux { class NSerializer { public: enum { OutputErrorIfFail = 0x01, NoOverWrite = 0x02, OverWriteReadOnly = 0x04, Unbuffered = 0x08, Append = 0x10, Read = 0x20, Write = 0x40, }; typedef enum { SeekStart = 0x00, SeekCurrent = 0x01, SeekEnd = 0x02, } SeekPos; // NSerializer interface. virtual ~NSerializer() {} virtual void SerializeFinal (void *V, long long Length) = 0; // template // void SerializeBuffer( T* buffer, unsigned long long NumberOfElements, unsigned long long ElementSize = sizeof(T)) // { // for(unsigned long long i = 0; i < NumberOfElements; i++) // { // unsigned char* bytebuffer = (unsigned char*)(&buffer[i]); // Serialize(bytebuffer, ElementSize); // } // } virtual bool isReader() = 0; virtual bool isWriter() = 0; virtual long long Tell() = 0; virtual long long GetFileSize() { return -1; } virtual long long Seek (long long FilePos, NSerializer::SeekPos) = 0; virtual bool Precache (INT /* PrecacheOffset */, INT /* PrecacheSize */) { return TRUE; } virtual void Flush() {}; virtual bool Close() = 0; virtual bool GetError() { return m_ErrorCode; } NSerializer &ByteOrderSerialize (void *V, INT Length ) { BOOL SwapBytes = 0; if ( SwapBytes ) { // Transferring between memory and file, so flip the byte order. for ( INT i = Length - 1; i >= 0; i-- ) Serialize ( (unsigned char *) V + i, 1 ); } else { // Transferring around within memory, so keep the byte order. Serialize ( (unsigned char *) V, Length); } return *this; } // Constructor. NSerializer() { Reset(); } NUX_INLINE bool IsError() const { return m_ErrorCode; } virtual void Serialize (char &data); virtual void Serialize (wchar_t &data); virtual void Serialize (bool &data); virtual void Serialize (unsigned char &data); virtual void Serialize (unsigned short &data); virtual void Serialize (short &data); virtual void Serialize (unsigned int &data); virtual void Serialize (int &data); virtual void Serialize (long &data); virtual void Serialize (unsigned long &data); virtual void Serialize (float &data); virtual void Serialize (double &data); virtual void Serialize (unsigned long long &data); virtual void Serialize (long long &data); virtual void Serialize (wchar_t *buffer, unsigned int len, unsigned int stride = sizeof (wchar_t) ); virtual void Serialize (bool *buffer, unsigned int len, unsigned int stride = sizeof (bool) ); virtual void Serialize (char *buffer, unsigned int len, unsigned int stride = sizeof (char) ); virtual void Serialize (unsigned char *buffer, unsigned int len, unsigned int stride = sizeof (unsigned char) ); virtual void Serialize (unsigned short *buffer, unsigned int len, unsigned int stride = sizeof (unsigned short) ); virtual void Serialize (short *buffer, unsigned int len, unsigned int stride = sizeof (short) ); virtual void Serialize (unsigned int *buffer, unsigned int len, unsigned int stride = sizeof (unsigned int) ); virtual void Serialize (int *buffer, unsigned int len, unsigned int stride = sizeof (int) ); virtual void Serialize (long *buffer, unsigned int len, unsigned int stride = sizeof (long) ); virtual void Serialize (unsigned long *buffer, unsigned int len, unsigned int stride = sizeof (unsigned long) ); virtual void Serialize (float *buffer, unsigned int len, unsigned int stride = sizeof (float) ); virtual void Serialize (double *buffer, unsigned int len, unsigned int stride = sizeof (double) ); virtual void Serialize (unsigned long long *buffer, unsigned int len, unsigned int stride = sizeof (unsigned long long) ); virtual void Serialize (long long *buffer, unsigned int len, unsigned int stride = sizeof (long long) ); virtual void Identify (const char* /* name */) {}; virtual void Begin() {}; virtual void End() {}; protected: void Reset (void) { m_ErrorCode = FALSE; } bool m_ErrorCode; }; NUX_INLINE NSerializer &operator << (NSerializer &Sr, bool &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, char &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, unsigned char &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, unsigned short &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, short &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, unsigned int &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, int &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, long &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, unsigned long &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, float &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, double &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, unsigned long long &v) { Sr.Serialize (v); return Sr; } NUX_INLINE NSerializer &operator << (NSerializer &Sr, long long &v) { Sr.Serialize (v); return Sr; } } #endif // NSERIALIZER_H nux-4.0.6+14.04.20140409/NuxCore/FileManager/NFileManagerGeneric.h0000644000015301777760000001707412321344237024441 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NFILEMANAGERGENERIC_H #define NFILEMANAGERGENERIC_H namespace nux { class NFileManagerWindows; class NFileTransferMonitor { public: NFileTransferMonitor() { m_bCancel = false; } virtual ~NFileTransferMonitor() {} void Cancel() { m_bCancel = true; } virtual bool Progress (float Fraction) = 0; #ifdef _WIN32 static DWORD CALLBACK CopyProgressRoutine ( NUX_IN LARGE_INTEGER TotalFileSize, NUX_IN LARGE_INTEGER TotalBytesTransferred, NUX_IN LARGE_INTEGER StreamSize, NUX_IN LARGE_INTEGER StreamBytesTransferred, NUX_IN DWORD dwStreamNumber, NUX_IN DWORD dwCallbackReason, NUX_IN HANDLE hSourceFile, NUX_IN HANDLE hDestinationFile, NUX_IN LPVOID lpData ) { NFileTransferMonitor *filetransfer = NUX_STATIC_CAST (NFileTransferMonitor *, lpData); if (filetransfer) { if (filetransfer->Progress (100.0 * double (TotalBytesTransferred.QuadPart) / double (TotalFileSize.QuadPart) ) == false) { return PROGRESS_CANCEL; } } return PROGRESS_CONTINUE; } //private: #endif BOOL m_bCancel; friend class NFileManagerWindows; }; class NFileManager { public: NFileManager() {} virtual ~NFileManager() {} /** Timestamp structure */ struct FileTimeStamp { // Time is in UTC INT Year; /* year */ INT Month; /* months since January - [0,11] */ INT Day; /* day of the month - [1,31] */ INT Hour; /* hours since midnight - [0,23] */ INT Minute; /* minutes after the hour - [0,59] */ INT Second; /* seconds after the minute - [0,59]*/ INT DayOfWeek; /* days since Sunday - [0,6] */ INT DayOfYear; /* days since January 1 - [0,365] */ INT GetJulian ( void ) const; INT GetSecondOfDay ( void ) const; bool operator == ( FileTimeStamp &Other ) const; bool operator != ( FileTimeStamp &Other ) const; bool operator < ( FileTimeStamp &Other ) const; bool operator > ( FileTimeStamp &Other ) const; bool operator >= ( FileTimeStamp &Other ) const; bool operator <= ( FileTimeStamp &Other ) const; }; virtual void Init (bool /* Startup */) {} virtual NSerializer *CreateFileReader ( const TCHAR *Filename, DWORD ReadFlags = 0, LogOutputDevice &Error = GNullDevice ) = 0; virtual NSerializer *CreateFileWriter ( const TCHAR *Filename, DWORD WriteFlags = 0, LogOutputDevice &Error = GNullDevice ) = 0; //! Return TRUE if the file exist. /*! Return TRUE if the file exist. @param Filename the full path of the file to search. @return TRUE if the file exist. */ virtual long long FileSize (const TCHAR *Filename) = 0; // Max file size is 16 terabytes minus 64 KB on NTFS. 4 gigabytes on Fat32. virtual bool FileExist (const TCHAR *Filename) = 0; virtual int Copy (const TCHAR *Dest, const TCHAR *Src, bool OverWriteExisting = true, bool OverWriteReadOnly = false, NFileTransferMonitor *Progress = NULL) = 0; virtual bool Move (const TCHAR *Dest, const TCHAR *Src, bool OverWriteExisting = true, bool OverWriteReadOnly = false, NFileTransferMonitor *Monitor = NULL) = 0; virtual bool Delete (const TCHAR *Filename, bool OverWriteReadOnly = false) = 0; virtual bool IsReadOnly (const TCHAR *Filename) = 0; virtual bool IsDirectory (const TCHAR *DirectoryName) = 0; virtual bool IsHidden (const TCHAR *Filename) = 0; virtual bool GetFileAttribute (const TCHAR *Filename, bool &isDirectory, bool &IsReadOnly, bool &IsHidden, long long &Size) = 0; virtual bool MakeDirectory (const TCHAR *Path, bool CreateCompletePath = false) = 0; //! Delete directory /*! Delete a Directory. If DeleteContent is true, The content of the directory is deleted before the directory itself; @param Path Path of the directory @param DeleteContentFirst Delete the content of the directory before deleting the directory itself. @return TRUE if the directory was deleted. */ virtual bool DeleteDirectory (const TCHAR *Path, bool DeleteContentFirst = false) = 0; /*! Creates a unique file name. The format of the name is "DirectoryPath/BaseName####.Extension" where #### is a 4-digit number in [0, 9999]. The new name is unique and does not exist in the path directory. The function returns the value of the index created for the new file name or -1 if none could be found. The return value can be saved and passed the he next call to CreateUniqueFileName in order to speed up the search. Example usage: Create a new file name for of form DirectoryPath/Filename####.ext CreateUniqueFileName(TEXT("DirectoryPath/Filename"), TEXT("ext"), Output); @param Filename Filename with optional path. @param Extension Extension. @param OutputFilename New filename. @param BaseIndex Base for index search. @return Index of the new file. -1 if the file couldn't be created The index has to be in the range [0, 9999]. */ virtual int CreateUniqueFileName (const TCHAR *Filename, const TCHAR *Extension, std::string &OutputFilename, unsigned int BaseIndex = 0xffffffff) = 0; virtual void FindFiles ( std::vector& FileNames, const TCHAR *Filename, bool Files, bool Directories ) = 0; virtual void ListFilesInDirectory ( std::vector& Result, const TCHAR *DirName) = 0; virtual time_t GetFileLastModified (const TCHAR *Filename) = 0; virtual double GetFileAgeSeconds (const TCHAR *Filename) = 0; virtual bool SetDefaultDirectory() = 0; virtual std::string GetCurrentDirectory() = 0; virtual bool GetTimeStamp ( const TCHAR *Path, FileTimeStamp &Timestamp ) = 0; protected: }; class NFileManagerGeneric : public NFileManager { public: int Copy (const TCHAR *InDestFile, const TCHAR *InSrcFile, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor *Monitor); bool MakeDirectory (const TCHAR *Path, bool CreateCompletePath = false); bool DeleteDirectory (const TCHAR *Path, bool DeleteContentFirst = false); bool Move (const TCHAR *Dest, const TCHAR *Src, bool OverWriteExisting = true, bool OverWriteReadOnly = false, NFileTransferMonitor *Monitor = NULL); int CreateUniqueFileName (const TCHAR *Filename, const TCHAR *Extension, std::string &OutputFilename, unsigned int BaseIndex = 0xffffffff); bool IsDrive (const TCHAR *Path); }; } #endif // NFILEMANAGERGENERIC_H nux-4.0.6+14.04.20140409/NuxCore/FileManager/NFileManagerGNU.cpp0000644000015301777760000004466712321344237024061 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" namespace nux { // Choose the size so it is a power of 2. Example (size-1)= 11111111. const int NGNUSerialFileReader::sBufferSize = 1024; NGNUSerialFileReader::NGNUSerialFileReader (int InFileDescriptor, LogOutputDevice &InError, int InSize) : m_FileDescriptor (InFileDescriptor) , m_Error (InError) , m_FileSize (InSize) , m_FilePos (0) , m_BufferBase (0) , m_BufferCount (0) { m_Buffer = new BYTE[sBufferSize]; } NGNUSerialFileReader::~NGNUSerialFileReader() { NUX_SAFE_DELETE_ARRAY (m_Buffer); if (m_FileDescriptor) { Close(); } } bool NGNUSerialFileReader::Precache (int PrecacheOffset, int PrecacheSize) { // Only pre-cache at current position and avoid work if pre-caching same offset twice. if ( (m_FilePos == PrecacheOffset) && (!m_BufferBase || !m_BufferCount || m_BufferBase != m_FilePos) ) { m_BufferBase = m_FilePos; // (sBufferSize - 1) contains only '1', i.e 1111111111. // So (m_FilePos & (sBufferSize-1)) is equal to m_FilePos if m_FilePos <= (sBufferSize-1). m_BufferCount = Min (Min (PrecacheSize, (int) (sBufferSize - (m_FilePos & (sBufferSize - 1) ) ) ), m_FileSize - m_FilePos); long long Count = 0; //GTotalBytesReadViaFileManager += m_BufferCount; Count = read (m_FileDescriptor, m_Buffer, m_BufferCount); if (Count == 0) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Precache] Reached end of file while attempting to read %i bytes"), m_BufferCount); } if (Count == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Precache] Read error while attempting to read file: ???") ); } } return TRUE; } long long NGNUSerialFileReader::Seek (long long InPos, NSerializer::SeekPos seekpos) { nuxAssert (InPos >= 0); nuxAssert (InPos <= m_FileSize); Flush(); // Because we precache our reads, we must perform Seek accordingly. long long pos = m_FilePos; long long filepos = 0; // Set the file pointer to m_FilePos. filepos = lseek (m_FileDescriptor, pos, SEEK_SET); if (filepos == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Seek] Seek to %i has failed."), InPos); } // Now the file pointer is current with what we have read so far. pos = InPos; filepos = lseek (m_FileDescriptor, pos, (seekpos == SeekStart) ? SEEK_SET : (seekpos == SeekCurrent) ? SEEK_CUR : SEEK_END); if ( filepos == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Seek] Seek to %i has failed."), InPos); } m_FilePos = filepos; m_BufferBase = 0; m_BufferCount = 0; Precache (m_FilePos, sBufferSize); return filepos; } long long NGNUSerialFileReader::Tell() { // Flush(); // LARGE_INTEGER pos; // LARGE_INTEGER filepos; // pos.QuadPart = 0; // ::SetFilePointerEx(m_FileDescriptor, pos, &filepos, FILE_CURRENT); // return filepos.QuadPart; return m_FilePos; } long long NGNUSerialFileReader::GetFileSize() { return m_FileSize; } bool NGNUSerialFileReader::Close() { if (m_FileDescriptor) { int ret = close (m_FileDescriptor); if (ret == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Close] Error while closing file") ); } } m_FileDescriptor = 0; return !m_ErrorCode; } void NGNUSerialFileReader::SerializeFinal (void *Dest, long long Length) { nuxAssert (Dest); while (Length > 0) { int DataSize = Min (Length, m_BufferBase + m_BufferCount - m_FilePos); if (DataSize == 0) { if (Length >= sBufferSize) { long long Count = 0; //GTotalBytesReadViaFileManager += Length; Count = read (m_FileDescriptor, Dest, Length); if (Count == 0) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Serialize] Reached end of file while attempting to read %i bytes"), Length); } if (Count == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Serialize] Read error while attempting to read file: ???") ); } m_FilePos += Length; m_BufferBase += Length; return; } Precache (m_FilePos, 0x7FFFFFFF); DataSize = Min (Length, m_BufferBase + m_BufferCount - m_FilePos); if (DataSize <= 0) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("ReadFile beyond EOF %i+%i/%i"), m_FilePos, Length, m_FileSize); } if (m_ErrorCode) return; } Memcpy (Dest, m_Buffer + m_FilePos - m_BufferBase, DataSize); m_FilePos += DataSize; Length -= DataSize; Dest = (BYTE *) Dest + DataSize; } } ////////////////////////////////////////////////////////////////////////// // Choose the size so it is a power of 2. Example (size-1)= 11111111. const int NGNUSerialFileWriter::sBufferSize = 32; NGNUSerialFileWriter::NGNUSerialFileWriter (int InFileDescriptor, LogOutputDevice &InError, int /* InPos */) : m_FileDescriptor (InFileDescriptor) , m_Error (InError) , m_BufferCount (0) { m_Pos = Tell(); m_Buffer = new BYTE[sBufferSize]; } NGNUSerialFileWriter::~NGNUSerialFileWriter() { NUX_SAFE_DELETE_ARRAY (m_Buffer); if (m_FileDescriptor) Close(); m_FileDescriptor = 0; } long long NGNUSerialFileWriter::Seek (long long InPos, NSerializer::SeekPos seekpos) { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileDescriptor); if (m_FileDescriptor == 0) return -1; _Flush(); long long pos = InPos; long long filepos = 0; filepos = lseek (m_FileDescriptor, pos, (seekpos == SeekStart) ? SEEK_SET : (seekpos == SeekCurrent) ? SEEK_CUR : SEEK_END); if (filepos == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileWriter::Seek] Seek to %i has failed."), InPos); } m_Pos = filepos; return filepos; } long long NGNUSerialFileWriter::Tell() { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileDescriptor); if (m_FileDescriptor == 0) return -1; _Flush(); long long pos = 0; long long filepos = 0; filepos = lseek (m_FileDescriptor, pos, SEEK_CUR); if (filepos == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileWriter::Tell] Seek to %i has failed."), pos); } return filepos; } bool NGNUSerialFileWriter::Close() { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileDescriptor); if (m_FileDescriptor == 0) return true; _Flush(); int ret = close (m_FileDescriptor); if (ret == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileWriter::Close] Error while closing file") ); } m_FileDescriptor = 0; return !m_ErrorCode; } long long NGNUSerialFileWriter::GetFileSize() { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileDescriptor); if (m_FileDescriptor == 0) return -1; struct stat sb; if (fstat (m_FileDescriptor, &sb) != 0) { m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileWriter::GetFileSize] Can't get file size.") ); return -1; } return sb.st_size; } void NGNUSerialFileWriter::SerializeFinal (void *V, long long Length) { // This method is not re-entrant by itself. It relies on m_Buffer and other variables // that belong to this object. Therefore, it is not thread safe. We add a critical section // to make it thread safe. NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileDescriptor); nuxAssert (V); NUX_RETURN_IF_NULL (m_FileDescriptor); m_Pos += Length; int FreeSpace; while (Length > (FreeSpace = sBufferSize - m_BufferCount) ) { // m_Buffer is Full. Write it to the file. Memcpy (m_Buffer + m_BufferCount, V, FreeSpace); m_BufferCount += FreeSpace; Length -= FreeSpace; V = (BYTE *) V + FreeSpace; _Flush(); } if (Length) { Memcpy (m_Buffer + m_BufferCount, V, Length); m_BufferCount += Length; // Count the number of Characters stored in m_Buffer. } } void NGNUSerialFileWriter::Flush() { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileDescriptor); if (m_FileDescriptor == 0) return; _Flush(); } void NGNUSerialFileWriter::_Flush() { //GTotalBytesWrittenViaFileManager += m_BufferCount; if (m_BufferCount) { long long Result = 0; Result = write (m_FileDescriptor, m_Buffer, m_BufferCount); if (Result == -1) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileWriter::Flush] Write error.") ); } } m_BufferCount = 0; } ////////////////////////////////////////////////////////////////////////// NUX_IMPLEMENT_GLOBAL_OBJECT (NFileManagerGNU); void NFileManagerGNU::Constructor() { } void NFileManagerGNU::Destructor() { } NSerializer *NFileManagerGNU::CreateFileReader (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error) { int FileDesc = open (TCHAR_TO_ANSI (Filename), O_RDONLY); if (FileDesc == -1) { nuxDebugMsg (TEXT ("[NFileManagerGNU::CreateFileReader] Can't create file reade for: %s"), Filename); if (Flags & NSerializer::OutputErrorIfFail) { nuxError (TEXT ("[NFileManagerGNU::CreateFileReader] Can't open file: %s"), Filename); } return NULL; } struct stat sb; if (fstat (FileDesc, &sb) != 0) { int ret = close (FileDesc); if (ret == -1) { Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NFileManagerGNU::CreateFileReader] Error while closing file descriptor: %s"), Filename); } nuxDebugMsg (TEXT ("[NFileManagerGNU::CreateFileReader] Can't get file descriptor: %s"), Filename); Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NFileManagerGNU::CreateFileReader] Can't get file descriptor: %s"), Filename); return NULL; } return new NGNUSerialFileReader (FileDesc, Error, sb.st_size); } NSerializer *NFileManagerGNU::CreateFileWriter (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error) { if (FileExist (Filename) && (Flags & NSerializer::OverWriteReadOnly) ) { int ret = chmod (TCHAR_TO_ANSI (Filename), S_IRUSR | S_IWUSR); if (ret == -1) { Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NFileManagerGNU::CreateFileWriter] Can't change file mode") ); } } DWORD ModeFlags = 0; if ( (Flags & NSerializer::Read) && (Flags & NSerializer::Write) ) { ModeFlags |= O_RDWR; } else if (Flags & NSerializer::Read) { ModeFlags |= O_RDONLY; } else if (Flags & NSerializer::Write) { ModeFlags |= O_WRONLY; } ModeFlags |= (Flags & NSerializer::Append) ? O_APPEND : O_TRUNC; ModeFlags |= (Flags & NSerializer::NoOverWrite) ? (O_CREAT | O_EXCL) /*fail if the file already exist*/ : O_CREAT /*create the file if it does not exist*/; int FileDesc = open (TCHAR_TO_ANSI (Filename), ModeFlags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (FileDesc == -1) { if (Flags & NSerializer::OutputErrorIfFail) { nuxError (TEXT ("[NFileManagerGNU::CreateFileWriter] Failed to create file %s."), Filename); } return NULL; } if (Flags & NSerializer::Append) { long long Pos = lseek (FileDesc, 0, SEEK_END); if (Pos == -1) { Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NGNUSerialFileReader::Seek] Seek to %i has failed."), Pos); } } struct stat sb; if (fstat (FileDesc, &sb) != 0) { int ret = close (FileDesc); if (ret == -1) { Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NFileManagerGNU::CreateFileWriter] Error while closing file") ); } Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NFileManagerGNU::CreateFileWriter] Can't create file reader.") ); return NULL; } // The third param is never used. return new NGNUSerialFileWriter (FileDesc, Error, 0); } long long NFileManagerGNU::FileSize (const TCHAR *Filename) { struct stat sb; if (stat (TCHAR_TO_ANSI (Filename), &sb) != 0) { nuxDebugMsg (TEXT ("[NFileManagerGNU::FileSize] Can't get file size") ); return 0; } if (sb.st_mode & S_IFDIR) { // This is a directory return 0; } return sb.st_size; } bool NFileManagerGNU::FileExist (const TCHAR *Filename) { struct stat sb; if (stat (TCHAR_TO_ANSI (Filename), &sb) != 0) { return false; } return true; } int NFileManagerGNU::Copy (const TCHAR *DestFile, const TCHAR *SrcFile, bool OverWriteExisting, bool /* OverWriteReadOnly */, NFileTransferMonitor * /* Monitor */) { size_t nmemb; //int nmemb; FILE *ifp, *ofp; char buf[BUFSIZ]; if (OverWriteExisting) { if (access (DestFile, F_OK) == 0) { //OUTLOG((FUNC, TRWRN, "file %s already exists\n", DestFile)); return false; } else if (errno != ENOENT) { //OUTLOG((FUNC, TRERR, "access(%s, F_OK) failed\n", DestFile)); return false; } } if ( (ifp = fopen (SrcFile, "r") ) == NULL) { //OUTLOG((FUNC, TRERR, "%s doesn't exist\n", SrcFile)); return false; } if ( (ofp = fopen (DestFile, "w+") ) == NULL) { //OUTLOG((FUNC, TRERR, "can't create %s\n", DestFile)); fclose (ifp); return false; } while ( (nmemb = fread (buf, 1, sizeof (buf), ifp) ) > 0) { if (fwrite (buf, 1, nmemb, ofp) != nmemb) { //OUTLOG((FUNC, TRERR, "fwrite failed\n")); fclose (ifp); fclose (ofp); return false; } } fclose (ifp); fclose (ofp); return true; } bool NFileManagerGNU::Delete (const TCHAR *Filename, bool OverWriteReadOnly) { if (OverWriteReadOnly) { chmod (TCHAR_TO_ANSI (Filename), S_IRUSR | S_IWUSR); } if (unlink (TCHAR_TO_ANSI (Filename) ) != 0) { nuxDebugMsg (TEXT ("[NFileManagerGNU::Delete] Error deleting file '%s'."), Filename); return false; } return true; } bool NFileManagerGNU::IsReadOnly (const TCHAR *Filename) { struct stat sb; if (stat (TCHAR_TO_ANSI (Filename), &sb) != 0) { nuxDebugMsg (TEXT ("[NFileManagerGNU::IsReadOnly] Error reading file status '%s'."), Filename); return false; } if ( (sb.st_mode & S_IRUSR) && ! (sb.st_mode & S_IWUSR) ) { return true; } return false; } bool NFileManagerGNU::IsDirectory (const TCHAR *DirectoryName) { struct stat sb; if (stat (TCHAR_TO_ANSI (DirectoryName), &sb) != 0) { nuxDebugMsg (TEXT ("[NFileManagerGNU::IsDirectory] Error reading file status '%s'."), DirectoryName); return false; } if (sb.st_mode & S_IFDIR) { return true; } return false; } bool NFileManagerGNU::IsHidden (const TCHAR * /* Filename */) { return false; } /*! @return TRUE is the file exist. */ bool NFileManagerGNU::GetFileAttribute (const TCHAR *Filename, bool &isDirectory, bool &isReadOnly, bool &isHidden, long long &Size) { isDirectory = false; isReadOnly = false; isHidden = false; Size = 0; struct stat sb; if (stat (TCHAR_TO_ANSI (Filename), &sb) != 0) { return false; } if (sb.st_mode & S_IFDIR) { isDirectory = true; } if ( (sb.st_mode & S_IRUSR) && ! (sb.st_mode & S_IWUSR) ) { isReadOnly = true; } Size = sb.st_mode; return true; } bool NFileManagerGNU::Move (const TCHAR * /* Dest */, const TCHAR * /* Src */, bool /* OverWriteExisting */, bool /* OverWriteReadOnly */, NFileTransferMonitor * /* Monitor */) { nuxAssert (0); return false; } bool NFileManagerGNU::MakeDirectory (const TCHAR *Path, bool CreateCompletePath) { if (CreateCompletePath) { return NFileManagerGeneric::MakeDirectory (Path, CreateCompletePath); } mkdir (TCHAR_TO_ANSI (Path), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH); // EEXIST = -2147418092 = 0x80010014 // if((errno != 0) && (errno != EEXIST)) // { // nuxDebugMsg(TEXT("[NFileManagerGNU::MakeDirectory] Error creating directory '%s'."), Path); // return NUX_ERROR; // } return NUX_OK; } bool NFileManagerGNU::DeleteDirectory (const TCHAR * /* Path */, bool /* DeleteContentFirst */) { // if(DeleteContentFirst) // { // return NFileManagerGeneric::DeleteDirectory(Path, DeleteContentFirst); // } // if((::RemoveDirectory(Path) == 0) && (::GetLastError() != ERROR_FILE_NOT_FOUND)) // { // nuxDebugMsg(TEXT("[NFileManagerWindows::DeleteDirectory] Error deleting directory '%s' (GetLastError: %d)"), Path, ::GetLastError()); // return false; // } return true; } } nux-4.0.6+14.04.20140409/NuxCore/FileManager/NFileManagerGNU.h0000644000015301777760000001205212321344237023505 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NFILEMANAGERGNU_H #define NFILEMANAGERGNU_H #include /*----------------------------------------------------------------------------- File Manager. -----------------------------------------------------------------------------*/ namespace nux { // File manager. class NGNUSerialFileReader : public NSerializer { public: NGNUSerialFileReader (int InFileDescriptor, LogOutputDevice &InError, int InSize); ~NGNUSerialFileReader(); virtual bool Precache (int PrecacheOffset, int PrecacheSize); virtual long long Seek (long long InPos, NSerializer::SeekPos seekpos); virtual long long Tell(); virtual long long GetFileSize(); virtual bool Close(); virtual void SerializeFinal (void *V, long long Length); virtual bool isReader() { return true; } virtual bool isWriter() { return false; } protected: int m_FileDescriptor; LogOutputDevice &m_Error; long long m_FileSize; long long m_FilePos; long long m_BufferBase; int m_BufferCount; BYTE *m_Buffer; static const int sBufferSize; }; class NGNUSerialFileWriter : public NSerializer { public: NGNUSerialFileWriter (int InFileDescriptor, LogOutputDevice &InError, int InPos); ~NGNUSerialFileWriter(); virtual long long Seek (long long InPos, NSerializer::SeekPos seekpos); virtual long long Tell(); virtual bool Close(); virtual void SerializeFinal (void *V, long long Length); virtual void Flush(); virtual long long GetFileSize(); virtual bool isReader() { return false; } virtual bool isWriter() { return true; } protected: void _Flush(); int m_FileDescriptor; LogOutputDevice &m_Error; long long m_Pos; int m_BufferCount; BYTE *m_Buffer; static const int sBufferSize; NCriticalSection m_CriticalSection; }; class NFileManagerGNU : public NFileManagerGeneric { NUX_DECLARE_GLOBAL_OBJECT (NFileManagerGNU, GlobalSingletonInitializer); public: // Flags is a combination of // NSerializer::OutputErrorIfFail // NSerializer::NoOverWrite // NSerializer::OverWriteReadOnly // NSerializer::Unbuffered // NSerializer::Append // NSerializer::Read virtual NSerializer *CreateFileReader (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error = GNullDevice); virtual NSerializer *CreateFileWriter (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error = GNullDevice); /*! @return Size of the File. Return -1 if an error occurs. */ long long FileSize (const TCHAR *Filename); bool FileExist (const TCHAR *Filename); int Copy (const TCHAR *DestFile, const TCHAR *SrcFile, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor *Monitor); bool Move (const TCHAR *Dest, const TCHAR *Src, bool OverWriteExisting = true, bool OverWriteReadOnly = false, NFileTransferMonitor *Monitor = NULL); bool Delete (const TCHAR *Filename, bool OverWriteReadOnly = false); bool IsReadOnly (const TCHAR *Filename); bool IsDirectory (const TCHAR *DirectoryName); bool IsHidden (const TCHAR *Filename); /*! @return TRUE is the file exist. */ bool GetFileAttribute (const TCHAR *Filename, bool &isDirectory, bool &isReadOnly, bool &isHidden, long long &Size); bool MakeDirectory (const TCHAR *Path, bool CreateCompletePath = false); bool DeleteDirectory (const TCHAR *Path, bool DeleteContentFirst = false); void FindFiles(std::vector& /* Result */, const TCHAR* /* Filename */, bool /* Files */, bool /* Directories */) {}; void ListFilesInDirectory (std::vector& /* Result */, const TCHAR* /* DirName */) {}; double GetFileAgeSeconds (const TCHAR* /* Filename */) { return 0; }; time_t GetFileLastModified (const TCHAR * /* Filename */) { return 0; }; bool SetDefaultDirectory() { return false; }; std::string GetCurrentDirectory() { return std::string(); }; bool GetTimeStamp (const TCHAR * /* Filename */, FileTimeStamp & /* Timestamp */) { return false; }; }; } #endif // NFILEMANAGERGNU_H nux-4.0.6+14.04.20140409/NuxCore/FileManager/NFileManagerWindows.h0000644000015301777760000001205512321344237024511 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NFILEMANAGERWINDOWS_H #define NFILEMANAGERWINDOWS_H /*----------------------------------------------------------------------------- File Manager. -----------------------------------------------------------------------------*/ // File manager. namespace nux { class NWindowsSerialFileReader: public NSerializer { public: NWindowsSerialFileReader (HANDLE InHandle, LogOutputDevice &InError); ~NWindowsSerialFileReader(); virtual bool Precache (int PrecacheOffset, int PrecacheSize); virtual long long Seek (long long InPos, NSerializer::SeekPos seekpos); virtual long long Tell(); virtual long long GetFileSize(); virtual bool Close(); virtual void SerializeFinal (void *V, long long Length); virtual bool isReader() { return true; } virtual bool isWriter() { return false; } protected: HANDLE m_FileHandle; LogOutputDevice &m_Error; long long m_FileSize; long long m_FilePos; long long m_BufferBase; int m_BufferCount; BYTE *m_Buffer; static const int sBufferSize; }; class NWindowsSerialFileWriter : public NSerializer { public: NWindowsSerialFileWriter (HANDLE InHandle, LogOutputDevice &InError); ~NWindowsSerialFileWriter(); virtual long long Seek (long long InPos, NSerializer::SeekPos seekpos); virtual long long Tell(); virtual bool Close(); virtual void SerializeFinal (void *V, long long Length); virtual void Flush(); virtual long long GetFileSize(); virtual bool isReader() { return false; } virtual bool isWriter() { return true; } protected: void _Flush(); HANDLE m_FileHandle; LogOutputDevice &m_Error; long long m_Pos; int m_BufferCount; BYTE *m_Buffer; static const int sBufferSize; NCriticalSection m_CriticalSection; }; class NFileManagerWindows : public NFileManagerGeneric { NUX_DECLARE_GLOBAL_OBJECT (NFileManagerWindows, GlobalSingletonInitializer); public: // Flags is a combination of // NSerializer::OutputErrorIfFail // NSerializer::NoOverWrite // NSerializer::OverWriteReadOnly // NSerializer::Unbuffered // NSerializer::Append // NSerializer::Read virtual NSerializer *CreateFileReader (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error = GNullDevice); virtual NSerializer *CreateFileWriter (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error = GNullDevice); HANDLE CreateReadFileHandle (const TCHAR *Filename, DWORD Flags); HANDLE CreateWriteFileHandle (const TCHAR *Filename, DWORD Flags); /*! @return Size of the File. Return -1 if an error occurs. */ long long FileSize (const TCHAR *Filename); bool FileExist (const TCHAR *Filename); int Copy (const TCHAR *DestFile, const TCHAR *SrcFile, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor *Monitor); bool Move (const TCHAR *Dest, const TCHAR *Src, bool OverWriteExisting = true, bool OverWriteReadOnly = false, NFileTransferMonitor *Monitor = NULL); bool Delete (const TCHAR *Filename, bool OverWriteReadOnly = false); bool IsReadOnly (const TCHAR *Filename); bool IsDirectory (const TCHAR *DirectoryName); bool IsHidden (const TCHAR *Filename); /*! @return TRUE is the file exist. */ bool GetFileAttribute (const TCHAR *Filename, bool &isDirectory, bool &isReadOnly, bool &isHidden, long long &Size); bool MakeDirectory (const TCHAR *Path, bool CreateCompletePath = false); bool DeleteDirectory (const TCHAR *Path, bool DeleteContentFirst = false); void FindFiles (std::vector& Result, const TCHAR *Filename, bool Files, bool Directories); void ListFilesInDirectory (std::vector& Result, const TCHAR *DirName); double GetFileAgeSeconds (const TCHAR *Filename); time_t GetFileLastModified (const TCHAR *Filename); bool GetFileLastModified (const TCHAR *Filename, SYSTEMTIME &sysTime, bool bLocalTime); bool SetDefaultDirectory(); std::string GetCurrentDirectory(); bool GetTimeStamp (const TCHAR *Filename, FileTimeStamp &Timestamp); }; } #endif // NFILEMANAGERWINDOWS_H nux-4.0.6+14.04.20140409/NuxCore/FileManager/NFileManagerWindows.cpp0000644000015301777760000006257412321344237025057 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "Math/MathUtility.h" namespace nux { // Choose the size so it is a power of 2. Example (size-1)= 11111111. const int NWindowsSerialFileReader::sBufferSize = 1024; NWindowsSerialFileReader::NWindowsSerialFileReader (HANDLE InHandle, LogOutputDevice &InError) : m_FileHandle (InHandle) , m_Error (InError) , m_FilePos (0) , m_BufferBase (0) , m_BufferCount (0) { m_Buffer = new BYTE[sBufferSize]; m_FileSize = GetFileSize(); } NWindowsSerialFileReader::~NWindowsSerialFileReader() { NUX_SAFE_DELETE_ARRAY (m_Buffer); if (m_FileHandle) { Close(); } } bool NWindowsSerialFileReader::Precache (int PrecacheOffset, int PrecacheSize) { // Only pre-cache at current position and avoid work if pre-caching same offset twice. if ( (m_FilePos == PrecacheOffset) && (!m_BufferBase || !m_BufferCount || m_BufferBase != m_FilePos) ) { m_BufferBase = m_FilePos; // (sBufferSize - 1) contains only '1', i.e 1111111111. // So (m_FilePos & (sBufferSize-1)) is equal to m_FilePos if m_FilePos <= (sBufferSize-1). m_BufferCount = Min (Min (PrecacheSize, (int) (sBufferSize - (m_FilePos & (sBufferSize - 1) ) ) ), m_FileSize - m_FilePos); unsigned int Count = 0; //GTotalBytesReadViaFileManager += m_BufferCount; ::ReadFile (m_FileHandle, m_Buffer, m_BufferCount, NUX_REINTERPRET_CAST (DWORD *, &Count), NULL); if (Count != m_BufferCount) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("ReadFile failed: Count=%i BufferCount=%i Error=%s"), Count, m_BufferCount, inlGetSystemErrorMessage() ); } } return TRUE; } long long NWindowsSerialFileReader::Seek (long long InPos, NSerializer::SeekPos seekpos) { nuxAssert (InPos >= 0); nuxAssert (InPos <= m_FileSize); Flush(); // Because we precache our reads, we must perform Seek accordingly. LARGE_INTEGER pos; pos.QuadPart = m_FilePos; LARGE_INTEGER filepos; filepos.QuadPart = 0; // Set the file pointer to m_FilePos. if (::SetFilePointerEx (m_FileHandle, pos, &filepos, FILE_BEGIN) == 0) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("SetFilePointer Failed %i/%i: %i %s"), InPos, m_FileSize, m_FilePos, inlGetSystemErrorMessage() ); } // Now the file pointer is current with what we have read so far. pos.QuadPart = InPos; filepos.QuadPart = 0; if (::SetFilePointerEx (m_FileHandle, pos, &filepos, (seekpos == SeekStart) ? FILE_BEGIN : (seekpos == SeekCurrent) ? FILE_CURRENT : FILE_END) == 0) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("SetFilePointer Failed %i/%i: %i %s"), InPos, m_FileSize, m_FilePos, inlGetSystemErrorMessage() ); } m_FilePos = filepos.QuadPart; m_BufferBase = 0; m_BufferCount = 0; Precache (m_FilePos, sBufferSize); return filepos.QuadPart; } long long NWindowsSerialFileReader::Tell() { // Flush(); // LARGE_INTEGER pos; // LARGE_INTEGER filepos; // pos.QuadPart = 0; // ::SetFilePointerEx(m_FileHandle, pos, &filepos, FILE_CURRENT); // return filepos.QuadPart; return m_FilePos; } long long NWindowsSerialFileReader::GetFileSize() { nuxAssert (m_FileHandle); if (m_FileHandle == NULL) return -1; long long Size = 0; if (::GetFileSizeEx (m_FileHandle, NUX_REINTERPRET_CAST (PLARGE_INTEGER, &Size) ) == 0) { Size = -1; } m_FileSize = Size > 0 ? Size : 0; return Size; } bool NWindowsSerialFileReader::Close() { if (m_FileHandle) { CloseHandle (m_FileHandle); } m_FileHandle = NULL; return !m_ErrorCode; } void NWindowsSerialFileReader::SerializeFinal (void* Dest, long long Length) { nuxAssert (Dest); while (Length > 0) { int DataSize = Min (Length, m_BufferBase + m_BufferCount - m_FilePos); if (DataSize == 0) { if (Length >= sBufferSize) { int Count = 0; //GTotalBytesReadViaFileManager += Length; ReadFile (m_FileHandle, Dest, Length, (DWORD*) &Count, NULL); if (Count != Length) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("ReadFile failed: Count=%i Length=%i Error=%s"), Count, Length, inlGetSystemErrorMessage() ); } m_FilePos += Length; m_BufferBase += Length; return; } Precache (m_FilePos, 0x7FFFFFFF); DataSize = Min (Length, m_BufferBase + m_BufferCount - m_FilePos); if (DataSize <= 0) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("ReadFile beyond EOF %i+%i/%i"), m_FilePos, Length, m_FileSize); } if (m_ErrorCode) return; } Memcpy (Dest, m_Buffer + m_FilePos - m_BufferBase, DataSize); m_FilePos += DataSize; Length -= DataSize; Dest = (BYTE *) Dest + DataSize; } } ////////////////////////////////////////////////////////////////////////// // Choose the size so it is a power of 2. Example (size-1)= 11111111. const int NWindowsSerialFileWriter::sBufferSize = 32; //NCriticalSection NWindowsSerialFileWriter::m_CriticalSection; NWindowsSerialFileWriter::NWindowsSerialFileWriter (HANDLE InHandle, LogOutputDevice &InError) : m_FileHandle (InHandle) , m_Error (InError) , m_BufferCount (0) { m_Pos = Tell(); m_Buffer = new BYTE[sBufferSize]; } NWindowsSerialFileWriter::~NWindowsSerialFileWriter() { NUX_SAFE_DELETE_ARRAY (m_Buffer); if (m_FileHandle) Close(); m_FileHandle = NULL; } long long NWindowsSerialFileWriter::Seek (long long InPos, NSerializer::SeekPos seekpos) { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileHandle); if (m_FileHandle == NULL) return -1; _Flush(); LARGE_INTEGER pos; pos.QuadPart = InPos; LARGE_INTEGER filepos; filepos.QuadPart = 0; if (::SetFilePointerEx (m_FileHandle, pos, &filepos, (seekpos == SeekStart) ? FILE_BEGIN : (seekpos == SeekCurrent) ? FILE_CURRENT : FILE_END) == 0) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("SeekFailed") ); } m_Pos = filepos.QuadPart; return filepos.QuadPart; } long long NWindowsSerialFileWriter::Tell() { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileHandle); if (m_FileHandle == NULL) return -1; _Flush(); LARGE_INTEGER pos; LARGE_INTEGER filepos; filepos.QuadPart = 0; pos.QuadPart = 0; ::SetFilePointerEx (m_FileHandle, pos, &filepos, FILE_CURRENT); return filepos.QuadPart; } bool NWindowsSerialFileWriter::Close() { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileHandle); if (m_FileHandle == NULL) return true; _Flush(); if (m_FileHandle && !CloseHandle (m_FileHandle) ) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("WriteFailed") ); } m_FileHandle = NULL; return !m_ErrorCode; } long long NWindowsSerialFileWriter::GetFileSize() { nuxAssert (m_FileHandle); if (m_FileHandle == NULL) return -1; long long Size = 0; if (::GetFileSizeEx (m_FileHandle, NUX_REINTERPRET_CAST (PLARGE_INTEGER, &Size) ) == 0) { Size = -1; } return Size; } void NWindowsSerialFileWriter::SerializeFinal (void *V, long long Length) { // This method is not re-entrant by itself. It relies on m_Buffer and other variables // that belong to this object. Therefore, it is not thread safe. We add a critical section // to make it thread safe. NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileHandle); nuxAssert (V); NUX_RETURN_IF_NULL (m_FileHandle); m_Pos += Length; int FreeSpace; while (Length > (FreeSpace = sBufferSize - m_BufferCount) ) { // m_Buffer is Full. Write it to the file. Memcpy (m_Buffer + m_BufferCount, V, FreeSpace); m_BufferCount += FreeSpace; Length -= FreeSpace; V = (BYTE *) V + FreeSpace; _Flush(); } if (Length) { Memcpy (m_Buffer + m_BufferCount, V, Length); m_BufferCount += Length; // Count the number of Characters stored in m_Buffer. } } void NWindowsSerialFileWriter::Flush() { NScopeLock Scope (&m_CriticalSection); nuxAssert (m_FileHandle); if (m_FileHandle == NULL) return; _Flush(); } void NWindowsSerialFileWriter::_Flush() { //GTotalBytesWrittenViaFileManager += m_BufferCount; if (m_BufferCount) { int Result = 0; if (!WriteFile (m_FileHandle, m_Buffer, m_BufferCount, (DWORD *) &Result, NULL) ) { m_ErrorCode = 1; m_Error.LogFunction (NUX_MSG_SEVERITY_NONE, TEXT ("[NWindowsSerialFileWriter::_Flush] Write failed") ); } } m_BufferCount = 0; } ////////////////////////////////////////////////////////////////////////// NUX_IMPLEMENT_GLOBAL_OBJECT (NFileManagerWindows); void NFileManagerWindows::Constructor() { } void NFileManagerWindows::Destructor() { } HANDLE NFileManagerWindows::CreateReadFileHandle (const TCHAR *Filename, DWORD Flags) { DWORD Access = GENERIC_READ; DWORD Create = OPEN_EXISTING; DWORD SharedModeFlags = 0; SharedModeFlags |= (Flags & NSerializer::Read) ? FILE_SHARE_READ : 0; SharedModeFlags |= (Flags & NSerializer::Write) ? FILE_SHARE_WRITE : 0; HANDLE Handle = ::CreateFile (Filename, Access, SharedModeFlags, NULL, Create, FILE_ATTRIBUTE_NORMAL, NULL); if (Handle == INVALID_HANDLE_VALUE) { if (Flags & NSerializer::OutputErrorIfFail) nuxError (TEXT ("Failed to read file: %s"), Filename); } return Handle; } NSerializer *NFileManagerWindows::CreateFileReader (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error) { HANDLE Handle = CreateReadFileHandle (Filename, Flags); if (Handle == INVALID_HANDLE_VALUE) { return 0; } return new NWindowsSerialFileReader (Handle, Error); } HANDLE NFileManagerWindows::CreateWriteFileHandle (const TCHAR *Filename, DWORD Flags) { if (Flags & NSerializer::OverWriteReadOnly) { ::SetFileAttributes (Filename, 0); } DWORD Access = GENERIC_WRITE; DWORD SharedModeFlags = 0; SharedModeFlags |= (Flags & NSerializer::Read) ? FILE_SHARE_READ : 0; SharedModeFlags |= (Flags & NSerializer::Write) ? FILE_SHARE_WRITE : 0; DWORD Create = 0; Create |= (Flags & NSerializer::Append) ? OPEN_ALWAYS : 0; Create |= (Flags & NSerializer::NoOverWrite) ? CREATE_NEW /*fail if the file already exist*/ : CREATE_ALWAYS /*create the file if it does not exist*/; HANDLE Handle = ::CreateFile (Filename, Access, SharedModeFlags, NULL, Create, FILE_ATTRIBUTE_NORMAL, NULL); if (Handle == INVALID_HANDLE_VALUE) { if (Flags & NSerializer::OutputErrorIfFail) { nuxError (TEXT ("[NFileManagerWindows::CreateFileWriter] Failed to create file %s (GetLastError: %d)"), Filename, ::GetLastError() ); } } if ( (Flags & NSerializer::Append) && (Handle != INVALID_HANDLE_VALUE) ) { int Pos = ::SetFilePointer (Handle, 0, 0, FILE_END); } return Handle; } NSerializer *NFileManagerWindows::CreateFileWriter (const TCHAR *Filename, DWORD Flags, LogOutputDevice &Error) { HANDLE Handle = CreateWriteFileHandle (Filename, Flags); if (Handle == INVALID_HANDLE_VALUE) { return 0; } return new NWindowsSerialFileWriter (Handle, Error); } /*! @return Size of the File. Return -1 if an error occurs. */ long long NFileManagerWindows::FileSize (const TCHAR *Filename) { HANDLE Handle = ::CreateFile (Filename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (Handle == INVALID_HANDLE_VALUE) { LPVOID lpMsgBuf = 0; ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, ::GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); nuxDebugMsg (TEXT ("[NFileManagerWindows::FileSize] Failed to open file %s for attribute read (GetLastError: %d - %s)"), Filename, ::GetLastError(), lpMsgBuf); ::LocalFree (lpMsgBuf); return -1; } long long Size = 0; if (::GetFileSizeEx (Handle, NUX_REINTERPRET_CAST (PLARGE_INTEGER, &Size) ) == 0) { Size = -1; } CloseHandle (Handle); return Size; } bool NFileManagerWindows::FileExist (const TCHAR *Filename) { WIN32_FILE_ATTRIBUTE_DATA FileAttrData; if (::GetFileAttributesEx (Filename, GetFileExInfoStandard, NUX_STATIC_CAST (void *, &FileAttrData) ) ) { return true; } return false; } int NFileManagerWindows::Copy (const TCHAR *DestFile, const TCHAR *SrcFile, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor *Monitor) { // In case file exist and OverWriteReadOnly is true, Remove the ReadOnly attribute from the file. if (OverWriteReadOnly) { ::SetFileAttributes (DestFile, FILE_ATTRIBUTE_NORMAL); } DWORD Flags = (OverWriteExisting ? 0 : COPY_FILE_FAIL_IF_EXISTS); BOOL *pCancel = NULL; if (Monitor) pCancel = & (Monitor->m_bCancel); if (::CopyFileEx (SrcFile, DestFile, NFileTransferMonitor::CopyProgressRoutine, NUX_REINTERPRET_CAST (void *, Monitor), pCancel, Flags) == 0) { LPVOID lpMsgBuf = 0; ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, ::GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); nuxDebugMsg (TEXT ("[NFileManagerWindows::Copy] Error copying file from '%s' to '%s'(GetLastError: %d - %s)"), SrcFile, DestFile, ::GetLastError(), lpMsgBuf); ::LocalFree (lpMsgBuf); return false; } ::SetFileAttributes (DestFile, FILE_ATTRIBUTE_NORMAL); return true; } bool NFileManagerWindows::Delete (const TCHAR *Filename, bool OverWriteReadOnly) { if (OverWriteReadOnly) { ::SetFileAttributes (Filename, FILE_ATTRIBUTE_NORMAL); } if ( (::DeleteFile (Filename) == 0) && (GetLastError() != ERROR_FILE_NOT_FOUND) ) { LPVOID lpMsgBuf = 0; ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, ::GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); nuxDebugMsg (TEXT ("[NFileManagerWindows::Delete] Error deleting file '%s' (GetLastError: %d - %s)"), Filename, ::GetLastError(), lpMsgBuf); ::LocalFree (lpMsgBuf); return false; } return true; } bool NFileManagerWindows::IsReadOnly (const TCHAR *Filename) { WIN32_FILE_ATTRIBUTE_DATA FileAttrData; if (::GetFileAttributesEx (Filename, GetFileExInfoStandard, NUX_STATIC_CAST (void *, &FileAttrData) ) ) { return ( (FileAttrData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0); } else { nuxDebugMsg (TEXT ("[NFileManagerWindows::IsReadOnly]: Error reading attributes for file '%s'"), Filename); } return false; } bool NFileManagerWindows::IsDirectory (const TCHAR *DirectoryName) { WIN32_FILE_ATTRIBUTE_DATA FileAttrData; if (::GetFileAttributesEx (DirectoryName, GetFileExInfoStandard, NUX_STATIC_CAST (void *, &FileAttrData) ) ) { return ( (FileAttrData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); } else { nuxDebugMsg (TEXT ("[NFileManagerWindows::IsDirectory]: Error reading attributes for directory '%s'"), DirectoryName); } return false; } bool NFileManagerWindows::IsHidden (const TCHAR *Filename) { WIN32_FILE_ATTRIBUTE_DATA FileAttrData; if (::GetFileAttributesEx (Filename, GetFileExInfoStandard, NUX_STATIC_CAST (void *, &FileAttrData) ) ) { return ( (FileAttrData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0); } else { nuxDebugMsg (TEXT ("[NFileManagerWindows::IsHidden]: Error reading attributes for file '%s'"), Filename); } return false; } /*! @return TRUE is the file exist. */ bool NFileManagerWindows::GetFileAttribute (const TCHAR *Filename, bool &isDirectory, bool &isReadOnly, bool &isHidden, long long &Size) { isDirectory = false; isReadOnly = false; isHidden = false; Size = 0; WIN32_FILE_ATTRIBUTE_DATA FileAttrData; if (::GetFileAttributesEx (Filename, GetFileExInfoStandard, (void *) &FileAttrData) ) { isDirectory = ( (FileAttrData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); isReadOnly = ( (FileAttrData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0); isHidden = ( (FileAttrData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0); Size = FileAttrData.nFileSizeLow | ( (long long) (FileAttrData.nFileSizeHigh) << 32); } else { nuxDebugMsg (TEXT ("[NFileManagerWindows::GetFileAttribute]: Error reading attributes for file '%s'"), Filename); return (0); } return TRUE; } bool NFileManagerWindows::Move (const TCHAR *Dest, const TCHAR *Src, bool Replace, bool EvenIfReadOnly, NFileTransferMonitor *Monitor) { DWORD Flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_FAIL_IF_NOT_TRACKABLE; Flags |= (EvenIfReadOnly ? MOVEFILE_REPLACE_EXISTING : 0); BOOL *pCancel = NULL; if (Monitor) pCancel = & (Monitor->m_bCancel); if (::MoveFileWithProgress (Src, Dest, NFileTransferMonitor::CopyProgressRoutine, NUX_REINTERPRET_CAST (void *, Monitor), Flags) != 0) { nuxDebugMsg (TEXT ("[NFileManagerWindows::Move] Error moving file '%s' to '%s' (GetLastError: %d)"), Src, Dest, ::GetLastError() ); return false; } return true; } bool NFileManagerWindows::MakeDirectory (const TCHAR *Path, bool CreateCompletePath) { if (CreateCompletePath) { return NFileManagerGeneric::MakeDirectory (Path, CreateCompletePath); } if ( (::CreateDirectory (Path, NULL) == 0) && (::GetLastError() != ERROR_ALREADY_EXISTS) ) { nuxDebugMsg (TEXT ("[NFileManagerWindows::MakeDirectory] Error creating directory '%s' (GetLastError: %d)"), Path, ::GetLastError() ); return NUX_ERROR; } return NUX_OK; } bool NFileManagerWindows::DeleteDirectory (const TCHAR *Path, bool DeleteContentFirst) { if (DeleteContentFirst) { return NFileManagerGeneric::DeleteDirectory (Path, DeleteContentFirst); } if ( (::RemoveDirectory (Path) == 0) && (::GetLastError() != ERROR_FILE_NOT_FOUND) ) { nuxDebugMsg (TEXT ("[NFileManagerWindows::DeleteDirectory] Error deleting directory '%s' (GetLastError: %d)"), Path, ::GetLastError() ); return false; } return true; } void NFileManagerWindows::FindFiles (std::vector& Result, const TCHAR *Filename, bool Files, bool Directories) { HANDLE Handle = INVALID_HANDLE_VALUE; WIN32_FIND_DATA SearchData; Handle = ::FindFirstFile (Filename, &SearchData); if (Handle != INVALID_HANDLE_VALUE) { do { if (Stricmp (SearchData.cFileName, TEXT (".") ) && Stricmp (SearchData.cFileName, TEXT ("..") ) && ! (SearchData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) && ! (SearchData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) { if ( (SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? Directories : Files) Result.push_back (std::string(SearchData.cFileName) ); } } while (::FindNextFile (Handle, &SearchData) ); } if (Handle != INVALID_HANDLE_VALUE) ::FindClose (Handle); } void NFileManagerWindows::ListFilesInDirectory (std::vector& Result, const TCHAR *DirName) { WIN32_FIND_DATA SearchData; HANDLE Handle = INVALID_HANDLE_VALUE; std::string DirectoryName = DirName; DirectoryName += TEXT ("\\*"); Handle = ::FindFirstFile (DirectoryName.c_str(), &SearchData); if (Handle != INVALID_HANDLE_VALUE) { // List all the other files in the directory. do { if (Stricmp (SearchData.cFileName, TEXT (".") ) && Stricmp (SearchData.cFileName, TEXT ("..") ) && ! (SearchData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) && ! (SearchData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ) { Result.push_back(std::string(SearchData.cFileName)); } } while (::FindNextFile (Handle, &SearchData) ); } if (Handle != INVALID_HANDLE_VALUE) ::FindClose (Handle); } double NFileManagerWindows::GetFileAgeSeconds (const TCHAR *Filename) { struct _stat FileInfo; if (_tstat (Filename, &FileInfo) == 0) { time_t CurrentTime, FileTime; FileTime = FileInfo.st_mtime; time (&CurrentTime); return difftime (CurrentTime, FileTime); } return -1.0; } time_t NFileManagerWindows::GetFileLastModified (const TCHAR *Filename) { struct _stat FileInfo; if (_tstat (Filename, &FileInfo) == 0) { time_t FileTime; FileTime = FileInfo.st_mtime; return FileTime; } return -1; } // bool GetFileLastModified(const TCHAR* Filename, SYSTEMTIME& sysTime, bool bLocalTime) // { // ZeroMemory(&sysTime, sizeof(SYSTEMTIME)); // // DWORD dwAttr = ::GetFileAttributes(Filename); // // // files only // if (dwAttr == 0xFFFFFFFF) // return false; // // WIN32_FIND_DATA findFileData; // HANDLE hFind = ::FindFirstFile((LPTSTR)Filename, &findFileData); // // if (hFind == INVALID_HANDLE_VALUE) // return FALSE; // // ::FindClose(hFind); // // FILETIME ft = findFileData.ftLastWriteTime; // // if (bLocalTime) // ::FileTimeToLocalFileTime(&findFileData.ftLastWriteTime, &ft); // // ::FileTimeToSystemTime(&ft, &sysTime); // return true; // } bool NFileManagerWindows::SetDefaultDirectory() { return CALL_OS_TCHAR_FUNCTION(SetCurrentDirectoryW(GetProgramDirectory()), SetCurrentDirectoryA(TCHAR_TO_ANSI(GetProgramDirectory().c_str()))) != 0; } std::string NFileManagerWindows::GetCurrentDirectory() { #if UNICODE TCHAR Buffer[1024] = TEXT (""); ::GetCurrentDirectoryW (NUX_ARRAY_COUNT (Buffer), Buffer); return std::string(Buffer); #else ANSICHAR Buffer[1024] = ""; ::GetCurrentDirectoryA (NUX_ARRAY_COUNT (Buffer), Buffer); return std::string(Buffer); #endif } bool NFileManagerWindows::GetTimeStamp (const TCHAR *Filename, FileTimeStamp &Timestamp) { Memzero (&Timestamp, sizeof (Timestamp) ); struct _stat FileInfo; if (_tstat (Filename, &FileInfo) == 0) { #ifdef WIN32_SECURE __time64_t FileTime; // FileTime represents seconds elapsed since midnight (00:00:00), January 1, 1970, coordinated universal time (UTC). FileTime = FileInfo.st_mtime; tm pTime; // _gmtime64_s can express time up to 23:59:59, December 31, 3000, UTC _gmtime64_s (&pTime, &FileTime); Timestamp.Day = pTime.tm_mday; Timestamp.DayOfWeek = pTime.tm_wday; Timestamp.DayOfYear = pTime.tm_yday; Timestamp.Hour = pTime.tm_hour; Timestamp.Minute = pTime.tm_min; Timestamp.Second = pTime.tm_sec; Timestamp.Year = pTime.tm_year + 1900; #else time_t FileTime; // FileTime represents seconds elapsed since midnight (00:00:00), January 1, 1970, coordinated universal time (UTC). FileTime = FileInfo.st_mtime; // gmtime can express time up to 03:14:07 January 19, 2038, UTC tm *pTime = gmtime (&FileTime); Timestamp.Day = pTime->tm_mday; Timestamp.DayOfWeek = pTime->tm_wday; Timestamp.DayOfYear = pTime->tm_yday; Timestamp.Hour = pTime->tm_hour; Timestamp.Minute = pTime->tm_min; Timestamp.Second = pTime->tm_sec; Timestamp.Year = pTime->tm_year + 1900; #endif return TRUE; } return FALSE; } } nux-4.0.6+14.04.20140409/NuxCore/FileManager/NSerializer.cpp0000644000015301777760000001167012321344237023432 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" namespace nux { // template // void NSerializer::SerializeBuffer(T* buffer, unsigned long long Length, unsigned long long ElementSize) // { // for(unsigned long long i = 0; i < Length; i++) // { // unsigned char* bytebuffer = (unsigned char*)(&buffer[i]); // Serialize(bytebuffer, ElementSize); // } // } // NSerializer& operator << (NSerializer& Sr, std::string& s) // { // Sr.SerializeBuffer(NUX_CONST_CAST(TCHAR*, s.GetTCharPtr()), s.Size()+1, sizeof(TCHAR)); // return Sr; // } // // NSerializer& operator << (NSerializer& Sr, std::string& s) // { // Sr.SerializeBuffer(NUX_CONST_CAST(char*, s.c_str()), s.size()+1, sizeof(char)); // return Sr; // } void NSerializer::Serialize (char &data) { SerializeFinal (&data, sizeof (char) ); } void NSerializer::Serialize (wchar_t &data) { SerializeFinal (&data, sizeof (wchar_t) ); } void NSerializer::Serialize (bool &data) { SerializeFinal (&data, sizeof (bool) ); } void NSerializer::Serialize (unsigned char &data) { SerializeFinal (&data, sizeof (unsigned char) ); } void NSerializer::Serialize (unsigned short &data) { SerializeFinal (&data, sizeof (unsigned short) ); } void NSerializer::Serialize (short &data) { SerializeFinal (&data, sizeof (short) ); } void NSerializer::Serialize (unsigned int &data) { SerializeFinal (&data, sizeof (unsigned int) ); } void NSerializer::Serialize (int &data) { SerializeFinal (&data, sizeof (int) ); } void NSerializer::Serialize (long &data) { SerializeFinal (&data, sizeof (long) ); } void NSerializer::Serialize (unsigned long &data) { SerializeFinal (&data, sizeof (unsigned long) ); } void NSerializer::Serialize (float &data) { SerializeFinal (&data, sizeof (float) ); } void NSerializer::Serialize (double &data) { SerializeFinal (&data, sizeof (double) ); } void NSerializer::Serialize (unsigned long long &data) { SerializeFinal (&data, sizeof (unsigned long long) ); } void NSerializer::Serialize (long long &data) { SerializeFinal (&data, sizeof (long long) ); } void NSerializer::Serialize (wchar_t *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (bool *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (char *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (unsigned char *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (unsigned short *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (short *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (unsigned int *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (int *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (long *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (unsigned long *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (float *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (double *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (unsigned long long *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } void NSerializer::Serialize (long long *buffer, unsigned int len, unsigned int stride) { SerializeFinal (buffer, len * stride); } } nux-4.0.6+14.04.20140409/NuxCore/Character/0000755000015301777760000000000012321344711020211 5ustar pbusernogroup00000000000000nux-4.0.6+14.04.20140409/NuxCore/Character/NUTF.h0000644000015301777760000000733212321344237021146 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUTF_H #define NUTF_H // http://en.wikipedia.org/wiki/UTF-16 // In computing, UTF-16 (16-bit Unicode Transformation Format) is a variable-length character encoding // for Unicode, capable of encoding the entire Unicode repertoire. The encoding form maps code points // (characters) into a sequence of 16-bit words, called code units. For characters in the Basic // Multilingual Plane (BMP) the resulting encoding is a single 16-bit word. For characters in the other // planes, the encoding will result in a pair of 16-bit words, together called a surrogate pair. All possible // code points from U+0000 through U+10FFFF, except for the surrogate code points U+D800U+DFFF // (which are not characters), are uniquely mapped by UTF-16 regardless of the code point's current or // future character assignment or use. // // As many uses in computing require units of bytes (octets) there are three related encoding schemes // which map to octet sequences instead of words: namely UTF-16, UTF-16BE, and UTF-16LE. They // differ only in the byte order chosen to represent each 16-bit unit and whether they make use of a // Byte Order Mark. All of the schemes will result in either a 2 or 4-byte sequence for any given character. // // UTF-16 is officially defined in Annex Q of the international standard ISO/IEC 10646-1. It is also // described in The Unicode Standard version 3.0 and higher, as well as in the IETF's RFC 2781. // // UCS-2 (2-byte Universal Character Set) is an obsolete character encoding which is a predecessor // to UTF-16. The UCS-2 encoding form is nearly identical to that of UTF-16, except that it does not // support surrogate pairs and therefore can only encode characters in the BMP range U+0000 through // U+FFFF. As a consequence it is a fixed-length encoding that always encodes characters into a // single 16-bit value. As with UTF-16, there are three related encoding schemes (UCS-2, UCS-2BE, UCS-2LE) // that map characters to a specific byte sequence. // // Because of the technical similarities and upwards compatibility from UCS-2 to UTF-16, the two // encodings are often erroneously conflated and used as if interchangeable, so that strings encoded // in UTF-16 are sometimes misidentified as being encoded in UCS-2. namespace nux { //! Convert UTF-16 to UTF-8 class NUTF8 { // UTF-8 encoded characters may theoretically be up to six bytes long, however 16-bit BMP characters are only up to three bytes long. public: explicit NUTF8 (const UNICHAR *Source); explicit NUTF8 (const std::wstring &Source); ~NUTF8(); operator const char* (); private: void Convert (const UNICHAR *); //void Convert(const t_UTF32*); char *utf8; }; //! Convert UTF-8 to UTF-16 class NUTF16 { public: explicit NUTF16 (const char *Source); explicit NUTF16 (const std::string &Source); ~NUTF16(); operator const UNICHAR* (); private: void Convert (const char *); UNICHAR *unicode; }; } #endif // NUTF_H nux-4.0.6+14.04.20140409/NuxCore/Character/NAscii.h0000644000015301777760000000164612321344237021542 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NTASCII_H #define NTASCII_H namespace nux { extern t_uchar GAscii[]; extern t_uchar GAsciiCP437[]; } #endif // NTASCII_H nux-4.0.6+14.04.20140409/NuxCore/Character/NUni.h0000644000015301777760000001602012321344237021235 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUNI_H #define NUNI_H /* * Copyright 2001-2004 Unicode, Inc. * * Disclaimer * * This source code is provided as is by Unicode, Inc. No claims are * made as to fitness for any particular purpose. No warranties of any * kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been * purchased on magnetic or optical media from Unicode, Inc., the * sole remedy for any claim will be exchange of defective media * within 90 days of receipt. * * Limitations on Rights to Redistribute This Code * * Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard, and to make copies of this file in any form * for internal or external distribution as long as this notice * remains attached. */ /* --------------------------------------------------------------------- Conversions between UTF32, UTF-16, and UTF-8. Header file. Several funtions are included here, forming a complete set of conversions between the three formats. UTF-7 is not included here, but is handled in a separate source file. Each of these routines takes pointers to input buffers and output buffers. The input buffers are const. Each routine converts the text between *sourceStart and sourceEnd, putting the result into the buffer between *targetStart and targetEnd. Note: the end pointers are *after* the last item: e.g. *(sourceEnd - 1) is the last item. The return result indicates whether the conversion was successful, and if not, whether the problem was in the source or target buffers. (Only the first encountered problem is indicated.) After the conversion, *sourceStart and *targetStart are both updated to point to the end of last text successfully converted in the respective buffers. Input parameters: sourceStart - pointer to a pointer to the source buffer. The contents of this are modified on return so that it points at the next thing to be converted. targetStart - similarly, pointer to pointer to the target buffer. sourceEnd, targetEnd - respectively pointers to the ends of the two buffers, for overflow checking only. These conversion functions take a ConversionFlags argument. When this flag is set to strict, both irregular sequences and isolated surrogates will cause an error. When the flag is set to lenient, both irregular sequences and isolated surrogates are converted. Whether the flag is strict or lenient, all illegal sequences will cause an error return. This includes sequences such as: , , or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code must check for illegal sequences. When the flag is set to lenient, characters over 0x10FFFF are converted to the replacement character; otherwise (when the flag is set to strict) they constitute an error. Output parameters: The value "sourceIllegal" is returned from some routines if the input sequence is malformed. When "sourceIllegal" is returned, the source value will point to the illegal value that caused the problem. E.g., in UTF-8 when a sequence is malformed, it points to the start of the malformed sequence. Author: Mark E. Davis, 1994. Rev History: Rick McGowan, fixes & updates May 2001. Fixes & updates, Sept 2001. ------------------------------------------------------------------------ */ /* --------------------------------------------------------------------- The following 4 definitions are compiler-specific. The C standard does not guarantee that wchar_t has at least 16 bits, so wchar_t is no less portable than unsigned short! All should be unsigned values to avoid sign extension during bit mask & shift operations. ------------------------------------------------------------------------ */ //typedef unsigned long unsigned int; /* at least 32 bits */ //typedef unsigned short wchar_t; /* at least 16 bits */ //typedef unsigned char unsigned char; /* typically 8 bits */ //typedef unsigned char Boolean; /* 0 or 1 */ namespace nux { /* Some fundamental constants */ #define UNI_REPLACEMENT_CHAR (unsigned int)0x0000FFFD #define UNI_MAX_BMP (unsigned int)0x0000FFFF #define UNI_MAX_UTF16 (unsigned int)0x0010FFFF #define UNI_MAX_UTF32 (unsigned int)0x7FFFFFFF #define UNI_MAX_LEGAL_UTF32 (unsigned int)0x0010FFFF typedef enum { conversionOK = 0, /* conversion successful */ sourceExhausted, /* partial character in source, but hit end */ targetExhausted, /* insuff. room in target for conversion */ sourceIllegal /* source sequence is illegal/malformed */ } ConversionResult; typedef enum { strictConversion = 0, lenientConversion } ConversionFlags; ConversionResult ConvertUTF8toUTF16 ( const unsigned char **sourceStart, const unsigned char *sourceEnd, wchar_t **targetStart, wchar_t *targetEnd, ConversionFlags flags); ConversionResult ConvertUTF16toUTF8 ( const wchar_t **sourceStart, const wchar_t *sourceEnd, unsigned char **targetStart, unsigned char *targetEnd, ConversionFlags flags); ConversionResult ConvertUTF8toUTF32 ( const unsigned char **sourceStart, const unsigned char *sourceEnd, unsigned int **targetStart, unsigned int *targetEnd, ConversionFlags flags); ConversionResult ConvertUTF32toUTF8 ( const unsigned int **sourceStart, const unsigned int *sourceEnd, unsigned char **targetStart, unsigned char *targetEnd, ConversionFlags flags); ConversionResult ConvertUTF16toUTF32 ( const wchar_t **sourceStart, const wchar_t *sourceEnd, unsigned int **targetStart, unsigned int *targetEnd, ConversionFlags flags); ConversionResult ConvertUTF32toUTF16 ( const unsigned int **sourceStart, const unsigned int *sourceEnd, wchar_t **targetStart, wchar_t *targetEnd, ConversionFlags flags); bool isLegalUTF8Sequence (const unsigned char *source, const unsigned char *sourceEnd); /* intended to work the same as g_utf8_validate */ bool tr_utf8_validate ( const char *str, int max_len, const char **end ); } #endif /* NUNI_H */ nux-4.0.6+14.04.20140409/NuxCore/Character/NUni.cpp0000644000015301777760000006116012321344237021575 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ /* * Copyright 2001-2004 Unicode, Inc. * * Disclaimer * * This source code is provided as is by Unicode, Inc. No claims are * made as to fitness for any particular purpose. No warranties of any * kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been * purchased on magnetic or optical media from Unicode, Inc., the * sole remedy for any claim will be exchange of defective media * within 90 days of receipt. * * Limitations on Rights to Redistribute This Code * * Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard, and to make copies of this file in any form * for internal or external distribution as long as this notice * remains attached. */ /* --------------------------------------------------------------------- Conversions between UTF32, UTF-16, and UTF-8. Source code file. Author: Mark E. Davis, 1994. Rev History: Rick McGowan, fixes & updates May 2001. Sept 2001: fixed const & error conditions per mods suggested by S. Parent & A. Lillich. June 2002: Tim Dodd added detection and handling of incomplete source sequences, enhanced error detection, added casts to eliminate compiler warnings. July 2003: slight mods to back out aggressive FFFE detection. Jan 2004: updated switches in from-UTF8 conversions. Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. May 2006: updated isLegalUTF8Sequence. See the header file "ConvertUTF.h" for complete documentation. ------------------------------------------------------------------------ */ #include "NuxCore.h" //#include "NUni.h" namespace nux { static const int halfShift = 10; /* used for shifting by 10 bits */ static const unsigned int halfBase = 0x0010000UL; static const unsigned int halfMask = 0x3FFUL; #define UNI_SUR_HIGH_START (unsigned int)0xD800 #define UNI_SUR_HIGH_END (unsigned int)0xDBFF #define UNI_SUR_LOW_START (unsigned int)0xDC00 #define UNI_SUR_LOW_END (unsigned int)0xDFFF ConversionResult ConvertUTF32toUTF16 (const unsigned int **sourceStart, const unsigned int *sourceEnd, wchar_t **targetStart, wchar_t *targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const unsigned int *source = *sourceStart; wchar_t *target = *targetStart; while (source < sourceEnd) { unsigned int ch; if (target >= targetEnd) { result = targetExhausted; break; } ch = *source++; if (ch <= UNI_MAX_BMP) /* Target is a character <= 0xFFFF */ { /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = (wchar_t) ch; /* normal case */ } } else if (ch > UNI_MAX_LEGAL_UTF32) { if (flags == strictConversion) { result = sourceIllegal; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ if (target + 1 >= targetEnd) { --source; /* Back up source pointer! */ result = targetExhausted; break; } ch -= halfBase; *target++ = (wchar_t) ( (ch >> halfShift) + UNI_SUR_HIGH_START); *target++ = (wchar_t) ( (ch & halfMask) + UNI_SUR_LOW_START); } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF16toUTF32 (const wchar_t **sourceStart, const wchar_t *sourceEnd, unsigned int **targetStart, unsigned int *targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const wchar_t *source = *sourceStart; unsigned int *target = *targetStart; unsigned int ch, ch2; while (source < sourceEnd) { const wchar_t *oldSource = source; /* In case we have to back up because of target overflow. */ ch = *source++; /* If we have a surrogate pair, convert to UTF32 first. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { /* If the 16 bits following the high surrogate are in the source buffer... */ if (source < sourceEnd) { ch2 = *source; /* If it's a low surrogate, convert to UTF32. */ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { ch = ( (ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase; ++source; } else if (flags == strictConversion) /* it's an unpaired high surrogate */ { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } else /* We don't have the 16 bits following the high surrogate. */ { --source; /* return to the high surrogate */ result = sourceExhausted; break; } } else if (flags == strictConversion) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } if (target >= targetEnd) { source = oldSource; /* Back up source pointer! */ result = targetExhausted; break; } *target++ = ch; } *sourceStart = source; *targetStart = target; #ifdef CVTUTF_DEBUG if (result == sourceIllegal) { fprintf (stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); fflush (stderr); } #endif return result; } /* --------------------------------------------------------------------- */ /* * Index into the table below with the first byte of a UTF-8 sequence to * get the number of trailing bytes that are supposed to follow it. * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is * left as-is for anyone who may want to do such conversion, which was * allowed in earlier algorithms. */ static const char trailingBytesForUTF8[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }; /* * Magic values subtracted from a buffer value during UTF8 conversion. * This table contains as many values as there might be trailing bytes * in a UTF-8 sequence. */ static const unsigned int offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; /* * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed * into the first byte, depending on how many bytes follow. There are * as many entries in this table as there are UTF-8 sequence types. * (I.e., one byte sequence, two byte... etc.). Remember that sequencs * for *legal* UTF-8 will be 4 or fewer bytes total. */ static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; /* --------------------------------------------------------------------- */ /* The interface converts a whole buffer to avoid function-call overhead. * Constants have been gathered. Loops & conditionals have been removed as * much as possible for efficiency, in favor of drop-through switches. * (See "Note A" at the bottom of the file for equivalent code.) * If your compiler supports it, the "isLegalUTF8" call can be turned * into an inline function. */ /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF16toUTF8 (const wchar_t **sourceStart, const wchar_t *sourceEnd, unsigned char **targetStart, unsigned char *targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const wchar_t *source = *sourceStart; unsigned char *target = *targetStart; while (source < sourceEnd) { unsigned int ch; unsigned short bytesToWrite = 0; const unsigned int byteMask = 0xBF; const unsigned int byteMark = 0x80; const wchar_t *oldSource = source; /* In case we have to back up because of target overflow. */ ch = *source++; /* If we have a surrogate pair, convert to UTF32 first. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { /* If the 16 bits following the high surrogate are in the source buffer... */ if (source < sourceEnd) { unsigned int ch2 = *source; /* If it's a low surrogate, convert to UTF32. */ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { ch = ( (ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase; ++source; } else if (flags == strictConversion) /* it's an unpaired high surrogate */ { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } else /* We don't have the 16 bits following the high surrogate. */ { --source; /* return to the high surrogate */ result = sourceExhausted; break; } } else if (flags == strictConversion) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } /* Figure out how many bytes the result will require */ if (ch < (unsigned int) 0x80) { bytesToWrite = 1; } else if (ch < (unsigned int) 0x800) { bytesToWrite = 2; } else if (ch < (unsigned int) 0x10000) { bytesToWrite = 3; } else if (ch < (unsigned int) 0x110000) { bytesToWrite = 4; } else { bytesToWrite = 3; ch = UNI_REPLACEMENT_CHAR; } target += bytesToWrite; if (target > targetEnd) { source = oldSource; /* Back up source pointer! */ target -= bytesToWrite; result = targetExhausted; break; } switch (bytesToWrite) /* note: everything falls through. */ { case 4: *--target = (unsigned char) ( (ch | byteMark) & byteMask); ch >>= 6; case 3: *--target = (unsigned char) ( (ch | byteMark) & byteMask); ch >>= 6; case 2: *--target = (unsigned char) ( (ch | byteMark) & byteMask); ch >>= 6; case 1: *--target = (unsigned char) (ch | firstByteMark[bytesToWrite]); } target += bytesToWrite; } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ /* * Utility routine to tell whether a sequence of bytes is legal UTF-8. * This must be called with the length pre-determined by the first byte. * If not calling this from ConvertUTF8to*, then the length can be set by: * length = trailingBytesForUTF8[*source]+1; * and the sequence is illegal right away if there aren't that many bytes * available. * If presented with a length > 4, this returns false. The Unicode * definition of UTF-8 goes up to 4-byte sequences. */ static bool isLegalUTF8 (const unsigned char *source, int length) { unsigned char a; const unsigned char *srcptr = source + length; switch (length) { default: return false; /* Everything else falls through when "true"... */ case 4: if ( (a = (*--srcptr) ) < 0x80 || a > 0xBF) return false; case 3: if ( (a = (*--srcptr) ) < 0x80 || a > 0xBF) return false; case 2: if ( (a = (*--srcptr) ) > 0xBF) return false; switch (*source) { /* no fall-through in this inner switch */ case 0xE0: if (a < 0xA0) return false; break; case 0xED: if ( (a < 0x80) || (a > 0x9F) ) return false; break; case 0xF0: if (a < 0x90) return false; break; case 0xF4: if (a > 0x8F) return false; break; default: if (a < 0x80) return false; } case 1: if (*source >= 0x80 && *source < 0xC2) return false; } if (*source > 0xF4) return false; return true; } /* --------------------------------------------------------------------- */ /* * Exported function to return whether a UTF-8 sequence is legal or not. * This is not used here; it's just exported. */ bool isLegalUTF8Sequence (const unsigned char *source, const unsigned char *sourceEnd) { int length; if (source == sourceEnd) { return true; } while (true) { length = trailingBytesForUTF8[*source] + 1; if (source + length > sourceEnd) { return false; } if (!isLegalUTF8 (source, length) ) { return false; } source += length; if (source >= sourceEnd) { return true; } } return true; } /** * This is a variation of isLegalUTF8Sequence() that behaves like g_utf8_validate(). * In addition to knowing if the sequence is legal, it also tells you the last good character. */ bool tr_utf8_validate ( const char *str, int max_len, const char **end ) { const unsigned char *source = (const unsigned char *) str; const unsigned char *sourceEnd; if ( max_len == 0 ) return true; if ( str == NULL ) return false; sourceEnd = source + ( (max_len < 0) ? strlen (str) : (size_t) max_len); if ( source == sourceEnd ) { if ( end != NULL ) *end = (const char *) source; return true; } for ( ;; ) { const int length = trailingBytesForUTF8[*source] + 1; if (source + length > sourceEnd) { if ( end != NULL ) *end = (const char *) source; return false; } if (!isLegalUTF8 (source, length) ) { if ( end != NULL ) *end = (const char *) source; return false; } source += length; if (source >= sourceEnd) { if ( end != NULL ) *end = (const char *) source; return true; } } return true; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF8toUTF16 (const unsigned char **sourceStart, const unsigned char *sourceEnd, wchar_t **targetStart, wchar_t *targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const unsigned char *source = *sourceStart; wchar_t *target = *targetStart; while (source < sourceEnd) { unsigned int ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (source + extraBytesToRead >= sourceEnd) { result = sourceExhausted; break; } /* Do this check whether lenient or strict */ if (! isLegalUTF8 (source, extraBytesToRead + 1) ) { result = sourceIllegal; break; } /* * The cases all fall through. See "Note A" below. */ switch (extraBytesToRead) { case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ case 3: ch += *source++; ch <<= 6; case 2: ch += *source++; ch <<= 6; case 1: ch += *source++; ch <<= 6; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; if (target >= targetEnd) { source -= (extraBytesToRead + 1); /* Back up source pointer! */ result = targetExhausted; break; } if (ch <= UNI_MAX_BMP) /* Target is a character <= 0xFFFF */ { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { source -= (extraBytesToRead + 1); /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = (wchar_t) ch; /* normal case */ } } else if (ch > UNI_MAX_UTF16) { if (flags == strictConversion) { result = sourceIllegal; source -= (extraBytesToRead + 1); /* return to the start */ break; /* Bail out; shouldn't continue */ } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ if (target + 1 >= targetEnd) { source -= (extraBytesToRead + 1); /* Back up source pointer! */ result = targetExhausted; break; } ch -= halfBase; *target++ = (wchar_t) ( (ch >> halfShift) + UNI_SUR_HIGH_START); *target++ = (wchar_t) ( (ch & halfMask) + UNI_SUR_LOW_START); } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF32toUTF8 ( const unsigned int **sourceStart, const unsigned int *sourceEnd, unsigned char **targetStart, unsigned char *targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const unsigned int *source = *sourceStart; unsigned char *target = *targetStart; while (source < sourceEnd) { unsigned int ch; unsigned short bytesToWrite = 0; const unsigned int byteMask = 0xBF; const unsigned int byteMark = 0x80; ch = *source++; if (flags == strictConversion ) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } /* * Figure out how many bytes the result will require. Turn any * illegally large UTF32 things (> Plane 17) into replacement chars. */ if (ch < (unsigned int) 0x80) { bytesToWrite = 1; } else if (ch < (unsigned int) 0x800) { bytesToWrite = 2; } else if (ch < (unsigned int) 0x10000) { bytesToWrite = 3; } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; } else { bytesToWrite = 3; ch = UNI_REPLACEMENT_CHAR; result = sourceIllegal; } target += bytesToWrite; if (target > targetEnd) { --source; /* Back up source pointer! */ target -= bytesToWrite; result = targetExhausted; break; } switch (bytesToWrite) /* note: everything falls through. */ { case 4: *--target = (unsigned char) ( (ch | byteMark) & byteMask); ch >>= 6; case 3: *--target = (unsigned char) ( (ch | byteMark) & byteMask); ch >>= 6; case 2: *--target = (unsigned char) ( (ch | byteMark) & byteMask); ch >>= 6; case 1: *--target = (unsigned char) (ch | firstByteMark[bytesToWrite]); } target += bytesToWrite; } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF8toUTF32 ( const unsigned char **sourceStart, const unsigned char *sourceEnd, unsigned int **targetStart, unsigned int *targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const unsigned char *source = *sourceStart; unsigned int *target = *targetStart; while (source < sourceEnd) { unsigned int ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (source + extraBytesToRead >= sourceEnd) { result = sourceExhausted; break; } /* Do this check whether lenient or strict */ if (! isLegalUTF8 (source, extraBytesToRead + 1) ) { result = sourceIllegal; break; } /* * The cases all fall through. See "Note A" below. */ switch (extraBytesToRead) { case 5: ch += *source++; ch <<= 6; case 4: ch += *source++; ch <<= 6; case 3: ch += *source++; ch <<= 6; case 2: ch += *source++; ch <<= 6; case 1: ch += *source++; ch <<= 6; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; if (target >= targetEnd) { source -= (extraBytesToRead + 1); /* Back up the source pointer! */ result = targetExhausted; break; } if (ch <= UNI_MAX_LEGAL_UTF32) { /* * UTF-16 surrogate values are illegal in UTF-32, and anything * over Plane 17 (> 0x10FFFF) is illegal. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { source -= (extraBytesToRead + 1); /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = ch; } } else /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ { result = sourceIllegal; *target++ = UNI_REPLACEMENT_CHAR; } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- Note A. The fall-through switches in UTF-8 reading code save a temp variable, some decrements & conditionals. The switches are equivalent to the following loop: { int tmpBytesToRead = extraBytesToRead+1; do { ch += *source++; --tmpBytesToRead; if (tmpBytesToRead) ch <<= 6; } while (tmpBytesToRead > 0); } In UTF-8 writing code, the switches on "bytesToWrite" are similarly unrolled loops. --------------------------------------------------------------------- */ } nux-4.0.6+14.04.20140409/NuxCore/Character/NUnicodeGNU.cpp0000644000015301777760000000153712321344237023004 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "NUnicodeGNU.h" namespace nux { } nux-4.0.6+14.04.20140409/NuxCore/Character/NUTF.cpp0000644000015301777760000002360312321344237021500 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "NUTF.h" namespace nux { NUTF8::NUTF8 (const UNICHAR *Source) { Convert (Source); } NUTF8::NUTF8 (const std::wstring &Source) { Convert (NUX_REINTERPRET_CAST (UNICHAR *, NUX_CONST_CAST (wchar_t *, Source.c_str() ) ) ); } void NUTF8::Convert (const UNICHAR *Source) { int NumBytes = 0; // *6 each UTF16 char can translate to up to 6 bytes in UTF8 // +1 for NULL char size_t Size = wcslen ( (wchar_t *) Source) * 6 + 1; utf8 = new char[Size]; memset (utf8, 0, Size); unsigned char TwoBytes[2]; TwoBytes[0] = '\0'; TwoBytes[1] = '\0'; utf8[0] = '\0'; // U-00000000 U-0000007F: 0xxxxxxx // U-00000080 U-000007FF: 110xxxxx 10xxxxxx // U-00000800 U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx // U-00010000 U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // U-00200000 U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // U-04000000 U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // The original specification of UTF-8 allowed for sequences of up to six bytes covering numbers up to 31 bits // (the original limit of the universal character set). However, UTF-8 was restricted by RFC 3629 to use only // the area covered by the formal Unicode definition, U+0000 to U+10FFFF, in November 2003. So UTF-8 code point is at most 4 bytes. for (size_t n = 0; Source[n] != 0; n++) { if (Source[n] <= 0x7F) { TwoBytes[0] = (char) Source[n]; STRCAT_S (utf8, Size, (const char *) &TwoBytes[0]); } else { // 11 valid bits 2 bytes if (Source[n] <= 0x7FF) { // Extract the 5 highest bits TwoBytes[0] = (char) (0xC0 + (Source[n] >> 6) ); NumBytes = 2; } // 16 valid bits 3 bytes else if (Source[n] <= 0xFFFF) { // Extract the highest 4 bits TwoBytes[0] = (char) (0xE0 + (Source[n] >> 12) ); NumBytes = 3; } // Unichar is only 16 bits. Do no continue because (Source[n] >> 18) does not make sense. // 21 valid bits 4 bytes else if (Source[n] <= 0x1FFFFF) { // Extract the highest 3 bits TwoBytes[0] = (char) (0xF0 + (Source[n] >> 18) ); NumBytes = 4; } // Split a 26 bit character into 5 bytes else if (Source[n] <= 0x3FFFFFF) { // Extract the highest 2 bits TwoBytes[0] = (char) (0xF8 + (Source[n] >> 24) ); NumBytes = 5; } // Split a 31 bit character into 6 bytes else if (Source[n] <= 0x7FFFFFFF) { // Extract the highest bit TwoBytes[0] = (char) (0xFC + (Source[n] >> 30) ); NumBytes = 6; } STRCAT_S (utf8, Size, (const char *) &TwoBytes[0]); // Extract the remaining bits - 6 bits at a time for (int i = 1, shift = (NumBytes - 2) * 6; shift >= 0; i++, shift -= 6) { TwoBytes[0] = (char) (0x80 + ( (Source[n] >> shift) & 0x3F) ); STRCAT_S (utf8, Size, (const char *) &TwoBytes[0]); } } } } // void NUTF8::Convert(const t_UTF32* Source) // { // int NumBytes = 0; // // int Size = 0; // while(Source[Size] != 0) // { // ++Size; // } // // *6: each UTF16 char can translate to up to 6 bytes in UTF8 // // +1: for NULL char // Size = Size * 6 + 1; // utf8 = new char[Size*sizeof(t_UTF32)]; // memset(utf8, 0, Size*sizeof(t_UTF32)); // // unsigned char TwoBytes[2]; // TwoBytes[0] = '\0'; TwoBytes[1] = '\0'; // // utf8[0] = '\0'; // // // U-00000000 U-0000007F: 0xxxxxxx // // U-00000080 U-000007FF: 110xxxxx 10xxxxxx // // U-00000800 U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx // // U-00010000 U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // // U-00200000 U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // // U-04000000 U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // // The original specification of UTF-8 allowed for sequences of up to six bytes covering numbers up to 31 bits // // (the original limit of the universal character set). However, UTF-8 was restricted by RFC 3629 to use only // // the area covered by the formal Unicode definition, U+0000 to U+10FFFF, in November 2003. So UTF-8 code point is at most 4 bytes. // // for(size_t n = 0; Source[n] != 0; n++) // { // if (Source[n] <= 0x7F) // { // TwoBytes[0] = (char)Source[n]; // STRCAT_S(utf8, Size, (const char*)&TwoBytes[0]); // } // else // { // // 11 valid bits 2 bytes // if (Source[n] <= 0x7FF) // { // // Extract the 5 highest bits // TwoBytes[0] = (char)(0xC0 + (Source[n] >> 6)); // NumBytes = 2; // } // // 16 valid bits 3 bytes // else if (Source[n] <= 0xFFFF) // { // // Extract the highest 4 bits // TwoBytes[0] = (char)(0xE0 + (Source[n] >> 12)); // NumBytes = 3; // } // // 21 valid bits 4 bytes // else if (Source[n] <= 0x1FFFFF) // { // // Extract the highest 3 bits // TwoBytes[0] = (char)(0xF0 + (Source[n] >> 18)); // NumBytes = 4; // } // // Split a 26 bit character into 5 bytes // else if (Source[n] <= 0x3FFFFFF) // { // // Extract the highest 2 bits // TwoBytes[0] = (char)(0xF8 + (Source[n] >> 24)); // NumBytes = 5; // } // // Split a 31 bit character into 6 bytes // else if (Source[n] <= 0x7FFFFFFF) // { // // Extract the highest bit // TwoBytes[0] = (char)(0xFC + (Source[n] >> 30)); // NumBytes = 6; // } // // STRCAT_S(utf8, Size, (const char*)&TwoBytes[0]); // // // Extract the remaining bits - 6 bits at a time // for(int i = 1, shift = (NumBytes-2)*6; shift >= 0; i++, shift -= 6) // { // TwoBytes[0] = (char)(0x80 + ((Source[n] >> shift) & 0x3F)); // STRCAT_S(utf8, Size, (const char*)&TwoBytes[0]); // } // } // } // } NUTF8::~NUTF8() { delete [] utf8; } NUTF8::operator const char* () { return utf8; } /////////////////////////////////////////////////////////////////////////////// // Convert each unicode character in the source to UTF-8 NUTF16::NUTF16 (const char *Source) { Convert (Source); } NUTF16::NUTF16 (const std::string &Source) { Convert (Source.c_str() ); } void NUTF16::Convert (const char *Source) { // U-00000000 U-0000007F: 0xxxxxxx // U-00000080 U-000007FF: 110xxxxx 10xxxxxx // U-00000800 U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx // U-00010000 U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // U-00200000 U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // U-04000000 U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx unsigned char MSB; int temp = 0; int numbytes = 0; // Number of bytes used to represent the unicode char int pos = 0; size_t len = strlen (Source) + 1; // +1 for NULL char unicode = new UNICHAR[len*6]; // Loop through the characters in the string and decode them for (size_t n = 0; n < len; ++n) { // Find the hexadecimal number following the equals sign MSB = Source[n]; if (MSB <= 0x7F) { unicode[pos++] = (UNICHAR) MSB; } else { // 2 bytes if (MSB >= 0xC0 && MSB <= 0xDF) { temp = (MSB - 0xC0) << 6; numbytes = 2; } // 3 bytes else if (MSB >= 0xE0 && MSB <= 0xEF) { temp = (MSB - 0xE0) << 12; numbytes = 3; } // 4 bytes else if (MSB >= 0xF0 && MSB <= 0xF7) { temp = (MSB - 0xF0) << 18; numbytes = 4; } // 5 bytes else if (MSB >= 0xF8 && MSB <= 0xFB) { temp = (MSB - 0xF8) << 24; numbytes = 5; } // 6 bytes else if (MSB >= 0xFC && MSB <= 0xFD) { temp = (MSB - 0xFC) << 30; numbytes = 6; } // Loop through the remaining hexadecimal numbers representing the next unicode character for (int i = 0, shift = (numbytes - 2) * 6; shift >= 0; i++, shift -= 6) { int nVal = ( ( (unsigned char) Source[n+1+i]) - 0x80 ) << shift; temp += nVal; } // Add the unicode character to the final string unicode[pos++] = (UNICHAR) temp; // Move the character index in the source to the next unicode character n += (numbytes - 1); } } } NUTF16::~NUTF16() { delete [] unicode; } NUTF16::operator const UNICHAR* () { return unicode; } } nux-4.0.6+14.04.20140409/NuxCore/Character/NTChar.h0000644000015301777760000000423712321344237021512 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NTCHAR_H #define NTCHAR_H namespace nux { inline TCHAR ToUpperCase ( TCHAR c ) { return (c < TEXT ('a') || c > TEXT ('z') ) ? (c) : (c + TEXT ('A') - TEXT ('a') ); } inline TCHAR ToLowerCase ( TCHAR c ) { return (c < TEXT ('A') || c > TEXT ('Z') ) ? (c) : (c + TEXT ('a') - TEXT ('A') ); } inline bool IsUpperCase ( TCHAR c ) { return (c >= TEXT ('A') && c <= TEXT ('Z') ); } inline bool IsLowerCase ( TCHAR c ) { return (c >= TEXT ('a') && c <= TEXT ('z') ); } inline bool IsAlphaChar ( TCHAR c ) { return (c >= TEXT ('a') && c <= TEXT ('z') ) || (c >= TEXT ('A') && c <= TEXT ('Z') ); } inline bool IsDigitChar ( TCHAR c ) { return c >= TEXT ('0') && c <= TEXT ('9'); } inline bool IsAlphanumericChar ( TCHAR c ) { return (c >= TEXT ('a') && c <= TEXT ('z') ) || (c >= TEXT ('A') && c <= TEXT ('Z') ) || (c >= TEXT ('0') && c <= TEXT ('9') ); } inline bool IsWhitespaceChar ( TCHAR c ) { return c == TEXT (' ') || c == TEXT ('\t'); } inline bool IsLinebreakChar ( TCHAR c ) { //@todo - support for language-specific line break characters return c == TEXT ('\n'); } /** Returns nonzero if character is a space character. */ inline bool IsSpaceChar ( TCHAR c ) { #ifdef NUX_UNICODE return ( std::iswspace (c) != 0 ); #else return ( std::isspace (c) != 0 ); #endif } } #endif // NTCHAR_H nux-4.0.6+14.04.20140409/NuxCore/Character/NUnicodeGNU.h0000644000015301777760000002445012321344237022450 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUNICODEGNU_H #define NUNICODEGNU_H namespace nux { // UTF-16 is the primary encoding mechanism used by Microsoft Windows 2000, Windows 2000 Server, Windows XP and Windows 2003 Server. // Unicode Byte Order Mark (BOM) enum {UNICODE_UTF32_BE = 0x0000FEFF }; enum {UNICODE_UTF32_LE = 0xFFFE0000 }; enum {UNICODE_UTF16_BE = 0xFEFF }; enum {UNICODE_UTF16_LE = 0xFFFE }; enum {UNICODE_UTF8 = 0xEFBBBF }; const BYTE UTF32_BE[] = {0x04 /*size*/, 0x00, 0x00, 0xFE, 0xFF }; const BYTE UTF32_LE[] = {0x04 /*size*/, 0xFF, 0xFE, 0x00, 0x00 }; const BYTE UTF16_BE[] = {0x02 /*size*/, 0xFE, 0xFF }; const BYTE UTF16_LE[] = {0x02 /*size*/, 0xFF, 0xFE }; const BYTE UTF8[] = {0x03 /*size*/, 0xEF, 0xBB, 0xBF }; enum {UNICODE_BOM = 0xfeff}; // UTF-16 is the default encoding form of the Unicode Standard // On Linux and Mac OS X, wchar_t is 4 bytes! // On windows wchar_t is 2 bytes! #ifdef UNICODE inline TCHAR ConvertAnsiCharToTCHAR (ANSICHAR In) { TCHAR output; const t_UTF8 *source_start = &In; const t_UTF8 *source_end = source_start + 1; t_UTF16 *target_start = reinterpret_cast (&output); t_UTF16 *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline ANSICHAR ConvertTCHARToAnsiChar (TCHAR In) { ANSICHAR output; const t_UTF16 *source_start = &In; const t_UTF16 *source_end = source_start + 1; t_UTF8 *target_start = reinterpret_cast (&output); t_UTF8 *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline TCHAR ConvertUnicodeCharToTCHAR (UNICHAR In) { return In; } inline UNICHAR ConvertTCHARToUnicodeChar (TCHAR In) { return In; } #else inline TCHAR ConvertUnicodeCharToTCHAR (UNICHAR In) { TCHAR output; const t_UTF16 *source_start = &In; const t_UTF16 *source_end = source_start + 1; t_UTF8 *target_start = reinterpret_cast (&output); t_UTF8 *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline UNICHAR ConvertTCHARToUnicodeChar (TCHAR In) { UNICHAR output; const t_UTF8 *source_start = reinterpret_cast (&In); const t_UTF8 *source_end = source_start + 1; t_UTF16 *target_start = reinterpret_cast (&output); t_UTF16 *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline TCHAR ConvertAnsiCharToTCHAR (ANSICHAR In) { return In; } inline ANSICHAR ConvertTCHARToAnsiChar (TCHAR In) { return In; } #endif /*! Convert a single UNICHAR to ANSICHAR. */ inline ANSICHAR ConvertUnicodeCharToAnsiChar (UNICHAR In) { TCHAR output; const t_UTF16 *source_start = &In; const t_UTF16 *source_end = source_start + 1; t_UTF8 *target_start = reinterpret_cast (&output); t_UTF8 *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } /*! Convert a single ANSICHAR to UNICHAR. */ inline UNICHAR ConvertAnsiCharToUnicodeChar (ANSICHAR In) { TCHAR output; const t_UTF8 *source_start = reinterpret_cast (&In); const t_UTF8 *source_end = source_start + 1; t_UTF16 *target_start = reinterpret_cast (&output); t_UTF16 *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } class UnicharToAnsicharConvertion { public: // Default to ANSI code page UnicharToAnsicharConvertion() {} /*! Convert from UNICHAR to ANSICHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ ANSICHAR *Convert (const UNICHAR *Source) { std::wstring utf16string (Source); size_t utf16size = utf16string.length(); size_t utf8size = 6 * utf16size + 1; ANSICHAR *utf8string = new ANSICHAR[utf8size]; const t_UTF16 *source_start = utf16string.c_str(); const t_UTF16 *source_end = source_start + utf16size; t_UTF8 *target_start = reinterpret_cast (&utf8string); t_UTF8 *target_end = target_start + utf8size; ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { delete [] utf8string; utf8string = 0; } // mark end of string *target_start = 0; return utf8string; } }; //! ANSICHAR to UNICHAR conversion class AnsicharToUnicharConvertion { public: NUX_INLINE AnsicharToUnicharConvertion() {} /*! Convert from ANSICHAR to UNICHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ NUX_INLINE UNICHAR *Convert (const ANSICHAR *Source) { std::string utf8string (Source); size_t utf8size = utf8string.length(); size_t utf16size = utf8size + 1; UNICHAR *utf16string = new UNICHAR[utf16size]; const t_UTF8 *source_start = reinterpret_cast (utf8string.c_str() ); const t_UTF8 *source_end = source_start + utf8size; t_UTF16 *target_start = reinterpret_cast (&utf16string); t_UTF16 *target_end = target_start + utf16size; ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { delete [] utf16string; utf16string = 0; } // mark end of string *target_start = 0; return utf16string; } }; //! TCHAR to ANSI conversion // TCHAR can be ansi or unicode depending if UNICODE is defined or not. class TCharToAnsiConvertion { public: NUX_INLINE TCharToAnsiConvertion() {} /*! Convert from TCHAR to ANSICHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ NUX_INLINE ANSICHAR *Convert (const TCHAR *Source) { // Determine whether we need to allocate memory or not #ifdef UNICODE UnicharToAnsicharConvertion convert; return convert.Convert (Source); #else int length = strlen (Source) + 1; int size = length * sizeof (ANSICHAR); ANSICHAR *Dest = new ANSICHAR[size]; STRNCPY_S (Dest, size, Source, length); return Dest; #endif } }; //! ANSI to TCHAR conversion // TCHAR can be ansi or unicode depending if UNICODE is defined or not. class AnsiToTCharConversion { public: NUX_INLINE AnsiToTCharConversion() {} /*! Convert from ANSICHAR to TCHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ NUX_INLINE TCHAR *Convert (const ANSICHAR *Source) { #ifdef UNICODE AnsicharToUnicharConvertion convert; return convert.Convert (Source); #else unsigned int length = strlen (Source) + 1; unsigned int size = length; TCHAR *Dest = new TCHAR[size]; STRNCPY_S (Dest, size, Source, length); return Dest; #endif } }; /*! Convert from one string format to another. */ template < typename CONVERT_TO, typename CONVERT_FROM, typename BASE_CONVERTER, DWORD DefaultConversionSize = 128 > class NCharacterConversion: public BASE_CONVERTER { CONVERT_TO *ConvertedString; // Hide the default constructor NCharacterConversion(); public: /*! Converts the data by using the Convert() method on the base class */ explicit inline NCharacterConversion (const CONVERT_FROM *Source) { if (Source != NULL) { // Use base class' convert method ConvertedString = BASE_CONVERTER::Convert (Source); } else { ConvertedString = NULL; } } /*! If memory was allocated, then it is freed below */ inline ~NCharacterConversion() { if (ConvertedString != NULL) { delete [] ConvertedString; } } // Operator to get access to the converted string inline operator CONVERT_TO* (void) const { return ConvertedString; } }; // Conversion typedefs typedef NCharacterConversion ANSI_To_TCHAR_Conversion; typedef NCharacterConversion TCHAR_To_ANSI_Conversion; typedef NCharacterConversion UNICHAR_To_ANSICHAR_Conversion; typedef NCharacterConversion ANSICHAR_To_UNICHAR_Conversion; } #endif // NUNICODEGNU_H nux-4.0.6+14.04.20140409/NuxCore/Character/NAscii.cpp0000644000015301777760000000564512321344237022100 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "NAscii.h" namespace nux { // Windows-1252 code page t_uchar GAscii[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0xFF, '', 0x81, '', '', '', '', '', '', '', '', '', '', '', 0x8d, '', 0x8f, 0x90, '', '', '', '', '', '', '', 0x98, '', '', '', '', 0x9d, '', '', 0xa0, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' }; } nux-4.0.6+14.04.20140409/NuxCore/Character/NUnicode.cpp0000644000015301777760000000466412321344237022436 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "NUnicode.h" namespace nux { ANSICHAR *UnicharToAnsicharConvertion::Convert (const UNICHAR *Source) { std::wstring utf16string (Source); size_t utf16size = utf16string.length(); size_t utf8size = 6 * utf16size; ANSICHAR *utf8string = new ANSICHAR[utf8size+1]; const wchar_t *source_start = utf16string.c_str(); const wchar_t *source_end = source_start + utf16size; unsigned char *target_start = reinterpret_cast (utf8string); unsigned char *target_end = target_start + utf8size; ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { delete [] utf8string; utf8string = 0; } // mark end of string *target_start = 0; return utf8string; } UNICHAR *AnsicharToUnicharConvertion::Convert (const ANSICHAR *Source) { std::string utf8string (Source); size_t utf8size = utf8string.length(); size_t utf16size = utf8size; UNICHAR *utf16string = new UNICHAR[utf16size+1]; const unsigned char *source_start = reinterpret_cast (utf8string.c_str() ); const unsigned char *source_end = source_start + utf8size; wchar_t *target_start = reinterpret_cast (utf16string); wchar_t *target_end = target_start + utf16size; ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { delete[] utf16string; utf16string = 0; } // mark end of string *target_start = 0; return utf16string; } } nux-4.0.6+14.04.20140409/NuxCore/Character/NUnicode.h0000644000015301777760000002474612321344237022106 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef NUNICODE_H #define NUNICODE_H namespace nux { // UTF-16 is the primary encoding mechanism used by Microsoft Windows 2000, Windows 2000 Server, Windows XP and Windows 2003 Server. // Unicode Byte Order Mark (BOM) enum {UNICODE_UTF32_BE = 0x0000FEFF }; enum {UNICODE_UTF32_LE = 0xFFFE0000 }; enum {UNICODE_UTF16_BE = 0xFEFF }; enum {UNICODE_UTF16_LE = 0xFFFE }; enum {UNICODE_UTF8 = 0xEFBBBF }; const BYTE UTF32_BE[] = {0x04 /*size*/, 0x00, 0x00, 0xFE, 0xFF }; const BYTE UTF32_LE[] = {0x04 /*size*/, 0xFF, 0xFE, 0x00, 0x00 }; const BYTE UTF16_BE[] = {0x02 /*size*/, 0xFE, 0xFF }; const BYTE UTF16_LE[] = {0x02 /*size*/, 0xFF, 0xFE }; const BYTE UTF8[] = {0x03 /*size*/, 0xEF, 0xBB, 0xBF }; enum {UNICODE_BOM = 0xfeff}; // UTF-16 is the default encoding form of the Unicode Standard // On Linux and Mac OS X, wchar_t is 4 bytes! // On windows wchar_t is 2 bytes! #ifdef UNICODE inline TCHAR ConvertAnsiCharToTCHAR (ANSICHAR In) { TCHAR output; const unsigned char *source_start = &In; const unsigned char *source_end = source_start + 1; wchar_t *target_start = reinterpret_cast (&output); wchar_t *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline ANSICHAR ConvertTCHARToAnsiChar (TCHAR In) { ANSICHAR output; const wchar_t *source_start = &In; const wchar_t *source_end = source_start + 1; unsigned char *target_start = reinterpret_cast (&output); unsigned char *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline TCHAR ConvertUnicodeCharToTCHAR (UNICHAR In) { return In; } inline UNICHAR ConvertTCHARToUnicodeChar (TCHAR In) { return In; } #else inline TCHAR ConvertUnicodeCharToTCHAR (UNICHAR In) { TCHAR output; const wchar_t *source_start = &In; const wchar_t *source_end = source_start + 1; unsigned char *target_start = reinterpret_cast (&output); unsigned char *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline UNICHAR ConvertTCHARToUnicodeChar (TCHAR In) { UNICHAR output; const unsigned char *source_start = reinterpret_cast (&In); const unsigned char *source_end = source_start + 1; wchar_t *target_start = reinterpret_cast (&output); wchar_t *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } inline TCHAR ConvertAnsiCharToTCHAR (ANSICHAR In) { return In; } inline ANSICHAR ConvertTCHARToAnsiChar (TCHAR In) { return In; } #endif /*! Convert a single UNICHAR to ANSICHAR. */ inline ANSICHAR ConvertUnicodeCharToAnsiChar (UNICHAR In) { TCHAR output; const wchar_t *source_start = &In; const wchar_t *source_end = source_start + 1; unsigned char *target_start = reinterpret_cast (&output); unsigned char *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF16toUTF8 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } /*! Convert a single ANSICHAR to UNICHAR. */ inline UNICHAR ConvertAnsiCharToUnicodeChar (ANSICHAR In) { UNICHAR output; const unsigned char *source_start = reinterpret_cast (&In); const unsigned char *source_end = source_start + 1; wchar_t *target_start = reinterpret_cast (&output); wchar_t *target_end = target_start + sizeof (wchar_t); ConversionResult res = ConvertUTF8toUTF16 (&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { output = 0; } return output; } class UnicharToAnsicharConvertion { public: // Default to ANSI code page UnicharToAnsicharConvertion() {} /*! Convert from UNICHAR to ANSICHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ ANSICHAR *Convert (const UNICHAR *Source); /*{ std::wstring utf16string(Source); size_t utf16size = utf16string.length(); size_t utf8size = 6 * utf16size; ANSICHAR *utf8string = new ANSICHAR[utf8size+1]; const wchar_t *source_start = utf16string.c_str(); const wchar_t *source_end = source_start + utf16size; unsigned char* target_start = reinterpret_cast(utf8string); unsigned char* target_end = target_start + utf8size; ConversionResult res = ConvertUTF16toUTF8(&source_start, source_end, &target_start, target_end, lenientConversion); if (res != conversionOK) { delete utf8string; utf8string = 0; } // mark end of string *target_start = 0; return utf8string; }*/ }; //! ANSICHAR to UNICHAR conversion class AnsicharToUnicharConvertion { public: AnsicharToUnicharConvertion() {} /*! Convert from ANSICHAR to UNICHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ UNICHAR *Convert (const ANSICHAR *Source); }; //! TCHAR to ANSI conversion // TCHAR can be ansi or unicode depending if UNICODE is defined or not. class TCharToAnsiConvertion { public: NUX_INLINE TCharToAnsiConvertion() {} /*! Convert from TCHAR to ANSICHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ NUX_INLINE ANSICHAR *Convert (const TCHAR *Source) { // Determine whether we need to allocate memory or not #ifdef UNICODE UnicharToAnsicharConvertion convert; return convert.Convert (Source); #else size_t length = strlen (Source) + 1; size_t size = length * sizeof (ANSICHAR); ANSICHAR *Dest = new ANSICHAR[size]; STRNCPY_S (Dest, size, Source, length); return Dest; #endif } }; //! TCHAR to Unichar conversion // TCHAR can be ansi or unicode depending if UNICODE is defined or not. class TCharToUnicharConvertion { public: NUX_INLINE TCharToUnicharConvertion() {} /*! Convert from TCHAR to ANSICHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ NUX_INLINE UNICHAR *Convert (const TCHAR *Source) { // Determine whether we need to allocate memory or not #ifdef UNICODE size_t length = strlen (Source) + 1; size_t size = length * sizeof (UNICHAR); UNICHAR *Dest = new UNICHAR[size]; STRNCPY_S (Dest, size, Source, length); return Dest; #else AnsicharToUnicharConvertion convert; return convert.Convert (Source); #endif } }; //! ANSI to TCHAR conversion // TCHAR can be ansi or unicode depending if UNICODE is defined or not. class AnsiToTCharConversion { public: NUX_INLINE AnsiToTCharConversion() {} /*! Convert from ANSICHAR to TCHAR @param Source String to convert. Null terminated. @return Return a pointer to the new string. Null terminated. */ NUX_INLINE TCHAR *Convert (const ANSICHAR *Source) { #ifdef UNICODE AnsicharToUnicharConvertion convert; return convert.Convert (Source); #else size_t length = strlen (Source) + 1; size_t size = length; TCHAR *Dest = new TCHAR[size]; STRNCPY_S (Dest, size, Source, length); return Dest; #endif } }; /*! Convert from one string format to another. */ template < typename CONVERT_TO, typename CONVERT_FROM, typename BASE_CONVERTER, DWORD DefaultConversionSize = 128 > class NCharacterConversion: public BASE_CONVERTER { CONVERT_TO *ConvertedString; // Hide the default constructor NCharacterConversion(); public: /*! Converts the data by using the Convert() method on the base class */ explicit inline NCharacterConversion (const CONVERT_FROM *Source) { if (Source != NULL) { // Use base class' convert method ConvertedString = BASE_CONVERTER::Convert (Source); } else { ConvertedString = NULL; } } /*! If memory was allocated, then it is freed below */ inline ~NCharacterConversion() { if (ConvertedString != NULL) { delete [] ConvertedString; } } // Operator to get access to the converted string inline operator CONVERT_TO* (void) const { return ConvertedString; } }; // Conversion typedefs // typedef NCharacterConversion ANSI_To_TCHAR_Conversion; // typedef NCharacterConversion TCHAR_To_ANSI_Conversion; // typedef NCharacterConversion UNICHAR_To_ANSICHAR_Conversion; // typedef NCharacterConversion ANSICHAR_To_UNICHAR_Conversion; } #endif // NUNICODE_H nux-4.0.6+14.04.20140409/NuxCore/TextString.cpp0000644000015301777760000000452212321344237021142 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" namespace nux { // // Copy a string with length checking. //warning: Behavior differs from strncpy; last character is zeroed. // TCHAR *Strncpy (TCHAR *Dest, size_t Size, const TCHAR *Src, size_t MaxLen) { STRNCPY_S (Dest, Size, Src, MaxLen); Dest[MaxLen] = 0; return Dest; } // Search a string inside a string. Return a pointer to the beginning of the searched string if it is found. Else, return NULL; // The shearched string must be preceded by a non alpha numeric character in Str. const TCHAR *Strfind (const TCHAR *Str, const TCHAR *Find) { nuxAssert (Find != NULL); nuxAssert (Str != NULL); if (Find == NULL || Str == NULL) { return NULL; } bool AlphaNum = 0; TCHAR First = ( (*Find < TEXT ('a') ) || (*Find > TEXT ('z') ) ) ? (*Find) : (*Find + TEXT ('A') - TEXT ('a') ); size_t Len = StringLength (Find++) - 1; TCHAR chr = *Str++; while (chr) { if ( (chr >= TEXT ('a') ) && (chr <= TEXT ('z') ) ) { chr += TEXT ('A') - TEXT ('a'); } if (!AlphaNum && (chr == First) && !TCharStringNICompare (Str, Find, Len) ) { return Str - 1; } AlphaNum = ( (chr >= TEXT ('A') ) && (chr <= TEXT ('Z') ) ) || ( (chr >= TEXT ('0') ) && (chr <= TEXT ('9') ) ); chr = *Str++; } return NULL; } VARARG_BODY (int, Snprintf, const TCHAR *, VARARG_EXTRA (TCHAR *Dest) VARARG_EXTRA (int Size) VARARG_EXTRA (int Count) ) { int Result = -1; GET_VARARGS_RESULT (Dest, Size, Count, Fmt, Result); return Result; } } nux-4.0.6+14.04.20140409/NuxCore/NUniqueIndex.cpp0000644000015301777760000000230312321344237021376 0ustar pbusernogroup00000000000000/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #include "NuxCore.h" #include "NUniqueIndex.h" namespace nux { NUX_IMPLEMENT_GLOBAL_OBJECT (UniqueIndex); NCriticalSection UniqueIndex::m_CriticalSection; void UniqueIndex::Constructor() { } void UniqueIndex::Destructor() { } unsigned long long UniqueIndex::GetUniqueIndex() { NScopeLock Scope (&m_CriticalSection); m_UniqueIndex.Increment(); return m_UniqueIndex.GetValue(); } } nux-4.0.6+14.04.20140409/NuxCore/Makefile.am0000644000015301777760000001252312321344237020357 0ustar pbusernogroup00000000000000CLEANFILES = DISTCLEANFILES = EXTRA_DIST = AM_CPPFLAGS = \ -I$(srcdir) \ -I$(top_srcdir) \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"NuxCore\" lib_LTLIBRARIES = \ libnux-core-@NUX_API_VERSION@.la libnux_core_@NUX_API_VERSION@_la_CPPFLAGS= \ $(GCC_FLAGS) \ $(NUX_CORE_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(COVERAGE_CFLAGS) libnux_core_@NUX_API_VERSION@_la_LIBADD = \ $(NUX_CORE_LIBS) -lpthread libnux_core_@NUX_API_VERSION@_la_LDFLAGS = \ $(NUX_LT_LDFLAGS) \ $(COVERAGE_LDFLAGS) source_cpp = \ $(srcdir)/Animation.cpp \ $(srcdir)/AnimationController.cpp \ $(srcdir)/AsyncFileWriter.cpp \ $(srcdir)/EasingCurve.cpp \ $(srcdir)/TextString.cpp \ $(srcdir)/TimeFunctions.cpp \ $(srcdir)/Template.cpp \ $(srcdir)/FilePath.cpp \ $(srcdir)/FileManager/NSerializer.cpp \ $(srcdir)/FileManager/NFileManagerGeneric.cpp \ $(srcdir)/FileManager/NFileManagerGNU.cpp \ $(srcdir)/SystemGNU.cpp \ $(srcdir)/OutputDevice.cpp \ $(srcdir)/Exception.cpp \ $(srcdir)/Memory.cpp \ $(srcdir)/Character/NUTF.cpp \ $(srcdir)/Character/NUni.cpp \ $(srcdir)/Character/NUnicode.cpp \ $(srcdir)/Color.cpp \ $(srcdir)/ColorPrivate.cpp \ $(srcdir)/Colors.cpp \ $(srcdir)/FileName.cpp \ $(srcdir)/ThreadGNU.cpp \ $(srcdir)/Parsing.cpp \ $(srcdir)/Logger.cpp \ $(srcdir)/LoggingWriter.cpp \ $(srcdir)/NUniqueIndex.cpp \ $(srcdir)/GlobalInitializer.cpp \ $(srcdir)/ObjectType.cpp \ $(srcdir)/Platform.cpp \ $(srcdir)/Rect.cpp \ $(srcdir)/FileIO.cpp \ $(srcdir)/Process.cpp \ $(srcdir)/NumberConversion.cpp \ $(srcdir)/NuxCore.cpp \ $(srcdir)/Object.cpp \ $(srcdir)/Math/Algo.cpp \ $(srcdir)/Math/Constants.cpp \ $(srcdir)/Math/MathFunctions.cpp \ $(srcdir)/Math/Line2D.cpp \ $(srcdir)/Math/Bezier.cpp \ $(srcdir)/Math/Spline.cpp \ $(srcdir)/Math/Quaternion.cpp \ $(srcdir)/Math/Matrix2.cpp \ $(srcdir)/Math/Trigonometry.cpp \ $(srcdir)/Math/Tweening.cpp \ $(srcdir)/Math/Complex.cpp \ $(srcdir)/Math/Point3D.cpp \ $(srcdir)/Math/Matrix4.cpp \ $(srcdir)/Math/Matrix3.cpp \ $(srcdir)/Math/Line3D.cpp \ $(srcdir)/RollingFileAppender.cpp \ $(srcdir)/InitiallyUnownedObject.cpp source_file_manager_h = \ $(srcdir)/FileManager/NFileManagerGNU.h \ $(srcdir)/FileManager/NFileManagerGeneric.h \ $(srcdir)/FileManager/NSerializer.h source_character_h = \ $(srcdir)/Character/NUTF.h \ $(srcdir)/Character/NUni.h \ $(srcdir)/Character/NUnicode.h \ $(srcdir)/Character/NTChar.h source_math_h = \ $(srcdir)/Math/Algo.h \ $(srcdir)/Math/Bezier.h \ $(srcdir)/Math/Constants.h \ $(srcdir)/Math/Point3D.h \ $(srcdir)/Math/Vector4.h \ $(srcdir)/Math/Matrix2.h \ $(srcdir)/Math/Spline.h \ $(srcdir)/Math/Vector3.h \ $(srcdir)/Math/MathFunctions.h \ $(srcdir)/Math/Quaternion.h \ $(srcdir)/Math/Trigonometry.h \ $(srcdir)/Math/Line3D.h \ $(srcdir)/Math/MathInc.h \ $(srcdir)/Math/Complex.h \ $(srcdir)/Math/Matrix3.h \ $(srcdir)/Math/Vector2.h \ $(srcdir)/Math/Line2D.h \ $(srcdir)/Math/Point2D.h \ $(srcdir)/Math/Point2D-inl.h \ $(srcdir)/Math/Tweening.h \ $(srcdir)/Math/Matrix4.h \ $(srcdir)/Math/MathUtility.h source_h = \ $(srcdir)/Animation.h \ $(srcdir)/Animation-inl.h \ $(srcdir)/AnimationController.h \ $(srcdir)/AsyncFileWriter.h \ $(srcdir)/EasingCurve.h \ $(srcdir)/Point.h \ $(srcdir)/FilePath.h \ $(srcdir)/System.h \ $(srcdir)/Parsing.h \ $(srcdir)/StringConversion.h \ $(srcdir)/GlobalInitializer.h \ $(srcdir)/Rect.h \ $(srcdir)/Platform.h \ $(srcdir)/Inalogic.h \ $(srcdir)/Color.h \ $(srcdir)/Colors.h \ $(srcdir)/Logger.h \ $(srcdir)/LoggerPrivate.h \ $(srcdir)/LoggingWriter.h \ $(srcdir)/RollingFileAppender.h \ $(srcdir)/Memory.h \ $(srcdir)/Error.h \ $(srcdir)/SystemGNU.h \ $(srcdir)/NuxCore.h \ $(srcdir)/FileName.h \ $(srcdir)/OutputDevice.h \ $(srcdir)/Process.h \ $(srcdir)/ObjectType.h \ $(srcdir)/ObjectPtr.h \ $(srcdir)/NumberConversion.h \ $(srcdir)/Object.h \ $(srcdir)/Size.h \ $(srcdir)/Size-inl.h \ $(srcdir)/Exception.h \ $(srcdir)/TimeFunctions.h \ $(srcdir)/Macros.h \ $(srcdir)/ThreadGNU.h \ $(srcdir)/TextString.h \ $(srcdir)/Template.h \ $(srcdir)/NUniqueIndex.h \ $(srcdir)/FileIO.h \ $(srcdir)/InitiallyUnownedObject.h \ $(srcdir)/Property.h \ $(srcdir)/Property-inl.h \ $(srcdir)/PropertyAnimation.h \ $(srcdir)/PropertyOperators.h \ $(srcdir)/PropertyTraits.h \ $(srcdir)/Win32Dialogs/NWin32Clipboard.h libnux_core_@NUX_API_VERSION@_la_SOURCES = \ $(source_cpp) \ $(source_h) \ $(source_character_h) \ $(source_file_manager_h) \ $(source_math_h) \ $(source_memory_h) nux_coredir = $(includedir)/Nux-@NUX_API_VERSION@/NuxCore nux_core_HEADERS = $(source_h) nux_chardir = $(nux_coredir)/Character nux_char_HEADERS = $(source_character_h) nux_file_managerdir = $(nux_coredir)/FileManager nux_file_manager_HEADERS = $(source_file_manager_h) nux_mathdir = $(nux_coredir)/Math nux_math_HEADERS = $(source_math_h) nux_memorydir = $(nux_coredir)/Memory nux_memory_HEADERS = $(source_memory_h) # pkg-config file nux-core-@NUX_API_VERSION@.pc: nux-core.pc $(AM_V_GEN) cp -f nux-core.pc nux-core-@NUX_API_VERSION@.pc pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = nux-core-@NUX_API_VERSION@.pc CLEANFILES += nux-core-@NUX_API_VERSION@.pc DISTCLEANFILES += nux-core.pc EXTRA_DIST += nux-core.pc.in nux-4.0.6+14.04.20140409/NuxCore/PropertyOperators.h0000644000015301777760000001644312321344237022224 0ustar pbusernogroup00000000000000// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright 2011 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Tim Penhey * */ #if defined(NUX_OS_WINDOWS) #pragma warning(disable : 4519) // error C4519: default template arguments are only allowed on a class template #endif #ifndef NUXCORE_PROPERTY_OPERATORS_H #define NUXCORE_PROPERTY_OPERATORS_H namespace nux { /** * This is a very boring file. * * It adds boolean operators for properties. The challenge has been making * operators that work for properties and only properties. Since we don't * want to add explicit methods for each type of property we have, we have the * default template argument VT which gets the ValueType from the Property * definition. Since things like std::_list_iterator doesn't have a * ValueType typedef, these functions are discarded from the possible choices, * but since the Property templates do, they are valid, and get chosen. * * However as much as I'd like to have more generic operators for !=, <=, > * and >=, we can't really without making these functions choosable for types * that we don't want, so we have three functions defined for each operator. */ // operator == template