mirror of
https://github.com/eddyem/eddys_snippets.git
synced 2025-12-06 10:45:12 +03:00
image view works!
This commit is contained in:
parent
4e5d015e53
commit
da3cde5816
@ -1,136 +1,151 @@
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
if(NOT GLUT_FOUND OR NOT OPENGL_FOUND)
|
||||
message("GLUT library not found, image view won't be available")
|
||||
else()
|
||||
# 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}\"
|
||||
|
||||
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}")
|
||||
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)
|
||||
# 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()
|
||||
|
||||
add_executable(${PROJ} ${IMSOURCES} ${PO_FILE} ${MO_FILE})
|
||||
|
||||
# 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 ${IMSOURCES} -c -k_ -kN_ -o ${PO_FILE}
|
||||
COMMAND sed -i 's/charset=.*\\\\n/charset=koi8-r\\\\n/' ${PO_FILE}
|
||||
COMMAND enconv ${PO_FILE}
|
||||
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(
|
||||
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 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)
|
||||
|
||||
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)
|
||||
|
||||
@ -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);
|
||||
break;
|
||||
case 'p':
|
||||
printf("zoom = %f\n", win->zoom);
|
||||
case 27:
|
||||
destroyWindow_async(win_GL_ID);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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__
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
|
||||
BIN
image_view_module/locale/ru/LC_MESSAGES/image_view_module.mo
Normal file
BIN
image_view_module/locale/ru/LC_MESSAGES/image_view_module.mo
Normal file
Binary file not shown.
Binary file not shown.
@ -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 ""
|
||||
|
||||
@ -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 "îÅ ÍÏÇÕ ÏÔÍÅÎÉÔØ ×ÙÐÏÌÎÅÎÉÅ ÐÏÔÏËÁ!"
|
||||
|
||||
@ -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");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user