image view works!

This commit is contained in:
eddyem 2015-03-02 14:00:26 +03:00
parent 4e5d015e53
commit da3cde5816
10 changed files with 313 additions and 193 deletions

View File

@ -1,51 +1,85 @@
cmake_minimum_required(VERSION 2.8)
# RUN cmake -DSTANDALONE=1 for standalone example
# -DEBUG=1 for debugging
# -DNOGETTEXT=1 for compilation without gettext support
#
# Into cmake file in parent directory add this:
#~ add_subdirectory(image_view_module)
#~ if(IMAGEVIEW_FOUND)
#~ message("Found OpenGL. Will use ${IMLIB} to show data")
#~ target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} -lm ${IMLIB})
#~ add_definitions(-DIMAGEVIEW)
#~ else()
#~ message("not found image view module")
#~ target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} -lm)
#~ endif()
# cmake -DEBUG=1 -> debugging
if(DEFINED EBUG)
add_definitions(-DEBUG)
set(CMAKE_VERBOSE_MAKEFILE ON)
cmake_minimum_required(VERSION 2.8)
set(IMLIB image_view_module)
if(DEFINED STANDALONE)
set(PROJ ${IMLIB})
project(${PROJ})
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)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} IMSOURCES)
# we can change file list
#if(NOT DEFINED something)
# set(SOURCES ${SOURCES} one_more_list)
# add_definitions(-DSOME_DEFS)
#endif()
find_package(PkgConfig REQUIRED)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
set(MODULES)
# additional modules on condition
#if(DEFINED SOMETHING)
# set(MODULES ${MODULES} more_modules>=version)
# add_definitions(-DSOMEDEFS)
#endif()
if(NOT GLUT_FOUND OR NOT OPENGL_FOUND)
message("GLUT library not found, image view won't be available")
else()
# exe file
project(${PROJ})
# change wrong behaviour with install prefix
if(CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
if(NOT DEFINED STANDALONE)
list(REMOVE_ITEM IMSOURCES main.c)
add_library(image_view_module ${IMSOURCES})
set(IMAGEVIEW_FOUND TRUE PARENT_SCOPE)
set(IMLIB ${IMLIB} PARENT_SCOPE)
if(DEFINED DEBUG)
set(LCPATH ${CMAKE_CURRENT_SOURCE_DIR}/locale/ru)
set(PO_FILE ${LCPATH}/messages.po)
set(RU_FILE ${LCPATH}/ru.po)
set(IMPO_FILE ${RU_FILE} PARENT_SCOPE)
add_custom_command(
OUTPUT ${PO_FILE}
COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} -D ${CMAKE_CURRENT_SOURCE_DIR} --from-code=koi8-r ${IMSOURCES} -c -k_ -kN_ -o ${PO_FILE}
COMMAND sed 's/charset=UTF-8/charset=koi8-r/' ${PO_FILE} | enconv > tmp && mv -f tmp ${PO_FILE}
COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE}
DEPENDS ${IMSOURCES}
)
endif()
else()
# cmake -DEBUG=1 -> debugging
if(DEFINED EBUG)
add_definitions(-DEBUG)
#set(CMAKE_VERBOSE_MAKEFILE ON)
endif()
set(MINOR_VERSION "1")
set(MID_VERSION "0")
set(MAJOR_VERSION "0")
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
message("VER: ${VERSION}")
# 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}")
endif()
message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}")
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}\")
if(NOT DEFINED NOGETTEXT)
# directory should contain dir locale/ru for gettext translations
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)
@ -58,42 +92,16 @@ if(NOT DEFINED NOGETTEXT)
set(PO_FILE ${LCPATH}/messages.po)
set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo)
set(RU_FILE ${LCPATH}/ru.po)
else()
else()
add_definitions(-DNOGETTEXT)
set(PO_FILE)
set(MO_FILE)
endif()
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()
add_executable(${PROJ} ${IMSOURCES} ${PO_FILE} ${MO_FILE})
#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)
# 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")
@ -101,36 +109,43 @@ if(NOT DEFINED DEBUG)
# 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()
else()
install(CODE "MESSAGE(\"Don't install in DEBUG mode! First run cmake without -DEBUG defined.\")")
endif(NOT DEFINED DEBUG)
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)
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)
endif()
file(MAKE_DIRECTORY ${LCPATH})
file(MAKE_DIRECTORY ${LCPATH}/LC_MESSAGES)
add_custom_command(
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 ${GETTEXT_XGETTEXT_EXECUTABLE} --from-code=utf-8 ${IMSOURCES} -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(
DEPENDS ${IMSOURCES}
)
# 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(
)
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)
)
endif(NOT DEFINED NOGETTEXT)
endif(NOT DEFINED STANDALONE)
target_link_libraries(${IMLIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} -lm -lpthread)
include_directories(${${IMLIB}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR})
link_directories(${${IMLIB}_LIBRARY_DIRS})
endif(NOT GLUT_FOUND OR NOT OPENGL_FOUND)

View File

@ -21,35 +21,22 @@
#include "events.h"
#include "imageview.h"
#include "macros.h"
/*
* æÕÎËÃÉÉ ÄÌÑ ÒÁÂÏÔÙ Ó OpenGL'ÎÙÍÉ ÓÏÂÙÔÉÑÍÉ
/**
* manage pressed keys & menu items
*/
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);
void processKeybrd(unsigned char key, int mod, int win_GL_ID, _U_ int x, _U_ int y){
windowData *win = searchWindow_byGLID(win_GL_ID);
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 '1': // return zoom to 1 & image to 0
win->zoom = 1;
win->x = 0; win->y = 0;
break;
// case 'i': more_info = !more_info;
// break;
case 27: destroyWindow(window, OPENGL);
case 27:
destroyWindow_async(win_GL_ID);
break;
case 'p':
printf("zoom = %f\n", win->zoom);
break;
// case 'm': createWindow(&mainWindow);
// break;
// case 'w': createWindow(&WaveWindow);
// break;
case 'Z':
win->zoom *= 1.1;
calc_win_props(win, NULL, NULL);
@ -58,11 +45,22 @@ void keyPressed(unsigned char key, //
win->zoom /= 1.1;
calc_win_props(win, NULL, NULL);
break;
// case 'h': createWindow(&SubWindow);
// break;
}
}
/*
* Process keyboard
*/
void keyPressed(unsigned char key,
_U_ int x, _U_ int y){
int mod = glutGetModifiers();
int window = glutGetWindow();
//mod: GLUT_ACTIVE_SHIFT, GLUT_ACTIVE_CTRL, GLUT_ACTIVE_ALT; result is their sum
//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
processKeybrd(key, mod, window, x, y);
}
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);
@ -73,18 +71,25 @@ int movingwin = 0; // ==1 when user moves image by middle button
void mousePressed(_U_ int key, _U_ int state, _U_ int x, _U_ int y){
// key: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
// state: GLUT_UP, GLUT_DOWN
int window = glutGetWindow();
int window = glutGetWindow(), mod = glutGetModifiers();
windowData *win = searchWindow_byGLID(window);
if(!win) return;
if(state == GLUT_DOWN){
oldx = x; oldy = y;
float X,Y;
conv_mouse_to_image_coords(x,y,&X,&Y,win);
DBG("press in (%d, %d) == (%f, %f) on image", x,y,X,Y);
DBG("press in (%d, %d) == (%f, %f) on image; mod == %d", x,y,X,Y, mod);
if(key == GLUT_MIDDLE_BUTTON) movingwin = 1;
if(key == 3){ // wheel UP
if(mod == 0) win->y += 10.*win->zoom; // nothing pressed - scroll up
else if(mod == GLUT_ACTIVE_SHIFT) win->x -= 10.*win->zoom; // shift pressed - scroll left
else if(mod == GLUT_ACTIVE_CTRL) win->zoom *= 1.1; // ctrl+wheel up == zoom+
}else if(key == 4){ // wheel DOWN
if(mod == 0) win->y -= 10.*win->zoom; // nothing pressed - scroll down
else if(mod == GLUT_ACTIVE_SHIFT) win->x += 10.*win->zoom; // shift pressed - scroll right
else if(mod == GLUT_ACTIVE_CTRL) win->zoom /= 1.1; // ctrl+wheel down == zoom-
}
calc_win_props(win, NULL, NULL);
}else{
movingwin = 0;
}
@ -134,21 +139,27 @@ void mouseMove(_U_ int x, _U_ int y){
}
}
void menuEvents(int opt){
FNAME();
int window = glutGetWindow();
if(opt == 'q') exit(0);
processKeybrd((unsigned char)opt, 0, window, 0, 0);
}
/**
* winID - inner !!!
*/
void createMenu(_U_ int winID){
glutCreateMenu(menuEvents);
void createMenu(int GL_ID){
FNAME();
windowData *win;
win = searchWindow_byGLID(GL_ID);
glutSetWindow(GL_ID);
if(win->menu) glutDestroyMenu(win->menu);
win->menu = glutCreateMenu(menuEvents);
DBG("created menu %d\n", win->menu);
glutAddMenuEntry("Quit (ctrl+q)", 'q');
glutAddMenuEntry("Close this window (ESC)", 27);
// if(window == &mainWindow){ // ÐÕÎËÔÙ ÍÅÎÀ ÇÌÁ×ÎÏÇÏ ÏËÎÁ
glutAddMenuEntry("Info in stderr (i)", 'i');
// }
;
glutAddMenuEntry("Restore zoom (1)", '1');
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
void menuEvents(int opt){
if(opt == 'q') exit(0);
keyPressed((unsigned char)opt, 0, 0);
}

View File

@ -30,6 +30,7 @@ volatile int wannacreate = 0; // flag: ==1 if someone wants to create window
windowData *wininiptr = NULL;
int initialized = 0; // ==1 if GLUT is initialized; ==0 after clear_GL_context
int wannakill_GL_ID = 0; // GL_ID of window for asynchroneous killing
void createWindow(windowData *win);
void RedrawWindow();
@ -88,19 +89,22 @@ void createWindow(windowData *win){
glGenTextures(1, &(win->Tex));
calc_win_props(win, NULL, NULL);
win->zoom = 1. / win->Daspect;
// 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);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
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, win->image->w, win->image->h, 0,
GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata);
glDisable(GL_TEXTURE_2D);
totWindows++;
createMenu(win->GL_ID);
DBG("OK, total opened windows: %d", totWindows);
}
@ -108,22 +112,23 @@ void createWindow(windowData *win){
int killwindow(int GL_ID){
DBG("try to kill win GL_ID=%d", GL_ID);
windowData *win;
int canceled = 1;
win = searchWindow_byGLID(GL_ID);
if(!win) return 0;
if(!pthread_cancel(win->thread)){ // cancel thread changing data
canceled = 0;
glutSetWindow(GL_ID); // obviously set window (for closing from menu)
if(!win->killthread){
pthread_mutex_lock(&win->mutex);
// say changed thread to die
win->killthread = 1;
pthread_mutex_unlock(&win->mutex);
DBG("wait for changed thread");
pthread_join(win->thread, NULL); // wait while thread dies
}
// pthread_join(win->thread, NULL);
glDeleteTextures(1, &win->Tex);
glFinish();
if(win->menu) glutDestroyMenu(win->menu);
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);
DBG("destroy texture %d", win->Tex);
glDeleteTextures(1, &(win->Tex));
glFinish();
if(!removeWindow(win->ID)) WARNX(_("Error removing from list"));
totWindows--;
return 1;
@ -138,16 +143,28 @@ int killwindow(int GL_ID){
int destroyWindow(int window, winIdType type){
if(!initialized) return 0;
int r = 0;
DBG("lock");
pthread_mutex_lock(&winini_mutex);
DBG("locked");
if(type == INNER){
windowData *win = searchWindow(window);
if(win) r = killwindow(win->GL_ID);
}else
r = killwindow(window);
pthread_mutex_unlock(&winini_mutex);
DBG("window killed");
return r;
}
/**
* asynchroneous destroying - for using from menu
*/
void destroyWindow_async(int window_GL_ID){
pthread_mutex_lock(&winini_mutex);
wannakill_GL_ID = window_GL_ID;
pthread_mutex_unlock(&winini_mutex);
}
void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color){
if(!initialized) return;
char *c;
@ -235,9 +252,17 @@ void RedrawWindow(){
* waits for global signals to create windows & make other actions
*/
void *Redraw(_U_ void *arg){
// pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
// struct timeval tv;
// struct timespec timeToWait;
// struct timeval now;
while(1){
pthread_mutex_lock(&winini_mutex);
if(!initialized) return NULL;
if(!initialized){
DBG("!initialized");
pthread_mutex_unlock(&winini_mutex);
pthread_exit(NULL);
}
if(wannacreate){ // someone asks to create window
DBG("call for window creating, id: %d", wininiptr->ID);
createWindow(wininiptr);
@ -245,9 +270,28 @@ void *Redraw(_U_ void *arg){
wininiptr = NULL;
wannacreate = 0;
}
if(wannakill_GL_ID){
usleep(10000); // wait a little to be sure that caller is closed
killwindow(wannakill_GL_ID);
wannakill_GL_ID = 0;
}
forEachWindow(redisplay);
/* gettimeofday(&now,NULL);
timeToWait.tv_sec = now.tv_sec;
timeToWait.tv_nsec = now.tv_usec * 1000UL + 10000000UL;
pthread_cond_timedwait(&fakeCond, &winini_mutex, &timeToWait);*/
pthread_mutex_unlock(&winini_mutex);
//pthread_testcancel();
if(totWindows) glutMainLoopEvent(); // process actions if there are windows
/* gettimeofday(&now,NULL);
timeToWait.tv_sec = now.tv_sec;
timeToWait.tv_nsec = now.tv_usec * 1000UL + 10000000UL;
pthread_mutex_lock(&fakeMutex);
pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
pthread_mutex_unlock(&fakeMutex);*/
/* tv.tv_sec = 0;
tv.tv_usec = 10000;
select(0, NULL, NULL, NULL, &tv);*/
usleep(10000);
}
return NULL;
@ -366,12 +410,18 @@ void killwindow_v(int GL_ID){
void clear_GL_context(){
FNAME();
if(!initialized) return;
DBG("lock");
pthread_mutex_lock(&winini_mutex);
forEachWindow(killwindow_v);
pthread_cancel(GLUTthread); // kill main GLUT thread
pthread_join(GLUTthread, NULL);
initialized = 0;
DBG("locked");
// kill main GLUT thread
// pthread_cancel(GLUTthread);
pthread_mutex_unlock(&winini_mutex);
forEachWindow(killwindow_v);
DBG("join");
pthread_join(GLUTthread, NULL); // wait while main thread exits
// pthread_mutex_unlock(&winini_mutex);
DBG("main GL thread cancelled");
}

View File

@ -45,4 +45,6 @@ void calc_win_props(windowData *win, GLfloat *Wortho, GLfloat *Hortho);
void conv_mouse_to_image_coords(int x, int y, float *X, float *Y, windowData *window);
void conv_image_to_mouse_coords(float X, float Y, int *x, int *y, windowData *window);
void destroyWindow_async(int window_GL_ID);
#endif // __BMPVIEW_H__

View File

@ -48,8 +48,10 @@ typedef struct{
float x0; float y0;// center of window for coords conversion
float zoom; // zoom aspect
float Daspect; // aspect ratio between image & window sizes
int menu; // window menu identifier
pthread_t thread; // identificator of thread that changes window data
pthread_mutex_t mutex;// mutex for operations with image
int killthread; // flag for killing data changing thread & also signal that there's no threads
} windowData;

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-28 19:36+0300\n"
"POT-Creation-Date: 2015-03-02 13:58+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -43,20 +43,15 @@ msgstr ""
msgid "Can't munmap"
msgstr ""
#. cancel thread changing data
#: /home/eddy/tmp/image_view_module/imageview.c:124
msgid "can't cancel a thread!"
msgstr ""
#: /home/eddy/tmp/image_view_module/imageview.c:127
#: /home/eddy/tmp/image_view_module/imageview.c:132
msgid "Error removing from list"
msgstr ""
#: /home/eddy/tmp/image_view_module/imageview.c:318
#: /home/eddy/tmp/image_view_module/imageview.c:362
msgid "Can't init mutex!"
msgstr ""
#. "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: /home/eddy/tmp/image_view_module/imageview.c:345
#: /home/eddy/tmp/image_view_module/imageview.c:389
msgid "Already initialized!"
msgstr ""

View File

@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-28 19:32+0300\n"
"POT-Creation-Date: 2015-03-02 12:05+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,15 +17,15 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Content-Transfer-Encoding: 8bit\n"
#. "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: /home/eddy/tmp/image_view_module/imageview.c:345
#: /home/eddy/tmp/image_view_module/imageview.c:389
msgid "Already initialized!"
msgstr ""
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
#: /home/eddy/tmp/image_view_module/macros.c:183
msgid "Can't close mmap'ed file"
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
#: /home/eddy/tmp/image_view_module/imageview.c:318
#: /home/eddy/tmp/image_view_module/imageview.c:362
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÉÒÏ×ÁÔØ ×ÚÁÉÍÎÏÅ ÉÓËÌÀÞÅÎÉÅ!"
@ -43,7 +43,7 @@ msgstr "
msgid "Can't stat %s"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat ÄÌÑ %s"
#: /home/eddy/tmp/image_view_module/imageview.c:127
#: /home/eddy/tmp/image_view_module/imageview.c:132
msgid "Error removing from list"
msgstr "ïÛÉÂËÁ ÕÄÁÌÅÎÉÑ ÉÚ ÓÐÉÓËÁ"
@ -55,11 +55,9 @@ msgstr "
msgid "No filename given!"
msgstr "îÅ ÕËÁÚÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
#. cancel thread changing data
#: /home/eddy/tmp/image_view_module/imageview.c:124
msgid "can't cancel a thread!"
msgstr "îÅ ÍÏÇÕ ÏÔÍÅÎÉÔØ ×ÙÐÏÌÎÅÎÉÅ ÐÏÔÏËÁ!"
#, fuzzy
#~ msgid "Can't init main GLUT mutex!"
#~ msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÉÒÏ×ÁÔØ ×ÚÁÉÍÎÏÅ ÉÓËÌÀÞÅÎÉÅ!"
#~ msgid "can't cancel a thread!"
#~ msgstr "îÅ ÍÏÇÕ ÏÔÍÅÎÉÔØ ×ÙÐÏÌÎÅÎÉÅ ÐÏÔÏËÁ!"

View File

@ -29,15 +29,24 @@
void* change_image(void *data){
FNAME();
//struct timeval tv;
windowData *win = (windowData*) data;
int w = win->image->w, h = win->image->h, x,y, id = win->ID;
GLubyte i;
DBG("w=%d, h=%d",w,h);
for(i = 1; ;i++){
// DBG("search to refresh %d", id);
if(!searchWindow(id)) pthread_exit(NULL);
if(!searchWindow(id)){
DBG("Window deleted");
pthread_exit(NULL);
}
// DBG("found, lock mutex");
pthread_mutex_lock(&win->mutex);
if(win->killthread){
pthread_mutex_unlock(&win->mutex);
DBG("got killthread");
pthread_exit(NULL);
}
// DBG("refresh");
GLubyte *raw = win->image->rawdata;
for(y = 0; y < h; y++){
@ -57,7 +66,41 @@ void* change_image(void *data){
win->image->changed = 1;
pthread_mutex_unlock(&win->mutex);
usleep(10000);
//sleep(1);
/*tv.tv_sec = 0;
tv.tv_usec = 10000;
select(0, NULL, NULL, NULL, &tv);*/
}
}
void* another_change(void *data){
FNAME();
windowData *win = (windowData*) data;
int w = win->image->w, h = win->image->h, x,y, id = win->ID;
GLubyte i;
for(i = 1; ;i++){
if(!searchWindow(id)){
DBG("Window deleted");
pthread_exit(NULL);
}
pthread_mutex_lock(&win->mutex);
GLubyte *raw = win->image->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;
}
}
win->image->changed = 1;
pthread_mutex_unlock(&win->mutex);
usleep(10000);
}
}
@ -65,6 +108,7 @@ void *main_thread(_U_ void *none){
// while(1){};
rawimage im;
windowData *mainwin, *win, *third;
pthread_t mainthread;
int w = 640, h = 480;
im.protected = 1;
im.rawdata = MALLOC(GLubyte, w*h*3);
@ -72,11 +116,14 @@ void *main_thread(_U_ void *none){
mainwin = createGLwin("Sample window", w, h, &im);
DBG("ok");
if(!mainwin) ERRX("can't create main");
pthread_create(&mainwin->thread, NULL, &change_image, (void*)mainwin);
// pthread_create(&mainwin->thread, NULL, &change_image, (void*)mainwin);
pthread_create(&mainthread, NULL, &another_change, (void*)mainwin);
mainwin->killthread = 1; // say that there's no thread for manipulating
win = createGLwin("Second window", w/2, h/2, NULL);
if(!win) ERRX("can't create second");
pthread_create(&win->thread, NULL, &change_image, (void*)win);
pthread_join(mainwin->thread, NULL);
//pthread_join(mainwin->thread, NULL);
pthread_join(mainthread, NULL);
pthread_join(win->thread, NULL);
clear_GL_context();
WARNX("Two windows closed, create another one");