diff --git a/.gitignore b/.gitignore index 44257d3..e12707a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.bck *.o .hg* +.dropbox.attr diff --git a/cmakelists_/CMakeLists_regular_01.txt b/cmakelists_/CMakeLists_regular_01.txt index fbe7687..76c15ae 100644 --- a/cmakelists_/CMakeLists_regular_01.txt +++ b/cmakelists_/CMakeLists_regular_01.txt @@ -22,23 +22,11 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES) # add_definitions(-DSOME_DEFS) #endif() -# cmake -DDEBUG=1 -> debugging -if(DEFINED DEBUG) +# cmake -DEBUG=1 -> debugging +if(DEFINED EBUG) add_definitions(-DEBUG) endif() -# directory should contain dir locale/ru for gettext translations -set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru) - -if(NOT DEFINED LOCALEDIR) - if(DEFINED DEBUG) - set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale) - else() - set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) - endif() -endif() - -# gettext modules set(MODULES libavformat libavcodec libswscale libavutil libavdevice) # additional modules on condition #if(DEFINED SOMETHING) @@ -54,6 +42,17 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND CMAKE_INSTALL_PREFIX MATCHES endif() message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}") +# directory should contain dir locale/ru for gettext translations +set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru) + +if(NOT DEFINED LOCALEDIR) + if(DEFINED DEBUG) + set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale) + else() + set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) + endif() +endif() + # gettext files set(PO_FILE ${LCPATH}/messages.po) set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo) @@ -61,26 +60,46 @@ set(RU_FILE ${LCPATH}/ru.po) # pkgconfig find_package(PkgConfig REQUIRED) -pkg_check_modules(${PROJ} REQUIRED ${MODULES}) +#find_package(OpenGL REQUIRED) +#find_package(GTK2 REQUIRED) +# etc +# set(${${PROJ}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ) +# set(${${PROJ}_LIBRARY_DIRS} ...) + +if(MODULES) + pkg_check_modules(${PROJ} REQUIRED ${MODULES}) +endif() + +#OpenMP +#include(FindOpenMP) +#if(OPENMP_FOUND) +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +#endif() # exe file add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE}) -target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES}) -include_directories(${${PROJ}_INCLUDE_DIRS}) -link_directories(${${PROJ}_LIBRARY_DIRS}) +target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} ${OPENGL_LIBRARIES} ...) +include_directories(${${PROJ}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ...) +link_directories(${${PROJ}_LIBRARY_DIRS} ) add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" -DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\" -DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\" -DMAJOR_VERSION=\"${MAJOR_VESION}\") # Installation of the program -INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES") - #PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) -INSTALL(TARGETS ${PROJ} DESTINATION "bin") - #PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) -# Script to be executed at installation time (kind of post-intallation script) to -# change the right accesses on the installed files -#INSTALL(SCRIPT inst.cmake) +if(NOT DEFINED DEBUG) + INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES") + #PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) + INSTALL(TARGETS ${PROJ} DESTINATION "bin") + #PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + # Script to be executed at installation time (kind of post-intallation script) to + # change the right accesses on the installed files + #INSTALL(SCRIPT inst.cmake) +else() + install(CODE "MESSAGE(\"Don't install in DEBUG mode! First run cmake without -DEBUG defined.\")") +endif(NOT DEFINED DEBUG) find_package(Gettext REQUIRED) find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) diff --git a/image_view_module/CMakeLists.txt b/image_view_module/CMakeLists.txt new file mode 100644 index 0000000..39d2fe8 --- /dev/null +++ b/image_view_module/CMakeLists.txt @@ -0,0 +1,136 @@ +cmake_minimum_required(VERSION 2.8) + +# cmake -DEBUG=1 -> debugging +if(DEFINED EBUG) + add_definitions(-DEBUG) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() + +set(PROJ openglview) +set(MINOR_VERSION "1") +set(MID_VERSION "0") +set(MAJOR_VERSION "0") +set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}") + +message("VER: ${VERSION}") + +# default flags +set(CFLAGS -O2 -Wextra -Wall -Werror -W -std=gnu99) + +set(CMAKE_COLOR_MAKEFILE ON) + +# here is one of two variants: all .c in directory or .c files in list +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES) +#set(SOURCES list_of_c_files) + +# we can change file list +#if(NOT DEFINED something) +# set(SOURCES ${SOURCES} one_more_list) +# add_definitions(-DSOME_DEFS) +#endif() + +set(MODULES) +# additional modules on condition +#if(DEFINED SOMETHING) +# set(MODULES ${MODULES} more_modules>=version) +# add_definitions(-DSOMEDEFS) +#endif() + +project(${PROJ}) +# change wrong behaviour with install prefix +if(CMAKE_INSTALL_PREFIX MATCHES "/usr/local") + message("Change default install path to /usr") + set(CMAKE_INSTALL_PREFIX "/usr") +endif() +message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}") + +if(NOT DEFINED NOGETTEXT) +# directory should contain dir locale/ru for gettext translations + set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru) + if(NOT DEFINED LOCALEDIR) + if(DEFINED DEBUG) + set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale) + else() + set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) + endif() + endif() + # gettext files + set(PO_FILE ${LCPATH}/messages.po) + set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo) + set(RU_FILE ${LCPATH}/ru.po) +else() + add_definitions(-DNOGETTEXT) + set(PO_FILE) + set(MO_FILE) +endif() + +# pkgconfig +find_package(PkgConfig REQUIRED) +find_package(OpenGL REQUIRED) +find_package(GLUT REQUIRED) +find_package(JPEG REQUIRED) +if(MODULES) + pkg_check_modules(${PROJ} REQUIRED ${MODULES}) +endif() + +#OpenMP +#include(FindOpenMP) +#if(OPENMP_FOUND) +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +#endif() + +# exe file +add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE}) +target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} ${OPENGL_LIBRARIES} ${JPEG_LIBRARIES} + ${GLUT_LIBRARIES} -lm -lpthread) +include_directories(${${PROJ}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ${GLUT_INCLUDE_DIR}) +link_directories(${${PROJ}_LIBRARY_DIRS}) +add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" + -DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\" + -DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\" + -DMAJOR_VERSION=\"${MAJOR_VESION}\" -DPROJNAME=\"${PROJ}\") + +# Installation of the program +if(NOT DEFINED DEBUG) + INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES") + #PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) + INSTALL(TARGETS ${PROJ} DESTINATION "bin") + #PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + # Script to be executed at installation time (kind of post-intallation script) to + # change the right accesses on the installed files + #INSTALL(SCRIPT inst.cmake) +else() + install(CODE "MESSAGE(\"Don't install in DEBUG mode! First run cmake without -DEBUG defined.\")") +endif(NOT DEFINED DEBUG) + +if(NOT DEFINED NOGETTEXT) +find_package(Gettext REQUIRED) +find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) +if(NOT GETTEXT_XGETTEXT_EXECUTABLE OR NOT GETTEXT_MSGFMT_EXECUTABLE) + message(FATAL_ERROR "xgettext not found") +endif() +file(MAKE_DIRECTORY ${LCPATH}) +file(MAKE_DIRECTORY ${LCPATH}/LC_MESSAGES) + +add_custom_command( + OUTPUT ${PO_FILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} --from-code=utf-8 ${SOURCES} -c -k_ -kN_ -o ${PO_FILE} + COMMAND sed -i 's/charset=.*\\\\n/charset=koi8-r\\\\n/' ${PO_FILE} + COMMAND enconv ${PO_FILE} + DEPENDS ${SOURCES} +) +# we need this to prewent ru.po from deleting by make clean +add_custom_target( + RU_FILE + COMMAND [ -f ${RU_FILE} ] && ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE} || cp ${PO_FILE} ${RU_FILE} + DEPENDS ${PO_FILE} +) +add_custom_command( + OUTPUT ${MO_FILE} + COMMAND make RU_FILE && ${GETTEXT_MSGFMT_EXECUTABLE} ${RU_FILE} -o ${MO_FILE} + DEPENDS ${PO_FILE} +) +endif(NOT DEFINED NOGETTEXT) diff --git a/image_view_module/bmpview.c b/image_view_module/bmpview.c new file mode 100644 index 0000000..a14ed44 --- /dev/null +++ b/image_view_module/bmpview.c @@ -0,0 +1,189 @@ +// bmpview.c +// +// Copyright 2010 Edward V. Emelianoff +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// 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, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +// MA 02110-1301, USA. +//-lglut +#include "bmpview.h" +#include "macros.h" +#include + +int totWindows = 0; // total number of opened windows + +/* +void *GLloop(){ + FNAME(); + glutMainLoop(); + return NULL; +}*/ + +/** + * create window & run main loop + */ +void createWindow(windowData *win){ + FNAME(); + if(!win) return; + int w = win->w, h = win->h; +/* + char *argv[] = {PROJNAME, NULL}; + int argc = 1; + glutInit(&argc, argv); +*/ + glGenTextures(1, &(win->Tex)); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + glutInitWindowSize(w, h); + win->GL_ID = glutCreateWindow(win->title); + DBG("created GL_ID=%d", win->GL_ID); + glutIdleFunc(Redraw); + glutReshapeFunc(Resize); + glutDisplayFunc(RedrawWindow); + glutKeyboardFunc(keyPressed); + glutSpecialFunc(keySpPressed); + glutMouseFunc(mousePressed); + glutMotionFunc(mouseMove); + win->z = 0.; + createMenu(win->ID); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, win->Tex); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, win->rawdata); + glDisable(GL_TEXTURE_2D); + totWindows++; +} +/* +void showid(int id){ + printf("ID: %d\n", id); +} +*/ +/** + * destroy window with OpenGL or inner identificator "window" + * @param window inner or OpenGL id + * @param idtype = INNER or OPENGL + * @return 1 in case of OK, 0 if fault + */ +int destroyWindow(int window, winIdType type){ + windowData *win; + int canceled = 1; + if(type == OPENGL) + win = searchWindow_byGLID(window); + else + win = searchWindow(window); + if(!win) return 0; + //forEachWindow(showid); + pthread_mutex_lock(&win->mutex); + if(!pthread_cancel(win->thread)){ // cancel thread changing data + canceled = 0; + } + pthread_join(win->thread, NULL); + glDeleteTextures(1, &win->Tex); + glFinish(); + glutDestroyWindow(win->GL_ID); + win->GL_ID = 0; // reset for forEachWindow() + pthread_mutex_unlock(&win->mutex); + if(!canceled && !pthread_cancel(win->thread)){ // cancel thread changing data + WARN(_("can't cancel a thread!")); + } + pthread_join(win->thread, NULL); + if(!removeWindow(win->ID)) WARNX(_("Error removing from list")); + totWindows--; + //forEachWindow(showid); + return 1; +} + +void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color){ + char *c; + int x1=x, W=0; + for(c = string; *c; c++){ + W += glutBitmapWidth(font,*c);// + 1; + } + x1 -= W/2; + glColor3ubv(color); + glLoadIdentity(); + glTranslatef(0.,0., -150); + //glTranslatef(x,y, -4000.); + for (c = string; *c != '\0'; c++){ + glColor3ubv(color); + glRasterPos2f(x1,y); + glutBitmapCharacter(font, *c); + //glutStrokeCharacter(GLUT_STROKE_ROMAN, *c); + x1 = x1 + glutBitmapWidth(font,*c);// + 1; + } +} + +void redisplay(int GL_ID){ + glutSetWindow(GL_ID); + glutPostRedisplay(); +} + +void Redraw(){ + forEachWindow(redisplay); + usleep(10000); +} + +void RedrawWindow(){ + int window; + window = glutGetWindow(); + windowData *win = searchWindow_byGLID(window); + if(!win) return; + if(pthread_mutex_trylock(&win->mutex) != 0) return; + /* Clear the windwindowDataow to black */ + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + glTranslatef(-win->w/2.,-win->h/2., win->z); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, win->Tex); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, win->w, win->h, GL_RGB, GL_UNSIGNED_BYTE, win->rawdata); + glBegin(GL_QUADS); + glTexCoord2f(0., 1.); glVertex3f(0., 0., 0.); + glTexCoord2f(0., 0.); glVertex3f(0., win->h, 0.); + glTexCoord2f(1., 0.); glVertex3f(win->w, win->h, 0.); + glTexCoord2f(1., 1.); glVertex3f(win->w, 0., 0.); + glEnd(); + glDisable(GL_TEXTURE_2D); + + glFinish(); + glutSwapBuffers(); + pthread_mutex_unlock(&win->mutex); +} + +void Resize(int width, int height){ + FNAME(); + int window = glutGetWindow(); + windowData *win = searchWindow_byGLID(window); + if(!win) return; + int GRAB_WIDTH = win->w, GRAB_HEIGHT = win->h; + float _U_ tmp, wd = (float) width/GRAB_WIDTH, ht = (float)height/GRAB_HEIGHT; + tmp = (wd + ht) / 2.; + width = (int)(tmp * GRAB_WIDTH); height = (int)(tmp * GRAB_HEIGHT); + glutReshapeWindow(width, height); + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + GLfloat W = (GLfloat)GRAB_WIDTH; GLfloat H = (GLfloat)GRAB_HEIGHT; + //glOrtho(-W,W, -H,H, -1., 1.); + gluPerspective(90., W/H, 0., 100.0); + gluLookAt(0., 0., H/2., 0., 0., 0., 0., 1., 0.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + diff --git a/image_view_module/bmpview.h b/image_view_module/bmpview.h new file mode 100644 index 0000000..ac6310d --- /dev/null +++ b/image_view_module/bmpview.h @@ -0,0 +1,43 @@ +/* + * bmpview.h + * + * Copyright 2015 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#pragma once +#ifndef __BMPVIEW_H__ +#define __BMPVIEW_H__ + +#include +#include +#include +#include "events.h" +#include "list.h" + +typedef enum{ + INNER, + OPENGL +} winIdType; + +void createWindow(windowData *win); +int destroyWindow(int window, winIdType type); +void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color); +void Redraw(); +void RedrawWindow(); +void Resize(int width, int height); + +#endif // __BMPVIEW_H__ diff --git a/image_view_module/events.c b/image_view_module/events.c new file mode 100644 index 0000000..bee6ee0 --- /dev/null +++ b/image_view_module/events.c @@ -0,0 +1,101 @@ +/* + * events.c + * + * Copyright 2015 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "events.h" +#include "bmpview.h" +#include "macros.h" +/* + * Функции для работы с OpenGL'ными событиями + */ + +int ShowWavelet = 0; + +void keyPressed(unsigned char key, // код введенного символа + _U_ int x, _U_ int y){ // координаты мыши при нажатии клавиши + int _U_ mod = glutGetModifiers(), window = glutGetWindow(); + windowData *win = searchWindow_byGLID(window); + if(!win) return; + //DBG("Key pressed. mod=%d, keycode=%d, point=(%d,%d)\n", mod, key, x,y); + if((mod == GLUT_ACTIVE_CTRL) && (key == 'q' || key == 17)) exit(0); // ctrl + q + switch(key){ +// case 'i': more_info = !more_info; +// break; + case 27: destroyWindow(window, OPENGL); + break; + case 'p': + printf("z = %f\n", win->z); + break; +// case 'm': createWindow(&mainWindow); +// break; +// case 'w': createWindow(&WaveWindow); +// break; + case 'Z': win->z += 1.0; + break; + case 'z': win->z -= 1.0; + break; +// case 'h': createWindow(&SubWindow); +// break; + } +} + +void keySpPressed(_U_ int key, _U_ int x, _U_ int y){ +// int mod = glutGetModifiers(); + DBG("Sp. key pressed. mod=%d, keycode=%d, point=(%d,%d)\n", glutGetModifiers(), key, x,y); +} + +void mousePressed(int _U_ key, int _U_ state, _U_ int x, _U_ int y){ +// GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON + DBG("Mouse button %s. point=(%d, %d); mod=%d, button=%d\n", + (state == GLUT_DOWN)? "pressed":"released", x, y, glutGetModifiers(), key); + +/* int window = glutGetWindow(); + if(window == WaveWindow){ // щелкнули в окне с вейвлетом + _U_ int w = glutGet(GLUT_WINDOW_WIDTH) / 2; + _U_ int h = glutGet(GLUT_WINDOW_HEIGHT) / 2; + if(state == GLUT_DOWN && key == GLUT_LEFT_BUTTON){ + //HistCoord[0] = (x > w); + //HistCoord[1] = (y > h); + } + } +*/ +} + +void mouseMove(_U_ int x, _U_ int y){ + DBG("Mouse moved to (%d, %d)\n", x, y); +} + +/** + * winID - inner !!! + */ +void createMenu(_U_ int winID){ + glutCreateMenu(menuEvents); + glutAddMenuEntry("Quit (ctrl+q)", 'q'); + glutAddMenuEntry("Close this window (ESC)", 27); +// if(window == &mainWindow){ // пункты меню главного окна + glutAddMenuEntry("Info in stderr (i)", 'i'); +// } + ; + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +void menuEvents(int opt){ + if(opt == 'q') exit(0); + keyPressed((unsigned char)opt, 0, 0); +} diff --git a/image_view_module/events.h b/image_view_module/events.h new file mode 100644 index 0000000..4fa41d6 --- /dev/null +++ b/image_view_module/events.h @@ -0,0 +1,41 @@ +/* + * events.h + * + * Copyright 2015 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __EVENTS_H__ +#define __EVENTS_H__ + +#include +#include +#include +#include + +extern float Z; // координата Z (zoom) + +void keyPressed(unsigned char key, int x, int y); +void keySpPressed(int key, int x, int y); +void mousePressed(int key, int state, int x, int y); +void mouseMove(int x, int y); +void createMenu(int window); +void menuEvents(int opt); + + +#endif // __EVENTS_H__ diff --git a/image_view_module/list.c b/image_view_module/list.c new file mode 100644 index 0000000..795dc17 --- /dev/null +++ b/image_view_module/list.c @@ -0,0 +1,182 @@ +/* + * simple_list.c - simple one-direction list + * + * + * Copyright 2013 Edward V. Emelianoff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "list.h" +#include "macros.h" + +typedef struct list_{ + windowData *data; + struct list_ *next; + struct list_ *prev; +} WinList; + +static WinList *root = NULL; + +/** + * add element v to list with root root (also this can be last element) + * @param root (io) - pointer to root (or last element) of list or NULL + * if *root == NULL, just created node will be placed there + * IDs in list are sorted, so if root's ID isn't 0, it will be moved + * @param w - data inserted (with empty ID - identificator will be assigned here) + * @return pointer to data inside created node or NULL + */ +windowData *addWindow(windowData *w){ + WinList *node, *last, *curr; + int freeID = 1, curID; + if((node = MALLOC(WinList, 1)) == 0) return NULL; // allocation error + node->data = w; // insert data + if(root){ // there was root node - search last + last = root; + if(last->data->ID != 0){ // root element have non-zero ID + node->next = last; + root->prev = node; + root = NULL; + }else{ // root element have ID==0, search first free ID + while((curr = last->next)){ + if((curID = curr->data->ID) > freeID) // we found a hole! + break; + else + freeID = curID + 1; + last = last->next; + } + last->next = node; // insert pointer to new node into last element in list + node->prev = last; // don't forget a pointer to previous element + node->next = curr; // next item after a hole or NULL if there isn't holes + w->ID = freeID; + } + } + if(!root){ // we need to change root to this element; (*root=NULL could be done upper) + root = node; + w->ID = 0; + } + DBG("added window with id = %d", w->ID); + return w; +} + +/** + * search window with given inner identificator winID + * @return pointer to window struct or NULL if not found + */ +WinList *searchWindowList(int winID){ + WinList *node = NULL, *next = root; + int curID; + if(!root){ + DBG("no root leaf"); + return NULL; + } + do{ + node = next; + next = node->next; + curID = node->data->ID; + }while(curID < winID && next); + if(curID != winID) return NULL; + return node; +} +/** + * the same as upper but for outern usage + */ +windowData *searchWindow(int winID){ + WinList *node = searchWindowList(winID); + if(!node) return NULL; + return node->data; +} + +/** + * search window with given OpenGL identificator GL_ID + * @return pointer to window struct or NULL if not found + */ +windowData *searchWindow_byGLID(int GL_ID){ + WinList *node = NULL, *next = root; + int curID; + if(!root) return NULL; + do{ + node = next; + next = node->next; + curID = node->data->GL_ID; + }while(curID != GL_ID && next); + if(curID != GL_ID) return NULL; + return node->data; +} + +/** + * free() all data for node of list + * !!! data for raw pixels (rawdata) doesn't removed as it should be used + * only for initialisation and free() by user !!! + */ +void WinList_freeNode(WinList **node){ + if(!node || !*node) return; + WinList *cur = *node, *prev = cur->prev, *next = cur->next; + windowData *win = cur->data; + if(root == cur) root = next; + FREE(win->title); + FREE(win->rawdata); + pthread_mutex_destroy(&win->mutex); + FREE(*node); + if(prev) + prev->next = next; + if(next) + next->prev = prev; +} + +/** + * remove window with ID winID + * @return 0 in case of error !0 if OK + */ +int removeWindow(int winID){ + WinList *node = searchWindowList(winID); + if(!node){ + DBG("Not found"); + return 0; + } + DBG("removing win ID=%d", winID); + WinList_freeNode(&node); + return 1; +} + +/** + * remove all nodes in list + * @param root - pointer to root node + */ +void freeWinList(){ + WinList *node = root, *next; + if(!root) return; + do{ + next = node->next; + WinList_freeNode(&node); + node = next; + }while(node); + root = NULL; +} + +/** + * run function for each window in list + */ +void forEachWindow(void (*fn)(int GL_ID)){ + WinList *node = root; + if(!root) return; + do{ + int id = node->data->GL_ID; + if(id) fn(id); + node = node->next; + }while(node); +} + diff --git a/image_view_module/list.h b/image_view_module/list.h new file mode 100644 index 0000000..f9fc67b --- /dev/null +++ b/image_view_module/list.h @@ -0,0 +1,56 @@ +/* + * simple_list.h - header file for simple list support + * TO USE IT you must define the type of data as + * typedef your_type listdata + * or at compiling time + * -Dlistdata=your_type + * or by changing this file + * + * Copyright 2013 Edward V. Emelianoff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#pragma once +#ifndef __SIMPLE_LIST_H__ +#define __SIMPLE_LIST_H__ + +#include "events.h" + +typedef struct{ + int ID; // identificator + char *title; // title of window + GLuint Tex; // texture for image inside window + int GL_ID; // identificator of OpenGL window + GLubyte *rawdata; // raw image data + int w; int h; // image size + float z; // z-coordinate (zoom) + pthread_t thread; // identificator of thread that changes window data + pthread_mutex_t mutex;// mutex for operations with image +} windowData; + + + +// add element v to list with root root (also this can be last element) +windowData *addWindow(windowData *w); +windowData *searchWindow(int winID); +windowData *searchWindow_byGLID(int winGLID); + +void forEachWindow(void (*fn)(int GL_ID)); + +int removeWindow(int winID); +void freeWinList(); + +#endif // __SIMPLE_LIST_H__ diff --git a/image_view_module/locale/ru/LC_MESSAGES/openglview.mo b/image_view_module/locale/ru/LC_MESSAGES/openglview.mo new file mode 100644 index 0000000..1e4cc61 Binary files /dev/null and b/image_view_module/locale/ru/LC_MESSAGES/openglview.mo differ diff --git a/image_view_module/locale/ru/messages.po b/image_view_module/locale/ru/messages.po new file mode 100644 index 0000000..8aabd6b --- /dev/null +++ b/image_view_module/locale/ru/messages.po @@ -0,0 +1,57 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-02-18 18:46+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=koi8-r\n" +"Content-Transfer-Encoding: 8bit\n" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:175 +msgid "No filename given!" +msgstr "Не указано имя файла!" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:177 +#, c-format +msgid "Can't open %s for reading" +msgstr "Не могу открыть %s для чтения" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:179 +#, c-format +msgid "Can't stat %s" +msgstr "Не могу выполнить stat для %s" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:182 +msgid "Mmap error for input" +msgstr "Ошибка mmap для входных данных" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:183 +msgid "Can't close mmap'ed file" +msgstr "Не могу закрыть mmap'нутый файл" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:192 +msgid "Can't munmap" +msgstr "Не могу вызывать munmap" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/main.c:106 +msgid "Can't init mutex!" +msgstr "Не могу инициировать взаимное исключение!" + +#. cancel thread changing data +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:102 +msgid "can't cancel a thread!" +msgstr "Не могу отменить выполнение потока!" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:105 +msgid "Error removing from list" +msgstr "Ошибка удаления из списка" diff --git a/image_view_module/locale/ru/ru.po b/image_view_module/locale/ru/ru.po new file mode 100644 index 0000000..c794abf --- /dev/null +++ b/image_view_module/locale/ru/ru.po @@ -0,0 +1,56 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "Project-Id-Version: PACKAGE VERSION\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2015-02-18 18:46+0300\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME \n" + "Language-Team: LANGUAGE \n" + "Language: \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=koi8-r\n" + "Content-Transfer-Encoding: 8bit\n" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:183 +msgid "Can't close mmap'ed file" +msgstr "Не могу закрыть mmap'нутый файл" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/main.c:106 +msgid "Can't init mutex!" +msgstr "Не могу инициировать взаимное исключение!" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:192 +msgid "Can't munmap" +msgstr "Не могу вызывать munmap" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:177 +#, c-format +msgid "Can't open %s for reading" +msgstr "Не могу открыть %s для чтения" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:179 +#, c-format +msgid "Can't stat %s" +msgstr "Не могу выполнить stat для %s" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:105 +msgid "Error removing from list" +msgstr "Ошибка удаления из списка" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:182 +msgid "Mmap error for input" +msgstr "Ошибка mmap для входных данных" + +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/macros.c:175 +msgid "No filename given!" +msgstr "Не указано имя файла!" + +#. cancel thread changing data +#: /home/eddy/tmp/wavelets-hough-and-so-on/image_view_module/bmpview.c:102 +msgid "can't cancel a thread!" +msgstr "Не могу отменить выполнение потока!" diff --git a/image_view_module/macros.c b/image_view_module/macros.c new file mode 100644 index 0000000..cc6bfe1 --- /dev/null +++ b/image_view_module/macros.c @@ -0,0 +1,195 @@ +/* + * usefull_macros.h - a set of usefull functions: memory, color etc + * + * Copyright 2013 Edward V. Emelianoff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "macros.h" + + +#include +/** + * function for different purposes that need to know time intervals + * @return double value: time in seconds + */ +double dtime(){ + double t; + struct timeval tv; + gettimeofday(&tv, NULL); + t = tv.tv_sec + ((double)tv.tv_usec)/1e6; + return t; +} + +/******************************************************************************\ + * Coloured terminal +\******************************************************************************/ +int globErr = 0; // errno for WARN/ERR + +// pointers to coloured output printf +int (*red)(const char *fmt, ...); +int (*green)(const char *fmt, ...); +int (*_WARN)(const char *fmt, ...); + +/* + * format red / green messages + * name: r_pr_, g_pr_ + * @param fmt ... - printf-like format + * @return number of printed symbols + */ +int r_pr_(const char *fmt, ...){ + va_list ar; int i; + printf(RED); + va_start(ar, fmt); + i = vprintf(fmt, ar); + va_end(ar); + printf(OLDCOLOR); + return i; +} +int g_pr_(const char *fmt, ...){ + va_list ar; int i; + printf(GREEN); + va_start(ar, fmt); + i = vprintf(fmt, ar); + va_end(ar); + printf(OLDCOLOR); + return i; +} +/* + * print red error/warning messages (if output is a tty) + * @param fmt ... - printf-like format + * @return number of printed symbols + */ +int r_WARN(const char *fmt, ...){ + va_list ar; int i = 1; + fprintf(stderr, RED); + va_start(ar, fmt); + if(globErr){ + errno = globErr; + vwarn(fmt, ar); + errno = 0; + globErr = 0; + }else + i = vfprintf(stderr, fmt, ar); + va_end(ar); + i++; + fprintf(stderr, OLDCOLOR "\n"); + return i; +} + +const char stars[] = "****************************************"; +/* + * notty variants of coloured printf + * name: s_WARN, r_pr_notty + * @param fmt ... - printf-like format + * @return number of printed symbols + */ +int s_WARN(const char *fmt, ...){ + va_list ar; int i; + i = fprintf(stderr, "\n%s\n", stars); + va_start(ar, fmt); + if(globErr){ + errno = globErr; + vwarn(fmt, ar); + errno = 0; + globErr = 0; + }else + i = +vfprintf(stderr, fmt, ar); + va_end(ar); + i += fprintf(stderr, "\n%s\n", stars); + i += fprintf(stderr, "\n"); + return i; +} +int r_pr_notty(const char *fmt, ...){ + va_list ar; int i; + i = printf("\n%s\n", stars); + va_start(ar, fmt); + i += vprintf(fmt, ar); + va_end(ar); + i += printf("\n%s\n", stars); + return i; +} + +/** + * Run this function in the beginning of main() to setup locale & coloured output + */ +void initial_setup(){ + // setup coloured output + if(isatty(STDOUT_FILENO)){ // make color output in tty + red = r_pr_; green = g_pr_; + }else{ // no colors in case of pipe + red = r_pr_notty; green = printf; + } + if(isatty(STDERR_FILENO)) _WARN = r_WARN; + else _WARN = s_WARN; + // Setup locale + setlocale(LC_ALL, ""); + setlocale(LC_NUMERIC, "C"); +#ifndef NOGETTEXT + bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); + textdomain(GETTEXT_PACKAGE); +#endif +} + +/******************************************************************************\ + * Memory +\******************************************************************************/ +/* + * safe memory allocation for macro ALLOC + * @param N - number of elements to allocate + * @param S - size of single element (typically sizeof) + * @return pointer to allocated memory area + */ +void *my_alloc(size_t N, size_t S){ + void *p = calloc(N, S); + if(!p) ERR("malloc"); + //assert(p); + return p; +} + +/** + * Mmap file to a memory area + * + * @param filename (i) - name of file to mmap + * @return stuct with mmap'ed file or die + */ +mmapbuf *My_mmap(char *filename){ + int fd; + char *ptr; + size_t Mlen; + struct stat statbuf; + if(!filename) ERRX(_("No filename given!")); + if((fd = open(filename, O_RDONLY)) < 0) + ERR(_("Can't open %s for reading"), filename); + if(fstat (fd, &statbuf) < 0) + ERR(_("Can't stat %s"), filename); + Mlen = statbuf.st_size; + if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) + ERR(_("Mmap error for input")); + if(close(fd)) ERR(_("Can't close mmap'ed file")); + mmapbuf *ret = MALLOC(mmapbuf, 1); + ret->data = ptr; + ret->len = Mlen; + return ret; +} + +void My_munmap(mmapbuf *b){ + if(munmap(b->data, b->len)) + ERR(_("Can't munmap")); + FREE(b); +} + diff --git a/image_view_module/macros.h b/image_view_module/macros.h new file mode 100644 index 0000000..6eed1b5 --- /dev/null +++ b/image_view_module/macros.h @@ -0,0 +1,117 @@ +/* + * macros.h + * + * Copyright 2015 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __MACROS_H__ +#define __MACROS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +// not used args +#define _U_ __attribute__((__unused__)) + +#define check_ptr(ptr, fn) \ + if((ptr) == NULL) { \ + printf("%10s: NULL pointer\n",(char *)(fn)); \ + perror((char *)(fn)); \ + exit(1); \ + } + +#ifdef NOGETTEXT + #ifdef gettext + #undef gettext + #endif + #define gettext(arg) arg +#endif +#define _(String) gettext(String) +#define gettext_noop(String) String +#define N_(String) gettext_noop(String) + +/* + * Coloured messages output + */ +#define RED "\033[1;31;40m" +#define GREEN "\033[1;32;40m" +#define OLDCOLOR "\033[0;0;0m" + +extern int globErr; + +#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0) +#define ERRX(...) do{globErr=0; _WARN(__VA_ARGS__); exit(-1);}while(0) +#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0) +#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0) + +/* + * print function name, debug messages + * debug mode, -DEBUG + */ +#ifdef EBUG + #define FNAME() fprintf(stderr, "\n%s (%s, line %d)\n", __func__, __FILE__, __LINE__) + #define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n");} while(0) +#else + #define FNAME() do{}while(0) + #define DBG(...) do{}while(0) +#endif //EBUG + +/* + * Memory allocation + */ +#define ALLOC(type, var, size) type * var = ((type *)my_alloc(size, sizeof(type))) +#define MALLOC(type, size) ((type *)my_alloc(size, sizeof(type))) +#define FREE(ptr) do{free(ptr); ptr = NULL;}while(0) + +// functions for color output in tty & no-color in pipes +extern int (*red)(const char *fmt, ...); +extern int (*_WARN)(const char *fmt, ...); +extern int (*green)(const char *fmt, ...); +void * my_alloc(size_t N, size_t S); +void initial_setup(); + +// mmap file +typedef struct{ + char *data; + size_t len; +} mmapbuf; +mmapbuf *My_mmap(char *filename); +void My_munmap(mmapbuf *b); + +#endif // __MACROS_H__ diff --git a/image_view_module/main.c b/image_view_module/main.c new file mode 100644 index 0000000..d811a99 --- /dev/null +++ b/image_view_module/main.c @@ -0,0 +1,152 @@ +/* + * main.c + * + * Copyright 2015 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include // XInitThreads(); + +#include "main.h" +#include "macros.h" +#include "bmpview.h" + + +//GLubyte *BitmapBits = NULL; + +/* +pthread_mutex_t m_ima = PTHREAD_MUTEX_INITIALIZER, m_wvlt = PTHREAD_MUTEX_INITIALIZER, + m_hist = PTHREAD_MUTEX_INITIALIZER; +*/ +unsigned int bufsize; + +void help(char *s){ + fprintf(stderr, "\n\n%s, simple interface for LOMO's webcam \"microscope\"\n", s); + fprintf(stderr, "Usage: %s [-h] [-d videodev] [-c channel]\n\n", s); + fprintf(stderr, + "-h, --help:\tthis help\n" + "-d, --device:\tcapture from \n" + "-c, --channel:\tset channel (0..3)\n" + ); + fprintf(stderr, "\n\n"); +} + +void* change_image(void *data){ + FNAME(); + windowData *win = (windowData*) data; + int w = win->w, h = win->h, x,y, id = win->ID; + GLubyte i; + DBG("w=%d, h=%d",w,h); + for(i = 1; ;i++){ + if(!searchWindow(id)) pthread_exit(NULL); + pthread_mutex_lock(&win->mutex); + GLubyte *raw = win->rawdata; + for(y = 0; y < h; y++){ + if(y%20 == 19){ + raw += w*3; + continue; + } + for(x = 0; x < w; x++){ + if(x%20 != 19){ + if(i < 80) raw[0]++; + else if(i < 170) raw[1]++; + else raw[2]++; + } + raw += 3; + } + } + pthread_mutex_unlock(&win->mutex); + usleep(10000); + } +} + +/* +void *GLloop(void *data){ + FNAME(); + windowData *win = (windowData *)data; + createWindow(win); + return NULL; +} +*/ + +/** + * create new window, run thread & return pointer to its structure or NULL + * @param title - header (copyed inside this function) + * @param w,h - image size + */ +windowData *createGLwin(char *title, int w, int h){ + windowData *win = MALLOC(windowData, 1); + if(!addWindow(win)){ + FREE(win); + return NULL; + } + GLubyte *raw = MALLOC(GLubyte, w*h*3); + win->title = strdup(title); + win->rawdata = raw; + if(pthread_mutex_init(&win->mutex, NULL)){ + WARN(_("Can't init mutex!")); + removeWindow(win->ID); + return NULL; + } + win->w = w; + win->h = h; +// pthread_create(&win->glthread, NULL, GLloop, (void*)win); + createWindow(win); + return win; +} + +/* +GLubyte *prepareImage(){ + static GLubyte *imPtr = NULL; + //static int bufferSize; + //int readlines, linesize; + //GLubyte *ptr; + if(!imPtr) imPtr = calloc(100, sizeof(GLubyte)); + return imPtr; +} +*/ + +int main(_U_ int argc, _U_ char** argv){ + windowData *mainwin, _U_ *win, _U_ *third; + int w = 640, h = 480; + + char *v[] = {PROJNAME, NULL}; + int c = 1; + glutInit(&c, v); + + initial_setup(); // locale & messages + XInitThreads(); // we need it for threaded windows + //BitmapBits = prepareImage(); + mainwin = createGLwin("Sample window", w, h); + if(!mainwin) return 1; + pthread_create(&mainwin->thread, NULL, &change_image, (void*)mainwin); + win = createGLwin("Second window", w/2, h/2); + if(!win) return 1; + pthread_create(&win->thread, NULL, &change_image, (void*)win); + third = createGLwin("Second window", w/4, h/4); + if(!win) return 1; + pthread_create(&third->thread, NULL, &change_image, (void*)third); + // wait for end + glutMainLoop(); + return 0; +} + diff --git a/image_view_module/main.h b/image_view_module/main.h new file mode 100644 index 0000000..f7c6bbf --- /dev/null +++ b/image_view_module/main.h @@ -0,0 +1,6 @@ +// pthread_t thread, thread_m; +#include "events.h" // GLubyte etc + +// GLubyte *prepareImage(); +void help(char *s); +