Browse Source

moved over wayland port

naelstrof 7 years ago
parent
commit
4a7c5fe6fb
70 changed files with 4701 additions and 5007 deletions
  1. 51
    151
      CMakeLists.txt
  2. 0
    220
      README.md
  3. 0
    44
      cmakemodules/FindGLX.cmake
  4. 0
    91
      cmakemodules/FindImlib2.cmake
  5. 0
    23
      cmakemodules/FindRT.cmake
  6. 0
    26
      cmakemodules/FindXExt.cmake
  7. 0
    26
      cmakemodules/FindXRandr.cmake
  8. 0
    47
      cmakemodules/FindXRender.cmake
  9. 0
    12
      generateReadme.sh
  10. 53
    0
      modules/FindEGL.cmake
  11. 52
    0
      modules/FindGLM.cmake
  12. 67
    0
      modules/FindWayland.cmake
  13. 9
    0
      share/slop-wayland/simple.frag
  14. 9
    0
      share/slop-wayland/simple.vert
  15. 13
    0
      share/slop-wayland/textured.frag
  16. 3
    3
      share/slop-wayland/textured.vert
  17. 0
    38
      share/slop/cross.frag
  18. 0
    1
      share/slop/gothic/corner_bl.png
  19. 0
    1
      share/slop/gothic/corner_br.png
  20. BIN
      share/slop/gothic/corner_tl.png
  21. 0
    1
      share/slop/gothic/corner_tr.png
  22. BIN
      share/slop/gothic/straight.png
  23. 0
    30
      share/slop/hippie.frag
  24. 0
    12
      share/slop/hippie.vert
  25. 0
    16
      share/slop/invert.frag
  26. 0
    13
      share/slop/invert.vert
  27. 0
    83
      share/slop/refract.frag
  28. 0
    12
      share/slop/refract.vert
  29. 0
    17
      share/slop/ripple.frag
  30. 0
    13
      share/slop/ripple.vert
  31. 0
    12
      share/slop/simple.frag
  32. 0
    12
      share/slop/simple.vert
  33. 0
    20
      share/slop/wiggle.frag
  34. 0
    12
      share/slop/wiggle.vert
  35. 0
    893
      src/cmdline.c
  36. 0
    240
      src/cmdline.in
  37. 65
    425
      src/framebuffer.cpp
  38. 17
    40
      src/framebuffer.hpp
  39. 1261
    0
      src/gl_core_3_3.c
  40. 1700
    0
      src/gl_core_3_3.h
  41. 0
    683
      src/glselectrectangle.cpp
  42. 0
    102
      src/glselectrectangle.hpp
  43. 58
    0
      src/keyboard.cpp
  44. 22
    0
      src/keyboard.hpp
  45. 77
    553
      src/main.cpp
  46. 111
    0
      src/mouse.cpp
  47. 32
    0
      src/mouse.hpp
  48. 199
    0
      src/options.cpp
  49. 0
    125
      src/options.ggo
  50. 37
    0
      src/options.hpp
  51. 243
    0
      src/rectangle.cpp
  52. 45
    0
      src/rectangle.hpp
  53. 20
    29
      src/resource.cpp
  54. 9
    14
      src/resource.hpp
  55. 0
    36
      src/selectrectangle.cpp
  56. 0
    60
      src/selectrectangle.hpp
  57. 40
    34
      src/shader.cpp
  58. 15
    24
      src/shader.hpp
  59. 141
    0
      src/slop.cpp
  60. 55
    0
      src/slop.hpp
  61. 51
    0
      src/slopstates.cpp
  62. 39
    0
      src/slopstates.hpp
  63. 55
    0
      src/wayland.cpp
  64. 36
    0
      src/wayland.hpp
  65. 80
    0
      src/window.cpp
  66. 36
    0
      src/window.hpp
  67. 0
    453
      src/x.cpp
  68. 0
    115
      src/x.hpp
  69. 0
    189
      src/xselectrectangle.cpp
  70. 0
    56
      src/xselectrectangle.hpp

+ 51
- 151
CMakeLists.txt View File

@@ -1,172 +1,72 @@
1
-cmake_minimum_required( VERSION 2.8 )
1
+#Change this if you need to target a specific CMake version
2
+cmake_minimum_required(VERSION 3.1)
2 3
 
3
-project( "slop" )
4
-set( slop_VERSION_MAJOR 4 )
5
-set( slop_VERSION_MINOR 3 )
6
-set( slop_VERSION_PATCH 21 )
7
-
8
-set( CMAKE_OPENGL_SUPPORT FALSE CACHE BOOL "Whether or not to compile with OpenGL, shaders, magnification, and theming support." )
9
-
10
-set( BIN_TARGET     "${PROJECT_NAME}" )
11
-if( NOT CMAKE_INSTALL_PREFIX )
12
-   set( CMAKE_INSTALL_PREFIX "/usr" )
4
+if(NOT CMAKE_BUILD_TYPE)
5
+  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build (Debug or Release)" FORCE)
13 6
 endif()
14 7
 
15
-if( NOT INSTALL_PREFIX )
16
-   set( INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "The path where slop thinks it resides in, so that it can find the shaders. This is not necessarily the CMAKE_INSTALL_PREFIX. For example if the shaders will exist in /usr/share/slop, INSTALL_PREFIX should be \"/usr\"." )
17
-endif()
18
-
19
-if( NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE )
20
-   set( CMAKE_BUILD_TYPE RelWithDebInfo )
8
+if( NOT CMAKE_INSTALL_PREFIX )
9
+    set( CMAKE_INSTALL_PREFIX "/usr" )
21 10
 endif()
22 11
 
23
-# Linux compiler initialization.
24
-if ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
25
-     "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
26
-     "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" )
27
-     set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-parameter" )
28
-     set( CMAKE_CXX_FLAGS_DEBUG "-Wextra -pedantic-errors -O0 -g" )
29
-     set( CMAKE_CXX_FLAGS_RELEASE "-O2" )
30
-     set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g" )
31
-         # -Wall:   Enable all warnings.
32
-         # -Wextra: Enable some more warnings.
33
-         # -Werror: Have errors on warnings.
34
-         # -pedantic-errors: Even more errors.
35
-         # -Wno-unused-parameter: Prevent unused variable warning. (Several functions are required to have unecessary variables because X11.)
36
-else()
37
-    message( FATAL_ERROR "Your operating system isn't supported yet! CMake will now exit." )
12
+if( NOT SHADER_PREFIX )
13
+    set( SHADER_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "The path where slop thinks it resides in, so that it can find the shaders. This is not necessarily the CMAKE_INSTALL_PREFIX. For example if the shaders will exist in /usr/share/slop-wayland, SHADER_PREFIX should be \"/usr\"." )
38 14
 endif()
39 15
 
40
-# Add a check target for our makefile.
41
-find_program( CPPCHECK_EXECUTABLE cppcheck
42
-              DOC "A tool for static C/C++ code analysis." )
43
-if (CPPCHECK_EXECUTABLE)
44
-    add_custom_target( "check"
45
-                       COMMAND "${CPPCHECK_EXECUTABLE}" "--enable=all" "*"
46
-                       WORKING_DIRECTORY src VERBATIM )
47
-endif()
16
+project(slop-wayland)
48 17
 
49
-# Here we generate some of our code if we can. I package it pre-generated
50
-# so nobody has to go find and install gengetopt if they don't want to.
51
-find_program( GENGETOPT_EXECUTABLE gengetopt
52
-              DOC "A tool to generate code to grab command line options." )
53
-find_program( SED_EXECUTABLE sed )
54
-if ( GENGETOPT_EXECUTABLE AND SED_EXECUTABLE )
55
-    message( "-- Regenerating cmdline.in" )
56
-    # gengetopt generates cmdline.h, then we move it to cmdline.in.
57
-    execute_process( COMMAND "${GENGETOPT_EXECUTABLE}" "--input=options.ggo"
58
-                     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src" )
59
-    file( RENAME "${CMAKE_CURRENT_SOURCE_DIR}/src/cmdline.h" "${CMAKE_CURRENT_SOURCE_DIR}/src/cmdline.in" )
60
-    # Due to a bug in gengetopt, we have to manually insert some code.
61
-    # Replace the first instance of REPLACEME with some text.
62
-    # Eight backslashes = two in the code because of how many instances of escaping is happening.
63
-    execute_process( COMMAND "${SED_EXECUTABLE}" "-i" "0,/REPLACEME/{s/REPLACEME/X=%x\\\\\\\\nY=%y\\\\\\\\nW=%w\\\\\\\\nH=%h\\\\\\\\nG=%g\\\\\\\\nID=%i\\\\\\\\nCancel=%c\\\\\\\\n/}" "cmdline.c"
64
-                     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src" )
65
-    # Then replace remaining instances.
66
-    execute_process( COMMAND "${SED_EXECUTABLE}" "-i" "s/REPLACEME/X=%x\\\\nY=%y\\\\nW=%w\\\\nH=%h\\\\nG=%g\\\\nID=%i\\\\nCancel=%c\\\\n/" "cmdline.c"
67
-                     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src" )
68
-else()
69
-    message( "Warning: Command gengetopt or sed not found! Won't regenerate command line code. (If you're just compiling this doesn't matter.)" )
70
-endif()
18
+set(CMAKE_CXX_STANDARD 14)
19
+set(CMAKE_CXX_STANDARD_REQUIRED on)
20
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wno-missing-braces")
21
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/")
71 22
 
72
-# By default our src/options.ggo has our cmake versions variables for
73
-# the 'version ""' line. We replace them here.
74
-# The ${CMAKE_SOURCE_DIR} is there to fix problems with OpenBSD's out-of-source build black magic.
75
-configure_file( "src/cmdline.in" "${CMAKE_SOURCE_DIR}/src/cmdline.h" )
23
+include_directories("${PROJECT_BINARY_DIR}")
76 24
 
77
-# This allows for "make README.md" to be ran to update the README's help
78
-# section automatically. We don't add it to ALL because running arbitrary
79
-# scripts is unsafe and I don't know if systems will actually have it
80
-# be executbable.
81
-add_custom_target( README.md "./generateReadme.sh" DEPENDS "slop" )
25
+# Define sources and executable
26
+set(EXECUTABLE_NAME "slop-wayland")
82 27
 
83
-# Sources
84
-if( CMAKE_OPENGL_SUPPORT )
85
-    set( source
86
-         src/cmdline.c
87
-         src/selectrectangle.cpp
88
-         src/glselectrectangle.cpp
89
-         src/shader.cpp
28
+set( source
29
+         src/wayland.cpp
30
+         src/window.cpp
31
+         src/mouse.cpp
32
+         src/keyboard.cpp
90 33
          src/framebuffer.cpp
91 34
          src/resource.cpp
92
-         src/xselectrectangle.cpp
93
-         src/x.cpp
94
-         src/main.cpp )
95
-else()
96
-    set( source
97
-         src/cmdline.c
98
-         src/selectrectangle.cpp
99
-         src/xselectrectangle.cpp
100
-         src/x.cpp
35
+         src/options.cpp
36
+         src/gl_core_3_3.c
37
+         src/shader.cpp
38
+         src/slopstates.cpp
39
+         src/slop.cpp
40
+         src/rectangle.cpp
101 41
          src/main.cpp )
102
-endif()
103 42
 
104
-# Obtain library paths and make sure they exist.
105
-set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmakemodules" )
106
-find_package( Imlib2    REQUIRED )
107
-find_package( X11       REQUIRED )
108
-find_package( XExt      REQUIRED )
109
-# This library is needed only for Ubuntu it seems, some platforms don't even
110
-# ship with it. I couldn't find a way to do a test compile to check if librt
111
-# was needed, so instead I just didn't mark it as REQUIRED.
112
-find_package( RT )
43
+add_executable(${EXECUTABLE_NAME} ${source})
113 44
 
114
-set( CMAKE_CXX_FLAGS
115
-     "${CMAKE_CXX_FLAGS} ${CMAKE_IMLIB2_CXX_FLAGS}" )
116 45
 
117
-# Includes
118
-include_directories( "${X11_INCLUDE_DIR}"
119
-                     "${XEXT_INCLUDE_DIR}" )
46
+# Detect and add SFML
47
+set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/modules" )
48
+#Find any version 2.X of SFML
49
+#See the FindSFML.cmake file for additional details and instructions
50
+find_package(Wayland REQUIRED)
51
+find_package(EGL REQUIRED)
52
+find_package(OpenGL REQUIRED)
53
+find_package(GLM REQUIRED)
120 54
 
121
-if ( CMAKE_OPENGL_SUPPORT )
122
-find_package( OpenGL    REQUIRED )
123
-find_package( GLX       REQUIRED )
124
-find_package( XRender   REQUIRED )
125
-find_package( XRandr    REQUIRED )
126
-find_package( GLEW      REQUIRED )
127
-include_directories( "${IMLIB2_INCLUDE_DIR}"
128
-                     "${XRANDR_INCLUDE_DIR}"
129
-                     "${OPENGL_INCLUDE_DIR}"
130
-                     "${GLX_INCLUDE_DIR}"
131
-                     ${GLEW_INCLUDE_DIRS}
132
-                     ${XRENDER_INCLUDE_DIRS} )
133
-endif()
134
-
135
-if ( RT_INCLUDE_DIR )
136
-    include_directories( ${RT_INCLUDE_DIR} )
137
-endif()
55
+include_directories(${WAYLAND_CLIENT_INCLUDE_DIR}
56
+                    ${WAYLAND_CURSOR_INCLUDE_DIR}
57
+                    ${WAYLAND_EGL_INCLUDE_DIR}
58
+                    ${EGL_INCLUDE_DIR}
59
+                    ${GLM_INCLUDE_DIR}
60
+                    ${OPENGL_INCLUDE_DIR})
138 61
 
139
-# Executable
140
-add_executable( "${BIN_TARGET}" ${source} )
141
-
142
-# Libraries
143
-target_link_libraries( "${BIN_TARGET}"
144
-                       ${X11_LIBRARIES}
145
-                       "${XEXT_LIBRARY}" )
146
-
147
-if ( CMAKE_OPENGL_SUPPORT )
148
-    target_link_libraries( "${BIN_TARGET}"
149
-                           ${IMLIB2_LIBRARIES}
150
-                           ${OPENGL_LIBRARIES}
151
-                           ${GLX_LIBRARIES}
152
-                           ${GLEW_LIBRARIES}
153
-                           ${XRENDER_LIBRARIES}
154
-                           "${XRANDR_LIBRARY}" )
155
-endif()
62
+target_link_libraries(${EXECUTABLE_NAME} ${WAYLAND_CLIENT_LIBRARIES}
63
+                      ${WAYLAND_CURSOR_LIBRARIES}
64
+                      ${WAYLAND_EGL_LIBRARIES}
65
+                      ${EGL_LIBRARIES}
66
+                      ${OPENGL_LIBRARIES})
156 67
 
68
+# Install targets
69
+install( TARGETS ${EXECUTABLE_NAME} DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" )
70
+install( DIRECTORY "${CMAKE_SOURCE_DIR}/share" DESTINATION "${CMAKE_INSTALL_PREFIX}" )
157 71
 
158
-if ( RT_LIBRARY )
159
-    target_link_libraries( "${BIN_TARGET}"
160
-                           "${RT_LIBRARY}" )
161
-endif()
162
-
163
-install( TARGETS ${BIN_TARGET}
164
-         DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" )
165
-
166
-add_definitions(-DINSTALL_PREFIX="${INSTALL_PREFIX}")
167
-
168
-if( CMAKE_OPENGL_SUPPORT )
169
-    install( DIRECTORY "${CMAKE_SOURCE_DIR}/share"
170
-             DESTINATION "${CMAKE_INSTALL_PREFIX}" )
171
-    add_definitions(-DOPENGL_ENABLED=1)
172
-endif()
72
+add_definitions(-DSHADER_PREFIX="${SHADER_PREFIX}")

+ 0
- 220
README.md View File

@@ -1,220 +0,0 @@
1
-# slop
2
-
3
-slop (Select Operation) is an application that queries for a selection from the user and prints the region to stdout. It grabs the mouse and turns it into a crosshair, lets the user click and drag to make a selection (or click on a window) while drawing a pretty box around it, then finally prints the selection's dimensions to stdout.
4
-
5
-## Features
6
-* Hovering over a window will cause a selection rectangle to appear over it.
7
-* Clicking on a window makes slop return the dimensions of the window.
8
-* Clicking and dragging causes a selection rectangle to appear, renders pretty well (compared to scrot). And will return the dimensions of that rectangle in absolute screen coords.
9
-* On startup it turns your cursor into a crosshair, then adjusts the cursor into angles as you drag the selection rectangle.
10
-* Supports simple arguments:
11
-    * Change selection rectangle border size.
12
-    * Select X display.
13
-    * Set padding size, even negative padding sizes!
14
-    * Set click tolerance for if you have a shaky mouse.
15
-    * Set the color of the selection rectangles to match your theme! (Even supports transparency!)
16
-    * Remove window decorations from selections.
17
-* Supports OpenGL hardware acceleration.
18
-* Supports textured themes.
19
-* Supports programmable shaders.
20
-* Supports a magnifying glass.
21
-
22
-## Practical applications
23
-slop can be used to create a video recording script in only two lines of code.
24
-```bash
25
-#!/bin/bash
26
-eval $(slop)
27
-ffmpeg -f x11grab -s "$W"x"$H" -i :0.0+$X,$Y -f alsa -i pulse ~/myfile.webm
28
-```
29
-slop lets you select a region or window and ffmpeg will record it in the format of your choice!
30
-Combined with keybinds and a server on your filesystem you can make a really neat and unobtrusive screenshooter.
31
-
32
-You can also take images using imagemagick like so:
33
-```bash
34
-#!/bin/bash
35
-eval $(slop)
36
-import -window root -crop $G ~/myimage.png
37
-```
38
-If you don't like ImageMagick's import: Check out [maim](https://github.com/naelstrof/maim) for a better screenshot utility.
39
-
40
-You can see my implementation of slop in a screenshooter here:
41
-https://gist.github.com/naelstrof/6530959
42
-
43
-For those of you who don't want eval to be an integral part of slop (Could be dangerous if I were evil!): You can change the output format and parse it manually like so:
44
-```bash
45
-#!/bin/bash
46
-read -r X Y W H G ID < <(slop -f "%x %y %w %h %g %i")
47
-maim -g "$G" -i "$ID"
48
-ffmpeg -f x11grab -s "$W"x"$H" -i ":0.0+$X,$Y" -f alsa -i pulse ~/myfile.webm
49
-```
50
-
51
-## Lets see some action
52
-Ok. Here's a comparison between 'scrot -s's selection and slop's:
53
-![scrotbad](http://farmpolice.com/content/images/2014-10-14-12:08:24.png)
54
-![slopgood](http://farmpolice.com/content/images/2014-10-14-12:14:51.png)
55
-
56
-You can see scrot leaves garbage lines over the things you're trying to screenshot!
57
-While slop not only looks nicer, it's impossible for it to end up in screenshots or recordings because it waits for DestroyNotify events before completely shutting down. Only after the window is completely destroyed can anything take a screenshot.
58
-
59
-## how to install
60
-
61
-### Install using your Package Manager (Preferred)
62
-
63
-* [Arch Linux: community/slop](https://www.archlinux.org/packages/community/x86_64/slop/)
64
-* [Void Linux: slop](https://github.com/voidlinux/void-packages/blob/24ac22af44018e2598047e5ef7fd3522efa79db5/srcpkgs/slop/template)
65
-* [FreeBSD: x11/slop](http://www.freshports.org/x11/slop/)
66
-* [OpenBSD: graphics/slop](http://openports.se/graphics/slop)
67
-* [CRUX: 6c37/slop](https://github.com/6c37/crux-ports/tree/3.2/slop)
68
-* [Gentoo: x11-misc/slop](https://packages.gentoo.org/packages/x11-misc/slop)
69
-* [GNU Guix: slop](https://www.gnu.org/software/guix/packages/#slop)
70
-* Please make a package for slop on your favorite system, and make a pull request to add it to this list.
71
-
72
-
73
-### Install using CMake (Requires CMake)
74
-
75
-*Note: Dependencies should be installed first: libxext, imlib2, mesa, libxrender, libxrandr, glew and glm.*
76
-
77
-```bash
78
-git clone https://github.com/naelstrof/slop.git
79
-cd slop
80
-cmake -DCMAKE_OPENGL_SUPPORT=true ./
81
-make && sudo make install
82
-```
83
-
84
-Make sure to check out and install [maim](https://github.com/naelstrof/maim) too if you want a proper screenshot utility.
85
-
86
-## Configuration
87
-Ever since slop had OpenGL support, it now has quite a few customizations that can be done.
88
-
89
-*Note: Configuration directories are located at __${XDG\_CONFIG\_HOME}/slop__ or __${CMAKE\_INSTALL\_PREFIX}/share/slop__, whichever comes first. These will be refferred to as __~/.config/slop__ and __/usr/share/slop__ respectively from here on.*
90
-
91
-### Shaders
92
-[![Demo Shaders](http://farmpolice.com/content/images/slop_demo.gif)](http://farmpolice.com/content/videos/8a5c37c4.webm)
93
-
94
-*Click for video*
95
-
96
-Slop supports shaders that are loaded from the configuration directories.
97
-They're all completely programmable, but they do lack some features like chaining right now.
98
-To configure the shaders or create your own, first copy the global configuration folder to your ~/.config folder like so:
99
-```bash
100
-cp -r /usr/share/slop ~/.config
101
-```
102
-Then edit or add new shaders at ~/.config/slop as if you were editing the originals, slop will reflect the changes on restart.
103
-If there's any missing features in the shaders: don't hesitate to make an issue to request them, and feel free to make your own shaders and submit a pull request to see if it can be officially included!
104
-
105
-### Themes
106
-![Demo Themes](http://farmpolice.com/content/images/1436653680.png)
107
-Slop has primitive support for texture themes, I've included a poorly made *gothic* theme that you can test with `slop --opengl --theme gothic`.
108
-To create your own you'll have to copy the configuration directory, just like with the shaders above, like so:
109
-```bash
110
-cp -r /usr/share/slop ~/.config
111
-```
112
-The theme names are taken from the folder names, the files inside represent the corresponding textures. For example *~/config/gothic/corner\_tr.png* would correspond to the top right square texture in a gothic themed selection.
113
-The theming is still missing offset configuration, and is quite limiting in design. Themes probably won't be flushed out further unless someone makes an issue to request more features.
114
-Feel free to make your own themes and submit a pull request to see if it can be officially included!
115
-
116
-help
117
-----
118
-```text
119
-slop v4.3.21
120
-
121
-Copyright (C) 2014 Dalton Nell, Slop Contributors
122
-(https://github.com/naelstrof/slop/graphs/contributors)
123
-
124
-Usage: slop [options]
125
-
126
-slop (Select Operation) is an application that queries for a selection from the
127
-user and prints the region to stdout.
128
-
129
-  -h, --help                    Print help and exit
130
-  -V, --version                 Print version and exit
131
-Options
132
-      --xdisplay=hostname:number.screen_number
133
-                                Sets the x display.
134
-      --nokeyboard              Disables the ability to cancel selections with
135
-                                  the keyboard.  (default=off)
136
-  -b, --bordersize=INT          Set the selection rectangle's thickness. Does
137
-                                  nothing when --highlight is enabled.
138
-                                  (default=`5')
139
-  -p, --padding=INT             Set the padding size of the selection. Can be
140
-                                  negative.  (default=`0')
141
-  -t, --tolerance=INT           How far in pixels the mouse can move after
142
-                                  clicking and still be detected as a normal
143
-                                  click instead of a click and drag. Setting
144
-                                  this to 0 will disable window selections.
145
-                                  (default=`2')
146
-  -g, --gracetime=FLOAT         Set the amount of time before slop will check
147
-                                  for keyboard cancellations in seconds.
148
-                                  (default=`0.4')
149
-  -c, --color=FLOAT,FLOAT,FLOAT,FLOAT
150
-                                Set the selection rectangle's color. Supports
151
-                                  RGB or RGBA values.
152
-                                  (default=`0.5,0.5,0.5,1')
153
-  -n, --nodecorations           Attempt to select child windows in order to
154
-                                  avoid window decorations.  (default=off)
155
-      --min=INT                 Set the minimum output of width or height
156
-                                  values. This is useful to avoid outputting 0.
157
-                                  Setting min and max to the same value
158
-                                  disables drag selections.  (default=`0')
159
-      --max=INT                 Set the maximum output of width or height
160
-                                  values. Setting min and max to the same value
161
-                                  disables drag selections.  (default=`0')
162
-  -l, --highlight               Instead of outlining selections, slop
163
-                                  highlights it. This is only useful when
164
-                                  --color is set to a transparent color.
165
-                                  (default=off)
166
-      --opengl                  Enable hardware acceleration. Only works with
167
-                                  modern systems that are also running a
168
-                                  compositor.  (default=off)
169
-      --magnify                 Display a magnifying glass when --opengl is
170
-                                  also enabled.  (default=off)
171
-      --magstrength=FLOAT       Sets how many times the magnification window
172
-                                  size is multiplied.  (default=`4')
173
-      --magpixels=INT           Sets how many pixels are displayed in the
174
-                                  magnification. The less pixels the bigger the
175
-                                  magnification.  (default=`64')
176
-      --theme=STRING            Sets the theme of the selection, using textures
177
-                                  from ~/.config/slop/ or /usr/share/.
178
-                                  (default=`none')
179
-      --shader=STRING           Sets the shader to load and use from
180
-                                  ~/.config/slop/ or /usr/share/.
181
-                                  (default=`simple')
182
-  -f, --format=STRING           Set the output format string. Format specifiers
183
-                                  are %x, %y, %w, %h, %i, %g, and %c.
184
-                                  (default=`X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n')
185
-
186
-Examples
187
-    $ # Gray, thick, transparent border for maximum visiblity.
188
-    $ slop -b 20 -c 0.5,0.5,0.5,0.8
189
-
190
-    $ # Remove window decorations.
191
-    $ slop --nodecorations
192
-
193
-    $ # Disable window selections. Useful for selecting individual pixels.
194
-    $ slop -t 0
195
-
196
-    $ # Classic Windows XP selection.
197
-    $ slop -l -c 0.3,0.4,0.6,0.4
198
-
199
-    $ # Wiggle wiggle!
200
-    $ slop --opengl --shader wiggle
201
-
202
-    $ # Edgy textures or something.
203
-    $ slop --opengl --theme gothic
204
-
205
-    $ # Change output format to use safer parsing
206
-    $ slopoutput=$(slop -f "%x %y %w %h")
207
-    $ X=$(echo $slopoutput | awk '{print $1}')
208
-    $ Y=$(echo $slopoutput | awk '{print $2}')
209
-    $ W=$(echo $slopoutput | awk '{print $3}')
210
-    $ H=$(echo $slopoutput | awk '{print $4}')
211
-
212
-Tips
213
-    * You can use the arrow keys to move the starting point of a
214
-drag-selection, just in case you missed it by a few pixels.
215
-    * If you don't like a selection: you can cancel it by right-clicking
216
-regardless of which options are enabled or disabled for slop.
217
-    * If slop doesn't seem to select a window accurately, the problem could be
218
-because of decorations getting in the way. Try enabling the --nodecorations
219
-flag.
220
-```

+ 0
- 44
cmakemodules/FindGLX.cmake View File

@@ -1,44 +0,0 @@
1
-# Try to find GLX. Once done, this will define:
2
-#
3
-#   GLX_FOUND - variable which returns the result of the search
4
-#   GLX_INCLUDE_DIRS - list of include directories
5
-#   GLX_LIBRARIES - options for the linker
6
-
7
-#=============================================================================
8
-# Copyright 2012 Benjamin Eikel
9
-#
10
-# Distributed under the OSI-approved BSD License (the "License");
11
-# see accompanying file Copyright.txt for details.
12
-#
13
-# This software is distributed WITHOUT ANY WARRANTY; without even the
14
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
-# See the License for more information.
16
-#=============================================================================
17
-# (To distribute this file outside of CMake, substitute the full
18
-#  License text for the above reference.)
19
-
20
-find_package(PkgConfig)
21
-pkg_check_modules(PC_GLX QUIET glx)
22
-
23
-find_path(GLX_INCLUDE_DIR
24
-    GL/glx.h
25
-    HINTS ${PC_GLX_INCLUDEDIR} ${PC_GLX_INCLUDE_DIRS}
26
-)
27
-find_library(GLX_LIBRARY
28
-    GL
29
-    HINTS ${PC_GLX_LIBDIR} ${PC_GLX_LIBRARY_DIRS}
30
-)
31
-
32
-set(GLX_INCLUDE_DIRS ${GLX_INCLUDE_DIR})
33
-set(GLX_LIBRARIES ${GLX_LIBRARY})
34
-
35
-include(FindPackageHandleStandardArgs)
36
-find_package_handle_standard_args(GLX DEFAULT_MSG
37
-    GLX_INCLUDE_DIR
38
-    GLX_LIBRARY
39
-)
40
-
41
-mark_as_advanced(
42
-    GLX_INCLUDE_DIR
43
-    GLX_LIBRARY
44
-)

+ 0
- 91
cmakemodules/FindImlib2.cmake View File

@@ -1,91 +0,0 @@
1
-#
2
-# This module finds if IMLIB2 is available and determines where the
3
-# include files and libraries are.
4
-# On Unix/Linux it relies on the output of imlib2-config.
5
-# This code sets the following variables:
6
-#
7
-#
8
-#
9
-# IMLIB2_FOUND              = system has IMLIB2 lib
10
-#
11
-# IMLIB2_LIBRARIES          = full path to the libraries
12
-#    on Unix/Linux with additional linker flags from "imlib2-config --libs"
13
-#
14
-# CMAKE_IMLIB2_CXX_FLAGS    = Unix compiler flags for IMLIB2, essentially "`imlib2-config --cxxflags`"
15
-#
16
-# IMLIB2_INCLUDE_DIR        = where to find headers
17
-#
18
-# IMLIB2_LINK_DIRECTORIES   = link directories, useful for rpath on Unix
19
-#
20
-#
21
-# author Jan Woetzel and Jan-Friso Evers
22
-# www.mip.informatik.uni-kiel.de/~jw
23
-
24
-IF(WIN32)
25
-    MESSAGE("FindIMLIB2.cmake: IMLIB2 not (yet) supported on WIN32")
26
-    SET(IMLIB2_FOUND OFF	)
27
-ELSE(WIN32)
28
-    IF(UNIX)
29
-        SET(IMLIB2_CONFIG_PREFER_PATH "$ENV{IMLIB2_HOME}/bin" CACHE STRING "preferred path to imlib2")
30
-        FIND_PROGRAM(IMLIB2_CONFIG imlib2-config
31
-                     ${IMLIB2_CONFIG_PREFER_PATH}
32
-                     /usr/bin/
33
-                     /opt/gnome/bin/)
34
-
35
-        IF (IMLIB2_CONFIG)
36
-            # OK, found imlib2-config.
37
-            # set CXXFLAGS to be fed into CXX_FLAGS by the user:
38
-            SET(IMLIB2_CXX_FLAGS "`${IMLIB2_CONFIG} --cflags`")
39
-
40
-            # set INCLUDE_DIRS to prefix+include
41
-            EXEC_PROGRAM(${IMLIB2_CONFIG}
42
-            ARGS --prefix
43
-            OUTPUT_VARIABLE IMLIB2_PREFIX)
44
-            SET(IMLIB2_INCLUDE_DIR ${IMLIB2_PREFIX}/include CACHE STRING INTERNAL)
45
-
46
-            # extract link dirs for rpath
47
-            EXEC_PROGRAM(${IMLIB2_CONFIG}
48
-                         ARGS --libs
49
-                         OUTPUT_VARIABLE IMLIB2_CONFIG_LIBS)
50
-
51
-            # set link libraries and link flags
52
-            #SET(IMLIB2_LIBRARIES "`${IMLIB2_CONFIG} --libs`")
53
-            SET(IMLIB2_LIBRARIES ${IMLIB2_CONFIG_LIBS})
54
-
55
-            # split off the link dirs (for rpath)
56
-            # use regular expression to match wildcard equivalent "-L*<endchar>"
57
-            # with <endchar> is a space or a semicolon
58
-            STRING(REGEX MATCHALL "[-][L]([^ ;])+"
59
-                   IMLIB2_LINK_DIRECTORIES_WITH_PREFIX
60
-                   "${IMLIB2_CONFIG_LIBS}")
61
-            #MESSAGE("DBG  IMLIB2_LINK_DIRECTORIES_WITH_PREFIX=${IMLIB2_LINK_DIRECTORIES_WITH_PREFIX}")
62
-
63
-            # remove prefix -L because we need the pure directory for LINK_DIRECTORIES
64
-            # replace -L by ; because the separator seems to be lost otherwise (bug or feature?)
65
-            IF (IMLIB2_LINK_DIRECTORIES_WITH_PREFIX)
66
-                STRING(REGEX REPLACE "[-][L]" ";" IMLIB2_LINK_DIRECTORIES ${IMLIB2_LINK_DIRECTORIES_WITH_PREFIX} )
67
-                #MESSAGE("DBG  IMLIB2_LINK_DIRECTORIES=${IMLIB2_LINK_DIRECTORIES}")
68
-            ENDIF (IMLIB2_LINK_DIRECTORIES_WITH_PREFIX)
69
-
70
-            # replace space separated string by semicolon separated vector to make 
71
-            # it work with LINK_DIRECTORIES
72
-            SEPARATE_ARGUMENTS(IMLIB2_LINK_DIRECTORIES)
73
-
74
-            MARK_AS_ADVANCED(IMLIB2_CXX_FLAGS
75
-                             IMLIB2_INCLUDE_DIR
76
-                             IMLIB2_LIBRARIES
77
-                             IMLIB2_LINK_DIRECTORIES
78
-                             IMLIB2_CONFIG_PREFER_PATH
79
-                             IMLIB2_CONFIG)
80
-
81
-        ELSE(IMLIB2_CONFIG)
82
-            MESSAGE( "FindIMLIB2.cmake: imlib2-config not found. Please set it manually. IMLIB2_CONFIG=${IMLIB2_CONFIG}")
83
-        ENDIF(IMLIB2_CONFIG)
84
-    ENDIF(UNIX)
85
-ENDIF(WIN32)
86
-
87
-IF(IMLIB2_LIBRARIES)
88
-    IF(IMLIB2_INCLUDE_DIR OR IMLIB2_CXX_FLAGS)
89
-        SET(IMLIB2_FOUND 1)
90
-    ENDIF(IMLIB2_INCLUDE_DIR OR IMLIB2_CXX_FLAGS)
91
-ENDIF(IMLIB2_LIBRARIES)

+ 0
- 23
cmakemodules/FindRT.cmake View File

@@ -1,23 +0,0 @@
1
-# - Find rt
2
-# Find the rt libraries, this is to fix ubuntu not having clock_gettime defined without it.
3
-#
4
-#  This module defines the following variables:
5
-#     RT_FOUND        - 1 if RT_INCLUDE_DIR & RT_LIBRARY are found, 0 otherwise
6
-#     RT_INCLUDE_DIR  - where to find Xlib.h, etc.
7
-#     RT_LIBRARY      - the X11 library
8
-#
9
-
10
-find_path( RT_INCLUDE_DIR
11
-           NAMES time.h )
12
-
13
-find_library( RT_LIBRARY
14
-              NAMES rt
15
-              PATHS /usr/lib /lib )
16
-
17
-if( RT_INCLUDE_DIR AND RT_LIBRARY )
18
-    set( RT_FOUND 1 )
19
-else()
20
-    set( RT_FOUND 0 )
21
-endif()
22
-
23
-mark_as_advanced( RT_INCLUDE_DIR RT_LIBRARY )

+ 0
- 26
cmakemodules/FindXExt.cmake View File

@@ -1,26 +0,0 @@
1
-# - Find XExt
2
-# Find the XExtension libraries (WARNING: It's geared and tested specifically for the XShape extension though)
3
-#
4
-#  This module defines the following variables:
5
-#     XEXT_FOUND        - 1 if XEXT_INCLUDE_DIR & XEXT_LIBRARY are found, 0 otherwise
6
-#     XEXT_INCLUDE_DIR  - where to find Xlib.h, etc.
7
-#     XEXT_LIBRARY      - the X11 library
8
-#
9
-
10
-find_path( XEXT_INCLUDE_DIR
11
-           NAMES X11/extensions/shape.h
12
-           PATH_SUFFIXES X11/extensions
13
-           DOC "The XExtension include directory" )
14
-
15
-find_library( XEXT_LIBRARY
16
-              NAMES Xext
17
-              PATHS /usr/lib /lib
18
-              DOC "The XExtension library" )
19
-
20
-if( XEXT_INCLUDE_DIR AND XEXT_LIBRARY )
21
-    set( XEXT_FOUND 1 )
22
-else()
23
-    set( XEXT_FOUND 0 )
24
-endif()
25
-
26
-mark_as_advanced( XEXT_INCLUDE_DIR XEXT_LIBRARY )

+ 0
- 26
cmakemodules/FindXRandr.cmake View File

@@ -1,26 +0,0 @@
1
-# - Find XRandr
2
-# Find the XRandr libraries
3
-#
4
-#  This module defines the following variables:
5
-#     XRANDR_FOUND        - 1 if XRANDR_INCLUDE_DIR & XRANDR_LIBRARY are found, 0 otherwise
6
-#     XRANDR_INCLUDE_DIR  - where to find Xlib.h, etc.
7
-#     XRANDR_LIBRARY      - the X11 library
8
-#
9
-
10
-find_path( XRANDR_INCLUDE_DIR
11
-           NAMES X11/extensions/Xrandr.h
12
-           PATH_SUFFIXES X11/extensions
13
-           DOC "The XRandr include directory" )
14
-
15
-find_library( XRANDR_LIBRARY
16
-              NAMES Xrandr
17
-              PATHS /usr/lib /lib
18
-              DOC "The XRandr library" )
19
-
20
-if( XRANDR_INCLUDE_DIR AND XRANDR_LIBRARY )
21
-    set( XRANDR_FOUND 1 )
22
-else()
23
-    set( XRANDR_FOUND 0 )
24
-endif()
25
-
26
-mark_as_advanced( XRANDR_INCLUDE_DIR XRANDR_LIBRARY )

+ 0
- 47
cmakemodules/FindXRender.cmake View File

@@ -1,47 +0,0 @@
1
-# - Find XRender
2
-# Find the XRender libraries
3
-#
4
-# This module defines the following variables:
5
-#   XRENDER_FOUND - true if XRENDER_INCLUDE_DIR & XRENDER_LIBRARY are found
6
-#   XRENDER_LIBRARIES - Set when Xrender_LIBRARY is found
7
-#   XRENDER_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found
8
-#
9
-#   XRENDER_INCLUDE_DIR - where to find Xrender.h, etc.
10
-#   XRENDER_LIBRARY - the Xrender library
11
-#
12
-
13
-#=============================================================================
14
-# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
15
-#
16
-# Licensed under the Apache License, Version 2.0 (the "License");
17
-# you may not use this file except in compliance with the License.
18
-# You may obtain a copy of the License at
19
-#
20
-#     http://www.apache.org/licenses/LICENSE-2.0
21
-#
22
-# Unless required by applicable law or agreed to in writing, software
23
-# distributed under the License is distributed on an "AS IS" BASIS,
24
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
-# See the License for the specific language governing permissions and
26
-# limitations under the License.
27
-#=============================================================================
28
-
29
-find_path(XRENDER_INCLUDE_DIR NAMES X11/extensions/Xrender.h
30
-          PATHS /opt/X11/include
31
-          DOC "The Xrender include directory")
32
-
33
-find_library(XRENDER_LIBRARY NAMES Xrender
34
-          PATHS /opt/X11/lib
35
-          DOC "The Xrender library")
36
-
37
-include(FindPackageHandleStandardArgs)
38
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG XRENDER_LIBRARY XRENDER_INCLUDE_DIR)
39
-
40
-if(XRENDER_FOUND)
41
-
42
-    set(XRENDER_LIBRARIES ${XRENDER_LIBRARY})
43
-    set(XRENDER_INCLUDE_DIRS ${XRENDER_INCLUDE_DIR})
44
-
45
-endif()
46
-
47
-mark_as_advanced(XRENDER_INCLUDE_DIR XRENDER_LIBRARY)

+ 0
- 12
generateReadme.sh View File

@@ -1,12 +0,0 @@
1
-#!/bin/sh
2
-# generateReadme.sh: Regenerates the help section of the README.md using output from ./slop --help.
3
-
4
-# Remove help section
5
-sed -i '/^help/,/^```$/d' README.md
6
-
7
-# Add the help section again.
8
-echo 'help' >> README.md
9
-echo '----' >> README.md
10
-echo '```text' >> README.md
11
-echo "$(./slop --help)" >> README.md
12
-echo '```' >> README.md

+ 53
- 0
modules/FindEGL.cmake View File

@@ -0,0 +1,53 @@
1
+# - Try to Find EGL
2
+# Once done, this will define
3
+#
4
+#  EGL_FOUND - system has EGL installed.
5
+#  EGL_INCLUDE_DIRS - directories which contain the EGL headers.
6
+#  EGL_LIBRARIES - libraries required to link against EGL.
7
+#  EGL_DEFINITIONS - Compiler switches required for using EGL.
8
+#
9
+# Copyright (C) 2012 Intel Corporation. All rights reserved.
10
+#
11
+# Redistribution and use in source and binary forms, with or without
12
+# modification, are permitted provided that the following conditions
13
+# are met:
14
+# 1.  Redistributions of source code must retain the above copyright
15
+#     notice, this list of conditions and the following disclaimer.
16
+# 2.  Redistributions in binary form must reproduce the above copyright
17
+#     notice, this list of conditions and the following disclaimer in the
18
+#     documentation and/or other materials provided with the distribution.
19
+#
20
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
21
+# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
24
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+
33
+find_package(PkgConfig)
34
+
35
+pkg_check_modules(PC_EGL egl)
36
+
37
+if (PC_EGL_FOUND)
38
+    set(EGL_DEFINITIONS ${PC_EGL_CFLAGS_OTHER})
39
+endif ()
40
+
41
+find_path(EGL_INCLUDE_DIRS NAMES EGL/egl.h
42
+    HINTS ${PC_EGL_INCLUDEDIR} ${PC_EGL_INCLUDE_DIRS}
43
+)
44
+
45
+set(EGL_NAMES ${EGL_NAMES} egl EGL)
46
+find_library(EGL_LIBRARIES NAMES ${EGL_NAMES}
47
+    HINTS ${PC_EGL_LIBDIR} ${PC_EGL_LIBRARY_DIRS}
48
+)
49
+
50
+include(FindPackageHandleStandardArgs)
51
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(EGL DEFAULT_MSG EGL_INCLUDE_DIRS EGL_LIBRARIES)
52
+
53
+mark_as_advanced(EGL_INCLUDE_DIRS EGL_LIBRARIES)

+ 52
- 0
modules/FindGLM.cmake View File

@@ -0,0 +1,52 @@
1
+#
2
+# Find GLM
3
+#
4
+# Try to find GLM : OpenGL Mathematics.
5
+# This module defines 
6
+# - GLM_INCLUDE_DIRS
7
+# - GLM_FOUND
8
+#
9
+# The following variables can be set as arguments for the module.
10
+# - GLM_ROOT_DIR : Root library directory of GLM 
11
+#
12
+# References:
13
+# - https://github.com/Groovounet/glm/blob/master/util/FindGLM.cmake
14
+# - https://bitbucket.org/alfonse/gltut/src/28636298c1c0/glm-0.9.0.7/FindGLM.cmake
15
+#
16
+
17
+# Additional modules
18
+include(FindPackageHandleStandardArgs)
19
+
20
+if (WIN32)
21
+	# Find include files
22
+	find_path(
23
+		GLM_INCLUDE_DIR
24
+		NAMES glm/glm.hpp
25
+		PATHS
26
+		$ENV{PROGRAMFILES}/include
27
+		${GLM_ROOT_DIR}/include
28
+		DOC "The directory where glm/glm.hpp resides")
29
+else()
30
+	# Find include files
31
+	find_path(
32
+		GLM_INCLUDE_DIR
33
+		NAMES glm/glm.hpp
34
+		PATHS
35
+		/usr/include
36
+		/usr/local/include
37
+		/sw/include
38
+		/opt/local/include
39
+		${GLM_ROOT_DIR}/include
40
+		DOC "The directory where glm/glm.hpp resides")
41
+endif()
42
+
43
+# Handle REQUIRD argument, define *_FOUND variable
44
+find_package_handle_standard_args(GLM DEFAULT_MSG GLM_INCLUDE_DIR)
45
+
46
+# Define GLM_INCLUDE_DIRS
47
+if (GLM_FOUND)
48
+	set(GLM_INCLUDE_DIRS ${GLM_INCLUDE_DIR})
49
+endif()
50
+
51
+# Hide some variables
52
+mark_as_advanced(GLM_INCLUDE_DIR)

+ 67
- 0
modules/FindWayland.cmake View File

@@ -0,0 +1,67 @@
1
+# Try to find Wayland on a Unix system
2
+#
3
+# This will define:
4
+#
5
+#   WAYLAND_FOUND       - True if Wayland is found
6
+#   WAYLAND_LIBRARIES   - Link these to use Wayland
7
+#   WAYLAND_INCLUDE_DIR - Include directory for Wayland
8
+#   WAYLAND_DEFINITIONS - Compiler flags for using Wayland
9
+#
10
+# In addition the following more fine grained variables will be defined:
11
+#
12
+#   WAYLAND_CLIENT_FOUND  WAYLAND_CLIENT_INCLUDE_DIR  WAYLAND_CLIENT_LIBRARIES
13
+#   WAYLAND_SERVER_FOUND  WAYLAND_SERVER_INCLUDE_DIR  WAYLAND_SERVER_LIBRARIES
14
+#   WAYLAND_EGL_FOUND     WAYLAND_EGL_INCLUDE_DIR     WAYLAND_EGL_LIBRARIES
15
+#   WAYLAND_CURSOR_FOUND  WAYLAND_CURSOR_INCLUDE_DIR  WAYLAND_CURSOR_LIBRARIES
16
+#
17
+# Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
18
+#
19
+# Redistribution and use is allowed according to the terms of the BSD license.
20
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
21
+
22
+IF (NOT WIN32)
23
+  IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES)
24
+    # In the cache already
25
+    SET(WAYLAND_FIND_QUIETLY TRUE)
26
+  ENDIF ()
27
+
28
+  # Use pkg-config to get the directories and then use these values
29
+  # in the FIND_PATH() and FIND_LIBRARY() calls
30
+  FIND_PACKAGE(PkgConfig)
31
+  PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
32
+
33
+  SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
34
+
35
+  FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR  NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
36
+  FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR  NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
37
+  FIND_PATH(WAYLAND_EGL_INCLUDE_DIR     NAMES wayland-egl.h    HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
38
+  FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR  NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
39
+
40
+  FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client   HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
41
+  FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server   HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
42
+  FIND_LIBRARY(WAYLAND_EGL_LIBRARIES    NAMES wayland-egl      HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
43
+  FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor   HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
44
+
45
+  set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR})
46
+
47
+  set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
48
+
49
+  list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR)
50
+
51
+  include(FindPackageHandleStandardArgs)
52
+
53
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT  DEFAULT_MSG  WAYLAND_CLIENT_LIBRARIES  WAYLAND_CLIENT_INCLUDE_DIR)
54
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER  DEFAULT_MSG  WAYLAND_SERVER_LIBRARIES  WAYLAND_SERVER_INCLUDE_DIR)
55
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL     DEFAULT_MSG  WAYLAND_EGL_LIBRARIES     WAYLAND_EGL_INCLUDE_DIR)
56
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR  DEFAULT_MSG  WAYLAND_CURSOR_LIBRARIES  WAYLAND_CURSOR_INCLUDE_DIR)
57
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND         DEFAULT_MSG  WAYLAND_LIBRARIES         WAYLAND_INCLUDE_DIR)
58
+
59
+  MARK_AS_ADVANCED(
60
+        WAYLAND_INCLUDE_DIR         WAYLAND_LIBRARIES
61
+        WAYLAND_CLIENT_INCLUDE_DIR  WAYLAND_CLIENT_LIBRARIES
62
+        WAYLAND_SERVER_INCLUDE_DIR  WAYLAND_SERVER_LIBRARIES
63
+        WAYLAND_EGL_INCLUDE_DIR     WAYLAND_EGL_LIBRARIES
64
+        WAYLAND_CURSOR_INCLUDE_DIR  WAYLAND_CURSOR_LIBRARIES
65
+  )
66
+
67
+ENDIF ()

+ 9
- 0
share/slop-wayland/simple.frag View File

@@ -0,0 +1,9 @@
1
+#version 130
2
+
3
+uniform vec4 color;
4
+out vec4 outColor;
5
+
6
+void main()
7
+{
8
+    outColor = color;
9
+}

+ 9
- 0
share/slop-wayland/simple.vert View File

@@ -0,0 +1,9 @@
1
+#version 130
2
+
3
+in vec2 position;
4
+uniform mat4 projection;
5
+
6
+void main()
7
+{
8
+    gl_Position = projection*vec4(position,0,1);
9
+}

+ 13
- 0
share/slop-wayland/textured.frag View File

@@ -0,0 +1,13 @@
1
+#version 130
2
+
3
+uniform sampler2D texture;
4
+
5
+varying vec2 uvCoord;
6
+
7
+out vec4 outColor;
8
+
9
+void main()
10
+{
11
+    outColor = texture2D( texture, uvCoord );
12
+}
13
+

share/slop/cross.vert → share/slop-wayland/textured.vert View File

@@ -1,6 +1,6 @@
1
-#version 120
1
+#version 130
2 2
 
3
-attribute vec2 vertex;
3
+attribute vec2 position;
4 4
 attribute vec2 uv;
5 5
 
6 6
 varying vec2 uvCoord;
@@ -8,5 +8,5 @@ varying vec2 uvCoord;
8 8
 void main()
9 9
 {
10 10
     uvCoord = uv;
11
-	gl_Position = vec4(vertex,0,1);
11
+    gl_Position = vec4(position,0,1);
12 12
 }

+ 0
- 38
share/slop/cross.frag View File

@@ -1,38 +0,0 @@
1
-#version 120
2
-
3
-uniform sampler2D texture;
4
-uniform sampler2D desktop;
5
-uniform int desktopWidth;
6
-uniform int desktopHeight;
7
-uniform float time;
8
-
9
-varying vec2 uvCoord;
10
-
11
-void main() {
12
-    float stitching_size = 6.0;
13
-    int invert = 0;
14
-
15
-    float size = stitching_size;
16
-    vec2 cPos = uvCoord * vec2(desktopWidth, desktopHeight);
17
-    vec2 tlPos = floor(cPos / vec2(size, size));
18
-    tlPos *= size;
19
-    int remX = int(mod(cPos.x, size));
20
-    int remY = int(mod(cPos.y, size));
21
-    if (remX == 0 && remY == 0)
22
-    tlPos = cPos;
23
-    vec2 blPos = tlPos;
24
-    blPos.y += (size - 1.0);
25
-    if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y))))) {
26
-        if (invert == 1) {
27
-            gl_FragColor = vec4(0.2, 0.15, 0.05, 1.0);
28
-        } else {
29
-            gl_FragColor = texture2D(texture, tlPos * vec2(1.0/desktopWidth, 1.0/desktopHeight)) * 1.4;
30
-        }
31
-    } else {
32
-        if (invert == 1) {
33
-            gl_FragColor = texture2D(texture, tlPos * vec2(1.0/desktopWidth, 1.0/desktopHeight)) * 1.4;
34
-        } else {
35
-            gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
36
-        }
37
-    }
38
-}

+ 0
- 1
share/slop/gothic/corner_bl.png View File

@@ -1 +0,0 @@
1
-corner_tl.png

+ 0
- 1
share/slop/gothic/corner_br.png View File

@@ -1 +0,0 @@
1
-corner_tl.png

BIN
share/slop/gothic/corner_tl.png View File


+ 0
- 1
share/slop/gothic/corner_tr.png View File

@@ -1 +0,0 @@
1
-corner_tl.png

BIN
share/slop/gothic/straight.png View File


+ 0
- 30
share/slop/hippie.frag View File

@@ -1,30 +0,0 @@
1
-#version 120
2
-
3
-uniform sampler2D texture;
4
-uniform sampler2D desktop;
5
-uniform int desktopWidth;
6
-uniform int desktopHeight;
7
-uniform float time;
8
-
9
-varying vec2 uvCoord;
10
-
11
-const float pi = 3.14159265f;
12
-
13
-vec3 color(float x) {
14
-    return max(min(sin(vec3(x,x+pi*2.0/3.0,x+pi*4.0/3.0))+0.5,1.0),0.0);
15
-}
16
-
17
-void main() {
18
-    vec2 resolution = vec2( desktopWidth, desktopHeight );
19
-    vec2 pos = (( gl_FragCoord.xy / resolution.xy )-0.5)*resolution.xy/resolution.x*4.0;
20
-    pos+=normalize(pos);
21
-    pos.xy+=sin(pos.yx*10.0)*0.1;
22
-    float r=(2.0/(dot(pos,pos)*10.0+1.0));
23
-    vec2 rr=vec2(cos(r),sin(r));
24
-    pos=pos.xy*rr.xx+pos.yx*rr.yy*vec2(-1.0,1.0);
25
-    float f=(length(pos)*10.0)+time;
26
-    //f=acos((pos.x/length(pos)*0.5+0.5)*pi);
27
-    f+=sin(atan(pos.y,pos.x)*7.0)*5.0;
28
-    float alpha = texture2D(texture,uvCoord).a;
29
-    gl_FragColor = vec4(color(f),alpha);
30
-}

+ 0
- 12
share/slop/hippie.vert View File

@@ -1,12 +0,0 @@
1
-#version 120
2
-
3
-attribute vec2 vertex;
4
-attribute vec2 uv;
5
-
6
-varying vec2 uvCoord;
7
-
8
-void main()
9
-{
10
-    uvCoord = uv;
11
-	gl_Position = vec4(vertex,0,1);
12
-}

+ 0
- 16
share/slop/invert.frag View File

@@ -1,16 +0,0 @@
1
-#version 120
2
-
3
-uniform sampler2D texture;
4
-uniform sampler2D desktop;
5
-uniform int desktopWidth;
6
-uniform int desktopHeight;
7
-uniform float time;
8
-
9
-varying vec2 uvCoord;
10
-
11
-void main() {
12
-    vec2 uv = vec2( uvCoord.x, -uvCoord.y );
13
-    vec4 color = texture2D(desktop,uv);
14
-    float alpha = texture2D(texture,uvCoord).a;
15
-    gl_FragColor = vec4( 1.0 - color.r, 1.0 - color.g, 1.0 - color.b, alpha );
16
-}

+ 0
- 13
share/slop/invert.vert View File

@@ -1,13 +0,0 @@
1
-#version 120
2
-
3
-attribute vec2 vertex;
4
-attribute vec2 uv;
5
-
6
-varying vec2 uvCoord;
7
-
8
-void main()
9
-{
10
-    uvCoord = uv;
11
-    gl_Position = vec4(vertex,0,1);
12
-}
13
-

+ 0
- 83
share/slop/refract.frag View File

@@ -1,83 +0,0 @@
1
-#version 120
2
-
3
-uniform sampler2D texture;
4
-uniform sampler2D desktop;
5
-uniform int desktopWidth;
6
-uniform int desktopHeight;
7
-uniform float time;
8
-
9
-varying vec2 uvCoord;
10
-
11
-vec2 getDesktopUV( vec2 uv ) {
12
-    // Desktop image is upside-down, blame X11 lmao
13
-    uv.y = -uv.y;
14
-    return uv;
15
-}
16
-
17
-const float pi = 3.14159265f;
18
-
19
-void main() {
20
-    float sigma = 5;
21
-    float numBlurPixelsPerSide = 2.0f;
22
-    float blurMultiplier = 2.0f;
23
-
24
-    vec2 tc = uvCoord.xy;
25
-    vec2 p = -1.0 + 2.0 * tc;
26
-    float len = length(p);
27
-    vec2 offset = (p/len)*cos(len*12.0-time*4.0)*0.005;
28
-
29
-    // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
30
-    float blurSize = 1.f/desktopWidth*blurMultiplier;
31
-    vec2 blurMultiplyVec      = vec2(0.0f, 1.0f);
32
-    vec3 incrementalGaussian;
33
-    incrementalGaussian.x = 1.0f / (sqrt(2.0f * pi) * sigma);
34
-    incrementalGaussian.y = exp(-0.5f / (sigma * sigma));
35
-    incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
36
-
37
-    vec4 avgValue = vec4(0.0f, 0.0f, 0.0f, 0.0f);
38
-    float coefficientSum = 0.0f;
39
-
40
-    // Take the central sample first...
41
-    vec4 color = texture2D( desktop, getDesktopUV( uvCoord.xy ) + offset );
42
-    color.a = texture2D( texture, uvCoord.xy ).a;
43
-    avgValue += color * incrementalGaussian.x;
44
-    coefficientSum += incrementalGaussian.x;
45
-    incrementalGaussian.xy *= incrementalGaussian.yz;
46
-
47
-    // Go through the remaining 8 vertical samples (4 on each side of the center)
48
-    for (float i = 1.0f; i <= numBlurPixelsPerSide; i++) {
49
-        vec2 uv = (uvCoord.xy - i * blurSize * blurMultiplyVec);
50
-        color = texture2D( desktop, getDesktopUV( uv ) + offset );
51
-        color.a = texture2D( texture, uv ).a;
52
-        avgValue += color * incrementalGaussian.x;
53
-        uv = (uvCoord.xy + i * blurSize * blurMultiplyVec);
54
-        color = texture2D( desktop, getDesktopUV( uv ) + offset );
55
-        color.a = texture2D( texture, uv ).a;
56
-        avgValue += color * incrementalGaussian.x;
57
-        coefficientSum += 2 * incrementalGaussian.x;
58
-        incrementalGaussian.xy *= incrementalGaussian.yz;
59
-    }
60
-
61
-    //Reset
62
-    blurSize = 1.f/desktopWidth*blurMultiplier;
63
-    blurMultiplyVec      = vec2(1.0f, 0.0f);
64
-    incrementalGaussian.x = 1.0f / (sqrt(2.0f * pi) * sigma);
65
-    incrementalGaussian.y = exp(-0.5f / (sigma * sigma));
66
-    incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
67
-
68
-    // Go through the remaining 8 horizontal samples (4 on each side of the center)
69
-    for (float i = 1.0f; i <= numBlurPixelsPerSide; i++) {
70
-        vec2 uv = (uvCoord.xy - i * blurSize * blurMultiplyVec);
71
-        vec4 color = texture2D( desktop, getDesktopUV( uv ) + offset );
72
-        color.a = texture2D( texture, uv ).a;
73
-        avgValue += color * incrementalGaussian.x;
74
-        uv = (uvCoord.xy + i * blurSize * blurMultiplyVec);
75
-        color = texture2D( desktop, getDesktopUV( uv ) + offset );
76
-        color.a = texture2D( texture, uv ).a;
77
-        avgValue += color * incrementalGaussian.x;
78
-        coefficientSum += 2 * incrementalGaussian.x;
79
-        incrementalGaussian.xy *= incrementalGaussian.yz;
80
-    }
81
-
82
-    gl_FragColor = avgValue / coefficientSum;
83
-}

+ 0
- 12
share/slop/refract.vert View File

@@ -1,12 +0,0 @@
1
-#version 120
2
-
3
-attribute vec2 vertex;
4
-attribute vec2 uv;
5
-
6
-varying vec2 uvCoord;
7
-
8
-void main()
9
-{
10
-    uvCoord = uv;
11
-	gl_Position = vec4(vertex,0,1);
12
-}

+ 0
- 17
share/slop/ripple.frag View File

@@ -1,17 +0,0 @@
1
-#version 120
2
-
3
-uniform sampler2D texture;
4
-uniform sampler2D desktop;
5
-uniform int desktopWidth;
6
-uniform int desktopHeight;
7
-uniform float time;
8
-
9
-varying vec2 uvCoord;
10
-
11
-void main() {
12
-    vec2 tc = uvCoord.xy;
13
-    vec2 p = -1.0 + 2.0 * tc;
14
-    float len = length(p);
15
-    vec2 uv = tc + (p/len)*cos(len*12.0-time*4.0)*0.02;
16
-    gl_FragColor = texture2D(texture,uv);
17
-}

+ 0
- 13
share/slop/ripple.vert View File

@@ -1,13 +0,0 @@
1
-#version 120
2
-
3
-attribute vec2 vertex;
4
-attribute vec2 uv;
5
-
6
-varying vec2 uvCoord;
7
-
8
-void main()
9
-{
10
-    uvCoord = uv;
11
-    gl_Position = vec4(vertex,0,1);
12
-}
13
-

+ 0
- 12
share/slop/simple.frag View File

@@ -1,12 +0,0 @@
1
-#version 120
2
-
3
-uniform sampler2D texture;
4
-uniform sampler2D desktop;
5
-uniform float time;
6
-
7
-varying vec2 uvCoord;
8
-
9
-void main()
10
-{
11
-    gl_FragColor = texture2D( texture, uvCoord );
12
-}

+ 0
- 12
share/slop/simple.vert View File

@@ -1,12 +0,0 @@
1
-#version 120
2
-
3
-attribute vec2 vertex;
4
-attribute vec2 uv;
5
-
6
-varying vec2 uvCoord;
7
-
8
-void main()
9
-{
10
-    uvCoord = uv;
11
-	gl_Position = vec4(vertex,0,1);
12
-}

+ 0
- 20
share/slop/wiggle.frag View File

@@ -1,20 +0,0 @@
1
-#version 120
2
-
3
-uniform sampler2D texture;
4
-uniform sampler2D desktop;
5
-uniform int desktopWidth;
6
-uniform int desktopHeight;
7
-uniform float time;
8
-
9
-varying vec2 uvCoord;
10
-
11
-void main()
12
-{
13
-    // Higher strength means bigger wobble
14
-    float strength = 8;
15
-    // Higher speed means faster wobble
16
-    float speed = 2;
17
-    float x = uvCoord.x + (sin( time*speed + uvCoord.y * desktopHeight/strength ) + 0.5)/desktopWidth*strength;
18
-    float y = uvCoord.y + (cos( time*speed + uvCoord.x * desktopWidth/strength ) + 0.5)/desktopHeight*strength;
19
-    gl_FragColor = texture2D( texture, vec2( x, y ) );
20
-}

+ 0
- 12
share/slop/wiggle.vert View File

@@ -1,12 +0,0 @@
1
-#version 120
2
-
3
-attribute vec2 vertex;
4
-attribute vec2 uv;
5
-
6
-varying vec2 uvCoord;
7
-
8
-void main()
9
-{
10
-    uvCoord = uv;
11
-	gl_Position = vec4(vertex,0,1);
12
-}

+ 0
- 893
src/cmdline.c View File

@@ -1,893 +0,0 @@
1
-/*
2
-  File autogenerated by gengetopt version 2.22.6
3
-  generated with the following command:
4
-  /usr/bin/gengetopt --input=options.ggo 
5
-
6
-  The developers of gengetopt consider the fixed text that goes in all
7
-  gengetopt output files to be in the public domain:
8
-  we make no copyright claims on it.
9
-*/
10
-
11
-/* If we use autoconf.  */
12
-#ifdef HAVE_CONFIG_H
13
-#include "config.h"
14
-#endif
15
-
16
-#include <stdio.h>
17
-#include <stdlib.h>
18
-#include <string.h>
19
-
20
-#ifndef FIX_UNUSED
21
-#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
22
-#endif
23
-
24
-#include <getopt.h>
25
-
26
-#include "cmdline.h"
27
-
28
-const char *gengetopt_args_info_purpose = "";
29
-
30
-const char *gengetopt_args_info_usage = "Usage: slop [options]";
31
-
32
-const char *gengetopt_args_info_versiontext = "Copyright (C) 2014 Dalton Nell, Slop Contributors\n(https://github.com/naelstrof/slop/graphs/contributors)";
33
-
34
-const char *gengetopt_args_info_description = "slop (Select Operation) is an application that queries for a selection from the\nuser and prints the region to stdout.";
35
-
36
-const char *gengetopt_args_info_help[] = {
37
-  "  -h, --help                    Print help and exit",
38
-  "  -V, --version                 Print version and exit",
39
-  "Options",
40
-  "      --xdisplay=hostname:number.screen_number\n                                Sets the x display.",
41
-  "      --nokeyboard              Disables the ability to cancel selections with\n                                  the keyboard.  (default=off)",
42
-  "  -b, --bordersize=INT          Set the selection rectangle's thickness. Does\n                                  nothing when --highlight is enabled.\n                                  (default=`5')",
43
-  "  -p, --padding=INT             Set the padding size of the selection. Can be\n                                  negative.  (default=`0')",
44
-  "  -t, --tolerance=INT           How far in pixels the mouse can move after\n                                  clicking and still be detected as a normal\n                                  click instead of a click and drag. Setting\n                                  this to 0 will disable window selections.\n                                  (default=`2')",
45
-  "  -g, --gracetime=FLOAT         Set the amount of time before slop will check\n                                  for keyboard cancellations in seconds.\n                                  (default=`0.4')",
46
-  "  -c, --color=FLOAT,FLOAT,FLOAT,FLOAT\n                                Set the selection rectangle's color. Supports\n                                  RGB or RGBA values.\n                                  (default=`0.5,0.5,0.5,1')",
47
-  "  -n, --nodecorations           Attempt to select child windows in order to\n                                  avoid window decorations.  (default=off)",
48
-  "      --min=INT                 Set the minimum output of width or height\n                                  values. This is useful to avoid outputting 0.\n                                  Setting min and max to the same value\n                                  disables drag selections.  (default=`0')",
49
-  "      --max=INT                 Set the maximum output of width or height\n                                  values. Setting min and max to the same value\n                                  disables drag selections.  (default=`0')",
50
-  "  -l, --highlight               Instead of outlining selections, slop\n                                  highlights it. This is only useful when\n                                  --color is set to a transparent color.\n                                  (default=off)",
51
-  "      --opengl                  Enable hardware acceleration. Only works with\n                                  modern systems that are also running a\n                                  compositor.  (default=off)",
52
-  "      --magnify                 Display a magnifying glass when --opengl is\n                                  also enabled.  (default=off)",
53
-  "      --magstrength=FLOAT       Sets how many times the magnification window\n                                  size is multiplied.  (default=`4')",
54
-  "      --magpixels=INT           Sets how many pixels are displayed in the\n                                  magnification. The less pixels the bigger the\n                                  magnification.  (default=`64')",
55
-  "      --theme=STRING            Sets the theme of the selection, using textures\n                                  from ~/.config/slop/ or /usr/share/.\n                                  (default=`none')",
56
-  "      --shader=STRING           Sets the shader to load and use from\n                                  ~/.config/slop/ or /usr/share/.\n                                  (default=`simple')",
57
-  "  -f, --format=STRING           Set the output format string. Format specifiers\n                                  are %x, %y, %w, %h, %i, %g, and %c.\n                                  (default=`X=%x\\nY=%y\\nW=%w\\nH=%h\\nG=%g\\nID=%i\\nCancel=%c\\n')",
58
-  "\nExamples\n    $ # Gray, thick, transparent border for maximum visiblity.\n    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n\n    $ # Remove window decorations.\n    $ slop --nodecorations\n\n    $ # Disable window selections. Useful for selecting individual pixels.\n    $ slop -t 0\n\n    $ # Classic Windows XP selection.\n    $ slop -l -c 0.3,0.4,0.6,0.4\n\n    $ # Wiggle wiggle!\n    $ slop --opengl --shader wiggle\n\n    $ # Edgy textures or something.\n    $ slop --opengl --theme gothic\n\n    $ # Change output format to use safer parsing\n    $ slopoutput=$(slop -f \"%x %y %w %h\")\n    $ X=$(echo $slopoutput | awk '{print $1}')\n    $ Y=$(echo $slopoutput | awk '{print $2}')\n    $ W=$(echo $slopoutput | awk '{print $3}')\n    $ H=$(echo $slopoutput | awk '{print $4}')\n\nTips\n    * You can use the arrow keys to move the starting point of a\ndrag-selection, just in case you missed it by a few pixels.\n    * If you don't like a selection: you can cancel it by right-clicking\nregardless of which options are enabled or disabled for slop.\n    * If slop doesn't seem to select a window accurately, the problem could be\nbecause of decorations getting in the way. Try enabling the --nodecorations\nflag.\n",
59
-    0
60
-};
61
-
62
-typedef enum {ARG_NO
63
-  , ARG_FLAG
64
-  , ARG_STRING
65
-  , ARG_INT
66
-  , ARG_FLOAT
67
-} cmdline_parser_arg_type;
68
-
69
-static
70
-void clear_given (struct gengetopt_args_info *args_info);
71
-static
72
-void clear_args (struct gengetopt_args_info *args_info);
73
-
74
-static int
75
-cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
76
-                        struct cmdline_parser_params *params, const char *additional_error);
77
-
78
-
79
-static char *
80
-gengetopt_strdup (const char *s);
81
-
82
-static
83
-void clear_given (struct gengetopt_args_info *args_info)
84
-{
85
-  args_info->help_given = 0 ;
86
-  args_info->version_given = 0 ;
87
-  args_info->xdisplay_given = 0 ;
88
-  args_info->nokeyboard_given = 0 ;
89
-  args_info->bordersize_given = 0 ;
90
-  args_info->padding_given = 0 ;
91
-  args_info->tolerance_given = 0 ;
92
-  args_info->gracetime_given = 0 ;
93
-  args_info->color_given = 0 ;
94
-  args_info->nodecorations_given = 0 ;
95
-  args_info->min_given = 0 ;
96
-  args_info->max_given = 0 ;
97
-  args_info->highlight_given = 0 ;
98
-  args_info->opengl_given = 0 ;
99
-  args_info->magnify_given = 0 ;
100
-  args_info->magstrength_given = 0 ;
101
-  args_info->magpixels_given = 0 ;
102
-  args_info->theme_given = 0 ;
103
-  args_info->shader_given = 0 ;
104
-  args_info->format_given = 0 ;
105
-}
106
-
107
-static
108
-void clear_args (struct gengetopt_args_info *args_info)
109
-{
110
-  FIX_UNUSED (args_info);
111
-  args_info->xdisplay_arg = NULL;
112
-  args_info->xdisplay_orig = NULL;
113
-  args_info->nokeyboard_flag = 0;
114
-  args_info->bordersize_arg = 5;
115
-  args_info->bordersize_orig = NULL;
116
-  args_info->padding_arg = 0;
117
-  args_info->padding_orig = NULL;
118
-  args_info->tolerance_arg = 2;
119
-  args_info->tolerance_orig = NULL;
120
-  args_info->gracetime_arg = gengetopt_strdup ("0.4");
121
-  args_info->gracetime_orig = NULL;
122
-  args_info->color_arg = gengetopt_strdup ("0.5,0.5,0.5,1");
123
-  args_info->color_orig = NULL;
124
-  args_info->nodecorations_flag = 0;
125
-  args_info->min_arg = 0;
126
-  args_info->min_orig = NULL;
127
-  args_info->max_arg = 0;
128
-  args_info->max_orig = NULL;
129
-  args_info->highlight_flag = 0;
130
-  args_info->opengl_flag = 0;
131
-  args_info->magnify_flag = 0;
132
-  args_info->magstrength_arg = 4;
133
-  args_info->magstrength_orig = NULL;
134
-  args_info->magpixels_arg = 64;
135
-  args_info->magpixels_orig = NULL;
136
-  args_info->theme_arg = gengetopt_strdup ("none");
137
-  args_info->theme_orig = NULL;
138
-  args_info->shader_arg = gengetopt_strdup ("simple");
139
-  args_info->shader_orig = NULL;
140
-  args_info->format_arg = gengetopt_strdup ("X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n");
141
-  args_info->format_orig = NULL;
142
-  
143
-}
144
-
145
-static
146
-void init_args_info(struct gengetopt_args_info *args_info)
147
-{
148
-
149
-
150
-  args_info->help_help = gengetopt_args_info_help[0] ;
151
-  args_info->version_help = gengetopt_args_info_help[1] ;
152
-  args_info->xdisplay_help = gengetopt_args_info_help[3] ;
153
-  args_info->nokeyboard_help = gengetopt_args_info_help[4] ;
154
-  args_info->bordersize_help = gengetopt_args_info_help[5] ;
155
-  args_info->padding_help = gengetopt_args_info_help[6] ;
156
-  args_info->tolerance_help = gengetopt_args_info_help[7] ;
157
-  args_info->gracetime_help = gengetopt_args_info_help[8] ;
158
-  args_info->color_help = gengetopt_args_info_help[9] ;
159
-  args_info->nodecorations_help = gengetopt_args_info_help[10] ;
160
-  args_info->min_help = gengetopt_args_info_help[11] ;
161
-  args_info->max_help = gengetopt_args_info_help[12] ;
162
-  args_info->highlight_help = gengetopt_args_info_help[13] ;
163
-  args_info->opengl_help = gengetopt_args_info_help[14] ;
164
-  args_info->magnify_help = gengetopt_args_info_help[15] ;
165
-  args_info->magstrength_help = gengetopt_args_info_help[16] ;
166
-  args_info->magpixels_help = gengetopt_args_info_help[17] ;
167
-  args_info->theme_help = gengetopt_args_info_help[18] ;
168
-  args_info->shader_help = gengetopt_args_info_help[19] ;
169
-  args_info->format_help = gengetopt_args_info_help[20] ;
170
-  
171
-}
172
-
173
-void
174
-cmdline_parser_print_version (void)
175
-{
176
-  printf ("%s %s\n",
177
-     (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
178
-     CMDLINE_PARSER_VERSION);
179
-
180
-  if (strlen(gengetopt_args_info_versiontext) > 0)
181
-    printf("\n%s\n", gengetopt_args_info_versiontext);
182
-}
183
-
184
-static void print_help_common(void) {
185
-  cmdline_parser_print_version ();
186
-
187
-  if (strlen(gengetopt_args_info_purpose) > 0)
188
-    printf("\n%s\n", gengetopt_args_info_purpose);
189
-
190
-  if (strlen(gengetopt_args_info_usage) > 0)
191
-    printf("\n%s\n", gengetopt_args_info_usage);
192
-
193
-  printf("\n");
194
-
195
-  if (strlen(gengetopt_args_info_description) > 0)
196
-    printf("%s\n\n", gengetopt_args_info_description);
197
-}
198
-
199
-void
200
-cmdline_parser_print_help (void)
201
-{
202
-  int i = 0;
203
-  print_help_common();
204
-  while (gengetopt_args_info_help[i])
205
-    printf("%s\n", gengetopt_args_info_help[i++]);
206
-}
207
-
208
-void
209
-cmdline_parser_init (struct gengetopt_args_info *args_info)
210
-{
211
-  clear_given (args_info);
212
-  clear_args (args_info);
213
-  init_args_info (args_info);
214
-}
215
-
216
-void
217
-cmdline_parser_params_init(struct cmdline_parser_params *params)
218
-{
219
-  if (params)
220
-    { 
221
-      params->override = 0;
222
-      params->initialize = 1;
223
-      params->check_required = 1;
224
-      params->check_ambiguity = 0;
225
-      params->print_errors = 1;
226
-    }
227
-}
228
-
229
-struct cmdline_parser_params *
230
-cmdline_parser_params_create(void)
231
-{
232
-  struct cmdline_parser_params *params = 
233
-    (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params));
234
-  cmdline_parser_params_init(params);  
235
-  return params;
236
-}
237
-
238
-static void
239
-free_string_field (char **s)
240
-{
241
-  if (*s)
242
-    {
243
-      free (*s);
244
-      *s = 0;
245
-    }
246
-}
247
-
248
-
249
-static void
250
-cmdline_parser_release (struct gengetopt_args_info *args_info)
251
-{
252
-
253
-  free_string_field (&(args_info->xdisplay_arg));
254
-  free_string_field (&(args_info->xdisplay_orig));
255
-  free_string_field (&(args_info->bordersize_orig));
256
-  free_string_field (&(args_info->padding_orig));
257
-  free_string_field (&(args_info->tolerance_orig));
258
-  free_string_field (&(args_info->gracetime_arg));
259
-  free_string_field (&(args_info->gracetime_orig));
260
-  free_string_field (&(args_info->color_arg));
261
-  free_string_field (&(args_info->color_orig));
262
-  free_string_field (&(args_info->min_orig));
263
-  free_string_field (&(args_info->max_orig));
264
-  free_string_field (&(args_info->magstrength_orig));
265
-  free_string_field (&(args_info->magpixels_orig));
266
-  free_string_field (&(args_info->theme_arg));
267
-  free_string_field (&(args_info->theme_orig));
268
-  free_string_field (&(args_info->shader_arg));
269
-  free_string_field (&(args_info->shader_orig));
270
-  free_string_field (&(args_info->format_arg));
271
-  free_string_field (&(args_info->format_orig));
272
-  
273
-  
274
-
275
-  clear_given (args_info);
276
-}
277
-
278
-
279
-static void
280
-write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
281
-{
282
-  FIX_UNUSED (values);
283
-  if (arg) {
284
-    fprintf(outfile, "%s=\"%s\"\n", opt, arg);
285
-  } else {
286
-    fprintf(outfile, "%s\n", opt);
287
-  }
288
-}
289
-
290
-
291
-int
292
-cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
293
-{
294
-  int i = 0;
295
-
296
-  if (!outfile)
297
-    {
298
-      fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
299
-      return EXIT_FAILURE;
300
-    }
301
-
302
-  if (args_info->help_given)
303
-    write_into_file(outfile, "help", 0, 0 );
304
-  if (args_info->version_given)
305
-    write_into_file(outfile, "version", 0, 0 );
306
-  if (args_info->xdisplay_given)
307
-    write_into_file(outfile, "xdisplay", args_info->xdisplay_orig, 0);
308
-  if (args_info->nokeyboard_given)
309
-    write_into_file(outfile, "nokeyboard", 0, 0 );
310
-  if (args_info->bordersize_given)
311
-    write_into_file(outfile, "bordersize", args_info->bordersize_orig, 0);
312
-  if (args_info->padding_given)
313
-    write_into_file(outfile, "padding", args_info->padding_orig, 0);
314
-  if (args_info->tolerance_given)
315
-    write_into_file(outfile, "tolerance", args_info->tolerance_orig, 0);
316
-  if (args_info->gracetime_given)
317
-    write_into_file(outfile, "gracetime", args_info->gracetime_orig, 0);
318
-  if (args_info->color_given)
319
-    write_into_file(outfile, "color", args_info->color_orig, 0);
320
-  if (args_info->nodecorations_given)
321
-    write_into_file(outfile, "nodecorations", 0, 0 );
322
-  if (args_info->min_given)
323
-    write_into_file(outfile, "min", args_info->min_orig, 0);
324
-  if (args_info->max_given)
325
-    write_into_file(outfile, "max", args_info->max_orig, 0);
326
-  if (args_info->highlight_given)
327
-    write_into_file(outfile, "highlight", 0, 0 );
328
-  if (args_info->opengl_given)
329
-    write_into_file(outfile, "opengl", 0, 0 );
330
-  if (args_info->magnify_given)
331
-    write_into_file(outfile, "magnify", 0, 0 );
332
-  if (args_info->magstrength_given)
333
-    write_into_file(outfile, "magstrength", args_info->magstrength_orig, 0);
334
-  if (args_info->magpixels_given)
335
-    write_into_file(outfile, "magpixels", args_info->magpixels_orig, 0);
336
-  if (args_info->theme_given)
337
-    write_into_file(outfile, "theme", args_info->theme_orig, 0);
338
-  if (args_info->shader_given)
339
-    write_into_file(outfile, "shader", args_info->shader_orig, 0);
340
-  if (args_info->format_given)
341
-    write_into_file(outfile, "format", args_info->format_orig, 0);
342
-  
343
-
344
-  i = EXIT_SUCCESS;
345
-  return i;
346
-}
347
-
348
-int
349
-cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
350
-{
351
-  FILE *outfile;
352
-  int i = 0;
353
-
354
-  outfile = fopen(filename, "w");
355
-
356
-  if (!outfile)
357
-    {
358
-      fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
359
-      return EXIT_FAILURE;
360
-    }
361
-
362
-  i = cmdline_parser_dump(outfile, args_info);
363
-  fclose (outfile);
364
-
365
-  return i;
366
-}
367
-
368
-void
369
-cmdline_parser_free (struct gengetopt_args_info *args_info)
370
-{
371
-  cmdline_parser_release (args_info);
372
-}
373
-
374
-/** @brief replacement of strdup, which is not standard */
375
-char *
376
-gengetopt_strdup (const char *s)
377
-{
378
-  char *result = 0;
379
-  if (!s)
380
-    return result;
381
-
382
-  result = (char*)malloc(strlen(s) + 1);
383
-  if (result == (char*)0)
384
-    return (char*)0;
385
-  strcpy(result, s);
386
-  return result;
387
-}
388
-
389
-int
390
-cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info)
391
-{
392
-  return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
393
-}
394
-
395
-int
396
-cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
397
-                   struct cmdline_parser_params *params)
398
-{
399
-  int result;
400
-  result = cmdline_parser_internal (argc, argv, args_info, params, 0);
401
-
402
-  if (result == EXIT_FAILURE)
403
-    {
404
-      cmdline_parser_free (args_info);
405
-      exit (EXIT_FAILURE);
406
-    }
407
-  
408
-  return result;
409
-}
410
-
411
-int
412
-cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
413
-{
414
-  int result;
415
-  struct cmdline_parser_params params;
416
-  
417
-  params.override = override;
418
-  params.initialize = initialize;
419
-  params.check_required = check_required;
420
-  params.check_ambiguity = 0;
421
-  params.print_errors = 1;
422
-
423
-  result = cmdline_parser_internal (argc, argv, args_info, &params, 0);
424
-
425
-  if (result == EXIT_FAILURE)
426
-    {
427
-      cmdline_parser_free (args_info);
428
-      exit (EXIT_FAILURE);
429
-    }
430
-  
431
-  return result;
432
-}
433
-
434
-int
435
-cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
436
-{
437
-  FIX_UNUSED (args_info);
438
-  FIX_UNUSED (prog_name);
439
-  return EXIT_SUCCESS;
440
-}
441
-
442
-
443
-static char *package_name = 0;
444
-
445
-/**
446
- * @brief updates an option
447
- * @param field the generic pointer to the field to update
448
- * @param orig_field the pointer to the orig field
449
- * @param field_given the pointer to the number of occurrence of this option
450
- * @param prev_given the pointer to the number of occurrence already seen
451
- * @param value the argument for this option (if null no arg was specified)
452
- * @param possible_values the possible values for this option (if specified)
453
- * @param default_value the default value (in case the option only accepts fixed values)
454
- * @param arg_type the type of this option
455
- * @param check_ambiguity @see cmdline_parser_params.check_ambiguity
456
- * @param override @see cmdline_parser_params.override
457
- * @param no_free whether to free a possible previous value
458
- * @param multiple_option whether this is a multiple option
459
- * @param long_opt the corresponding long option
460
- * @param short_opt the corresponding short option (or '-' if none)
461
- * @param additional_error possible further error specification
462
- */
463
-static
464
-int update_arg(void *field, char **orig_field,
465
-               unsigned int *field_given, unsigned int *prev_given, 
466
-               char *value, const char *possible_values[],
467
-               const char *default_value,
468
-               cmdline_parser_arg_type arg_type,
469
-               int check_ambiguity, int override,
470
-               int no_free, int multiple_option,
471
-               const char *long_opt, char short_opt,
472
-               const char *additional_error)
473
-{
474
-  char *stop_char = 0;
475
-  const char *val = value;
476
-  int found;
477
-  char **string_field;
478
-  FIX_UNUSED (field);
479
-
480
-  stop_char = 0;
481
-  found = 0;
482
-
483
-  if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
484
-    {
485
-      if (short_opt != '-')
486
-        fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", 
487
-               package_name, long_opt, short_opt,
488
-               (additional_error ? additional_error : ""));
489
-      else
490
-        fprintf (stderr, "%s: `--%s' option given more than once%s\n", 
491
-               package_name, long_opt,
492
-               (additional_error ? additional_error : ""));
493
-      return 1; /* failure */
494
-    }
495
-
496
-  FIX_UNUSED (default_value);
497
-    
498
-  if (field_given && *field_given && ! override)
499
-    return 0;
500
-  if (prev_given)
501
-    (*prev_given)++;
502
-  if (field_given)
503
-    (*field_given)++;
504
-  if (possible_values)
505
-    val = possible_values[found];
506
-
507
-  switch(arg_type) {
508
-  case ARG_FLAG:
509
-    *((int *)field) = !*((int *)field);
510
-    break;
511
-  case ARG_INT:
512
-    if (val) *((int *)field) = strtol (val, &stop_char, 0);
513
-    break;
514
-  case ARG_FLOAT:
515
-    if (val) *((float *)field) = (float)strtod (val, &stop_char);
516
-    break;
517
-  case ARG_STRING:
518
-    if (val) {
519
-      string_field = (char **)field;
520
-      if (!no_free && *string_field)
521
-        free (*string_field); /* free previous string */
522
-      *string_field = gengetopt_strdup (val);
523
-    }
524
-    break;
525
-  default:
526
-    break;
527
-  };
528
-
529
-  /* check numeric conversion */
530
-  switch(arg_type) {
531
-  case ARG_INT:
532
-  case ARG_FLOAT:
533
-    if (val && !(stop_char && *stop_char == '\0')) {
534
-      fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
535
-      return 1; /* failure */
536
-    }
537
-    break;
538
-  default:
539
-    ;
540
-  };
541
-
542
-  /* store the original value */
543
-  switch(arg_type) {
544
-  case ARG_NO:
545
-  case ARG_FLAG:
546
-    break;
547
-  default:
548
-    if (value && orig_field) {
549
-      if (no_free) {
550
-        *orig_field = value;
551
-      } else {
552
-        if (*orig_field)
553
-          free (*orig_field); /* free previous string */
554
-        *orig_field = gengetopt_strdup (value);
555
-      }
556
-    }
557
-  };
558
-
559
-  return 0; /* OK */
560
-}
561
-
562
-
563
-int
564
-cmdline_parser_internal (
565
-  int argc, char **argv, struct gengetopt_args_info *args_info,
566
-                        struct cmdline_parser_params *params, const char *additional_error)
567
-{
568
-  int c;	/* Character of the parsed option.  */
569
-
570
-  int error_occurred = 0;
571
-  struct gengetopt_args_info local_args_info;
572
-  
573
-  int override;
574
-  int initialize;
575
-  int check_required;
576
-  int check_ambiguity;
577
-  
578
-  package_name = argv[0];
579
-  
580
-  override = params->override;
581
-  initialize = params->initialize;
582
-  check_required = params->check_required;
583
-  check_ambiguity = params->check_ambiguity;
584
-
585
-  if (initialize)
586
-    cmdline_parser_init (args_info);
587
-
588
-  cmdline_parser_init (&local_args_info);
589
-
590
-  optarg = 0;
591
-  optind = 0;
592
-  opterr = params->print_errors;
593
-  optopt = '?';
594
-
595
-  while (1)
596
-    {
597
-      int option_index = 0;
598
-
599
-      static struct option long_options[] = {
600
-        { "help",	0, NULL, 'h' },
601
-        { "version",	0, NULL, 'V' },
602
-        { "xdisplay",	1, NULL, 0 },
603
-        { "nokeyboard",	0, NULL, 0 },
604
-        { "bordersize",	1, NULL, 'b' },
605
-        { "padding",	1, NULL, 'p' },
606
-        { "tolerance",	1, NULL, 't' },
607
-        { "gracetime",	1, NULL, 'g' },
608
-        { "color",	1, NULL, 'c' },
609
-        { "nodecorations",	0, NULL, 'n' },
610
-        { "min",	1, NULL, 0 },
611
-        { "max",	1, NULL, 0 },
612
-        { "highlight",	0, NULL, 'l' },
613
-        { "opengl",	0, NULL, 0 },
614
-        { "magnify",	0, NULL, 0 },
615
-        { "magstrength",	1, NULL, 0 },
616
-        { "magpixels",	1, NULL, 0 },
617
-        { "theme",	1, NULL, 0 },
618
-        { "shader",	1, NULL, 0 },
619
-        { "format",	1, NULL, 'f' },
620
-        { 0,  0, 0, 0 }
621
-      };
622
-
623
-      c = getopt_long (argc, argv, "hVb:p:t:g:c:nlf:", long_options, &option_index);
624
-
625
-      if (c == -1) break;	/* Exit from `while (1)' loop.  */
626
-
627
-      switch (c)
628
-        {
629
-        case 'h':	/* Print help and exit.  */
630
-          cmdline_parser_print_help ();
631
-          cmdline_parser_free (&local_args_info);
632
-          exit (EXIT_SUCCESS);
633
-
634
-        case 'V':	/* Print version and exit.  */
635
-          cmdline_parser_print_version ();
636
-          cmdline_parser_free (&local_args_info);
637
-          exit (EXIT_SUCCESS);
638
-
639
-        case 'b':	/* Set the selection rectangle's thickness. Does nothing when --highlight is enabled..  */
640
-        
641
-        
642
-          if (update_arg( (void *)&(args_info->bordersize_arg), 
643
-               &(args_info->bordersize_orig), &(args_info->bordersize_given),
644
-              &(local_args_info.bordersize_given), optarg, 0, "5", ARG_INT,
645
-              check_ambiguity, override, 0, 0,
646
-              "bordersize", 'b',
647
-              additional_error))
648
-            goto failure;
649
-        
650
-          break;
651
-        case 'p':	/* Set the padding size of the selection. Can be negative..  */
652
-        
653
-        
654
-          if (update_arg( (void *)&(args_info->padding_arg), 
655
-               &(args_info->padding_orig), &(args_info->padding_given),
656
-              &(local_args_info.padding_given), optarg, 0, "0", ARG_INT,
657
-              check_ambiguity, override, 0, 0,
658
-              "padding", 'p',
659
-              additional_error))
660
-            goto failure;
661
-        
662
-          break;
663
-        case 't':	/* How far in pixels the mouse can move after clicking and still be detected as a normal click instead of a click and drag. Setting this to 0 will disable window selections..  */
664
-        
665
-        
666
-          if (update_arg( (void *)&(args_info->tolerance_arg), 
667
-               &(args_info->tolerance_orig), &(args_info->tolerance_given),
668
-              &(local_args_info.tolerance_given), optarg, 0, "2", ARG_INT,
669
-              check_ambiguity, override, 0, 0,
670
-              "tolerance", 't',
671
-              additional_error))
672
-            goto failure;
673
-        
674
-          break;
675
-        case 'g':	/* Set the amount of time before slop will check for keyboard cancellations in seconds..  */
676
-        
677
-        
678
-          if (update_arg( (void *)&(args_info->gracetime_arg), 
679
-               &(args_info->gracetime_orig), &(args_info->gracetime_given),
680
-              &(local_args_info.gracetime_given), optarg, 0, "0.4", ARG_STRING,
681
-              check_ambiguity, override, 0, 0,
682
-              "gracetime", 'g',
683
-              additional_error))
684
-            goto failure;
685
-        
686
-          break;
687
-        case 'c':	/* Set the selection rectangle's color. Supports RGB or RGBA values..  */
688
-        
689
-        
690
-          if (update_arg( (void *)&(args_info->color_arg), 
691
-               &(args_info->color_orig), &(args_info->color_given),
692
-              &(local_args_info.color_given), optarg, 0, "0.5,0.5,0.5,1", ARG_STRING,
693
-              check_ambiguity, override, 0, 0,
694
-              "color", 'c',
695
-              additional_error))
696
-            goto failure;
697
-        
698
-          break;
699
-        case 'n':	/* Attempt to select child windows in order to avoid window decorations..  */
700
-        
701
-        
702
-          if (update_arg((void *)&(args_info->nodecorations_flag), 0, &(args_info->nodecorations_given),
703
-              &(local_args_info.nodecorations_given), optarg, 0, 0, ARG_FLAG,
704
-              check_ambiguity, override, 1, 0, "nodecorations", 'n',
705
-              additional_error))
706
-            goto failure;
707
-        
708
-          break;
709
-        case 'l':	/* Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color..  */
710
-        
711
-        
712
-          if (update_arg((void *)&(args_info->highlight_flag), 0, &(args_info->highlight_given),
713
-              &(local_args_info.highlight_given), optarg, 0, 0, ARG_FLAG,
714
-              check_ambiguity, override, 1, 0, "highlight", 'l',
715
-              additional_error))
716
-            goto failure;
717
-        
718
-          break;
719
-        case 'f':	/* Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c..  */
720
-        
721
-        
722
-          if (update_arg( (void *)&(args_info->format_arg), 
723
-               &(args_info->format_orig), &(args_info->format_given),
724
-              &(local_args_info.format_given), optarg, 0, "X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n", ARG_STRING,
725
-              check_ambiguity, override, 0, 0,
726
-              "format", 'f',
727
-              additional_error))
728
-            goto failure;
729
-        
730
-          break;
731
-
732
-        case 0:	/* Long option with no short option */
733
-          /* Sets the x display..  */
734
-          if (strcmp (long_options[option_index].name, "xdisplay") == 0)
735
-          {
736
-          
737
-          
738
-            if (update_arg( (void *)&(args_info->xdisplay_arg), 
739
-                 &(args_info->xdisplay_orig), &(args_info->xdisplay_given),
740
-                &(local_args_info.xdisplay_given), optarg, 0, 0, ARG_STRING,
741
-                check_ambiguity, override, 0, 0,
742
-                "xdisplay", '-',
743
-                additional_error))
744
-              goto failure;
745
-          
746
-          }
747
-          /* Disables the ability to cancel selections with the keyboard..  */
748
-          else if (strcmp (long_options[option_index].name, "nokeyboard") == 0)
749
-          {
750
-          
751
-          
752
-            if (update_arg((void *)&(args_info->nokeyboard_flag), 0, &(args_info->nokeyboard_given),
753
-                &(local_args_info.nokeyboard_given), optarg, 0, 0, ARG_FLAG,
754
-                check_ambiguity, override, 1, 0, "nokeyboard", '-',
755
-                additional_error))
756
-              goto failure;
757
-          
758
-          }
759
-          /* Set the minimum output of width or height values. This is useful to avoid outputting 0. Setting min and max to the same value disables drag selections..  */
760
-          else if (strcmp (long_options[option_index].name, "min") == 0)
761
-          {
762
-          
763
-          
764
-            if (update_arg( (void *)&(args_info->min_arg), 
765
-                 &(args_info->min_orig), &(args_info->min_given),
766
-                &(local_args_info.min_given), optarg, 0, "0", ARG_INT,
767
-                check_ambiguity, override, 0, 0,
768
-                "min", '-',
769
-                additional_error))
770
-              goto failure;
771
-          
772
-          }
773
-          /* Set the maximum output of width or height values. Setting min and max to the same value disables drag selections..  */
774
-          else if (strcmp (long_options[option_index].name, "max") == 0)
775
-          {
776
-          
777
-          
778
-            if (update_arg( (void *)&(args_info->max_arg), 
779
-                 &(args_info->max_orig), &(args_info->max_given),
780
-                &(local_args_info.max_given), optarg, 0, "0", ARG_INT,
781
-                check_ambiguity, override, 0, 0,
782
-                "max", '-',
783
-                additional_error))
784
-              goto failure;
785
-          
786
-          }
787
-          /* Enable hardware acceleration. Only works with modern systems that are also running a compositor..  */
788
-          else if (strcmp (long_options[option_index].name, "opengl") == 0)
789
-          {
790
-          
791
-          
792
-            if (update_arg((void *)&(args_info->opengl_flag), 0, &(args_info->opengl_given),
793
-                &(local_args_info.opengl_given), optarg, 0, 0, ARG_FLAG,
794
-                check_ambiguity, override, 1, 0, "opengl", '-',
795
-                additional_error))
796
-              goto failure;
797
-          
798
-          }
799
-          /* Display a magnifying glass when --opengl is also enabled..  */
800
-          else if (strcmp (long_options[option_index].name, "magnify") == 0)
801
-          {
802
-          
803
-          
804
-            if (update_arg((void *)&(args_info->magnify_flag), 0, &(args_info->magnify_given),
805
-                &(local_args_info.magnify_given), optarg, 0, 0, ARG_FLAG,
806
-                check_ambiguity, override, 1, 0, "magnify", '-',
807
-                additional_error))
808
-              goto failure;
809
-          
810
-          }
811
-          /* Sets how many times the magnification window size is multiplied..  */
812
-          else if (strcmp (long_options[option_index].name, "magstrength") == 0)
813
-          {
814
-          
815
-          
816
-            if (update_arg( (void *)&(args_info->magstrength_arg), 
817
-                 &(args_info->magstrength_orig), &(args_info->magstrength_given),
818
-                &(local_args_info.magstrength_given), optarg, 0, "4", ARG_FLOAT,
819
-                check_ambiguity, override, 0, 0,
820
-                "magstrength", '-',
821
-                additional_error))
822
-              goto failure;
823
-          
824
-          }
825
-          /* Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification..  */
826
-          else if (strcmp (long_options[option_index].name, "magpixels") == 0)
827
-          {
828
-          
829
-          
830
-            if (update_arg( (void *)&(args_info->magpixels_arg), 
831
-                 &(args_info->magpixels_orig), &(args_info->magpixels_given),
832
-                &(local_args_info.magpixels_given), optarg, 0, "64", ARG_INT,
833
-                check_ambiguity, override, 0, 0,
834
-                "magpixels", '-',
835
-                additional_error))
836
-              goto failure;
837
-          
838
-          }
839
-          /* Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/..  */
840
-          else if (strcmp (long_options[option_index].name, "theme") == 0)
841
-          {
842
-          
843
-          
844
-            if (update_arg( (void *)&(args_info->theme_arg), 
845
-                 &(args_info->theme_orig), &(args_info->theme_given),
846
-                &(local_args_info.theme_given), optarg, 0, "none", ARG_STRING,
847
-                check_ambiguity, override, 0, 0,
848
-                "theme", '-',
849
-                additional_error))
850
-              goto failure;
851
-          
852
-          }
853
-          /* Sets the shader to load and use from ~/.config/slop/ or /usr/share/..  */
854
-          else if (strcmp (long_options[option_index].name, "shader") == 0)
855
-          {
856
-          
857
-          
858
-            if (update_arg( (void *)&(args_info->shader_arg), 
859
-                 &(args_info->shader_orig), &(args_info->shader_given),
860
-                &(local_args_info.shader_given), optarg, 0, "simple", ARG_STRING,
861
-                check_ambiguity, override, 0, 0,
862
-                "shader", '-',
863
-                additional_error))
864
-              goto failure;
865
-          
866
-          }
867
-          
868
-          break;
869
-        case '?':	/* Invalid option.  */
870
-          /* `getopt_long' already printed an error message.  */
871
-          goto failure;
872
-
873
-        default:	/* bug: option not considered.  */
874
-          fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
875
-          abort ();
876
-        } /* switch */
877
-    } /* while */
878
-
879
-
880
-
881
-
882
-  cmdline_parser_release (&local_args_info);
883
-
884
-  if ( error_occurred )
885
-    return (EXIT_FAILURE);
886
-
887
-  return 0;
888
-
889
-failure:
890
-  
891
-  cmdline_parser_release (&local_args_info);
892
-  return (EXIT_FAILURE);
893
-}

+ 0
- 240
src/cmdline.in View File

@@ -1,240 +0,0 @@
1
-/** @file cmdline.h
2
- *  @brief The header file for the command line option parser
3
- *  generated by GNU Gengetopt version 2.22.6
4
- *  http://www.gnu.org/software/gengetopt.
5
- *  DO NOT modify this file, since it can be overwritten
6
- *  @author GNU Gengetopt by Lorenzo Bettini */
7
-
8
-#ifndef CMDLINE_H
9
-#define CMDLINE_H
10
-
11
-/* If we use autoconf.  */
12
-#ifdef HAVE_CONFIG_H
13
-#include "config.h"
14
-#endif
15
-
16
-#include <stdio.h> /* for FILE */
17
-
18
-#ifdef __cplusplus
19
-extern "C" {
20
-#endif /* __cplusplus */
21
-
22
-#ifndef CMDLINE_PARSER_PACKAGE
23
-/** @brief the program name (used for printing errors) */
24
-#define CMDLINE_PARSER_PACKAGE "slop"
25
-#endif
26
-
27
-#ifndef CMDLINE_PARSER_PACKAGE_NAME
28
-/** @brief the complete program name (used for help and version) */
29
-#define CMDLINE_PARSER_PACKAGE_NAME "slop"
30
-#endif
31
-
32
-#ifndef CMDLINE_PARSER_VERSION
33
-/** @brief the program version */
34
-#define CMDLINE_PARSER_VERSION "v@slop_VERSION_MAJOR@.@slop_VERSION_MINOR@.@slop_VERSION_PATCH@"
35
-#endif
36
-
37
-/** @brief Where the command line options are stored */
38
-struct gengetopt_args_info
39
-{
40
-  const char *help_help; /**< @brief Print help and exit help description.  */
41
-  const char *version_help; /**< @brief Print version and exit help description.  */
42
-  char * xdisplay_arg;	/**< @brief Sets the x display..  */
43
-  char * xdisplay_orig;	/**< @brief Sets the x display. original value given at command line.  */
44
-  const char *xdisplay_help; /**< @brief Sets the x display. help description.  */
45
-  int nokeyboard_flag;	/**< @brief Disables the ability to cancel selections with the keyboard. (default=off).  */
46
-  const char *nokeyboard_help; /**< @brief Disables the ability to cancel selections with the keyboard. help description.  */
47
-  int bordersize_arg;	/**< @brief Set the selection rectangle's thickness. Does nothing when --highlight is enabled. (default='5').  */
48
-  char * bordersize_orig;	/**< @brief Set the selection rectangle's thickness. Does nothing when --highlight is enabled. original value given at command line.  */
49
-  const char *bordersize_help; /**< @brief Set the selection rectangle's thickness. Does nothing when --highlight is enabled. help description.  */
50
-  int padding_arg;	/**< @brief Set the padding size of the selection. Can be negative. (default='0').  */
51
-  char * padding_orig;	/**< @brief Set the padding size of the selection. Can be negative. original value given at command line.  */
52
-  const char *padding_help; /**< @brief Set the padding size of the selection. Can be negative. help description.  */
53
-  int tolerance_arg;	/**< @brief How far in pixels the mouse can move after clicking and still be detected as a normal click instead of a click and drag. Setting this to 0 will disable window selections. (default='2').  */
54
-  char * tolerance_orig;	/**< @brief How far in pixels the mouse can move after clicking and still be detected as a normal click instead of a click and drag. Setting this to 0 will disable window selections. original value given at command line.  */
55
-  const char *tolerance_help; /**< @brief How far in pixels the mouse can move after clicking and still be detected as a normal click instead of a click and drag. Setting this to 0 will disable window selections. help description.  */
56
-  char * gracetime_arg;	/**< @brief Set the amount of time before slop will check for keyboard cancellations in seconds. (default='0.4').  */
57
-  char * gracetime_orig;	/**< @brief Set the amount of time before slop will check for keyboard cancellations in seconds. original value given at command line.  */
58
-  const char *gracetime_help; /**< @brief Set the amount of time before slop will check for keyboard cancellations in seconds. help description.  */
59
-  char * color_arg;	/**< @brief Set the selection rectangle's color. Supports RGB or RGBA values. (default='0.5,0.5,0.5,1').  */
60
-  char * color_orig;	/**< @brief Set the selection rectangle's color. Supports RGB or RGBA values. original value given at command line.  */
61
-  const char *color_help; /**< @brief Set the selection rectangle's color. Supports RGB or RGBA values. help description.  */
62
-  int nodecorations_flag;	/**< @brief Attempt to select child windows in order to avoid window decorations. (default=off).  */
63
-  const char *nodecorations_help; /**< @brief Attempt to select child windows in order to avoid window decorations. help description.  */
64
-  int min_arg;	/**< @brief Set the minimum output of width or height values. This is useful to avoid outputting 0. Setting min and max to the same value disables drag selections. (default='0').  */
65
-  char * min_orig;	/**< @brief Set the minimum output of width or height values. This is useful to avoid outputting 0. Setting min and max to the same value disables drag selections. original value given at command line.  */
66
-  const char *min_help; /**< @brief Set the minimum output of width or height values. This is useful to avoid outputting 0. Setting min and max to the same value disables drag selections. help description.  */
67
-  int max_arg;	/**< @brief Set the maximum output of width or height values. Setting min and max to the same value disables drag selections. (default='0').  */
68
-  char * max_orig;	/**< @brief Set the maximum output of width or height values. Setting min and max to the same value disables drag selections. original value given at command line.  */
69
-  const char *max_help; /**< @brief Set the maximum output of width or height values. Setting min and max to the same value disables drag selections. help description.  */
70
-  int highlight_flag;	/**< @brief Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color. (default=off).  */
71
-  const char *highlight_help; /**< @brief Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color. help description.  */
72
-  int opengl_flag;	/**< @brief Enable hardware acceleration. Only works with modern systems that are also running a compositor. (default=off).  */
73
-  const char *opengl_help; /**< @brief Enable hardware acceleration. Only works with modern systems that are also running a compositor. help description.  */
74
-  int magnify_flag;	/**< @brief Display a magnifying glass when --opengl is also enabled. (default=off).  */
75
-  const char *magnify_help; /**< @brief Display a magnifying glass when --opengl is also enabled. help description.  */
76
-  float magstrength_arg;	/**< @brief Sets how many times the magnification window size is multiplied. (default='4').  */
77
-  char * magstrength_orig;	/**< @brief Sets how many times the magnification window size is multiplied. original value given at command line.  */
78
-  const char *magstrength_help; /**< @brief Sets how many times the magnification window size is multiplied. help description.  */
79
-  int magpixels_arg;	/**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. (default='64').  */
80
-  char * magpixels_orig;	/**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. original value given at command line.  */
81
-  const char *magpixels_help; /**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. help description.  */
82
-  char * theme_arg;	/**< @brief Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/. (default='none').  */
83
-  char * theme_orig;	/**< @brief Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/. original value given at command line.  */
84
-  const char *theme_help; /**< @brief Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/. help description.  */
85
-  char * shader_arg;	/**< @brief Sets the shader to load and use from ~/.config/slop/ or /usr/share/. (default='simple').  */
86
-  char * shader_orig;	/**< @brief Sets the shader to load and use from ~/.config/slop/ or /usr/share/. original value given at command line.  */
87
-  const char *shader_help; /**< @brief Sets the shader to load and use from ~/.config/slop/ or /usr/share/. help description.  */
88
-  char * format_arg;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. (default='REPLACEME').  */
89
-  char * format_orig;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. original value given at command line.  */
90
-  const char *format_help; /**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. help description.  */
91
-  
92
-  unsigned int help_given ;	/**< @brief Whether help was given.  */
93
-  unsigned int version_given ;	/**< @brief Whether version was given.  */
94
-  unsigned int xdisplay_given ;	/**< @brief Whether xdisplay was given.  */
95
-  unsigned int nokeyboard_given ;	/**< @brief Whether nokeyboard was given.  */
96
-  unsigned int bordersize_given ;	/**< @brief Whether bordersize was given.  */
97
-  unsigned int padding_given ;	/**< @brief Whether padding was given.  */
98
-  unsigned int tolerance_given ;	/**< @brief Whether tolerance was given.  */
99
-  unsigned int gracetime_given ;	/**< @brief Whether gracetime was given.  */
100
-  unsigned int color_given ;	/**< @brief Whether color was given.  */
101
-  unsigned int nodecorations_given ;	/**< @brief Whether nodecorations was given.  */
102
-  unsigned int min_given ;	/**< @brief Whether min was given.  */
103
-  unsigned int max_given ;	/**< @brief Whether max was given.  */
104
-  unsigned int highlight_given ;	/**< @brief Whether highlight was given.  */
105
-  unsigned int opengl_given ;	/**< @brief Whether opengl was given.  */
106
-  unsigned int magnify_given ;	/**< @brief Whether magnify was given.  */
107
-  unsigned int magstrength_given ;	/**< @brief Whether magstrength was given.  */
108
-  unsigned int magpixels_given ;	/**< @brief Whether magpixels was given.  */
109
-  unsigned int theme_given ;	/**< @brief Whether theme was given.  */
110
-  unsigned int shader_given ;	/**< @brief Whether shader was given.  */
111
-  unsigned int format_given ;	/**< @brief Whether format was given.  */
112
-
113
-} ;
114
-
115
-/** @brief The additional parameters to pass to parser functions */
116
-struct cmdline_parser_params
117
-{
118
-  int override; /**< @brief whether to override possibly already present options (default 0) */
119
-  int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */
120
-  int check_required; /**< @brief whether to check that all required options were provided (default 1) */
121
-  int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */
122
-  int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */
123
-} ;
124
-
125
-/** @brief the purpose string of the program */
126
-extern const char *gengetopt_args_info_purpose;
127
-/** @brief the usage string of the program */
128
-extern const char *gengetopt_args_info_usage;
129
-/** @brief the description string of the program */
130
-extern const char *gengetopt_args_info_description;
131
-/** @brief all the lines making the help output */
132
-extern const char *gengetopt_args_info_help[];
133
-
134
-/**
135
- * The command line parser
136
- * @param argc the number of command line options
137
- * @param argv the command line options
138
- * @param args_info the structure where option information will be stored
139
- * @return 0 if everything went fine, NON 0 if an error took place
140
- */
141
-int cmdline_parser (int argc, char **argv,
142
-  struct gengetopt_args_info *args_info);
143
-
144
-/**
145
- * The command line parser (version with additional parameters - deprecated)
146
- * @param argc the number of command line options
147
- * @param argv the command line options
148
- * @param args_info the structure where option information will be stored
149
- * @param override whether to override possibly already present options
150
- * @param initialize whether to initialize the option structure my_args_info
151
- * @param check_required whether to check that all required options were provided
152
- * @return 0 if everything went fine, NON 0 if an error took place
153
- * @deprecated use cmdline_parser_ext() instead
154
- */
155
-int cmdline_parser2 (int argc, char **argv,
156
-  struct gengetopt_args_info *args_info,
157
-  int override, int initialize, int check_required);
158
-
159
-/**
160
- * The command line parser (version with additional parameters)
161
- * @param argc the number of command line options
162
- * @param argv the command line options
163
- * @param args_info the structure where option information will be stored
164
- * @param params additional parameters for the parser
165
- * @return 0 if everything went fine, NON 0 if an error took place
166
- */
167
-int cmdline_parser_ext (int argc, char **argv,
168
-  struct gengetopt_args_info *args_info,
169
-  struct cmdline_parser_params *params);
170
-
171
-/**
172
- * Save the contents of the option struct into an already open FILE stream.
173
- * @param outfile the stream where to dump options
174
- * @param args_info the option struct to dump
175
- * @return 0 if everything went fine, NON 0 if an error took place
176
- */
177
-int cmdline_parser_dump(FILE *outfile,
178
-  struct gengetopt_args_info *args_info);
179
-
180
-/**
181
- * Save the contents of the option struct into a (text) file.
182
- * This file can be read by the config file parser (if generated by gengetopt)
183
- * @param filename the file where to save
184
- * @param args_info the option struct to save
185
- * @return 0 if everything went fine, NON 0 if an error took place
186
- */
187
-int cmdline_parser_file_save(const char *filename,
188
-  struct gengetopt_args_info *args_info);
189
-
190
-/**
191
- * Print the help
192
- */
193
-void cmdline_parser_print_help(void);
194
-/**
195
- * Print the version
196
- */
197
-void cmdline_parser_print_version(void);
198
-
199
-/**
200
- * Initializes all the fields a cmdline_parser_params structure 
201
- * to their default values
202
- * @param params the structure to initialize
203
- */
204
-void cmdline_parser_params_init(struct cmdline_parser_params *params);
205
-
206
-/**
207
- * Allocates dynamically a cmdline_parser_params structure and initializes
208
- * all its fields to their default values
209
- * @return the created and initialized cmdline_parser_params structure
210
- */
211
-struct cmdline_parser_params *cmdline_parser_params_create(void);
212
-
213
-/**
214
- * Initializes the passed gengetopt_args_info structure's fields
215
- * (also set default values for options that have a default)
216
- * @param args_info the structure to initialize
217
- */
218
-void cmdline_parser_init (struct gengetopt_args_info *args_info);
219
-/**
220
- * Deallocates the string fields of the gengetopt_args_info structure
221
- * (but does not deallocate the structure itself)
222
- * @param args_info the structure to deallocate
223
- */
224
-void cmdline_parser_free (struct gengetopt_args_info *args_info);
225
-
226
-/**
227
- * Checks that all the required options were specified
228
- * @param args_info the structure to check
229
- * @param prog_name the name of the program that will be used to print
230
- *   possible errors
231
- * @return
232
- */
233
-int cmdline_parser_required (struct gengetopt_args_info *args_info,
234
-  const char *prog_name);
235
-
236
-
237
-#ifdef __cplusplus
238
-}
239
-#endif /* __cplusplus */
240
-#endif /* CMDLINE_H */

+ 65
- 425
src/framebuffer.cpp View File

@@ -1,444 +1,84 @@
1 1
 #include "framebuffer.hpp"
2 2
 
3
-slop::Framebuffer::Framebuffer() {
4
-    m_shader = new slop::Shader( "simple", resource->getRealPath( "simple.vert" ), resource->getRealPath( "simple.frag" ) );
5
-    generatedBuffers = false;
6
-    m_width = 0;
7
-    m_height = 0;
8
-    m_flags = (slop::Framebuffer::buffers)0;
9
-    m_depth = 0;
10
-    m_stencil = 0;
11
-    m_frame = 0;
12
-    m_buffers[0] = 0;
13
-    m_buffers[1] = 0;
14
-    m_texture = 0;
15
-}
16
-
17
-void slop::Framebuffer::setShader( std::string shader ) {
18
-    delete m_shader;
19
-    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
20
-}
21
-
22
-slop::Framebuffer::Framebuffer( unsigned int width, unsigned int height, unsigned char flags, std::string shader ) {
23
-    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
24
-    generatedBuffers = false;
25
-    m_width = width;
26
-    m_height = height;
27
-    m_flags = flags;
28
-    if ( m_flags & stencil && m_flags & depth ) {
29
-        fprintf( stderr, "Most hardware doesn't support using a FBO with a depth and stencil attached! Condensing them to one render buffer..." );
30
-    }
31
-    if ( GLEW_VERSION_3_0 ) {
32
-        glGenFramebuffers( 1, &m_frame );
33
-        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
34
-        if ( m_flags & color ) {
35
-            glGenTextures( 1, &m_texture );
36
-            glBindTexture( GL_TEXTURE_2D, m_texture );
37
-            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
38
-            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
39
-            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
40
-            glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
41
-        }
42
-
43
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
44
-            glGenRenderbuffers( 1, &m_depth );
45
-            glBindRenderbuffer( GL_RENDERBUFFER, m_depth );
46
-            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_width, m_height );
47
-            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth );
48
-        }
49
-
50
-        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
51
-        if ( m_flags & stencil ) {
52
-            glGenRenderbuffers( 1, &m_stencil );
53
-            glBindRenderbuffer( GL_RENDERBUFFER, m_stencil );
54
-            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_width, m_height );
55
-            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
56
-            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
57
-        }
58
-        check();
59
-        //Make sure we unbind when we're done.
60
-        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
61
-    } else if ( GLEW_EXT_framebuffer_object ) {
62
-        glGenFramebuffersEXT( 1, &m_frame );
63
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
64
-
65
-        if ( m_flags & color ) {
66
-            glGenTextures( 1, &m_texture );
67
-            glBindTexture( GL_TEXTURE_2D, m_texture );
68
-            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
69
-            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
70
-            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
71
-            glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
72
-        }
73
-
74
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
75
-            glGenRenderbuffersEXT( 1, &m_depth );
76
-            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depth );
77
-            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height );
78
-            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depth );
79
-        }
80
-
81
-        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
82
-        if ( m_flags & stencil ) {
83
-            glGenRenderbuffersEXT( 1, &m_stencil );
84
-            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_stencil );
85
-            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, m_width, m_height );
86
-            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
87
-            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
88
-        }
89
-        check();
90
-        //Make sure we unbind when we're done.
91
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
92
-    } else {
93
-        throw std::runtime_error( "Error: Failed to create framebuffer! You need OpenGL 3.0 or the GL_EXT_framebuffer_object extension!" );
94
-    }
95
-}
96
-
97
-slop::Framebuffer::~Framebuffer() {
98
-    if ( GLEW_VERSION_3_0 ) {
99
-        glDeleteFramebuffers( 1, &m_frame );
100
-        if ( m_flags & color ) {
101
-            glDeleteTextures( 1, &m_texture );
102
-        }
103
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
104
-            glDeleteRenderbuffers( 1, &m_depth );
105
-        }
106
-        if ( m_flags & stencil ) {
107
-            glDeleteRenderbuffers( 1, &m_stencil );
108
-        }
109
-    } else if ( GLEW_EXT_framebuffer_object ) {
110
-        glDeleteFramebuffersEXT( 1, &m_frame );
111
-        if ( m_flags & color ) {
112
-            glDeleteTextures( 1, &m_texture );
113
-        }
114
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
115
-            glDeleteRenderbuffersEXT( 1, &m_depth );
116
-        }
117
-        if ( m_flags & stencil ) {
118
-            glDeleteRenderbuffersEXT( 1, &m_stencil );
119
-        }
120
-    }
121
-    if ( generatedBuffers ) {
122
-        glDeleteBuffers( 2, m_buffers );
123
-    }
124
-    delete m_shader;
125
-}
126
-
127
-void slop::Framebuffer::bind() {
128
-    if ( GLEW_VERSION_3_0 ) {
129
-        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
130
-    } else if ( GLEW_EXT_framebuffer_object ) {
131
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
132
-    }
133
-}
134
-
135
-void slop::Framebuffer::unbind() {
136
-    if ( GLEW_VERSION_3_0 ) {
137
-        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
138
-    } else if ( GLEW_EXT_framebuffer_object ) {
139
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
140
-    }
141
-}
142
-
143
-void slop::Framebuffer::createFromTexture( unsigned int texture, std::string shader ) {
144
-    // First make sure we're empty.
145
-    if ( GLEW_VERSION_3_0 ) {
146
-        glDeleteFramebuffers( 1, &m_frame );
147
-        if ( m_flags & color ) {
148
-            glDeleteTextures( 1, &m_texture );
149
-        }
150
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
151
-            glDeleteRenderbuffers( 1, &m_depth );
152
-        }
153
-        if ( m_flags & stencil ) {
154
-            glDeleteRenderbuffers( 1, &m_stencil );
155
-        }
156
-    } else if ( GLEW_EXT_framebuffer_object ) {
157
-        glDeleteFramebuffersEXT( 1, &m_frame );
158
-        if ( m_flags & color ) {
159
-            glDeleteTextures( 1, &m_texture );
160
-        }
161
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
162
-            glDeleteRenderbuffersEXT( 1, &m_depth );
163
-        }
164
-        if ( m_flags & stencil ) {
165
-            glDeleteRenderbuffersEXT( 1, &m_stencil );
166
-        }
167
-    }
168
-    delete m_shader;
169
-    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
170
-    // Set flags to 0 so we don't delete the texture on deconstruction.
171
-    m_flags = 0;
172
-    m_texture = texture;
173
-    if ( GLEW_VERSION_3_0 ) {
174
-        glGenFramebuffers( 1, &m_frame );
175
-        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
176
-        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
177
-    } else if ( GLEW_EXT_framebuffer_object ) {
178
-        glGenFramebuffersEXT( 1, &m_frame );
179
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
180
-        glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
181
-    }
182
-    check();
183
-    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
184
-}
185
-
186
-void slop::Framebuffer::create( unsigned int width, unsigned int height, unsigned char flags, std::string shader ) {
187
-    if ( m_width == width && m_height == height && m_flags == flags ) {
188
-        return;
189
-    }
190
-    delete m_shader;
191
-    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
192
-    if ( GLEW_VERSION_3_0 ) {
193
-        glDeleteFramebuffers( 1, &m_frame );
194
-        if ( m_flags & color ) {
195
-            glDeleteTextures( 1, &m_texture );
196
-        }
197
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
198
-            glDeleteRenderbuffers( 1, &m_depth );
199
-        }
200
-        if ( m_flags & stencil ) {
201
-            glDeleteRenderbuffers( 1, &m_stencil );
202
-        }
203
-    } else if ( GLEW_EXT_framebuffer_object ) {
204
-        glDeleteFramebuffersEXT( 1, &m_frame );
205
-        if ( m_flags & color ) {
206
-            glDeleteTextures( 1, &m_texture );
207
-        }
208
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
209
-            glDeleteRenderbuffersEXT( 1, &m_depth );
210
-        }
211
-        if ( m_flags & stencil ) {
212
-            glDeleteRenderbuffersEXT( 1, &m_stencil );
213
-        }
214
-    }
215
-    m_flags = flags;
216
-    m_width = width;
217
-    m_height = height;
218
-    if ( GLEW_VERSION_3_0 ) {
219
-        glGenFramebuffers( 1, &m_frame );
220
-        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
221
-
222
-        if ( m_flags & color ) {
223
-            glGenTextures( 1, &m_texture );
224
-            glBindTexture( GL_TEXTURE_2D, m_texture );
225
-            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
226
-            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
227
-            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
228
-            glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
229
-        }
230
-
231
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
232
-            glGenRenderbuffers( 1, &m_depth );
233
-            glBindRenderbuffer( GL_RENDERBUFFER, m_depth );
234
-            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_width, m_height );
235
-            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth );
236
-        }
237
-
238
-        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
239
-        if ( m_flags & stencil ) {
240
-            glGenRenderbuffers( 1, &m_stencil );
241
-            glBindRenderbuffer( GL_RENDERBUFFER, m_stencil );
242
-            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_width, m_height );
243
-            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
244
-            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
245
-        }
246
-        //Make sure we unbind when we're done.
247
-        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
248
-    } else if ( GLEW_EXT_framebuffer_object ) {
249
-        glGenFramebuffersEXT( 1, &m_frame );
250
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
251
-
252
-        if ( m_flags & color ) {
253
-            glGenTextures( 1, &m_texture );
254
-            glBindTexture( GL_TEXTURE_2D, m_texture );
255
-            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
256
-           glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
257
-            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
258
-            glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
259
-        }
260
-
261
-        if ( m_flags & depth && !( m_flags & stencil ) ) {
262
-            glGenRenderbuffersEXT( 1, &m_depth );
263
-            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depth );
264
-            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height );
265
-            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depth );
266
-        }
267
-
268
-        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
269
-        if ( m_flags & stencil ) {
270
-            glGenRenderbuffersEXT( 1, &m_stencil );
271
-            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_stencil );
272
-            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, m_width, m_height );
273
-            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
274
-            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
275
-        }
276
-        //Make sure we unbind when we're done.
277
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
278
-    }
279
-}
280
-
281
-void slop::Framebuffer::check()
282
-{
283
-    if ( GLEW_VERSION_3_0 ) {
284
-        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
285
-        unsigned int err = glCheckFramebufferStatus( GL_FRAMEBUFFER );
286
-        if ( err == GL_FRAMEBUFFER_COMPLETE ) {
287
-            return;
288
-        }
289
-        fprintf( stderr, "Error: Framebuffer failed a check procedure for reason: " );
290
-        switch ( err ) {
291
-            case GL_FRAMEBUFFER_UNDEFINED: {
292
-                fprintf( stderr, "GL_FRAMEBUFFER_UNDEFINED\n" );
293
-                break;
294
-            }
295
-            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: {
296
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n" );
297
-                break;
298
-            }
299
-            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: {
300
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n" );
301
-                break;
302
-            }
303
-            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: {
304
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n" );
305
-                break;
306
-            }
307
-            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: {
308
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n" );
309
-                break;
310
-            }
311
-            case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: {
312
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\n" );
313
-                break;
314
-            }
315
-            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: {
316
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n" );
317
-                break;
318
-            }
319
-            case GL_FRAMEBUFFER_UNSUPPORTED: {
320
-                fprintf( stderr, "GL_FRAMEBUFFER_UNSUPPORTED\n" );
321
-                break;
322
-            }
323
-            default: {
324
-                fprintf( stderr, "UNKNOWN\n" );
325
-                break;
326
-            }
327
-        }
328
-        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
329
-    } else if ( GLEW_EXT_framebuffer_object ) {
330
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
331
-        unsigned int err = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
332
-        if ( err == GL_FRAMEBUFFER_COMPLETE_EXT ) {
333
-            return;
334
-        }
335
-        switch ( err ) {
336
-            /* Apparently doesn't exist as an extension.
337
-               case GL_FRAMEBUFFER_UNDEFINED_EXT: {
338
-                fprintf( stderr, "GL_FRAMEBUFFER_UNDEFINED_EXT\n" );
339
-                break;
340
-            }*/
341
-            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: {
342
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n" );
343
-                break;
344
-            }
345
-            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: {
346
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n" );
347
-                break;
348
-            }
349
-            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: {
350
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n" );
351
-                break;
352
-            }
353
-            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: {
354
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n" );
355
-                break;
356
-            }
357
-            case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT: {
358
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT\n" );
359
-                break;
360
-            }
361
-            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: {
362
-                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT\n" );
363
-                break;
364
-            }
365
-            case GL_FRAMEBUFFER_UNSUPPORTED_EXT: {
366
-                fprintf( stderr, "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n" );
367
-                break;
368
-            }
369
-            default: {
370
-                fprintf( stderr, "Unknown framebuffer error!\n" );
371
-                break;
372
-            }
373
-        }
374
-        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
375
-    }
376
-}
377
-
378
-void slop::Framebuffer::generateBuffers() {
379
-    if ( generatedBuffers ) {
380
-        return;
381
-    }
3
+Framebuffer::Framebuffer( int w, int h ) {
4
+    shader = new Shader( "textured.vert", "textured.frag" );
5
+    glGenFramebuffers( 1, &fbuffer );
6
+    glBindFramebuffer( GL_FRAMEBUFFER, fbuffer );
7
+    glGenTextures(1, &image);
8
+    glBindTexture(GL_TEXTURE_2D, image);
9
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
10
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
11
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
12
+    glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image, 0);
13
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
14
+    // generate our vertex and uv buffers
382 15
     std::vector<glm::vec2> verts;
383 16
     std::vector<glm::vec2> uvs;
384
-    verts.push_back( glm::vec2( -1, -1 ) );
385
-    verts.push_back( glm::vec2( 1, -1 ) );
386
-    verts.push_back( glm::vec2( 1, 1 ) );
387
-    verts.push_back( glm::vec2( -1, 1 ) );
388
-    uvs.push_back( glm::vec2( 0, 0 ) );
389
-    uvs.push_back( glm::vec2( 1, 0 ) );
17
+
18
+    verts.push_back( glm::vec2(1,1) );
390 19
     uvs.push_back( glm::vec2( 1, 1 ) );
20
+    verts.push_back( glm::vec2(-1,-1) );
21
+    uvs.push_back( glm::vec2( 0, 0 ) );
22
+    verts.push_back( glm::vec2(-1,1) );
391 23
     uvs.push_back( glm::vec2( 0, 1 ) );
24
+    verts.push_back( glm::vec2(-1,-1) );
25
+    uvs.push_back( glm::vec2( 0, 0 ) );
26
+    verts.push_back( glm::vec2(1,1) );
27
+    uvs.push_back( glm::vec2( 1, 1 ) );
28
+    verts.push_back( glm::vec2(1,-1) );
29
+    uvs.push_back( glm::vec2( 1, 0 ) );
392 30
 
393
-    glGenBuffers( 2, m_buffers );
394
-    glBindBuffer( GL_ARRAY_BUFFER, m_buffers[0] );
31
+    glGenBuffers( 2, buffers );
32
+    glBindBuffer( GL_ARRAY_BUFFER, buffers[0] );
395 33
     glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof( glm::vec2 ), &verts[0], GL_STATIC_DRAW );
396
-    glBindBuffer( GL_ARRAY_BUFFER, m_buffers[1] );
34
+    glBindBuffer( GL_ARRAY_BUFFER, buffers[1] );
397 35
     glBufferData( GL_ARRAY_BUFFER, uvs.size() * sizeof( glm::vec2 ), &uvs[0], GL_STATIC_DRAW );
398
-    generatedBuffers = true;
36
+    vertCount = verts.size();
399 37
 }
400 38
 
401
-void slop::Framebuffer::clear( glm::vec4 clearcolor, unsigned char flags ) {
402
-    // FIXME: This should auto-bind and unbind, but I was too lazy to find out how to push and pop gl states.
403
-    unsigned int colorbit = 0;
404
-    if ( flags & color ) {
405
-        colorbit = colorbit | GL_COLOR_BUFFER_BIT;
406
-    }
407
-    if ( m_flags & depth && flags & depth ) {
408
-        colorbit = colorbit | GL_DEPTH_BUFFER_BIT;
409
-    }
410
-    if ( m_flags & stencil && flags & stencil) {
411
-        colorbit = colorbit | GL_STENCIL_BUFFER_BIT;
412
-    }
413
-    glClearColor( clearcolor.x, clearcolor.y, clearcolor.z, clearcolor.w );
414
-    glClear( colorbit );
39
+void Framebuffer::setShader( std::string name ) {
40
+    delete shader;
41
+    shader = new Shader( name + ".vert", name + ".frag" );
415 42
 }
416 43
 
417
-void slop::Framebuffer::draw( float time, unsigned int desktop ) {
418
-    if ( !( m_flags & color ) ) {
419
-        return;
420
-    }
44
+Framebuffer::~Framebuffer() {
45
+    glDeleteTextures(1, &image);
46
+    glDeleteFramebuffers(1,&fbuffer);
47
+    glDeleteBuffers(2,buffers);
48
+    delete shader;
49
+}
421 50
 
422
-    generateBuffers();
51
+void Framebuffer::resize( int w, int h ) {
52
+    // Regenerate the image
53
+    glDeleteTextures(1, &image);
54
+    glBindTexture(GL_TEXTURE_2D, image);
55
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
56
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
57
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
58
+
59
+    // Re-bind it to the framebuffer
60
+    glBindFramebuffer( GL_FRAMEBUFFER, fbuffer );
61
+    glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image, 0);
62
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
63
+}
423 64
 
424
-    //slop::Shader* shader = shaders->get( "simple" );
425
-    m_shader->bind();
426
-    m_shader->setParameter( "texture", 0 );
427
-    m_shader->setParameter( "desktop", 1 );
428
-    m_shader->setParameter( "time", time );
429
-    m_shader->setParameter( "desktopWidth", (int)xengine->getWidth() );
430
-    m_shader->setParameter( "desktopHeight", (int)xengine->getHeight() );
431
-    m_shader->setAttribute( "vertex", m_buffers[0], 2 );
432
-    m_shader->setAttribute( "uv", m_buffers[1], 2 );
65
+void Framebuffer::bind() {
66
+    glBindFramebuffer( GL_FRAMEBUFFER, fbuffer );
67
+}
433 68
 
434
-    glActiveTexture(GL_TEXTURE0 + 0);
435
-    glBindTexture( GL_TEXTURE_2D, m_texture );
436
-    glActiveTexture(GL_TEXTURE0 + 1);
437
-    glBindTexture( GL_TEXTURE_2D, desktop );
438
-    glActiveTexture(GL_TEXTURE0 + 0);
69
+void Framebuffer::unbind() {
70
+    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
71
+}
72
+
73
+void Framebuffer::draw(){
74
+    shader->bind();
75
+    shader->setParameter( "texture", 0 );
76
+    shader->setAttribute( "position", buffers[0], 2 );
77
+    shader->setAttribute( "uv", buffers[1], 2 );
78
+    glActiveTexture(GL_TEXTURE0);
79
+    glBindTexture( GL_TEXTURE_2D, image );
439 80
     glEnable( GL_TEXTURE_2D );
440
-    glDrawArrays( GL_QUADS, 0, 4 );
81
+    glDrawArrays( GL_TRIANGLES, 0, vertCount );
441 82
     glDisable( GL_TEXTURE_2D );
442
-
443
-    m_shader->unbind();
83
+    shader->unbind();
444 84
 }

+ 17
- 40
src/framebuffer.hpp View File

@@ -1,51 +1,28 @@
1
-#ifndef IS_FRAMEBUFFER_H_
2
-#define IS_FRAMEBUFFER_H_
1
+#ifndef N_FRAMEBUFFER_H_
2
+#define N_FRAMEBUFFER_H_
3 3
 
4
-#include <GL/glew.h>
5
-#include <GL/gl.h>
4
+#include "gl_core_3_3.h"
6 5
 #include <glm/glm.hpp>
7
-#include <stdexcept>
6
+#include <GL/gl.h>
7
+#include <vector>
8 8
 
9
-#include "x.hpp"
10 9
 #include "shader.hpp"
11
-#include "resource.hpp"
12
-
13
-namespace slop {
14 10
 
15
-class Framebuffer
16
-{
11
+class Framebuffer {
12
+private:
13
+    unsigned int fbuffer;
14
+    unsigned int image;
15
+    unsigned int buffers[2];
16
+    unsigned int vertCount;
17
+    Shader* shader;
17 18
 public:
18
-    enum buffers
19
-    {
20
-        color = 0x01,
21
-        depth = 0x02,
22
-        stencil = 0x04
23
-    };
24
-    Framebuffer();
25
-    Framebuffer( unsigned int width, unsigned int height, unsigned char flags = color, std::string shader = "simple" );
19
+    Framebuffer( int w, int h );
26 20
     ~Framebuffer();
27
-    void create( unsigned int width, unsigned int height, unsigned char flags = color, std::string shader = "simple" );
28
-    void createFromTexture( unsigned int texture, std::string shader = "simple" );
29
-    void setShader( std::string shader = "simple" );
30
-    void clear( glm::vec4 color = glm::vec4( 0, 0, 0, 1 ), unsigned char flags = color | depth | stencil );
21
+    void setShader( std::string );
22
+    void draw();
23
+    void resize( int w, int h );
31 24
     void bind();
32 25
     void unbind();
33
-    void draw( float time, unsigned int image );
34
-    unsigned int m_texture;
35
-    unsigned int m_depth;
36
-    unsigned int m_stencil;
37
-    slop::Shader* m_shader;
38
-private:
39
-    unsigned int m_width;
40
-    unsigned int m_height;
41
-    void check();
42
-    void generateBuffers();
43
-    unsigned char m_flags;
44
-    bool generatedBuffers;
45
-    unsigned int m_frame;
46
-    unsigned int m_buffers[2];
47 26
 };
48 27
 
49
-}
50
-
51
-#endif //IS_FRAMEBUFFER_H_
28
+#endif

+ 1261
- 0
src/gl_core_3_3.c
File diff suppressed because it is too large
View File


+ 1700
- 0
src/gl_core_3_3.h
File diff suppressed because it is too large
View File


+ 0
- 683
src/glselectrectangle.cpp View File

@@ -1,683 +0,0 @@
1
-/* glrectangle.hpp: Handles creating hardware accelerated rectangles on the screen using X11 and OpenGL.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-#include "glselectrectangle.hpp"
21
-
22
-static Bool isDestroyNotify( Display* dpy, XEvent* ev, XPointer win ) {
23
-    return ev->type == DestroyNotify && ev->xdestroywindow.window == *((Window*)win);
24
-}
25
-
26
-slop::GLSelectRectangle::~GLSelectRectangle() {
27
-    if ( m_window == None ) {
28
-        return;
29
-    }
30
-    xengine->freeCRTCS( m_monitors );
31
-    delete m_framebuffer;
32
-    // Try to erase the window before destroying it.
33
-    glClearColor( 0, 0, 0, 0 );
34
-    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
35
-    glXSwapBuffers( xengine->m_display, m_glxWindow );
36
-    // Sleep for 0.1 seconds in hope that the rectangle was erased.
37
-    usleep( 10000 );
38
-    XDestroyWindow( xengine->m_display, m_window );
39
-    XEvent event;
40
-    // Block until the window is actually completely removed.
41
-    XIfEvent( xengine->m_display, &event, &isDestroyNotify, (XPointer)&m_window );
42
-    // Sleep for 0.1 seconds in hope that the screen actually cleared the window.
43
-    usleep( 10000 );
44
-}
45
-
46
-void slop::GLSelectRectangle::constrainWithinMonitor( int* x, int* y, int* w, int* h ) {
47
-    m_offsetx = 0;
48
-    m_offsety = 0;
49
-    m_offsetw = 0;
50
-    m_offseth = 0;
51
-    for ( unsigned int i=0;i<m_monitors.size();i++ ) {
52
-        XRRCrtcInfo* monitor = m_monitors[ i ];
53
-        if ( !((int)xengine->m_mousex >= (int)monitor->x && (int)xengine->m_mousey >= (int)monitor->y &&
54
-               (int)xengine->m_mousex <= (int)(monitor->x+monitor->width) && (int)xengine->m_mousey <= (int)(monitor->y+monitor->height) ) ) {
55
-            continue;
56
-        }
57
-        if ( (int)*x < (int)monitor->x ) {
58
-            m_offsetx = monitor->x-*x;
59
-            *w += *x-monitor->x;
60
-            *x = monitor->x;
61
-        }
62
-        if ( (int)(*x+*w) >= (int)(monitor->x+monitor->width) ) {
63
-            m_offsetw = (monitor->width-1-(*x-monitor->x+*w));
64
-            *w = monitor->width-1-(*x-monitor->x);
65
-        }
66
-        if ( (int)*y < (int)monitor->y ) {
67
-            m_offsety = monitor->y-*y;
68
-            *h += *y-monitor->y;
69
-            *y = monitor->y;
70
-        }
71
-        if ( (int)(*y+*h) >= (int)(monitor->y+monitor->height) ) {
72
-            m_offseth = (monitor->height-1-(*y-monitor->y+*h));
73
-            *h = monitor->height-1-(*y-monitor->y);
74
-        }
75
-        break;
76
-    }
77
-    m_offsetx *= m_glassSize;
78
-    m_offsety *= m_glassSize;
79
-    m_offsetw *= m_glassSize;
80
-    m_offseth *= m_glassSize;
81
-}
82
-
83
-void slop::GLSelectRectangle::setShader( std::string shader ) {
84
-    m_shader = shader;
85
-    m_framebuffer->setShader( shader );
86
-}
87
-
88
-void slop::GLSelectRectangle::setMagnifySettings( bool on, float magstrength, unsigned int pixels ) {
89
-    m_glassSize = magstrength;
90
-    m_glassPixels = pixels;
91
-    m_glassEnabled = on;
92
-    m_glassx = xengine->m_mousex;
93
-    m_glassy = xengine->m_mousey;
94
-    m_realglassx = xengine->m_mousex;
95
-    m_realglassy = xengine->m_mousey;
96
-}
97
-
98
-void slop::GLSelectRectangle::pushOut( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh ) {
99
-    // AABB to test for collision
100
-    if (!(
101
-          *x < rx + rw &&
102
-          *x + w > rx &&
103
-          *y < ry + rh &&
104
-          h + *y > ry
105
-       )) {
106
-        // No collision, so we do nothing.
107
-        return;
108
-    }
109
-    // Otherwise we find an optimal angle to push ourselves out at.
110
-    int centerx = rx+rw/2;
111
-    int centery = ry+rh/2;
112
-    float ang = -atan2( (float)(*y+(float)h/2.f)-(float)centery, (float)(*x+(float)w/2.f)-(float)centerx );
113
-    float pi = 3.1415926535897;
114
-    float upright = pi/2 - atan( (2.f*float(rx+rw)-2.f*(float)centerx)/(float)rh );
115
-    float upleft = pi/2 - atan( (2.f*(float)rx-2.f*(float)centerx)/(float)rh );
116
-    float downright = -upright;
117
-    float downleft = -upleft;
118
-    if ( ang >= upright && ang <= upleft ) {
119
-        *x = centerx + ((rh*cos(ang))/(2*sin(ang))) - w/2;
120
-        *y = centery - rh/2 - h;
121
-    } else if ( ang <= downright && ang >= downleft) {
122
-        *x = centerx - ((rh*cos(ang))/(2*sin(ang))) - w/2;
123
-        *y = centery + rh/2;
124
-    } else if ( ang < downleft || ang > upleft ) {
125
-        *x = centerx - rw/2 - w;
126
-        *y = centery + (rw*sin(ang))/(2*cos(ang)) - h/2;
127
-    } else {
128
-        *x = centerx + rw/2;
129
-        *y = centery - (rw*sin(ang))/(2*cos(ang)) - h/2;
130
-    }
131
-}
132
-
133
-void slop::GLSelectRectangle::pushIn( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh ) {
134
-    if ( *x > rx && *y > ry &&
135
-         *x+w < rx+rw && *y+h < ry+rh ) {
136
-        // We're already fully contained...
137
-        return;
138
-    }
139
-    // Otherwise we find an optimal angle to push ourselves in at.
140
-    int centerx = rx+rw/2;
141
-    int centery = ry+rh/2;
142
-    float ang = -atan2( (float)(*y+(float)h/2.f)-(float)centery, (float)(*x+(float)w/2.f)-(float)centerx );
143
-    float pi = 3.1415926535897;
144
-    float upright = pi/2 - atan( (2.f*float(rx+rw)-2.f*(float)centerx)/(float)rh );
145
-    float upleft = pi/2 - atan( (2.f*(float)rx-2.f*(float)centerx)/(float)rh );
146
-    float downright = -upright;
147
-    float downleft = -upleft;
148
-    if ( ang >= upright && ang <= upleft ) {
149
-        *x = centerx + ((rh*cos(ang))/(2*sin(ang))) - w/2;
150
-        *y = centery - rh/2;
151
-    } else if ( ang <= downright && ang >= downleft) {
152
-        *x = centerx - ((rh*cos(ang))/(2*sin(ang))) - w/2;
153
-        *y = centery + rh/2 - h;
154
-    } else if ( ang < downleft || ang > upleft ) {
155
-        *x = centerx - rw/2;
156
-        *y = centery + (rw*sin(ang))/(2*cos(ang)) - h/2;
157
-    } else {
158
-        *x = centerx + rw/2 - w;
159
-        *y = centery - (rw*sin(ang))/(2*cos(ang)) - h/2;
160
-    }
161
-    if ( !(*x > rx && *y > ry &&
162
-         *x+w < rx+rw && *y+h < ry+rh) ) {
163
-        if ( *x+w > rx+rw ) {
164
-            *x -= w/2;
165
-        }
166
-        if ( *x < rx ) {
167
-            *x += w/2;
168
-        }
169
-        if ( *y+h > ry+rh ) {
170
-            *y -= h/2;
171
-        }
172
-        if ( *y < ry ) {
173
-            *y += h/2;
174
-        }
175
-    }
176
-}
177
-
178
-void slop::GLSelectRectangle::findOptimalGlassPosition() {
179
-    // Try to move the glass next to the mouse.
180
-    m_glassx = xengine->m_mousex+m_glassPixels/2+5-m_glassBorder;
181
-    m_glassy = xengine->m_mousey+m_glassPixels/2+5-m_glassBorder;
182
-    XRectangle view, selection, combined;
183
-    view.x = xengine->m_mousex-(m_glassPixels+1+m_glassBorder)/2;
184
-    view.y = xengine->m_mousey-(m_glassPixels+1+m_glassBorder)/2;
185
-    view.width = m_glassPixels+1;
186
-    view.height = m_glassPixels+1;
187
-    selection.x = m_x-m_border;
188
-    selection.y = m_y-m_border;
189
-    selection.width = m_width+m_border*2;
190
-    selection.height = m_height+m_border*2;
191
-    combined.x = std::min( selection.x, view.x );
192
-    combined.y = std::min( selection.y, view.y );
193
-    combined.width = selection.width + std::max( selection.x-view.x, (view.x+view.width)-(selection.x+selection.width) );
194
-    combined.height = selection.height + std::max( selection.y-view.y, (view.y+view.height)-(selection.y+selection.height) );
195
-    for ( unsigned int i=0;i<m_monitors.size();i++ ) {
196
-        XRRCrtcInfo* monitor = m_monitors[ i ];
197
-        // Push the glass inside the monitor the mouse is on.
198
-        if ( (int)xengine->m_mousex >= (int)monitor->x && (int)xengine->m_mousex <= (int)(monitor->x + monitor->width) &&
199
-             (int)xengine->m_mousey >= (int)monitor->y && (int)xengine->m_mousey <= (int)(monitor->y + monitor->height) ) {
200
-            pushIn( &m_glassx, &m_glassy, m_glassPixels*m_glassSize+m_glassBorder*2, m_glassPixels*m_glassSize+m_glassBorder*2, monitor->x, monitor->y, monitor->width, monitor->height );
201
-            break;
202
-        }
203
-    }
204
-    // Push the glass outside of the selection, but only if we are left clicking, and always keep it out of the "shot"
205
-    if ( xengine->getCursor() != slop::Left ) {
206
-        pushOut( &m_glassx, &m_glassy, m_glassPixels*m_glassSize+m_glassBorder*2, m_glassPixels*m_glassSize+m_glassBorder*2, combined.x, combined.y, combined.width, combined.height );
207
-    } else {
208
-        pushOut( &m_glassx, &m_glassy, m_glassPixels*m_glassSize+m_glassBorder*2, m_glassPixels*m_glassSize+m_glassBorder*2, view.x, view.y, view.width, view.height );
209
-    }
210
-    m_glassx += m_glassBorder;
211
-    m_glassy += m_glassBorder;
212
-}
213
-
214
-void slop::GLSelectRectangle::generateMagnifyingGlass() {
215
-    int x = xengine->m_mousex-m_glassPixels/2;
216
-    int y = xengine->m_mousey-m_glassPixels/2;
217
-    bool fx = xengine->m_mousex < m_x+m_width/2;
218
-    bool fy = xengine->m_mousey < m_y+m_height/2;
219
-    // Mouse behavior SUCKS
220
-    if ( !fx && !fy ) {
221
-        x += 1;
222
-        y += 1;
223
-    } else if ( fx && !fy ) {
224
-        y += 1;
225
-    } else if ( !fx && fy ) {
226
-        x += 1;
227
-    }
228
-    int w = m_glassPixels;
229
-    int h = m_glassPixels;
230
-    constrainWithinMonitor( &x, &y, &w, &h );
231
-    XImage* image = XGetImage( xengine->m_display, xengine->m_root, x, y, w, h, 0xffffffff, ZPixmap );
232
-    glEnable(GL_TEXTURE_2D);
233
-    glGenTextures(1, &m_texid);
234
-    glBindTexture(GL_TEXTURE_2D, m_texid);
235
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
236
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
237
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
238
-    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(image->data[0])));
239
-    XDestroyImage( image );
240
-    glDisable(GL_TEXTURE_2D);
241
-}
242
-
243
-void slop::GLSelectRectangle::setTheme( bool on, std::string name ) {
244
-    if ( !on || name == "none" ) {
245
-        return;
246
-    }
247
-    std::string root = resource->getRealPath( name );
248
-    std::string tl = root + "/corner_tl.png";
249
-    std::string bl = root + "/corner_bl.png";
250
-    std::string tr = root + "/corner_tr.png";
251
-    std::string br = root + "/corner_br.png";
252
-    std::string straight = root + "/straight.png";
253
-    // One of the textures didn't exist, so we cancel the theme.
254
-    if (!resource->validatePath( tl ) ||
255
-        !resource->validatePath( bl ) ||
256
-        !resource->validatePath( tr ) ||
257
-        !resource->validatePath( br ) ||
258
-        !resource->validatePath( straight ) ) {
259
-        fprintf( stderr, "One of the textures was missing in the theme... disabling.\n" );
260
-        return;
261
-    }
262
-    // Otherwise we load each one :)
263
-    loadImage( &(m_cornerids[0]), tl );
264
-    loadImage( &(m_cornerids[1]), tr );
265
-    loadImage( &(m_cornerids[2]), bl );
266
-    loadImage( &(m_cornerids[3]), br );
267
-    loadImage( &(m_straightid), straight );
268
-    glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &m_straightwidth );
269
-    glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &m_straightheight );
270
-    m_themed = on;
271
-}
272
-
273
-unsigned int slop::GLSelectRectangle::loadImage( unsigned int* texture, std::string path ) {
274
-    glActiveTexture(GL_TEXTURE0);
275
-    glEnable(GL_TEXTURE_2D);
276
-    glGenTextures( 1, texture );
277
-    glBindTexture( GL_TEXTURE_2D, *texture );
278
-    Imlib_Load_Error err;
279
-    Imlib_Image image = imlib_load_image_with_error_return( path.c_str(), &err );
280
-    if ( err != IMLIB_LOAD_ERROR_NONE ) {
281
-        std::string message = "Failed to load image: ";
282
-        message += path;
283
-        message += "\n\t";
284
-        switch( err ) {
285
-            default: {
286
-                message += "unknown error ";
287
-                message += (int)err;
288
-                message += "\n";
289
-                break;
290
-            }
291
-            case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS:
292
-                message += "out of file descriptors\n";
293
-                break;
294
-            case IMLIB_LOAD_ERROR_OUT_OF_MEMORY:
295
-                message += "out of memory\n";
296
-                break;
297
-            case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS:
298
-                message += "path contains too many symbolic links\n";
299
-                break;
300
-            case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE:
301
-                message += "path points outside address space\n";
302
-                break;
303
-            case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY:
304
-                message += "path component is not a directory\n";
305
-                break;
306
-            case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT:
307
-                message += "path component is non-existant (~ isn't expanded inside quotes!)\n";
308
-                break;
309
-            case IMLIB_LOAD_ERROR_PATH_TOO_LONG:
310
-                message += "path is too long\n";
311
-                break;
312
-            case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT:
313
-                message += "no loader for file format (unsupported format)\n";
314
-                break;
315
-            case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE: {
316
-                message += "not enough disk space\n";
317
-                break;
318
-            }
319
-            case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST: {
320
-                message += "file does not exist\n";
321
-                break;
322
-            }
323
-            case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY: {
324
-                message += "file is a directory\n";
325
-                break;
326
-            }
327
-            case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE:
328
-            case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ: {
329
-                message += "permission denied\n";
330
-                break;
331
-            }
332
-        }
333
-        throw std::runtime_error( message.c_str() );
334
-        return *texture;
335
-    }
336
-    imlib_context_set_image( image );
337
-    DATA32* data = imlib_image_get_data_for_reading_only();
338
-    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, imlib_image_get_width(), imlib_image_get_height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)data );
339
-    if ( GLEW_VERSION_3_0 ) {
340
-        glHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST );
341
-        glGenerateMipmap( GL_TEXTURE_2D );
342
-        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
343
-        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );
344
-    } else {
345
-        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
346
-        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
347
-    }
348
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
349
-    imlib_free_image();
350
-    glDisable(GL_TEXTURE_2D);
351
-    return *texture;
352
-}
353
-
354
-
355
-
356
-slop::GLSelectRectangle::GLSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a ) {
357
-    m_x = std::min( sx, ex );
358
-    m_y = std::min( sy, ey );
359
-    m_width = std::max( sx, ex ) - m_x;
360
-    m_height = std::max( sy, ey ) - m_y;
361
-    m_r = r;
362
-    m_g = g;
363
-    m_b = b;
364
-    m_a = a;
365
-    m_border = border;
366
-    m_window = None;
367
-    m_highlight = highlight;
368
-    m_glassPixels = 64;
369
-    m_glassx = xengine->m_mousex;
370
-    m_glassy = xengine->m_mousey;
371
-    m_realglassx = xengine->m_mousex;
372
-    m_realglassy = xengine->m_mousey;
373
-    m_glassSize = 4;
374
-    m_glassBorder = 1;
375
-    m_monitors = xengine->getCRTCS();
376
-    m_themed = false;
377
-    m_shader = "simple";
378
-    m_time = 0;
379
-
380
-    // If we don't have a border, we don't exist, so just die.
381
-    if ( m_border == 0 ) {
382
-        return;
383
-    }
384
-
385
-    if ( m_highlight ) {
386
-        m_border = 0;
387
-    }
388
-
389
-    static int visdata[] = {
390
-        GLX_RENDER_TYPE, GLX_RGBA_BIT,
391
-        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
392
-        GLX_DOUBLEBUFFER, True,
393
-        GLX_RED_SIZE, 8,
394
-        GLX_GREEN_SIZE, 8,
395
-        GLX_BLUE_SIZE, 8,
396
-        GLX_ALPHA_SIZE, 8,
397
-        GLX_DEPTH_SIZE, 16,
398
-        None
399
-    };
400
-
401
-    int numfbconfigs = 0;
402
-    GLXFBConfig* fbconfigs = glXChooseFBConfig( xengine->m_display,  DefaultScreen( xengine->m_display ), visdata, &numfbconfigs );
403
-    m_fbconfig = 0;
404
-    for ( int i=0; i<numfbconfigs; i++ ) {
405
-        m_visual = (XVisualInfo*)glXGetVisualFromFBConfig( xengine->m_display, fbconfigs[i] );
406
-        if ( !m_visual ) {
407
-            continue;
408
-        }
409
-        m_pictFormat = XRenderFindVisualFormat( xengine->m_display, m_visual->visual );
410
-        if ( !m_pictFormat ) {
411
-            continue;
412
-        }
413
-        m_fbconfig = fbconfigs[i];
414
-        if ( m_pictFormat->direct.alphaMask > 0 ) {
415
-            break;
416
-        }
417
-    }
418
-
419
-    if ( !m_fbconfig ) {
420
-        fprintf( stderr, "Couldn't find a matching FB config for a transparent OpenGL window!\n");
421
-    }
422
-
423
-    m_cmap = XCreateColormap( xengine->m_display, xengine->m_root, m_visual->visual, AllocNone );
424
-
425
-    XSetWindowAttributes attributes;
426
-    attributes.colormap = m_cmap;
427
-    attributes.background_pixmap = None;
428
-    attributes.border_pixmap = None;
429
-    attributes.border_pixel = 0;
430
-    // Disable window decorations.
431
-    attributes.override_redirect = True;
432
-    // Make sure we know when we've been successfully destroyed later!
433
-    attributes.event_mask = StructureNotifyMask;
434
-    unsigned long valueMask = CWOverrideRedirect | CWEventMask | CWBackPixmap | CWColormap | CWBorderPixel;
435
-
436
-
437
-    // Create the window
438
-    m_window = XCreateWindow( xengine->m_display, xengine->m_root, 0, 0, xengine->getWidth(), xengine->getHeight(),
439
-                              0, m_visual->depth, InputOutput,
440
-                              m_visual->visual, valueMask, &attributes );
441
-
442
-    if ( !m_window ) {
443
-        fprintf( stderr, "Couldn't create a GL window!\n");
444
-    }
445
-
446
-    m_glxWindow = m_window;
447
-
448
-    static char title[] = "OpenGL Slop";
449
-    XWMHints* startup_state = XAllocWMHints();
450
-    startup_state->initial_state = NormalState;
451
-    startup_state->flags = StateHint;
452
-    XTextProperty textprop;
453
-    textprop.value = (unsigned char*)title;
454
-    textprop.encoding = XA_STRING;
455
-    textprop.format = 8;
456
-    textprop.nitems = strlen( title );
457
-    XSizeHints sizehints;
458
-    sizehints.x = 0;
459
-    sizehints.y = 0;
460
-    sizehints.width = xengine->getWidth();
461
-    sizehints.height = xengine->getHeight();
462
-    sizehints.flags = USPosition | USSize;
463
-    XClassHint classhints;
464
-    char name[] = "slop";
465
-    classhints.res_name = name;
466
-    classhints.res_class = name;
467
-    XSetClassHint( xengine->m_display, m_window, &classhints );
468
-    XSetWMProperties( xengine->m_display, m_window, &textprop, &textprop, NULL, 0, &sizehints, startup_state, NULL );
469
-    XFree( startup_state );
470
-
471
-    // Make it so all input falls through
472
-    XRectangle rect;
473
-    rect.x = rect.y = rect.width = rect.height = 0;
474
-    XShapeCombineRectangles( xengine->m_display, m_window, ShapeInput, 0, 0, &rect, 1, ShapeSet, 0);
475
-
476
-    XMapWindow( xengine->m_display, m_window );
477
-
478
-    int dummy;
479
-    if ( !glXQueryExtension( xengine->m_display, &dummy, &dummy ) ) {
480
-        fprintf( stderr, "OpenGL is not supported!\n" );
481
-    }
482
-    m_renderContext = glXCreateNewContext( xengine->m_display, m_fbconfig, GLX_RGBA_TYPE, 0, True );
483
-    if ( !m_renderContext ) {
484
-        fprintf( stderr, "Failed to create a GL context.\n" );
485
-    }
486
-    if ( !glXMakeContextCurrent( xengine->m_display, m_glxWindow, m_glxWindow, m_renderContext ) ) {
487
-        fprintf( stderr, "Failed to attach GL context to window!\n" );
488
-    }
489
-    GLenum err = glewInit();
490
-    if ( GLEW_OK != err ) {
491
-        /* Problem: glewInit failed, something is seriously wrong. */
492
-        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
493
-    }
494
-
495
-    // Get an image of the entire desktop for use in shaders.
496
-    XImage* image = XGetImage( xengine->m_display, xengine->m_root, 0, 0, xengine->getWidth(), xengine->getHeight(), 0xffffffff, ZPixmap );
497
-    glEnable(GL_TEXTURE_2D);
498
-    glGenTextures(1, &m_desktop);
499
-    glBindTexture(GL_TEXTURE_2D, m_desktop);
500
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
501
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
502
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
503
-    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, xengine->getWidth(), xengine->getHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(image->data[0])));
504
-    XDestroyImage( image );
505
-
506
-    glDisable(GL_TEXTURE_2D);
507
-    m_framebuffer = new slop::Framebuffer( xengine->getWidth(), xengine->getHeight(), slop::Framebuffer::color, m_shader );
508
-    m_framebuffer->bind();
509
-    glEnable( GL_BLEND );
510
-    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
511
-    glClearColor( 0, 0, 0, 0 );
512
-    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
513
-    glXSwapBuffers( xengine->m_display, m_glxWindow );
514
-    m_framebuffer->unbind();
515
-}
516
-
517
-void slop::GLSelectRectangle::setGeo( int sx, int sy, int ex, int ey ) {
518
-    int x = std::min( sx, ex );
519
-    int y = std::min( sy, ey );
520
-    int w = std::max( sx, ex ) - x;
521
-    int h = std::max( sy, ey ) - y;
522
-
523
-    m_x = x;
524
-    m_y = y;
525
-    m_width = w;
526
-    m_height = h;
527
-}
528
-
529
-void slop::GLSelectRectangle::update( double dt ) {
530
-    m_time += dt;
531
-    m_framebuffer->bind();
532
-    glViewport( 0, 0, xengine->getWidth(), xengine->getHeight() );
533
-
534
-    glClearColor( 0, 0, 0, 0 );
535
-    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
536
-
537
-    glMatrixMode( GL_PROJECTION );
538
-    glLoadIdentity();
539
-    glOrtho( 0, xengine->getWidth(), xengine->getHeight(), 0, 1, -1 );
540
-
541
-    glMatrixMode( GL_MODELVIEW );
542
-    glLoadIdentity();
543
-
544
-    if ( !m_themed ) {
545
-        glColor4f( m_r, m_g, m_b, m_a );
546
-        if ( m_highlight ) {
547
-            glRecti( m_x-m_border, m_y+m_height+m_border, m_x+m_width+m_border, m_y-m_border );
548
-        } else {
549
-            glRecti( m_x-m_border, m_y, m_x+m_width+m_border, m_y-m_border );
550
-            glRecti( m_x-m_border, m_y+m_height, m_x+m_width+m_border, m_y+m_height+m_border );
551
-            glRecti( m_x-m_border, m_y, m_x, m_y+m_height );
552
-            glRecti( m_x+m_width, m_y, m_x+m_width+m_border, m_y+m_height );
553
-        }
554
-    } else {
555
-        glColor4f( m_r, m_g, m_b, m_a );
556
-        glEnable( GL_TEXTURE_2D );
557
-        if ( !m_highlight ) {
558
-            glBindTexture( GL_TEXTURE_2D, m_straightid );
559
-            float something = (float)(m_border)/(float)m_straightheight;
560
-            float txoffset = (((float)m_width+m_border)/(float)m_straightwidth)/something;
561
-            float tyoffset = (((float)m_height+m_border)/(float)m_straightwidth)/something;
562
-            //float ratio = ((float)m_straightwidth/(float)m_straightheight);
563
-            glBegin( GL_QUADS );
564
-            // straight top
565
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x-m_border/2, m_y-m_border );
566
-            glTexCoord2f(txoffset, 0.0); glVertex2f( m_x+m_width+m_border/2, m_y-m_border );
567
-            glTexCoord2f(txoffset, 1.0); glVertex2f( m_x+m_width+m_border/2, m_y );
568
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x-m_border/2, m_y );
569
-            // straight bot
570
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x-m_border/2, m_y+m_height );
571
-            glTexCoord2f(txoffset, 0.0); glVertex2f( m_x+m_width+m_border/2, m_y+m_height );
572
-            glTexCoord2f(txoffset, 1.0); glVertex2f( m_x+m_width+m_border/2, m_y+m_height+m_border );
573
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x-m_border/2, m_y+m_height+m_border );
574
-            // straight left
575
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x-m_border, m_y-m_border/2 );
576
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x, m_y-m_border/2 );
577
-            glTexCoord2f(tyoffset, 0.0); glVertex2f( m_x, m_y+m_height+m_border/2 );
578
-            glTexCoord2f(tyoffset, 1.0); glVertex2f( m_x-m_border, m_y+m_height+m_border/2 );
579
-            // straight right
580
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x+m_width, m_y-m_border/2 );
581
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x+m_width+m_border, m_y-m_border/2 );
582
-            glTexCoord2f(tyoffset, 0.0); glVertex2f( m_x+m_width+m_border, m_y+m_height+m_border/2 );
583
-            glTexCoord2f(tyoffset, 1.0); glVertex2f( m_x+m_width, m_y+m_height+m_border/2 );
584
-            glEnd();
585
-            // top left corner
586
-            glBindTexture( GL_TEXTURE_2D, m_cornerids[0] );
587
-            glBegin( GL_QUADS );
588
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x-m_border, m_y-m_border );
589
-            glTexCoord2f(1.0, 0.0); glVertex2f( m_x, m_y-m_border );
590
-            glTexCoord2f(1.0, 1.0); glVertex2f( m_x, m_y );
591
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x-m_border, m_y );
592
-            glEnd();
593
-            // top right
594
-            glBindTexture( GL_TEXTURE_2D, m_cornerids[1] );
595
-            glBegin( GL_QUADS );
596
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x+m_width, m_y-m_border );
597
-            glTexCoord2f(1.0, 0.0); glVertex2f( m_x+m_width+m_border, m_y-m_border );
598
-            glTexCoord2f(1.0, 1.0); glVertex2f( m_x+m_width+m_border, m_y );
599
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x+m_width, m_y );
600
-            glEnd();
601
-            // bottom left
602
-            glBindTexture( GL_TEXTURE_2D, m_cornerids[2] );
603
-            glBegin( GL_QUADS );
604
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x-m_border, m_y+m_height );
605
-            glTexCoord2f(1.0, 0.0); glVertex2f( m_x, m_y+m_height );
606
-            glTexCoord2f(1.0, 1.0); glVertex2f( m_x, m_y+m_height+m_border );
607
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x-m_border, m_y+m_height+m_border );
608
-            glEnd();
609
-            // bottom right
610
-            glBindTexture( GL_TEXTURE_2D, m_cornerids[2] );
611
-            glBegin( GL_QUADS );
612
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x+m_width, m_y+m_height );
613
-            glTexCoord2f(1.0, 0.0); glVertex2f( m_x+m_width+m_border, m_y+m_height );
614
-            glTexCoord2f(1.0, 1.0); glVertex2f( m_x+m_width+m_border, m_y+m_height+m_border );
615
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x+m_width, m_y+m_height+m_border );
616
-            glEnd();
617
-        } else {
618
-            glBindTexture( GL_TEXTURE_2D, m_cornerids[0] );
619
-            glBegin( GL_QUADS );
620
-            // straight top
621
-            glTexCoord2f(0.0, 1.0); glVertex2f( m_x-m_border, m_y+m_border+m_height );
622
-            glTexCoord2f(1.0, 1.0); glVertex2f( m_x+m_width+m_border, m_y+m_border+m_height );
623
-            glTexCoord2f(1.0, 0.0); glVertex2f( m_x+m_width+m_border, m_y-m_border );
624
-            glTexCoord2f(0.0, 0.0); glVertex2f( m_x-m_border, m_y-m_border );
625
-            glEnd();
626
-        }
627
-        glDisable( GL_TEXTURE_2D );
628
-    }
629
-
630
-    m_framebuffer->unbind();
631
-
632
-    glClearColor( 0, 0, 0, 0 );
633
-    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
634
-
635
-    m_framebuffer->draw( (float) m_time, m_desktop );
636
-
637
-    if ( m_glassEnabled ) {
638
-        generateMagnifyingGlass();
639
-        findOptimalGlassPosition();
640
-
641
-        // Takes .1 second to reach the real position. Used for easing.
642
-        m_realglassx -= float(m_realglassx - (float)m_glassx) * dt * 10;
643
-        m_realglassy -= float(m_realglassy - (float)m_glassy) * dt * 10;
644
-
645
-        // Black outline...
646
-
647
-        glColor4f( 0, 0, 0, 1 );
648
-        glBegin( GL_QUADS );
649
-        glTexCoord2f(0.0, 1.0); glVertex3f( m_realglassx+m_offsetx-m_glassBorder,                               m_realglassy+(m_glassSize*m_glassPixels)+m_offseth+m_glassBorder, 0.0);
650
-        glTexCoord2f(1.0, 1.0); glVertex3f( m_realglassx+(m_glassSize*m_glassPixels)+m_offsetw+m_glassBorder,   m_realglassy+(m_glassSize*m_glassPixels)+m_offseth+1, 0.0);
651
-        glTexCoord2f(1.0, 0.0); glVertex3f( m_realglassx+(m_glassSize*m_glassPixels)+m_offsetw+m_glassBorder,   m_realglassy+m_offsety-m_glassBorder, 0.0);
652
-        glTexCoord2f(0.0, 0.0); glVertex3f( m_realglassx+m_offsetx-m_glassBorder,                               m_realglassy+m_offsety-m_glassBorder, 0.0);
653
-        glEnd();
654
-
655
-        glEnable( GL_TEXTURE_2D );
656
-        glBindTexture( GL_TEXTURE_2D, m_texid );
657
-        glColor4f( 1, 1, 1, 1 );
658
-        glBegin( GL_QUADS );
659
-        glTexCoord2f(0.0, 1.0); glVertex3f( m_realglassx+m_offsetx,                             m_realglassy+(m_glassSize*m_glassPixels)+m_offseth, 0.0);
660
-        glTexCoord2f(1.0, 1.0); glVertex3f( m_realglassx+(m_glassSize*m_glassPixels)+m_offsetw, m_realglassy+(m_glassSize*m_glassPixels)+m_offseth, 0.0);
661
-        glTexCoord2f(1.0, 0.0); glVertex3f( m_realglassx+(m_glassSize*m_glassPixels)+m_offsetw, m_realglassy+m_offsety, 0.0);
662
-        glTexCoord2f(0.0, 0.0); glVertex3f( m_realglassx+m_offsetx,                             m_realglassy+m_offsety, 0.0);
663
-        glEnd();
664
-        glDisable( GL_TEXTURE_2D );
665
-
666
-        glLogicOp(GL_INVERT);
667
-        glEnable(GL_COLOR_LOGIC_OP);
668
-        glLineWidth( 2 );
669
-        glColor4f( 0, 0, 0, 1 );
670
-        glBegin( GL_LINES );
671
-        float cx = m_realglassx+(m_glassSize*m_glassPixels)/2;
672
-        float cy = m_realglassy+(m_glassSize*m_glassPixels)/2;
673
-        glVertex3f( cx-5, cy, 0 );
674
-        glVertex3f( cx+5, cy, 0 );
675
-        glVertex3f( cx, cy-5, 0 );
676
-        glVertex3f( cx, cy+5, 0 );
677
-        glEnd();
678
-        glLogicOp(GL_NOOP);
679
-        glDisable(GL_COLOR_LOGIC_OP);
680
-    }
681
-
682
-    glXSwapBuffers( xengine->m_display, m_glxWindow );
683
-}

+ 0
- 102
src/glselectrectangle.hpp View File

@@ -1,102 +0,0 @@
1
-/* glselectrectangle.hpp: Handles creating hardware accelerated rectangles on the screen using X11 and OpenGL.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
-#ifndef IS_GL_SELECT_RECTANGLE_H_
22
-#define IS_GL_SELECT_RECTANGLE_H_
23
-
24
-#include "x.hpp"
25
-#include "selectrectangle.hpp"
26
-#include "resource.hpp"
27
-#include "framebuffer.hpp"
28
-
29
-#include <unistd.h>
30
-
31
-#include <Imlib2.h>
32
-#include <GL/gl.h>
33
-#include <GL/glx.h>
34
-#include <GL/glew.h>
35
-#include <GL/glxext.h>
36
-#include <X11/Xlib.h>
37
-#include <X11/Xatom.h>
38
-#include <X11/extensions/Xrender.h>
39
-#include <X11/Xutil.h>
40
-
41
-#include <cstdlib>
42
-#include <cmath>
43
-#include <cstdio>
44
-#include <string>
45
-#include <vector>
46
-
47
-namespace slop {
48
-
49
-class GLSelectRectangle: public SelectRectangle {
50
-public:
51
-                        GLSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a );
52
-                        ~GLSelectRectangle();
53
-    void                setGeo( int x, int y, int w, int h );
54
-    void                update( double dt );
55
-    void                generateMagnifyingGlass();
56
-    void                setMagnifySettings( bool on, float magstrength, unsigned int pixels );
57
-    void                pushIn( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh );
58
-    void                pushOut( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh );
59
-    void                findOptimalGlassPosition();
60
-    void                constrainWithinMonitor( int* x, int* y, int* w, int* h );
61
-    void                setTheme( bool on, std::string name );
62
-    void                setShader( std::string name );
63
-    float               m_r;
64
-    float               m_g;
65
-    float               m_b;
66
-    float               m_a;
67
-    GLXFBConfig         m_fbconfig;
68
-    XVisualInfo*        m_visual;
69
-    XRenderPictFormat*  m_pictFormat;
70
-    GLXContext          m_renderContext;
71
-    GLXWindow           m_glxWindow;
72
-    Colormap            m_cmap;
73
-    bool                m_themed;
74
-    unsigned int        m_texid;
75
-    unsigned int        m_cornerids[4];
76
-    unsigned int        m_straightid;
77
-    int                 m_straightwidth;
78
-    int                 m_straightheight;
79
-    int                 m_offsetx;
80
-    int                 m_offsety;
81
-    int                 m_offsetw;
82
-    int                 m_offseth;
83
-    unsigned int        m_desktop;
84
-    unsigned int        m_glassPixels;
85
-    float               m_glassSize;
86
-    int                 m_glassBorder;
87
-    float               m_realglassx;
88
-    float               m_realglassy;
89
-    int                 m_glassx;
90
-    int                 m_glassy;
91
-    bool                m_glassEnabled;
92
-    double              m_time;
93
-    std::string         m_shader;
94
-    std::vector<XRRCrtcInfo*> m_monitors;
95
-    slop::Framebuffer*  m_framebuffer;
96
-private:
97
-    unsigned int loadImage( unsigned int* texture, std::string path );
98
-};
99
-
100
-}
101
-
102
-#endif // IS_GL_SELECT_RECTANGLE_H_

+ 58
- 0
src/keyboard.cpp View File

@@ -0,0 +1,58 @@
1
+#include "keyboard.hpp"
2
+
3
+static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {
4
+}
5
+
6
+static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
7
+}
8
+
9
+static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {
10
+}
11
+
12
+static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
13
+    Keyboard* kb = (Keyboard*)data;
14
+    kb->setKey( key, state );
15
+}
16
+
17
+static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
18
+}
19
+
20
+static const struct wl_keyboard_listener keyboard_listener = {
21
+    keyboard_handle_keymap,
22
+    keyboard_handle_enter,
23
+    keyboard_handle_leave,
24
+    keyboard_handle_key,
25
+    keyboard_handle_modifiers,
26
+};
27
+
28
+Keyboard::Keyboard(Wayland* wayland) {
29
+    wl_keyboard_add_listener(wl_seat_get_keyboard(wayland->seat), &keyboard_listener, this);
30
+}
31
+
32
+void Keyboard::setKey( int key, int state ) {
33
+    for (unsigned int i=0;i<keys.size();i++ ) {
34
+        if ( keys[i].x == key ) {
35
+            keys[i].y = state;
36
+            return;
37
+        }
38
+    }
39
+    keys.push_back(glm::ivec2(key,state));
40
+}
41
+
42
+int Keyboard::getKey( int button ) {
43
+    for (unsigned int i=0;i<keys.size();i++ ) {
44
+        if ( keys[i].x == button ) {
45
+            return keys[i].y;
46
+        }
47
+    }
48
+    return 0;
49
+}
50
+
51
+bool Keyboard::anyKeyDown() {
52
+    for ( glm::ivec2 combo : keys ) {
53
+        if ( combo.y == 1 ) {
54
+            return true;
55
+        }
56
+    }
57
+    return false;
58
+}

+ 22
- 0
src/keyboard.hpp View File

@@ -0,0 +1,22 @@
1
+#ifndef N_KEYBOARD_H_
2
+#define N_KEYBOARD_H_
3
+
4
+
5
+#include <glm/glm.hpp>
6
+#include <wayland-client.h>
7
+#include <vector>
8
+#include "wayland.hpp"
9
+
10
+class Keyboard {
11
+private:
12
+    std::vector<glm::ivec2> keys;
13
+public:
14
+    Keyboard( Wayland* wayland );
15
+    void setKey( int key, int state );
16
+    int getKey( int key );
17
+    bool anyKeyDown();
18
+};
19
+
20
+extern Keyboard* keyboard;
21
+
22
+#endif // N_KEYBOARD_H_

+ 77
- 553
src/main.cpp View File

@@ -1,570 +1,94 @@
1
-/* main.cpp
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-#include <unistd.h>
21
-#include <time.h>
22
-#include <cstdio>
1
+#include <iostream>
23 2
 #include <sstream>
24
-#include <stdexcept>
3
+#include "slop.hpp"
4
+#include "options.hpp"
25 5
 
26
-#ifdef __MACH__
27
-#include <mach/clock.h>
28
-#include <mach/mach.h>
29
-#endif
30
-
31
-#include "x.hpp"
32
-#include "selectrectangle.hpp"
33
-#ifdef OPENGL_ENABLED
34
-#include "glselectrectangle.hpp"
35
-#endif //OPENGL_ENABLED
36
-#include "xselectrectangle.hpp"
37
-#include "cmdline.h"
38
-
39
-// Work around lack of clock_gettime in OSX
40
-// https://gist.github.com/jbenet/1087739
41
-void current_utc_time(struct timespec *ts) {
42
-    #ifdef __MACH__
43
-        // OS X does not have clock_gettime, use clock_get_time
44
-        clock_serv_t cclock;
45
-        mach_timespec_t mts;
46
-        host_get_clock_service( mach_host_self(), CALENDAR_CLOCK, &cclock );
47
-        clock_get_time( cclock, &mts );
48
-        mach_port_deallocate( mach_task_self(), cclock );
49
-        ts->tv_sec = mts.tv_sec;
50
-        ts->tv_nsec = mts.tv_nsec;
51
-    #else
52
-        clock_gettime( CLOCK_REALTIME, ts );
53
-    #endif
54
-}
55
-
56
-int printSelection( std::string format, bool cancelled, int x, int y, int w, int h, int window ) {
57
-    size_t pos = 0;
58
-    while ( ( pos = format.find( "%", pos ) ) != std::string::npos ) {
59
-        if ( pos + 1 > format.size() ) {
60
-            fprintf( stderr, "Format error: %% found at the end of format string.\n" );
61
-            return EXIT_FAILURE;
62
-        }
63
-        std::stringstream foo;
64
-        switch( format[ pos + 1 ] ) {
65
-            case '%':
66
-                format.replace( pos, 2, "%" );
67
-                pos += 1;
68
-                break;
69
-            case 'x':
70
-            case 'X':
71
-                foo << x;
72
-                format.replace( pos, 2, foo.str() );
73
-                break;
74
-            case 'y':
75
-            case 'Y':
76
-                foo << y;
77
-                format.replace( pos, 2, foo.str() );
78
-                break;
79
-            case 'w':
80
-            case 'W':
81
-                foo << w;
82
-                format.replace( pos, 2, foo.str() );
83
-                break;
84
-            case 'h':
85
-            case 'H':
86
-                foo << h;
87
-                format.replace( pos, 2, foo.str() );
88
-                break;
89
-            case 'g':
90
-            case 'G':
91
-                foo << w << 'x' << h << '+' << x << '+' << y;
92
-                format.replace( pos, 2, foo.str() );
93
-                break;
94
-            case 'i':
95
-            case 'I':
96
-                foo << window;
97
-                format.replace( pos, 2, foo.str() );
98
-                break;
99
-            case 'c':
100
-            case 'C':
101
-                format.replace( pos, 2, cancelled ? "true" : "false" );
102
-                break;
103
-            default:
104
-                fprintf( stderr, "Format error: %%%c is an unknown replacement identifier.\n", format[ pos + 1 ] );
105
-                fprintf( stderr, "Valid replacements: %%x, %%y, %%w, %%h, %%i, %%c, %%.\n" );
106
-                return EXIT_FAILURE;
107
-                break;
108
-        }
109
-    }
110
-    pos = 0;
111
-    while ( ( pos = format.find( "\\", pos ) ) != std::string::npos ) {
112
-        if ( pos + 1 > format.size() ) {
113
-            break;
114
-        }
115
-        if ( format[ pos + 1 ] == 'n' ) {
116
-            format.replace( pos, 2, "\n" );
117
-        }
118
-        pos = pos + 1;
119
-    }
120
-    printf( "%s", format.c_str() );
121
-    return EXIT_SUCCESS;
122
-}
123
-
124
-int parseColor( std::string arg, float* r, float* g, float* b, float* a ) {
125
-    std::string copy = arg;
126
-    int find = copy.find( "," );
127
-    while( find != (int)copy.npos ) {
128
-        copy.at( find ) = ' ';
129
-        find = copy.find( "," );
130
-    }
131
-
132
-    // Just in case we didn't include an alpha value
133
-    *a = 1;
134
-    int num = sscanf( copy.c_str(), "%f %f %f %f", r, g, b, a );
135
-    if ( num != 3 && num != 4 ) {
136
-        return EXIT_FAILURE;
137
-    }
138
-    return EXIT_SUCCESS;
6
+SlopOptions* getOptions( Options& options ) {
7
+    SlopOptions* foo = new SlopOptions();
8
+    options.getFloat("bordersize", 'b', foo->borderSize);
9
+    options.getFloat("padding", 'p', foo->padding);
10
+    glm::vec4 color = glm::vec4( foo->r, foo->g, foo->b, foo->a );
11
+    options.getColor("color", 'c', color);
12
+    foo->r = color.r;
13
+    foo->g = color.g;
14
+    foo->b = color.b;
15
+    foo->a = color.a;
16
+    options.getBool("highlight", 'h', foo->highlight);
17
+    return foo;
139 18
 }
140 19
 
141
-void constrain( int sx, int sy, int ex, int ey, int padding, int minimumsize, int maximumsize, int* rsx, int* rsy, int* rex, int* rey ) {
142
-    if ( minimumsize > maximumsize && maximumsize > 0 ) {
143
-        fprintf( stderr, "Error: minimumsize is greater than maximumsize.\n" );
144
-        exit( 1 );
145
-    }
146
-    int x = std::min( sx, ex );
147
-    int y = std::min( sy, ey );
148
-    // We add one to make sure we select the pixel under the mouse.
149
-    int w = std::max( sx, ex ) - x + 1;
150
-    int h = std::max( sy, ey ) - y + 1;
151
-    // Make sure we don't turn inside out...
152
-    if ( w + padding*2 >= 0 ) {
153
-        x -= padding;
154
-        w += padding*2;
155
-    }
156
-    if ( h + padding*2 >= 0 ) {
157
-        y -= padding;
158
-        h += padding*2;
159
-    }
160
-    if ( w < minimumsize ) {
161
-        int diff = minimumsize - w;
162
-        w = minimumsize;
163
-        x -= diff/2;
164
-    }
165
-    if ( h < minimumsize ) {
166
-        int diff = minimumsize - h;
167
-        h = minimumsize;
168
-        y -= diff/2;
169
-    }
170
-    if ( maximumsize > 0 ) {
171
-        if ( w > maximumsize ) {
172
-            int diff = w;
173
-            w = maximumsize;
174
-            x += diff/2 - maximumsize/2;
175
-        }
176
-        if ( h > maximumsize ) {
177
-            int diff = h;
178
-            h = maximumsize;
179
-            y += diff/2 - maximumsize/2;
180
-        }
181
-    }
182
-    // Center around mouse if we have a fixed size.
183
-    if ( maximumsize == minimumsize && w == maximumsize && h == maximumsize ) {
184
-        x = ex - maximumsize/2;
185
-        y = ey - maximumsize/2;
186
-    }
187
-    *rsx = x;
188
-    *rsy = y;
189
-    *rex = x + w;
190
-    *rey = y + h;
191
-}
192
-
193
-// Some complicated key detection to replicate key repeating
194
-bool keyRepeat( KeySym key, double curtime, double repeatdelay, double* time, bool* memory ) {
195
-    if ( xengine->keyPressed( key ) != *memory ) {
196
-        if ( xengine->keyPressed( key ) ) {
197
-            *memory = true;
198
-            *time = curtime;
199
-            return true;
200
-        } else {
201
-            *memory = false;
20
+std::string formatOutput( std::string input, SlopSelection selection ) {
21
+    std::stringstream output;
22
+    for( unsigned int i=0;i<input.length();i++) {
23
+        if ( input[i] == '%' ) {
24
+            if ( input.length() <= i+1 ) {
25
+                throw new std::invalid_argument( "Expected character after `%`, got END." );
26
+            }
27
+            switch( input[i+1] ) {
28
+                case 'x':
29
+                case 'X': output << round(selection.x); break;
30
+                case 'y':
31
+                case 'Y': output << round(selection.y); break;
32
+                case 'w':
33
+                case 'W': output << round(selection.w); break;
34
+                case 'h':
35
+                case 'H': output << round(selection.h); break;
36
+                case 'g':
37
+                case 'G': output << round(selection.w) << "x" << round(selection.h)
38
+                          << "+" << round(selection.x) << "+" << round(selection.y); break;
39
+                case '%': output << "%"; break;
40
+                default: throw new std::invalid_argument( std::string()+"Expected x, y, w, h, g, or % after % in format. Got `" + input[i+1] + "`." );
41
+             }
42
+            i++;
43
+            continue;
202 44
         }
45
+        output << input[i];
203 46
     }
204
-    if ( xengine->keyPressed( key ) && curtime - *time > repeatdelay ) {
205
-        return true;
206
-    }
207
-    return false;
47
+    return output.str();
208 48
 }
209 49
 
210 50
 int app( int argc, char** argv ) {
211
-    gengetopt_args_info options;
212
-    int err = cmdline_parser( argc, argv, &options );
213
-    if ( err != EXIT_SUCCESS ) {
214
-        return EXIT_FAILURE;
215
-    }
216
-    int state = 0;
217
-    bool running = true;
218
-    bool opengl = options.opengl_flag;
219
-    slop::SelectRectangle* selection = NULL;
220
-    Window window = None;
221
-    Window windowmemory = None;
222
-    std::string xdisplay;
223
-    if ( options.xdisplay_given ) {
224
-        xdisplay = options.xdisplay_arg;
225
-    } else {
226
-        // If we weren't specifically given a xdisplay, we try
227
-        // to parse it from environment variables
228
-        char* display = getenv( "DISPLAY" );
229
-        if ( display ) {
230
-            xdisplay = display;
231
-        } else {
232
-            fprintf( stderr, "Warning: Failed to parse environment variable: DISPLAY. Using \":0\" instead.\n" );
233
-            xdisplay = ":0";
234
-        }
235
-    }
236
-    int padding = options.padding_arg;
237
-    int borderSize = options.bordersize_arg;
238
-    int tolerance = options.tolerance_arg;
239
-    float r, g, b, a;
240
-    err = parseColor( options.color_arg, &r, &g, &b, &a );
241
-    if ( err != EXIT_SUCCESS ) {
242
-        fprintf( stderr, "Error parsing color %s\n", options.color_arg );
243
-        return EXIT_FAILURE;
244
-    }
245
-    float gracetime;
246
-    err = sscanf( options.gracetime_arg, "%f", &gracetime );
247
-    if ( err != 1 ) {
248
-        fprintf( stderr, "Error parsing %s as a float for gracetime!\n", options.gracetime_arg );
249
-        return EXIT_FAILURE;
250
-    }
251
-    bool highlight = options.highlight_flag;
252
-    bool keyboard = !options.nokeyboard_flag;
253
-    bool decorations = !options.nodecorations_flag;
254
-    bool themeon = (bool)options.theme_given;
255
-    std::string theme = options.theme_arg;
256
-#ifdef OPENGL_ENABLED
257
-    bool shadergiven = (bool)options.shader_given;
258
-#endif
259
-    std::string shader = options.shader_arg;
260
-    struct timespec start, time;
261
-    int xoffset = 0;
262
-    int yoffset = 0;
263
-    int cx = 0;
264
-    int cy = 0;
265
-    int xmem = 0;
266
-    int ymem = 0;
267
-    int wmem = 0;
268
-    int hmem = 0;
269
-    int minimumsize = options.min_arg;
270
-    int maximumsize = options.max_arg;
271
-    bool pressedMemory[4];
272
-    double pressedTime[4];
273
-    for ( int i=0;i<4;i++ ) {
274
-        pressedMemory[ i ] = false;
275
-        pressedTime[ i ] = 0;
276
-    }
277
-    std::string format = options.format_arg;
278
-    bool magenabled = options.magnify_flag;
279
-#ifdef OPENGL_ENABLED
280
-    float magstrength = options.magstrength_arg;
281
-    if ( options.magpixels_arg < 0 ) {
282
-        fprintf( stderr, "Error: --magpixels < 0, it's an unsigned integer you twat. Stop trying to underflow me!\n" );
283
-        return EXIT_FAILURE;
284
-    }
285
-    unsigned int magpixels = (unsigned int)options.magpixels_arg;
286
-#endif
287
-    cmdline_parser_free( &options );
288
-#ifndef OPENGL_ENABLED
289
-    if ( opengl || themeon || magenabled ) {
290
-        throw std::runtime_error( "Slop wasn't compiled with OpenGL support, so themes, magnifications, and shaders are disabled! Try compiling it with the CMAKE_OPENGL_SUPPORT set to true." );
291
-    }
292
-#else // OPENGL_ENABLED
293
-    if ( ( themeon || magenabled || shadergiven ) && !opengl ) {
294
-        throw std::runtime_error( "Slop needs --opengl enabled to use themes, shaders, or magnifications." );
295
-    }
296
-#endif
51
+    // Options just validates all of our input from argv
52
+    Options options( argc, argv );
53
+    // We then parse the options into something slop can understand.
54
+    SlopOptions* parsedOptions = getOptions( options );
297 55
 
298
-    // First we set up the x interface and grab the mouse,
299
-    // if we fail for either we exit immediately.
300
-    err = xengine->init( xdisplay.c_str() );
301
-    if ( err != EXIT_SUCCESS ) {
302
-        printSelection( format, true, 0, 0, 0, 0, None );
303
-        return EXIT_FAILURE;
56
+    // We want to validate our format option if we got one, we do that by just doing a dry run
57
+    // on a fake selection.
58
+    SlopSelection selection(0,0,0,0);
59
+    std::string format;
60
+    bool gotFormat = options.getString("format", 'f', format);
61
+    if ( gotFormat ) {
62
+        formatOutput( format, selection );
304 63
     }
305
-    if ( !slop::isSelectRectangleSupported() ) {
306
-        fprintf( stderr, "Error: Your X server doesn't support the XShape extension. There's nothing slop can do about this!\n" );
307
-        fprintf( stderr, "  Try updating X and making sure you have XExtensions installed. (/usr/lib/libXext.so, /usr/include/X11/extensions/shape.h)\n" );
308
-        return EXIT_FAILURE;
309
-    }
310
-    err = xengine->grabCursor( slop::Cross, gracetime );
311
-    if ( err != EXIT_SUCCESS ) {
312
-        printSelection( format, true, 0, 0, 0, 0, None );
313
-        return EXIT_FAILURE;
314
-    }
315
-    if ( keyboard ) {
316
-        err = xengine->grabKeyboard();
317
-        if ( err ) {
318
-            fprintf( stderr, "Warning: Failed to grab the keyboard. This is non-fatal, keyboard presses might fall through to other applications.\n" );
319
-        }
320
-    }
321
-    current_utc_time( &start );
322
-    double deltatime = 0;
323
-    double curtime = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
324
-    while ( running ) {
325
-        current_utc_time( &time );
326
-        // "ticking" the xengine makes it process all queued events.
327
-        xengine->tick();
328
-        // If the user presses any key on the keyboard, exit the application.
329
-        // Make sure at least gracetime has passed before allowing canceling
330
-        double newtime = double( time.tv_sec*1000000000L + time.tv_nsec )/1000000000.f;
331
-        deltatime = newtime-curtime;
332
-        curtime = newtime;
333
-        double starttime = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
334
-        if ( curtime - starttime > gracetime ) {
335
-            if ( keyRepeat( XK_Up, curtime, 0.5, &pressedTime[ 0 ], &pressedMemory[ 0 ] ) ) {
336
-                yoffset -= 1;
337
-            }
338
-            if ( keyRepeat( XK_Down, curtime, 0.5, &pressedTime[ 1 ], &pressedMemory[ 1 ] ) ) {
339
-                yoffset += 1;
340
-            }
341
-            if ( keyRepeat( XK_Left, curtime, 0.5, &pressedTime[ 2 ], &pressedMemory[ 2 ] ) ) {
342
-                xoffset -= 1;
343
-            }
344
-            if ( keyRepeat( XK_Right, curtime, 0.5, &pressedTime[ 3 ], &pressedMemory[ 3 ] ) ) {
345
-                xoffset += 1;
346
-            }
347
-            // If we pressed enter we move the state onward.
348
-            if ( xengine->keyPressed( XK_Return ) ) {
349
-                // If we're highlight windows, just select the active window.
350
-                if ( state == 0 ) {
351
-                    state = 1;
352
-                // If we're making a custom selection, select the custom selection.
353
-                } else if ( state == 2 ) {
354
-                    state = 3;
355
-                }
356
-            }
357
-            // If we press any key other than the arrow keys or enter key, we shut down!
358
-            if ( !( xengine->keyPressed( XK_Up ) || xengine->keyPressed( XK_Down ) || xengine->keyPressed( XK_Left ) || xengine->keyPressed( XK_Right ) ) &&
359
-                !( xengine->keyPressed( XK_Return ) ) &&
360
-                ( ( xengine->anyKeyPressed() && keyboard ) || xengine->mouseDown( 3 ) ) ) {
361
-                printSelection( format, true, 0, 0, 0, 0, None );
362
-                fprintf( stderr, "User pressed key. Canceled selection.\n" );
363
-                state = -1;
364
-                running = false;
365
-            }
366
-        }
367
-        // Our adorable little state manager will handle what state we're in.
368
-        switch ( state ) {
369
-            default: {
370
-                break;
371
-            }
372
-            case 0: {
373
-                // If xengine has found a window we're hovering over (or if it changed)
374
-                // create a rectangle around it so the user knows he/she can click on it.
375
-                // --but only if the user wants us to
376
-                if ( window != xengine->m_hoverWindow && tolerance > 0 ) {
377
-                    slop::WindowRectangle t;
378
-                    t.setGeometry( xengine->m_hoverWindow, decorations );
379
-                    t.applyPadding( padding );
380
-                    t.applyMinMaxSize( minimumsize, maximumsize );
381
-                    // Make sure we only apply offsets to windows that we've forcibly removed decorations on.
382
-                    if ( !selection ) {
383
-#ifdef OPENGL_ENABLED
384
-                        if ( opengl ) {
385
-                            selection = new slop::GLSelectRectangle( t.m_x, t.m_y,
386
-                                                                     t.m_x + t.m_width,
387
-                                                                     t.m_y + t.m_height,
388
-                                                                     borderSize,
389
-                                                                     highlight,
390
-                                                                     r, g, b, a );
391
-                            // Haha why is this so hard to cast?
392
-                            ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
393
-                            ((slop::GLSelectRectangle*)(selection))->setTheme( themeon, theme );
394
-                            ((slop::GLSelectRectangle*)(selection))->setShader( shader );
395
-                        } else {
396
-#endif // OPENGL_ENABLED
397
-                            selection = new slop::XSelectRectangle( t.m_x, t.m_y,
398
-                                                                    t.m_x + t.m_width,
399
-                                                                    t.m_y + t.m_height,
400
-                                                                    borderSize,
401
-                                                                    highlight,
402
-                                                                    r, g, b, a );
403
-#ifdef OPENGL_ENABLED
404
-                        }
405
-#endif // OPENGL_ENABLED
406
-                    } else {
407
-                        selection->setGeo( t.m_x, t.m_y, t.m_x + t.m_width, t.m_y + t.m_height );
408
-                    }
409
-                    //window = xengine->m_hoverWindow;
410
-                    // Since WindowRectangle can select different windows depending on click location...
411
-                    window = t.getWindow();
412
-                }
413
-                if ( selection ) {
414
-                    selection->update( deltatime );
415
-                }
416
-                // If the user clicked we move on to the next state.
417
-                if ( xengine->mouseDown( 1 ) ) {
418
-                    state++;
419
-                }
420
-                break;
421
-            }
422
-            case 1: {
423
-                // Set the mouse position of where we clicked, used so that click tolerance doesn't affect the rectangle's position.
424
-                cx = xengine->m_mousex;
425
-                cy = xengine->m_mousey;
426
-                // Make sure we don't have un-seen applied offsets.
427
-                xoffset = 0;
428
-                yoffset = 0;
429
-                // Also remember where the original selection was
430
-                if ( selection ) {
431
-                    xmem = selection->m_x;
432
-                    ymem = selection->m_y;
433
-                    wmem = selection->m_width;
434
-                    hmem = selection->m_height;
435
-                } else {
436
-                    xmem = cx;
437
-                    ymem = cy;
438
-                }
439
-                state++;
440
-                break;
441
-            }
442
-            case 2: {
443
-                // It's possible that our selection doesn't exist still, lets make sure it actually gets created here.
444
-                if ( !selection ) {
445
-                    int sx, sy, ex, ey;
446
-                    constrain( cx, cy, xengine->m_mousex, xengine->m_mousey, padding, minimumsize, maximumsize, &sx, &sy, &ex, &ey );
447
-#ifdef OPENGL_ENABLED
448
-                    if ( opengl ) {
449
-                        selection = new slop::GLSelectRectangle( sx, sy,
450
-                                                                 ex, ey,
451
-                                                                 borderSize,
452
-                                                                 highlight,
453
-                                                                 r, g, b, a );
454
-                        // Haha why is this so hard to cast?
455
-                        ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
456
-                        ((slop::GLSelectRectangle*)(selection))->setTheme( themeon, theme );
457
-                        ((slop::GLSelectRectangle*)(selection))->setShader( shader );
458
-                    } else {
459
-#endif // OPENGL_ENABLED
460
-                        selection = new slop::XSelectRectangle( sx, sy,
461
-                                                                ex, ey,
462
-                                                                borderSize,
463
-                                                                highlight,
464
-                                                                r, g, b, a );
465
-#ifdef OPENGL_ENABLED
466
-                    }
467
-#endif // OPENGL_ENABLED
468
-                }
469
-                windowmemory = window;
470
-                // If the user has let go of the mouse button, we'll just
471
-                // continue to the next state.
472
-                if ( !xengine->mouseDown( 1 ) ) {
473
-                    state++;
474
-                    break;
475
-                }
476
-                // Check to make sure the user actually wants to drag for a selection before moving things around.
477
-                int w = xengine->m_mousex - cx;
478
-                int h = xengine->m_mousey - cy;
479
-                if ( ( std::abs( w ) < tolerance && std::abs( h ) < tolerance ) ) {
480
-                    // We make sure the selection rectangle stays on the window we had selected
481
-                    selection->setGeo( xmem, ymem, xmem + wmem, ymem + hmem );
482
-                    selection->update( deltatime );
483
-                    xengine->setCursor( slop::Left );
484
-                    // Make sure
485
-                    window = windowmemory;
486
-                    continue;
487
-                }
488
-                // If we're not selecting a window.
489
-                windowmemory = window;
490
-                window = None;
491
-                // We also detect which way the user is pulling and set the mouse icon accordingly.
492
-                bool x = cx > xengine->m_mousex;
493
-                bool y = cy > xengine->m_mousey;
494
-                if ( ( selection->m_width <= 1 && selection->m_height <= 1 ) || ( minimumsize == maximumsize && minimumsize != 0 && maximumsize != 0 ) ) {
495
-                    xengine->setCursor( slop::Cross );
496
-                } else if ( !x && !y ) {
497
-                    xengine->setCursor( slop::LowerRightCorner );
498
-                } else if ( x && !y ) {
499
-                    xengine->setCursor( slop::LowerLeftCorner );
500
-                } else if ( !x && y ) {
501
-                    xengine->setCursor( slop::UpperRightCorner );
502
-                } else if ( x && y ) {
503
-                    xengine->setCursor( slop::UpperLeftCorner );
504
-                }
505
-                // Apply padding and minimum size adjustments.
506
-                int sx, sy, ex, ey;
507
-                constrain( cx, cy, xengine->m_mousex, xengine->m_mousey, padding, minimumsize, maximumsize, &sx, &sy, &ex, &ey );
508
-                // Set the selection rectangle's dimensions to mouse movement.
509
-                selection->setGeo( sx + xoffset, sy + yoffset, ex, ey );
510
-                selection->update( deltatime );
511
-                break;
512
-            }
513
-            case 3: {
514
-                int x, y, w, h;
515
-                // Exit the utility after this state runs once.
516
-                running = false;
517
-                // We pull the dimensions and positions from the selection rectangle.
518
-                // The selection rectangle automatically converts the positions and
519
-                // dimensions to absolute coordinates when we set them earilier.
520
-                x = selection->m_x;
521
-                y = selection->m_y;
522
-                w = selection->m_width;
523
-                h = selection->m_height;
524
-                // Delete the rectangle, which will remove it from the screen.
525
-                delete selection;
526
-                // Make sure if no window was specifically specified, that we output the root window.
527
-                Window temp = window;
528
-                if ( temp == None ) {
529
-                    temp = xengine->m_root;
530
-                }
531
-                // Print the selection :)
532
-                printSelection( format, false, x, y, w, h, temp );
533
-                break;
534
-            }
535
-        }
536
-        // This sleep is required because drawing the rectangles is a very expensive task that acts really weird with Xorg when called as fast as possible.
537
-        // 0.01 seconds
538
-        usleep( 10000 );
539
-    }
540
-    xengine->releaseCursor();
541
-    xengine->releaseKeyboard();
542
-    // Try to process any last-second requests.
543
-    //xengine->tick();
544
-    // Clean up global classes.
545
-    delete xengine;
546
-    // Sleep for 0.05 seconds to ensure everything was cleaned up. (Without this, slop's window often shows up in screenshots.)
547
-    usleep( 50000 );
548
-    // If we canceled the selection, return error.
549
-    if ( state == -1 ) {
550
-        return EXIT_FAILURE;
551
-    }
552
-    return EXIT_SUCCESS;
64
+
65
+    // Finally we do the real selection.
66
+    bool cancelled = false;
67
+    selection = SlopSelect(parsedOptions, &cancelled);
68
+    
69
+    // Here we're done with the parsed option data.
70
+    delete parsedOptions;
71
+    // We know if we cancelled or not
72
+    if ( cancelled ) {
73
+        std::cerr << "Selection was cancelled by keystroke or right-click.\n";
74
+        return 1;
75
+    }
76
+    // If we recieved a format option, we output the specified output.
77
+    if ( gotFormat ) {
78
+        std::cout << formatOutput( format, selection );
79
+        return 0;
80
+    }
81
+    // Otherwise we default to an `eval` compatible format.
82
+    std::cout << formatOutput( "X=%x\nY=%y\nW=%w\nH=%h\nG=%g\n", selection );
83
+    return 0;
553 84
 }
554 85
 
555 86
 int main( int argc, char** argv ) {
556 87
     try {
557 88
         return app( argc, argv );
558
-    } catch( std::bad_alloc const& exception ) {
559
-        fprintf( stderr, "Couldn't allocate enough memory! No space left in RAM." );
560
-    } catch( std::exception const& exception ) {
561
-        fprintf( stderr, "Unhandled Exception Thrown: %s\n", exception.what() );
562
-    } catch( std::string err ) {
563
-        fprintf( stderr, "Unhandled Exception Thrown: %s\n", err.c_str() );
564
-    } catch( char* err ) {
565
-        fprintf( stderr, "Unhandled Exception Thrown: %s\n", err );
566
-    } catch( ... ) {
567
-        fprintf( stderr, "Unknown Exception Thrown!\n" );
568
-    }
569
-    return EXIT_FAILURE;
89
+    } catch( std::exception* e ) {
90
+        std::cerr << "Slop encountered an error:\n" << e->what() << "\n";
91
+        return 1;
92
+    } // let the operating system handle any other kind of exception.
93
+    return 1;
570 94
 }

+ 111
- 0
src/mouse.cpp View File

@@ -0,0 +1,111 @@
1
+#include "mouse.hpp"
2
+
3
+static void pointer_handle_enter(void *data, struct wl_pointer *pointer,
4
+		                         uint32_t serial, struct wl_surface *surface,
5
+		                         wl_fixed_t sx_w, wl_fixed_t sy_w) {
6
+    Mouse* m = (Mouse*)data;
7
+	float sx = wl_fixed_to_double(sx_w);
8
+	float sy = wl_fixed_to_double(sy_w);
9
+    m->setMousePos( sx, sy );
10
+    m->serial = serial;
11
+    m->pointer = pointer;
12
+    struct wl_cursor_image *image = m->cursor->images[0];
13
+    wl_pointer_set_cursor(pointer, serial, m->surface, image->hotspot_x, image->hotspot_y);
14
+}
15
+
16
+static void pointer_handle_leave(void *data, struct wl_pointer *pointer,
17
+		                         uint32_t serial, struct wl_surface *surface) {
18
+}
19
+
20
+static void pointer_handle_motion(void *data, struct wl_pointer *pointer,
21
+		                          uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
22
+{
23
+    Mouse* m = (Mouse*)data;
24
+	float sx = wl_fixed_to_double(sx_w);
25
+	float sy = wl_fixed_to_double(sy_w);
26
+    m->pointer = pointer;
27
+    m->setMousePos( sx, sy );
28
+}
29
+
30
+static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
31
+                                  uint32_t time, uint32_t button, uint32_t state_w) {
32
+    Mouse* m = (Mouse*)data;
33
+    m->pointer = pointer;
34
+    m->setButton( button, state_w );
35
+}
36
+
37
+static void pointer_handle_axis(void *data, struct wl_pointer *pointer,
38
+		                        uint32_t time, uint32_t axis, wl_fixed_t value) {
39
+}
40
+
41
+static const struct wl_pointer_listener pointer_listener = {
42
+	pointer_handle_enter,
43
+	pointer_handle_leave,
44
+	pointer_handle_motion,
45
+	pointer_handle_button,
46
+	pointer_handle_axis,
47
+};
48
+
49
+void Mouse::setButton( int button, int state ) {
50
+    for (unsigned int i=0;i<buttons.size();i++ ) {
51
+        if ( buttons[i].x == button ) {
52
+            buttons[i].y = state;
53
+            return;
54
+        }
55
+    }
56
+    buttons.push_back(glm::ivec2(button,state));
57
+}
58
+
59
+int Mouse::getButton( int button ) {
60
+    for (unsigned int i=0;i<buttons.size();i++ ) {
61
+        if ( buttons[i].x == button ) {
62
+            return buttons[i].y;
63
+        }
64
+    }
65
+    return 0;
66
+}
67
+
68
+void Mouse::setMousePos(float x, float y) {
69
+    this->x = x;
70
+    this->y = y;
71
+}
72
+
73
+glm::vec2 Mouse::getMousePos() {
74
+    return glm::vec2( x, y );
75
+}
76
+
77
+void Mouse::setCursor( std::string name ) {
78
+    if ( name == currentMouseCursor ) {
79
+        return;
80
+    }
81
+    // First we gotta delete the old mouse surface.
82
+    wl_surface_destroy( surface );
83
+
84
+    // Then we get the new cursor image.
85
+    cursor = wl_cursor_theme_get_cursor(theme, name.c_str());
86
+    struct wl_cursor_image *image = cursor->images[0];
87
+    struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image);
88
+    
89
+    // Then we create the new surface
90
+    surface = wl_compositor_create_surface(wayland->compositor);
91
+    wl_surface_attach(surface, cursor_buf, 0, 0);
92
+    wl_surface_damage(surface, 0, 0, image->width, image->height);
93
+    wl_surface_commit(surface);
94
+
95
+    // Finally assign the surface as a pointer
96
+    wl_pointer_set_cursor(pointer, serial, surface, image->hotspot_x, image->hotspot_y);
97
+}
98
+
99
+Mouse::Mouse(Wayland* wayland) {
100
+    wl_pointer_add_listener(wl_seat_get_pointer(wayland->seat), &pointer_listener, this);
101
+    theme = wl_cursor_theme_load("default", 16, wayland->shm );
102
+    cursor = wl_cursor_theme_get_cursor(theme, "cross");
103
+    std::string currentMouseCursor = "cross";
104
+
105
+    surface = wl_compositor_create_surface(wayland->compositor);
106
+    struct wl_cursor_image *image = cursor->images[0];
107
+    struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image);
108
+    wl_surface_attach(surface, cursor_buf, 0, 0);
109
+    wl_surface_damage(surface, 0, 0, image->width, image->height);
110
+    wl_surface_commit(surface);
111
+}

+ 32
- 0
src/mouse.hpp View File

@@ -0,0 +1,32 @@
1
+#ifndef N_MOUSE_H_
2
+#define N_MOUSE_H_
3
+
4
+#include <wayland-client.h>
5
+#include <wayland-cursor.h>
6
+#include <vector>
7
+#include <glm/glm.hpp>
8
+#include "linux/input-event-codes.h"
9
+#include "wayland.hpp"
10
+
11
+class Mouse {
12
+private:
13
+    wl_cursor_theme* theme;
14
+    float x,y;
15
+    std::vector<glm::ivec2> buttons;
16
+    std::string currentMouseCursor;
17
+public:
18
+    wl_surface* surface;
19
+    wl_cursor* cursor;
20
+    wl_pointer* pointer;
21
+    int serial;
22
+    Mouse( Wayland* wayland );
23
+    void setMousePos( float x, float y );
24
+    void setCursor( std::string name );
25
+    glm::vec2 getMousePos();
26
+    void setButton( int button, int state );
27
+    int getButton( int button );
28
+};
29
+
30
+extern Mouse* mouse;
31
+
32
+#endif // N_MOUSE_H_

+ 199
- 0
src/options.cpp View File

@@ -0,0 +1,199 @@
1
+#include "options.hpp"
2
+
3
+int Options::validateStringOption( int argc, char** argv, int argumentIndex ) {
4
+    std::string argument = argv[argumentIndex];
5
+    unsigned int index = 0;
6
+    while( index < validArgumentCount ) {
7
+        std::string& check = validStringArguments[index];
8
+        for( unsigned int i=0;i<check.length();i++ ) {
9
+            if ( check[i] != argument[i+2] ) {
10
+                break;
11
+            }
12
+            if ( i == check.length()-1 ) {
13
+                if ( !isFlagArgument[index] && argument.find("=") == std::string::npos ) {
14
+                    throw new std::invalid_argument("Expected `=` after " + arguments[i]);
15
+                }
16
+                if ( argument[i+3] != '=' ) {
17
+                    break;
18
+                }
19
+                return parseStringOption( argc, argv, argumentIndex, index );
20
+            }
21
+        }
22
+        index++;
23
+    }
24
+    throw new std::invalid_argument("Invalid argument " + argument);
25
+    return 0;
26
+}
27
+
28
+int Options::parseCharOption( int argc, char** argv, int argumentIndex, int validIndex ) {
29
+    std::string argument = argv[argumentIndex];
30
+    // If we're a flag, we take no arguments, nor do we allow = signs or whatever.
31
+    if ( isFlagArgument[validIndex] ) {
32
+        if ( argument != std::string()+"-"+validCharArguments[validIndex] ) {
33
+            throw new std::invalid_argument( std::string()+"Unexpected characters around flag `" + argument + "`." );
34
+            return 0;
35
+        } else {
36
+            arguments.push_back( std::string()+argument[1] );
37
+            values.push_back("");
38
+            return 1;
39
+        }
40
+    }
41
+    arguments.push_back( std::string()+argument[1] );
42
+    // If they supplied the parameters with spaces
43
+    if ( argument == std::string()+"-"+validCharArguments[validIndex] ) {
44
+        values.push_back(argv[argumentIndex+1]);
45
+        return 2;
46
+    }
47
+    // If they didn't supply the parameters with spaces
48
+    if ( argument[2] == '=' ) {
49
+        values.push_back(argument.substr(3));
50
+        return 1;
51
+    }
52
+    values.push_back(argument.substr(2));
53
+    return 1;
54
+}
55
+
56
+int Options::parseStringOption( int argc, char** argv, int argumentIndex, int validIndex ) {
57
+    std::string argument = argv[argumentIndex];
58
+    if ( isFlagArgument[validIndex] ) {
59
+        arguments.push_back( argument.substr(2) );
60
+        values.push_back("");
61
+        return 1;
62
+    }
63
+    arguments.push_back( argument.substr(2,argument.find_first_of('=')) );
64
+    values.push_back(argument.substr(argument.find_first_of('=')));
65
+    return 1;
66
+}
67
+
68
+int Options::validateCharOption( int argc, char** argv, int argumentIndex ) {
69
+    std::string argument = argv[argumentIndex];
70
+    unsigned int index = 0;
71
+    while( index < validArgumentCount ) {
72
+        char check = validCharArguments[index];
73
+        if ( argument.length() < 2 ) {
74
+            continue;
75
+        }
76
+        if ( check == argument[1] && ( argument.find("=") == 2 || argument.find('=') == std::string::npos ) && argument[0] == '-' ) {
77
+            return parseCharOption( argc, argv, argumentIndex, index );
78
+        }
79
+        index++;
80
+    }
81
+    throw new std::invalid_argument("Invalid argument `" + argument + "`.");
82
+    return 0;
83
+}
84
+
85
+void Options::validate( int argc, char** argv ) {
86
+    for ( int i=1;i<argc;) {
87
+        std::string argument = argv[i];
88
+        if ( argument[0] != '-' ) {
89
+            floatingValues.push_back( argument );
90
+            if ( floatingValues.size() > maxFloatingValues ) {
91
+                throw new std::invalid_argument("Unexpected floating value `" + argument + "`. Forget to specify an option?" );
92
+            }
93
+        }
94
+        if ( argument[0] == '-' && argument[1] == '-' ) {
95
+            i += validateStringOption( argc, argv, i );
96
+            continue;
97
+        }
98
+        i += validateCharOption( argc, argv, i );
99
+    }
100
+}
101
+
102
+Options::Options( int argc, char** argv ) {
103
+    validate( argc, argv );
104
+}
105
+
106
+bool Options::getFloat( std::string name, char namec, float& found ) {
107
+    for( unsigned int i=0;i<arguments.size();i++ ) {
108
+        if ( arguments[i] == name || arguments[i] == std::string("")+namec ) {
109
+            std::string::size_type sz;
110
+            float retvar;
111
+            try {
112
+                retvar = std::stof(values[i],&sz);
113
+            } catch ( ... ) {
114
+                throw new std::invalid_argument("Unable to parse `" + arguments[i] + "`'s value `" + values[i] + "` as a float.");
115
+            }
116
+            if ( sz != values[i].length() ) {
117
+                throw new std::invalid_argument("Unable to parse `" + arguments[i] + "`'s value `" + values[i] + "` as a float.");
118
+            }
119
+            found = retvar;
120
+            return true;
121
+        }
122
+    }
123
+    return false;
124
+}
125
+
126
+bool Options::getInt( std::string name, char namec, int& found ) {
127
+    for( unsigned int i=0;i<arguments.size();i++ ) {
128
+        if ( arguments[i] == name || arguments[i] == std::string("")+namec ) {
129
+            if ( arguments[i].size() > 1 && arguments[i].find("=") == std::string::npos ) {
130
+                throw new std::invalid_argument("Expected `=` after " + arguments[i]);
131
+            }
132
+            std::string::size_type sz;
133
+            float retvar;
134
+            try {
135
+                retvar = std::stoi(values[i],&sz);
136
+            } catch ( ... ) {
137
+                throw new std::invalid_argument("Unable to parse " + arguments[i] + "'s value " + values[i] + " as an integer.");
138
+            }
139
+            if ( sz != values[i].length() ) {
140
+                throw new std::invalid_argument("Unable to parse " + arguments[i] + "'s value " + values[i] + " as an integer.");
141
+            }
142
+            found = retvar;
143
+            return true;
144
+        }
145
+    }
146
+    return false;
147
+}
148
+
149
+bool Options::getString( std::string name, char namec, std::string& found ) {
150
+    for( unsigned int i=0;i<arguments.size();i++ ) {
151
+        if ( arguments[i] == name || arguments[i] == std::string("")+namec ) {
152
+            found = values[i];
153
+            return true;
154
+        }
155
+    }
156
+    return false;
157
+}
158
+
159
+bool Options::getColor( std::string name, char namec, glm::vec4& found ) {
160
+    for( unsigned int i=0;i<arguments.size();i++ ) {
161
+        if ( arguments[i] == name || arguments[i] == std::string("")+namec ) {
162
+            std::string::size_type sz;
163
+            std::string value = values[i];
164
+            try {
165
+                found[0] = std::stof(value,&sz);
166
+                value = value.substr(sz+1);
167
+                found[1] = std::stof(value,&sz);
168
+                value = value.substr(sz+1);
169
+                found[2] = std::stof(value,&sz);
170
+                if ( value.size() != sz ) {
171
+                    value = value.substr(sz+1);
172
+                    found[3] = std::stof(value,&sz);
173
+                    if ( value.size() != sz ) {
174
+                        throw "dur";
175
+                    }
176
+                } else {
177
+                    found[3] = 1;
178
+                }
179
+            } catch ( ... ) {
180
+                throw new std::invalid_argument("Unable to parse `" + arguments[i] + "`'s value `" + values[i] + "` as a color. Should be in the format r,g,b or r,g,b,a. Like 1,1,1,1.");
181
+            }
182
+            return true;
183
+        }
184
+    }
185
+    return false;
186
+}
187
+
188
+bool Options::getBool( std::string name, char namec, bool& found ) {
189
+    for( unsigned int i=0;i<arguments.size();i++ ) {
190
+        if ( arguments[i] == name || arguments[i] == std::string("")+namec ) {
191
+            if ( values[i] != "" ) {
192
+                throw new std::invalid_argument("Unexpected value `" + values[i] + "` for flag argument `" + arguments[i] + "`.");
193
+            }
194
+            found = true;
195
+            return true;
196
+        }
197
+    }
198
+    return false;
199
+}

+ 0
- 125
src/options.ggo View File

@@ -1,125 +0,0 @@
1
-package "slop"
2
-version "v@slop_VERSION_MAJOR@.@slop_VERSION_MINOR@.@slop_VERSION_PATCH@"
3
-usage "slop [options]"
4
-description "slop (Select Operation) is an application that queries for a selection from the user and prints the region to stdout."
5
-versiontext "Copyright (C) 2014 Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors)"
6
-
7
-text "Options"
8
-
9
-option "xdisplay" - "Sets the x display."
10
-    string
11
-    typestr="hostname:number.screen_number"
12
-    optional
13
-
14
-option "nokeyboard" - "Disables the ability to cancel selections with the keyboard."
15
-    flag
16
-    off
17
-
18
-option "bordersize" b "Set the selection rectangle's thickness. Does nothing when --highlight is enabled."
19
-    int
20
-    default="5"
21
-    optional
22
-
23
-option "padding" p "Set the padding size of the selection. Can be negative."
24
-    int
25
-    default="0"
26
-    optional
27
-
28
-option "tolerance" t "How far in pixels the mouse can move after clicking and still be detected as a normal click instead of a click and drag. Setting this to 0 will disable window selections."
29
-    int
30
-    default="2"
31
-    optional
32
-
33
-option "gracetime" g "Set the amount of time before slop will check for keyboard cancellations in seconds."
34
-    string
35
-    typestr="FLOAT"
36
-    default="0.4"
37
-    optional
38
-
39
-option "color" c "Set the selection rectangle's color. Supports RGB or RGBA values."
40
-    string
41
-    typestr="FLOAT,FLOAT,FLOAT,FLOAT"
42
-    default="0.5,0.5,0.5,1"
43
-    optional
44
-
45
-option "nodecorations" n "Attempt to select child windows in order to avoid window decorations."
46
-    flag
47
-    off
48
-
49
-option "min" - "Set the minimum output of width or height values. This is useful to avoid outputting 0. Setting min and max to the same value disables drag selections."
50
-    int
51
-    default="0"
52
-    optional
53
-
54
-option "max" - "Set the maximum output of width or height values. Setting min and max to the same value disables drag selections."
55
-    int
56
-    default="0"
57
-    optional
58
-
59
-option "highlight" l "Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color."
60
-    flag
61
-    off
62
-
63
-option "opengl" - "Enable hardware acceleration. Only works with modern systems that are also running a compositor."
64
-    flag
65
-    off
66
-
67
-option "magnify" - "Display a magnifying glass when --opengl is also enabled."
68
-    flag
69
-    off
70
-
71
-option "magstrength" - "Sets how many times the magnification window size is multiplied."
72
-    float
73
-    default="4"
74
-    optional
75
-
76
-option "magpixels" - "Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification."
77
-    int
78
-    default="64"
79
-    optional
80
-
81
-option "theme" - "Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/."
82
-    string
83
-    default="none"
84
-    optional
85
-
86
-option "shader" - "Sets the shader to load and use from ~/.config/slop/ or /usr/share/."
87
-    string
88
-    default="simple"
89
-    optional
90
-
91
-option "format" f "Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c."
92
-    string
93
-    default="REPLACEME"
94
-    optional
95
-
96
-text "\nExamples\n"
97
-text "    $ # Gray, thick, transparent border for maximum visiblity.\n"
98
-text "    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n"
99
-text "\n"
100
-text "    $ # Remove window decorations.\n"
101
-text "    $ slop --nodecorations\n"
102
-text "\n"
103
-text "    $ # Disable window selections. Useful for selecting individual pixels.\n"
104
-text "    $ slop -t 0\n"
105
-text "\n"
106
-text "    $ # Classic Windows XP selection.\n"
107
-text "    $ slop -l -c 0.3,0.4,0.6,0.4\n"
108
-text "\n"
109
-text "    $ # Wiggle wiggle!\n"
110
-text "    $ slop --opengl --shader wiggle\n"
111
-text "\n"
112
-text "    $ # Edgy textures or something.\n"
113
-text "    $ slop --opengl --theme gothic\n"
114
-text "\n"
115
-text "    $ # Change output format to use safer parsing\n"
116
-text "    $ slopoutput=$(slop -f \"%x %y %w %h\")\n"
117
-text "    $ X=$(echo $slopoutput | awk '{print $1}')\n"
118
-text "    $ Y=$(echo $slopoutput | awk '{print $2}')\n"
119
-text "    $ W=$(echo $slopoutput | awk '{print $3}')\n"
120
-text "    $ H=$(echo $slopoutput | awk '{print $4}')\n"
121
-
122
-text "\nTips\n"
123
-text "    * You can use the arrow keys to move the starting point of a drag-selection, just in case you missed it by a few pixels.\n"
124
-text "    * If you don't like a selection: you can cancel it by right-clicking regardless of which options are enabled or disabled for slop.\n"
125
-text "    * If slop doesn't seem to select a window accurately, the problem could be because of decorations getting in the way. Try enabling the --nodecorations flag.\n"

+ 37
- 0
src/options.hpp View File

@@ -0,0 +1,37 @@
1
+#ifndef N_OPTIONS_H_
2
+#define N_OPTIONS_H_
3
+
4
+#include <iostream>
5
+#include <string>
6
+#include <exception>
7
+#include <stdexcept>
8
+#include <vector>
9
+#include <glm/glm.hpp>
10
+
11
+static std::string validStringArguments[] = { "borderSize", "padding", "color", "shader", "highlight", "format" };
12
+static char validCharArguments[] = { 'b', 'p', 'c', 's', 'h', 'f' };
13
+// 0 for flag, 1 for how many arguments to eat up
14
+static unsigned int isFlagArgument[] = { false, false, false, false, true, false };
15
+static unsigned int validArgumentCount = 6;
16
+static unsigned int maxFloatingValues = 0;
17
+
18
+class Options {
19
+private:
20
+    std::vector<std::string> arguments;
21
+    std::vector<std::string> values;
22
+    std::vector<std::string> floatingValues;
23
+    int parseCharOption( int argc, char** argv, int argumentIndex, int validIndex );
24
+    int parseStringOption( int argc, char** argv, int argumentIndex, int validIndex );
25
+    int validateStringOption( int argc, char** argv, int argumentIndex );
26
+    int validateCharOption( int argc, char** argv, int argumentIndex );
27
+    void validate( int argc, char** argv );
28
+public:
29
+    Options( int argc, char** argv );
30
+    bool getFloat( std::string name, char namec, float& found );
31
+    bool getInt( std::string name, char namec, int& found );
32
+    bool getString( std::string name, char namec, std::string& found );
33
+    bool getColor( std::string name, char namec, glm::vec4& found );
34
+    bool getBool( std::string name, char namec, bool& found );
35
+};
36
+
37
+#endif // N_OPTIONS_H_

+ 243
- 0
src/rectangle.cpp View File

@@ -0,0 +1,243 @@
1
+#include "rectangle.hpp"
2
+
3
+Rectangle::Rectangle( glm::vec2 p1, glm::vec2 p2, float border, float padding, glm::vec4 color, bool highlight ) {
4
+    this->color = color;
5
+    this->border = border;
6
+    this->padding = padding;
7
+    this->highlight = highlight;
8
+    // Find each corner of the rectangle
9
+    ul = glm::vec2( glm::min( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
10
+    bl = glm::vec2( glm::min( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
11
+    ur = glm::vec2( glm::max( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
12
+    br = glm::vec2( glm::max( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
13
+    // Offset the inner corners by the padding.
14
+    ul = ul + glm::vec2(-padding,padding);
15
+    bl = bl + glm::vec2(-padding,-padding);
16
+    ur = ur + glm::vec2(padding,padding);
17
+    br = br + glm::vec2(padding,-padding);
18
+    // Create the outer corners by offsetting the inner by the bordersize
19
+    oul = ul + glm::vec2(-border,border);
20
+    obl = bl + glm::vec2(-border,-border);
21
+    our = ur + glm::vec2(border,border);
22
+    obr = br + glm::vec2(border,-border);
23
+    generateBuffers();
24
+    shader = new Shader( "simple.vert", "simple.frag" );
25
+}
26
+
27
+void Rectangle::setPoints( glm::vec2 p1, glm::vec2 p2 ) {
28
+    // Find each corner of the rectangle
29
+    ul = glm::vec2( glm::min( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
30
+    bl = glm::vec2( glm::min( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
31
+    ur = glm::vec2( glm::max( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
32
+    br = glm::vec2( glm::max( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
33
+    // Offset the inner corners by the padding.
34
+    ul = ul + glm::vec2(-padding,padding);
35
+    bl = bl + glm::vec2(-padding,-padding);
36
+    ur = ur + glm::vec2(padding,padding);
37
+    br = br + glm::vec2(padding,-padding);
38
+    // Create the outer corners by offsetting the inner by the bordersize
39
+    oul = ul + glm::vec2(-border,border);
40
+    obl = bl + glm::vec2(-border,-border);
41
+    our = ur + glm::vec2(border,border);
42
+    obr = br + glm::vec2(border,-border);
43
+    generateBuffers();
44
+}
45
+
46
+void Rectangle::generateBuffers() {
47
+    std::vector<glm::vec2> rectangle_verts;
48
+    std::vector<glm::vec2> rectangle_uvs;
49
+    std::vector<glm::vec2> corner_verts;
50
+    std::vector<glm::vec2> corner_uvs;
51
+    std::vector<glm::vec2> center_verts;
52
+    std::vector<glm::vec2> center_uvs;
53
+
54
+    // Top left corner
55
+    corner_verts.push_back( oul );
56
+    corner_uvs.push_back( glm::vec2(0, 1) );
57
+    corner_verts.push_back( ul );
58
+    corner_uvs.push_back( glm::vec2(1, 0) );
59
+    corner_verts.push_back( ul + glm::vec2( -border, 0 ) );
60
+    corner_uvs.push_back( glm::vec2(0, 0) );
61
+
62
+    corner_verts.push_back( oul );
63
+    corner_uvs.push_back( glm::vec2(0, 1) );
64
+    corner_verts.push_back( ul + glm::vec2( 0, border ) );
65
+    corner_uvs.push_back( glm::vec2(1, 1) );
66
+    corner_verts.push_back( ul );
67
+    corner_uvs.push_back( glm::vec2(1, 0) );
68
+
69
+    // Top right corner
70
+    corner_verts.push_back( ur + glm::vec2( 0, border ) );
71
+    corner_uvs.push_back( glm::vec2(0, 1) );
72
+    corner_verts.push_back( ur + glm::vec2( border, 0 ) );
73
+    corner_uvs.push_back( glm::vec2(1, 0) );
74
+    corner_verts.push_back( ur );
75
+    corner_uvs.push_back( glm::vec2(0, 0) );
76
+
77
+    corner_verts.push_back( ur + glm::vec2( 0, border ) );
78
+    corner_uvs.push_back( glm::vec2(0, 1) );
79
+    corner_verts.push_back( our );
80
+    corner_uvs.push_back( glm::vec2(1, 1) );
81
+    corner_verts.push_back( ur + glm::vec2( border, 0 ) );
82
+    corner_uvs.push_back( glm::vec2(1, 0) );
83
+
84
+    // Bottom left corner
85
+    corner_verts.push_back( bl + glm::vec2( -border, 0 ) );
86
+    corner_uvs.push_back( glm::vec2(0, 1) );
87
+    corner_verts.push_back( obl + glm::vec2( border, 0 ) );
88
+    corner_uvs.push_back( glm::vec2(1, 0) );
89
+    corner_verts.push_back( obl );
90
+    corner_uvs.push_back( glm::vec2(0, 0) );
91
+
92
+    corner_verts.push_back( bl + glm::vec2( -border, 0 ) );
93
+    corner_uvs.push_back( glm::vec2(0, 1) );
94
+    corner_verts.push_back( bl );
95
+    corner_uvs.push_back( glm::vec2(1, 1) );
96
+    corner_verts.push_back( bl + glm::vec2( 0, -border ) );
97
+    corner_uvs.push_back( glm::vec2(1, 0) );
98
+
99
+    // Bottom right corner
100
+    corner_verts.push_back( br );
101
+    corner_uvs.push_back( glm::vec2(0, 1) );
102
+    corner_verts.push_back( obr );
103
+    corner_uvs.push_back( glm::vec2(1, 0) );
104
+    corner_verts.push_back( br + glm::vec2( 0, -border ) );
105
+    corner_uvs.push_back( glm::vec2(0, 0) );
106
+
107
+    corner_verts.push_back( br );
108
+    corner_uvs.push_back( glm::vec2(0, 1) );
109
+    corner_verts.push_back( br + glm::vec2( border, 0 ) );
110
+    corner_uvs.push_back( glm::vec2(1, 1) );
111
+    corner_verts.push_back( obr );
112
+    corner_uvs.push_back( glm::vec2(1, 0) );
113
+
114
+    // Left Rectangle
115
+    rectangle_verts.push_back( ul + glm::vec2( -border, 0 ) );
116
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
117
+    rectangle_verts.push_back( bl );
118
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
119
+    rectangle_verts.push_back( bl + glm::vec2( -border, 0 ) );
120
+    rectangle_uvs.push_back( glm::vec2(0, 0) );
121
+
122
+    rectangle_verts.push_back( ul + glm::vec2( -border, 0 ) );
123
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
124
+    rectangle_verts.push_back( ul );
125
+    rectangle_uvs.push_back( glm::vec2(1, 1) );
126
+    rectangle_verts.push_back( bl );
127
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
128
+
129
+    // Right Rectangle
130
+    rectangle_verts.push_back( ur );
131
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
132
+    rectangle_verts.push_back( br + glm::vec2( border, 0 ) );
133
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
134
+    rectangle_verts.push_back( br );
135
+    rectangle_uvs.push_back( glm::vec2(0, 0) );
136
+
137
+    rectangle_verts.push_back( ur );
138
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
139
+    rectangle_verts.push_back( ur + glm::vec2( border, 0 ) );
140
+    rectangle_uvs.push_back( glm::vec2(1, 1) );
141
+    rectangle_verts.push_back( br + glm::vec2( border, 0 ) );
142
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
143
+
144
+    // Top Rectangle
145
+    rectangle_verts.push_back( ul + glm::vec2( 0, border ) );
146
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
147
+    rectangle_verts.push_back( ur );
148
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
149
+    rectangle_verts.push_back( ul );
150
+    rectangle_uvs.push_back( glm::vec2(0, 0) );
151
+
152
+    rectangle_verts.push_back( ul + glm::vec2( 0, border ) );
153
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
154
+    rectangle_verts.push_back( ur + glm::vec2( 0, border ) );
155
+    rectangle_uvs.push_back( glm::vec2(1, 1) );
156
+    rectangle_verts.push_back( ur );
157
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
158
+
159
+    // Bot Rectangle
160
+    rectangle_verts.push_back( bl );
161
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
162
+    rectangle_verts.push_back( br + glm::vec2( 0, -border ) );
163
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
164
+    rectangle_verts.push_back( bl + glm::vec2( 0, -border ) );
165
+    rectangle_uvs.push_back( glm::vec2(0, 0) );
166
+
167
+    rectangle_verts.push_back( bl );
168
+    rectangle_uvs.push_back( glm::vec2(0, 1) );
169
+    rectangle_verts.push_back( br );
170
+    rectangle_uvs.push_back( glm::vec2(1, 1) );
171
+    rectangle_verts.push_back( br + glm::vec2( 0, -border ) );
172
+    rectangle_uvs.push_back( glm::vec2(1, 0) );
173
+
174
+    center_verts.push_back( ul );
175
+    center_uvs.push_back( glm::vec2(0, 1) );
176
+    center_verts.push_back( br );
177
+    center_uvs.push_back( glm::vec2(1, 0) );
178
+    center_verts.push_back( bl );
179
+    center_uvs.push_back( glm::vec2(0, 0) );
180
+
181
+    center_verts.push_back( ul );
182
+    center_uvs.push_back( glm::vec2(0, 1) );
183
+    center_verts.push_back( ur );
184
+    center_uvs.push_back( glm::vec2(1, 1) );
185
+    center_verts.push_back( br );
186
+    center_uvs.push_back( glm::vec2(1, 0) );
187
+
188
+    glGenBuffers( 6, (GLuint*)&buffer );
189
+    glBindBuffer( GL_ARRAY_BUFFER, buffer.corner_verts );
190
+    glBufferData( GL_ARRAY_BUFFER, corner_verts.size() * sizeof( glm::vec2 ), &corner_verts[0], GL_STATIC_DRAW );
191
+    glBindBuffer( GL_ARRAY_BUFFER, buffer.corner_uvs );
192
+    glBufferData( GL_ARRAY_BUFFER, corner_uvs.size() * sizeof( glm::vec2 ), &corner_uvs[0], GL_STATIC_DRAW );
193
+
194
+    glBindBuffer( GL_ARRAY_BUFFER, buffer.rectangle_verts );
195
+    glBufferData( GL_ARRAY_BUFFER, rectangle_verts.size() * sizeof( glm::vec2 ), &rectangle_verts[0], GL_STATIC_DRAW );
196
+    glBindBuffer( GL_ARRAY_BUFFER, buffer.rectangle_uvs );
197
+    glBufferData( GL_ARRAY_BUFFER, rectangle_uvs.size() * sizeof( glm::vec2 ), &rectangle_uvs[0], GL_STATIC_DRAW );
198
+
199
+    glBindBuffer( GL_ARRAY_BUFFER, buffer.center_verts );
200
+    glBufferData( GL_ARRAY_BUFFER, center_verts.size() * sizeof( glm::vec2 ), &center_verts[0], GL_STATIC_DRAW );
201
+    glBindBuffer( GL_ARRAY_BUFFER, buffer.rectangle_uvs );
202
+    glBufferData( GL_ARRAY_BUFFER, center_uvs.size() * sizeof( glm::vec2 ), &center_uvs[0], GL_STATIC_DRAW );
203
+    corner_vertCount = corner_verts.size();
204
+    rectangle_vertCount = rectangle_verts.size();
205
+    center_vertCount = center_verts.size();
206
+}
207
+
208
+Rectangle::~Rectangle() {
209
+    delete shader;
210
+    glDeleteBuffers( 6, (GLuint*)&buffer );
211
+}
212
+
213
+void Rectangle::draw( glm::mat4& matrix ) {
214
+    glEnable( GL_BLEND );
215
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
216
+    shader->bind();
217
+    shader->setParameter( "projection", matrix );
218
+    if ( highlight ) {
219
+        // Draw the center of the highlight
220
+        shader->setParameter( "color", color );
221
+        shader->setAttribute( "position", buffer.center_verts, 2 );
222
+        glDrawArrays(GL_TRIANGLES, 0, center_vertCount );
223
+        // Set the color to have no alpha, then draw the borders.
224
+        glm::vec4 fullAlpha = glm::vec4(color.r,color.g,color.b,1);
225
+        shader->setParameter( "color", fullAlpha );
226
+        shader->setAttribute( "position", buffer.corner_verts, 2 );
227
+        glDrawArrays(GL_TRIANGLES, 0, corner_vertCount );
228
+        shader->setAttribute( "position", buffer.rectangle_verts, 2 );
229
+        glDrawArrays(GL_TRIANGLES, 0, rectangle_vertCount );
230
+    } else {
231
+        shader->setParameter( "color", color );
232
+        shader->setAttribute( "position", buffer.corner_verts, 2 );
233
+        glDrawArrays(GL_TRIANGLES, 0, corner_vertCount );
234
+        shader->setAttribute( "position", buffer.rectangle_verts, 2 );
235
+        glDrawArrays(GL_TRIANGLES, 0, rectangle_vertCount );
236
+    }
237
+    shader->unbind();
238
+    glDisable( GL_BLEND );
239
+}
240
+
241
+glm::vec4 Rectangle::getRect() {
242
+    return glm::vec4( bl.x, bl.y, ur.x-ul.x, ul.y-bl.y );
243
+}

+ 45
- 0
src/rectangle.hpp View File

@@ -0,0 +1,45 @@
1
+#ifndef N_RECTANGLE_H_
2
+#define N_RECTANGLE_H_
3
+
4
+#include "gl_core_3_3.h"
5
+#include <iostream>
6
+#include <glm/glm.hpp>
7
+#include <GL/gl.h>
8
+#include <vector>
9
+
10
+#include "shader.hpp"
11
+
12
+struct RectangleBuffer {
13
+    unsigned int corner_verts;
14
+    unsigned int corner_uvs;
15
+    unsigned int rectangle_verts;
16
+    unsigned int rectangle_uvs;
17
+    unsigned int center_verts;
18
+    unsigned int center_uvs;
19
+};
20
+
21
+class Rectangle {
22
+private:
23
+    glm::vec2 ul, oul;
24
+    glm::vec2 bl, obl;
25
+    glm::vec2 ur, our;
26
+    glm::vec2 br, obr;
27
+    bool highlight;
28
+    void generateBuffers();
29
+    RectangleBuffer buffer;
30
+    unsigned int corner_vertCount;
31
+    unsigned int rectangle_vertCount;
32
+    unsigned int center_vertCount;
33
+    float border;
34
+    float padding;
35
+    Shader* shader;
36
+    glm::vec4 color;
37
+public:
38
+    glm::vec4 getRect();
39
+    Rectangle(glm::vec2 p1, glm::vec2 p2, float border = 1, float padding = 0, glm::vec4 color = glm::vec4(1,1,1,1), bool highlight = false );
40
+    ~Rectangle();
41
+    void setPoints( glm::vec2 p1, glm::vec2 p2 );
42
+    void draw(glm::mat4& matrix);
43
+};
44
+
45
+#endif // N_RECTANGLE_H_

+ 20
- 29
src/resource.cpp View File

@@ -1,4 +1,4 @@
1
-/* resource.cpp: Handles getting resources like textures and stuff.
1
+/* resource.cpp: Handles converting local paths to full paths.
2 2
  *
3 3
  * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4 4
  *
@@ -20,52 +20,43 @@
20 20
 
21 21
 #include "resource.hpp"
22 22
 
23
-slop::Resource* resource = new slop::Resource();
24
-
25
-slop::Resource::Resource() {
23
+Resource::Resource() {
26 24
     // Find the configuration directory.
27
-    // usually ~/.config/slop and /usr/share/slop
25
+    // usually ~/.config/slop-wayland and /usr/share/slop-wayland
28 26
     char* config = getenv( "XDG_CONFIG_HOME" );
29 27
     if ( config == NULL ) {
30 28
         char* home = getpwuid(getuid())->pw_dir;
31
-        m_usrconfig += home;
32
-        m_usrconfig += "/.config/slop/";
33
-        m_sysconfig = INSTALL_PREFIX;
34
-        m_sysconfig += "/share/slop/";
29
+        usrconfig += home;
30
+        usrconfig += "/.config/slop-wayland/";
31
+        // SHADER_PREFIX is defined within the CMakeLists.txt
32
+        sysconfig = SHADER_PREFIX;
33
+        sysconfig += "/share/slop-wayland/";
35 34
         return;
36 35
     }
37
-    m_usrconfig += config;
38
-    m_usrconfig += "/slop/";
39
-    m_sysconfig = INSTALL_PREFIX;
40
-    m_sysconfig += "/share/slop/";
36
+    usrconfig += config;
37
+    usrconfig += "/slop-wayland/";
38
+    sysconfig = SHADER_PREFIX;
39
+    sysconfig += "/share/slop-wayland/";
41 40
 }
42 41
 
43
-std::string slop::Resource::getRealPath( std::string localpath ) {
44
-    if ( validatePath( m_usrconfig + localpath ) ) {
45
-        return m_usrconfig + localpath;
42
+std::string Resource::getRealPath( std::string localpath ) {
43
+    if ( validatePath( usrconfig + localpath ) ) {
44
+        return usrconfig + localpath;
46 45
     }
47
-    if ( validatePath( m_sysconfig + localpath ) ) {
48
-        return m_sysconfig + localpath;
46
+    if ( validatePath( sysconfig + localpath ) ) {
47
+        return sysconfig + localpath;
49 48
     }
50
-    std::string err = "The file or folder " + localpath + " was not found in either " + m_sysconfig + " or " + m_usrconfig + "\n";
51
-    throw err;
49
+    std::string err = "The file or folder " + localpath + " was not found in either " + sysconfig + " or " + usrconfig + "\n";
50
+    throw std::runtime_error(err);
52 51
     return localpath;
53 52
 }
54 53
 
55
-bool slop::Resource::validatePath( std::string path ) {
56
-
54
+bool Resource::validatePath( std::string path ) {
57 55
     struct stat st;
58
-
59 56
     const char* dirname = path.c_str();
60 57
     if ( stat( dirname, &st ) != 0 ) {
61 58
         return false;
62 59
     }
63
-    // No read permissions.
64
-    //if ( !(st.st_mode & S_IROTH) &&
65
-         //(st.st_uid != getuid() || !(st.st_mode & S_IRUSR)) &&
66
-         //(st.st_gid != getgid() || !(st.st_mode & S_IRGRP)) ) {
67
-        //return false;
68
-    //}
69 60
     // Lookin' good!
70 61
     return true;
71 62
 }

+ 9
- 14
src/resource.hpp View File

@@ -18,9 +18,10 @@
18 18
  * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19 19
  */
20 20
 
21
-#ifndef IS_RESOURCE_H_
22
-#define IS_RESOURCE_H_
21
+#ifndef N_RESOURCE_H_
22
+#define N_RESOURCE_H_
23 23
 
24
+#include <stdexcept>
24 25
 #include <stdlib.h>
25 26
 #include <cassert>
26 27
 #include <cstdio>
@@ -32,22 +33,16 @@
32 33
 #include <sys/stat.h>
33 34
 #include <pwd.h>
34 35
 
35
-namespace slop {
36
-
37 36
 class Resource {
38 37
 public:
39
-
40
-                    Resource();
41
-                    ~Resource();
42
-    std::string     getRealPath( std::string localpath );
43
-    bool            validatePath( std::string path );
38
+    Resource();
39
+    std::string getRealPath( std::string localpath );
44 40
 private:
45
-    std::string     m_usrconfig;
46
-    std::string     m_sysconfig;
41
+    bool validatePath( std::string path );
42
+    std::string usrconfig;
43
+    std::string sysconfig;
47 44
 };
48 45
 
49
-}
50
-
51
-extern slop::Resource* resource;
46
+extern Resource* resource;
52 47
 
53 48
 #endif // IS_RESOURCE_H_

+ 0
- 36
src/selectrectangle.cpp View File

@@ -1,36 +0,0 @@
1
-/* selectrectangle.cpp: Handles creating rectangles on the screen.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-#include "selectrectangle.hpp"
21
-
22
-bool slop::isSelectRectangleSupported() {
23
-    int event_base;
24
-    int error_base;
25
-    return XShapeQueryExtension( xengine->m_display, &event_base, &error_base );
26
-}
27
-
28
-slop::SelectRectangle::~SelectRectangle() {
29
-}
30
-
31
-void slop::SelectRectangle::update( double dt ) {
32
-}
33
-
34
-void slop::SelectRectangle::setGeo( int sx, int sy, int ex, int ey ) {
35
-    fprintf( stderr, "Tried to use a class function that's meant to be overridden!\n");
36
-}

+ 0
- 60
src/selectrectangle.hpp View File

@@ -1,60 +0,0 @@
1
-/* selectrectangle.hpp: Handles creating rectangles on the screen.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
-#ifndef IS_SELECT_RECTANGLE_H_
22
-#define IS_SELECT_RECTANGLE_H_
23
-
24
-#include "x.hpp"
25
-#include "selectrectangle.hpp"
26
-#include "shader.hpp"
27
-
28
-#include <unistd.h>
29
-
30
-#include <X11/Xlib.h>
31
-#include <X11/extensions/shape.h>
32
-#include <X11/Xatom.h>
33
-
34
-#include <cstdlib>
35
-#include <cmath>
36
-#include <cstdio>
37
-#include <string>
38
-#include <vector>
39
-
40
-namespace slop {
41
-
42
-class SelectRectangle {
43
-public:
44
-    virtual ~SelectRectangle();
45
-    virtual void    setGeo( int x, int y, int w, int h );
46
-    virtual void    update( double dt );
47
-    Window          m_window;
48
-    int             m_x;
49
-    int             m_y;
50
-    int             m_width;
51
-    int             m_height;
52
-    int             m_border;
53
-    bool            m_highlight;
54
-};
55
-
56
-bool isSelectRectangleSupported();
57
-
58
-}
59
-
60
-#endif // IS_SELECT_RECTANGLE_H_

+ 40
- 34
src/shader.cpp View File

@@ -1,15 +1,8 @@
1 1
 #include "shader.hpp"
2 2
 
3
-slop::Shader::Shader( std::string name, std::string vert, std::string frag, std::string type ) {
4
-    m_name = name;
5
-    // Set up the type of the shader, this is read by render to know what kind of matricies it needs.
6
-    if ( type == "perspective" ) {
7
-        m_type = 0;
8
-    } else if ( type == "orthographic" ) {
9
-        m_type = 1;
10
-    } else {
11
-        m_type = -1;
12
-    }
3
+Shader::Shader( std::string vert, std::string frag) {
4
+    vert = resource->getRealPath(vert);
5
+    frag = resource->getRealPath(frag);
13 6
     m_good = false;
14 7
     // Create the program to link to.
15 8
     m_program = glCreateProgram();
@@ -23,33 +16,46 @@ slop::Shader::Shader( std::string name, std::string vert, std::string frag, std:
23 16
 
24 17
     const char* vertsrc = vert_contents.c_str();
25 18
     const char* fragsrc = frag_contents.c_str();
19
+    
20
+    if ( vert_contents.length() <= 0 ) {
21
+        std::string errstring = "Failed to open file (or is empty) `" + vert + "`.\n";
22
+        throw new std::runtime_error(errstring);
23
+    }
24
+
25
+    if ( frag_contents.length() <= 0 ) {
26
+        std::string errstring = "Failed to open file (or is empty) `" + frag + "`.\n";
27
+        throw new std::runtime_error(errstring);
28
+    }
26 29
 
27 30
     // Compile both shaders.
28 31
     unsigned int vertShader = glCreateShader( GL_VERTEX_SHADER );
29 32
     glShaderSource( vertShader, 1, &vertsrc , NULL );
30
-    int err = compile( vertShader );
33
+    std::string errortxt;
34
+    int err = compile( vertShader, errortxt );
31 35
 
32 36
     if ( err ) {
33
-        fprintf( stderr, "Failed to compile shader %s.\n", vert.c_str() );
37
+        std::string errstring = "Failed to compile shader `" + vert + "`:\n" + errortxt;
38
+        throw new std::runtime_error(errstring);
34 39
         glDeleteShader( vertShader );
35 40
         return;
36 41
     }
37 42
 
38 43
     unsigned int fragShader = glCreateShader( GL_FRAGMENT_SHADER );
39 44
     glShaderSource( fragShader, 1, &fragsrc, NULL );
40
-    err = compile( fragShader );
45
+    err = compile( fragShader, errortxt );
41 46
     if ( err ) {
42
-        fprintf( stderr, "Failed to compile shader %s.\n", frag.c_str() );
47
+        std::string errstring = "Failed to compile shader `" + frag + "`:\n" + errortxt;
48
+        throw new std::runtime_error(errstring);
43 49
         glDeleteShader( vertShader );
44 50
         glDeleteShader( fragShader );
45 51
         return;
46 52
     }
47 53
 
48
-
49 54
     // Then attempt to link them to this shader.
50
-    err = link( vertShader, fragShader );
55
+    err = link( vertShader, fragShader, errortxt );
51 56
     if ( err ) {
52
-        fprintf( stderr, "Failed to link shader %s.\n", name.c_str() );
57
+        std::string errstring = "Failed to link shader `" + vert + "` and  `" + frag + "`:\n" + errortxt;
58
+        throw new std::runtime_error(errstring);
53 59
         glDeleteShader( vertShader );
54 60
         glDeleteShader( fragShader );
55 61
         return;
@@ -62,57 +68,57 @@ slop::Shader::Shader( std::string name, std::string vert, std::string frag, std:
62 68
     glUseProgram( 0 );
63 69
 }
64 70
 
65
-slop::Shader::~Shader() {
71
+Shader::~Shader() {
66 72
     glDeleteProgram( m_program );
67 73
 }
68 74
 
69
-unsigned int slop::Shader::getProgram() {
75
+unsigned int Shader::getProgram() {
70 76
     return m_program;
71 77
 }
72 78
 
73
-void slop::Shader::bind() {
79
+void Shader::bind() {
74 80
     glUseProgram( m_program );
75 81
 }
76 82
 
77
-int slop::Shader::compile( unsigned int shader ) {
83
+int Shader::compile( unsigned int shader, std::string& error ) {
78 84
     glCompileShader( shader );
79 85
 
80 86
     // Compiling the shader is the easy part, all this junk down here is for printing the error it might generate.
81
-    int result;
87
+    int result = GL_FALSE;
82 88
     int logLength;
83 89
     glGetShaderiv( shader, GL_COMPILE_STATUS, &result );
84 90
     glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLength );
85 91
     if ( result == GL_FALSE ) {
86 92
         char* errormsg = new char[ logLength ];
87 93
         glGetShaderInfoLog( shader, logLength, NULL, errormsg );
88
-        fprintf( stderr, "%s\n", errormsg );
94
+        error = errormsg;
89 95
         delete[] errormsg;
90 96
         return 1;
91 97
     }
92 98
     return 0;
93 99
 }
94 100
 
95
-int slop::Shader::link( unsigned int vertshader, unsigned int fragshader ) {
101
+int Shader::link( unsigned int vertshader, unsigned int fragshader, std::string& error ) {
96 102
     glAttachShader( m_program, vertshader );
97 103
     glAttachShader( m_program, fragshader );
98 104
     glLinkProgram( m_program );
99 105
 
100 106
     // Linking the shader is the easy part, all this junk down here is for printing the error it might generate.
101
-    int result;
107
+    int result = GL_FALSE;
102 108
     int logLength;
103 109
     glGetProgramiv( m_program, GL_LINK_STATUS, &result);
104 110
     glGetProgramiv( m_program, GL_INFO_LOG_LENGTH, &logLength);
105 111
     if ( result == GL_FALSE ) {
106 112
         char* errormsg = new char[ logLength ];
107 113
         glGetProgramInfoLog( m_program, logLength, NULL, errormsg );
108
-        fprintf( stderr, "%s\n", errormsg );
114
+        error = errormsg;
109 115
         delete[] errormsg;
110 116
         return 1;
111 117
     }
112 118
     return 0;
113 119
 }
114 120
 
115
-unsigned int slop::Shader::getUniformLocation( std::string name ) {
121
+unsigned int Shader::getUniformLocation( std::string name ) {
116 122
     if ( !m_good ) {
117 123
         return 0;
118 124
     }
@@ -120,42 +126,42 @@ unsigned int slop::Shader::getUniformLocation( std::string name ) {
120 126
     return glGetUniformLocation( m_program, name.c_str() );
121 127
 }
122 128
 
123
-void slop::Shader::setParameter( std::string name, int foo ) {
129
+void Shader::setParameter( std::string name, int foo ) {
124 130
     if ( !m_good ) {
125 131
         return;
126 132
     }
127 133
     glUniform1i( getUniformLocation( name ), foo );
128 134
 }
129 135
 
130
-void slop::Shader::setParameter( std::string name, float foo ) {
136
+void Shader::setParameter( std::string name, float foo ) {
131 137
     if ( !m_good ) {
132 138
         return;
133 139
     }
134 140
     glUniform1f( getUniformLocation( name ), foo );
135 141
 }
136 142
 
137
-void slop::Shader::setParameter( std::string name, glm::mat4 foo ) {
143
+void Shader::setParameter( std::string name, glm::mat4& foo ) {
138 144
     if ( !m_good ) {
139 145
         return;
140 146
     }
141 147
     glUniformMatrix4fv( getUniformLocation( name ), 1, GL_FALSE, glm::value_ptr( foo ) );
142 148
 }
143 149
 
144
-void slop::Shader::setParameter( std::string name, glm::vec4 foo ) {
150
+void Shader::setParameter( std::string name, glm::vec4 foo ) {
145 151
     if ( !m_good ) {
146 152
         return;
147 153
     }
148 154
     glUniform4f( getUniformLocation( name ), foo.x, foo.y, foo.z, foo.w );
149 155
 }
150 156
 
151
-void slop::Shader::setParameter( std::string name, glm::vec2 foo ) {
157
+void Shader::setParameter( std::string name, glm::vec2 foo ) {
152 158
     if ( !m_good ) {
153 159
         return;
154 160
     }
155 161
     glUniform2f( getUniformLocation( name ), foo.x, foo.y );
156 162
 }
157 163
 
158
-void slop::Shader::setAttribute( std::string name, unsigned int buffer, unsigned int stepsize ) {
164
+void Shader::setAttribute( std::string name, unsigned int buffer, unsigned int stepsize ) {
159 165
     unsigned int a = glGetAttribLocation( m_program, name.c_str() );
160 166
     glEnableVertexAttribArray( a );
161 167
     glBindBuffer( GL_ARRAY_BUFFER, buffer );
@@ -163,7 +169,7 @@ void slop::Shader::setAttribute( std::string name, unsigned int buffer, unsigned
163 169
     m_activeattribs.push_back( a );
164 170
 }
165 171
 
166
-void slop::Shader::unbind() {
172
+void Shader::unbind() {
167 173
     for ( unsigned int i=0; i<m_activeattribs.size(); i++ ) {
168 174
         glDisableVertexAttribArray( m_activeattribs[i] );
169 175
     }

+ 15
- 24
src/shader.hpp View File

@@ -1,48 +1,39 @@
1
-// shader.hpp: Loads shaders into opengl
1
+#ifndef N_SHADER_H_
2
+#define N_SHADER_H_
2 3
 
3
-#ifndef IS_SHADER_H_
4
-#define IS_SHADER_H_
5
-
6
-#include <string>
7
-#include <cstdio>
4
+#include <fstream>
8 5
 #include <vector>
9
-#ifdef OPENGL_ENABLED
6
+#include <string>
7
+#include <exception>
8
+
9
+#include "gl_core_3_3.h"
10 10
 #include <glm/glm.hpp>
11 11
 #include <glm/gtc/type_ptr.hpp>
12
-#include <GL/glew.h>
13
-#endif
14
-#include <string>
15
-#include <fstream>
16
-#include <streambuf>
12
+#include <EGL/egl.h>
13
+#include <GL/gl.h>
17 14
 
18
-namespace slop {
15
+#include "resource.hpp"
19 16
 
20 17
 class Shader {
21 18
 public:
22
-    Shader( std::string name, std::string vert, std::string frag, std::string shadertype = "other" );
19
+    Shader( std::string vert, std::string frag );
23 20
     ~Shader();
24 21
     unsigned int    getProgram();
25
-    std::string     m_name;
26 22
     void            bind();
27 23
     void            unbind();
28 24
     void            setParameter( std::string name, int foo );
29 25
     void            setParameter( std::string name, float foo );
30
-#ifdef OPENGL_ENABLED
31
-    void            setParameter( std::string name, glm::mat4 foo );
26
+    void            setParameter( std::string name, glm::mat4& foo );
32 27
     void            setParameter( std::string name, glm::vec4 foo );
33 28
     void            setParameter( std::string name, glm::vec2 foo );
34
-#endif
35 29
     void            setAttribute( std::string name, unsigned int buffer, unsigned int stepsize );
36
-    int             m_type;
37 30
 private:
38 31
     std::vector<unsigned int>   m_activeattribs;
39 32
     bool                        m_good;
40 33
     unsigned int                getUniformLocation( std::string );
41
-    int                         compile( unsigned int shader );
42
-    int                         link( unsigned int vert, unsigned int frag );
34
+    int                         compile( unsigned int shader, std::string& error );
35
+    int                         link( unsigned int vert, unsigned int frag, std::string& error );
43 36
     unsigned int                m_program;
44 37
 };
45 38
 
46
-};
47
-
48
-#endif // IS_SHADER_H_
39
+#endif // N_SHADER_H_

+ 141
- 0
src/slop.cpp View File

@@ -0,0 +1,141 @@
1
+#include "slop.hpp"
2
+
3
+Wayland* wayland;
4
+Mouse* mouse;
5
+Keyboard* keyboard;
6
+Resource* resource;
7
+
8
+// Defaults!
9
+SlopOptions::SlopOptions() {
10
+    borderSize = 1;
11
+    padding = 0;
12
+    shader = "textured";
13
+    highlight = false;
14
+    r = 0.5;
15
+    g = 0.5;
16
+    b = 0.5;
17
+    a = 1;
18
+}
19
+
20
+SlopSelection::SlopSelection( float x, float y, float w, float h ) {
21
+    this->x = x;
22
+    this->y = y;
23
+    this->w = w;
24
+    this->h = h;
25
+}
26
+
27
+SlopMemory::SlopMemory( SlopOptions* options ) {
28
+    running = true;
29
+    state = (SlopState*)new SlopStart();
30
+    nextState = NULL;
31
+    rectangle = new Rectangle(glm::vec2(0,0), glm::vec2(0,0), options->borderSize, options->padding, glm::vec4( options->r, options->g, options->b, options->a ), options->highlight);
32
+}
33
+
34
+SlopMemory::~SlopMemory() {
35
+    delete state;
36
+    if ( nextState ) {
37
+        delete nextState;
38
+    }
39
+    delete rectangle;
40
+}
41
+
42
+void SlopMemory::update( double dt ) {
43
+    state->update( *this, dt );
44
+    if ( nextState ) {
45
+        state->onExit( *this );
46
+        delete state;
47
+        state = nextState;
48
+        state->onEnter( *this );
49
+        nextState = NULL;
50
+    }
51
+}
52
+
53
+void SlopMemory::setState( SlopState* state ) {
54
+    if ( nextState ) {
55
+        delete nextState;
56
+    }
57
+    nextState = state;
58
+}
59
+
60
+void SlopMemory::draw( glm::mat4& matrix ) {
61
+    state->draw( *this, matrix );
62
+}
63
+
64
+SlopSelection SlopSelect( SlopOptions* options, bool* cancelled ) {
65
+    bool deleteOptions = false;
66
+    if ( !options ) {
67
+        deleteOptions = true;
68
+        options = new SlopOptions();
69
+    }
70
+    resource = new Resource();
71
+    // Set up wayland temporarily
72
+    wayland = new Wayland();
73
+    wayland->init();
74
+    mouse = new Mouse( wayland );
75
+    keyboard = new Keyboard( wayland );
76
+
77
+    // Set up window with GL context
78
+    Window* window = new Window( 1, 1 );
79
+    window->setTitle("slop");
80
+    window->setClass("slop");
81
+    window->setFullScreen();
82
+    window->setCurrent();
83
+
84
+    window->framebuffer->setShader( options->shader );
85
+
86
+    // Init our little state machine, memory is a tad of a misnomer
87
+    SlopMemory memory( options );
88
+
89
+    // This is where we'll run through all of our stuffs
90
+    //FIXME: We need to sync up with wayland's draw pings so that we don't overdraw ever...
91
+    while( memory.running ) {
92
+        // This is specifically for wayland updates.
93
+        wl_display_dispatch_pending(wayland->display);
94
+        memory.update( 1 );
95
+
96
+        // Then we draw our junk to a framebuffer.
97
+        window->framebuffer->bind();
98
+        glClearColor (0.0, 0.0, 0.0, 0.0);
99
+        glClear (GL_COLOR_BUFFER_BIT);
100
+        memory.draw( window->camera );
101
+        window->framebuffer->unbind();
102
+
103
+        // Then we draw the framebuffer to the screen
104
+        window->framebuffer->draw();
105
+        window->display();
106
+        GLenum err = glGetError();
107
+        if ( err != GL_NO_ERROR ) {
108
+            throw err;
109
+        }
110
+        if ( keyboard->anyKeyDown() || mouse->getButton( BTN_RIGHT ) ) {
111
+            memory.running = false;
112
+            if ( cancelled ) {
113
+                *cancelled = true;
114
+            }
115
+        } else {
116
+            *cancelled = false;
117
+        }
118
+    }
119
+
120
+    // Now we should have a selection! We parse everything we know about it here.
121
+    glm::vec4 output = memory.rectangle->getRect();
122
+
123
+    // Lets now clear both front and back buffers before closing.
124
+    // hopefully it'll be completely transparent while closing!
125
+    glClearColor (0.0, 0.0, 0.0, 0.0);
126
+    glClear (GL_COLOR_BUFFER_BIT);
127
+    window->display();
128
+    glClearColor (0.0, 0.0, 0.0, 0.0);
129
+    glClear (GL_COLOR_BUFFER_BIT);
130
+    window->display();
131
+    // Then we clean up.
132
+    delete window;
133
+    delete mouse;
134
+    delete wayland;
135
+    delete resource;
136
+    if ( deleteOptions ) {
137
+        delete options;
138
+    }
139
+    // Finally return the data.
140
+    return SlopSelection( output.x, output.y, output.z+1, output.w+1 );
141
+}

+ 55
- 0
src/slop.hpp View File

@@ -0,0 +1,55 @@
1
+#ifndef N_SLOP_H_
2
+#define N_SLOP_H_
3
+
4
+#include <string>
5
+
6
+#include "window.hpp"
7
+#include "shader.hpp"
8
+#include "framebuffer.hpp"
9
+#include "rectangle.hpp"
10
+#include "slopstates.hpp"
11
+#include "keyboard.hpp"
12
+#include "mouse.hpp"
13
+#include "resource.hpp"
14
+
15
+class SlopState;
16
+
17
+class SlopOptions {
18
+public:
19
+    SlopOptions();
20
+    float borderSize;
21
+    float padding;
22
+    bool highlight;
23
+    std::string shader;
24
+    float r;
25
+    float g;
26
+    float b;
27
+    float a;
28
+};
29
+
30
+class SlopSelection {
31
+public:
32
+    SlopSelection( float x, float y, float w, float h );
33
+    float x;
34
+    float y;
35
+    float w;
36
+    float h;
37
+};
38
+
39
+class SlopMemory {
40
+private:
41
+    SlopState* state;
42
+    SlopState* nextState;
43
+public:
44
+    SlopMemory( SlopOptions* options );
45
+    ~SlopMemory();
46
+    bool running;
47
+    Rectangle* rectangle;
48
+    void setState( SlopState* state );
49
+    void update( double dt );
50
+    void draw( glm::mat4& matrix );
51
+};
52
+
53
+SlopSelection SlopSelect( SlopOptions* options = NULL, bool* cancelled = NULL );
54
+
55
+#endif // N_SLOP_H_

+ 51
- 0
src/slopstates.cpp View File

@@ -0,0 +1,51 @@
1
+#include "slopstates.hpp"
2
+
3
+SlopState::~SlopState() {
4
+}
5
+void SlopState::onEnter( SlopMemory& memory ) {
6
+}
7
+void SlopState::onExit( SlopMemory& memory ) {
8
+}
9
+void SlopState::update( SlopMemory& memory, double dt ) {
10
+}
11
+void SlopState::draw( SlopMemory& memory, glm::mat4 matrix ) {
12
+}
13
+
14
+// Start
15
+void SlopStart::update( SlopMemory& memory, double dt ) {
16
+    if ( mouse->getButton( BTN_LEFT ) ) {
17
+        memory.setState( (SlopState*)new SlopStartDrag( mouse->getMousePos() ) );
18
+    }
19
+}
20
+
21
+SlopStartDrag::SlopStartDrag( glm::vec2 point ) {
22
+    startPoint = point;
23
+}
24
+
25
+void SlopStartDrag::onEnter( SlopMemory& memory ) {
26
+    memory.rectangle->setPoints(startPoint, startPoint);
27
+}
28
+
29
+void SlopStartDrag::update( SlopMemory& memory, double dt ) {
30
+    memory.rectangle->setPoints(startPoint, mouse->getMousePos());
31
+    char a = startPoint.y > mouse->getMousePos().y;
32
+    char b = startPoint.x > mouse->getMousePos().x;
33
+    char c = (a << 1) | b;
34
+    switch ( c ) {
35
+        case 0: mouse->setCursor( "lr_angle" ); break;
36
+        case 1: mouse->setCursor( "ll_angle" ); break;
37
+        case 2: mouse->setCursor( "ur_angle" ); break;
38
+        case 3: mouse->setCursor( "ul_angle" ); break;
39
+    }
40
+    if ( !mouse->getButton( BTN_LEFT ) ) {
41
+        memory.setState( (SlopState*)new SlopEndDrag() );
42
+    }
43
+}
44
+
45
+void SlopStartDrag::draw( SlopMemory& memory, glm::mat4 matrix ) {
46
+    memory.rectangle->draw( matrix );
47
+}
48
+
49
+void SlopEndDrag::onEnter( SlopMemory& memory ) {
50
+    memory.running = false;
51
+}

+ 39
- 0
src/slopstates.hpp View File

@@ -0,0 +1,39 @@
1
+#ifndef N_SLOPSTATES_H_
2
+#define N_SLOPSTATES_H_
3
+
4
+#include "mouse.hpp"
5
+#include "rectangle.hpp"
6
+#include "slop.hpp"
7
+
8
+class SlopMemory;
9
+
10
+class SlopState {
11
+public:
12
+    virtual ~SlopState();
13
+    virtual void onEnter( SlopMemory& memory );
14
+    virtual void onExit( SlopMemory& memory );
15
+    virtual void update( SlopMemory& memory, double dt );
16
+    virtual void draw( SlopMemory& memory, glm::mat4 matrix );
17
+};
18
+
19
+class SlopStart : SlopState {
20
+public:
21
+    virtual void update( SlopMemory& memory, double dt );
22
+};
23
+
24
+class SlopStartDrag : SlopState {
25
+private:
26
+    glm::vec2 startPoint;
27
+public:
28
+    SlopStartDrag( glm::vec2 point );
29
+    virtual void onEnter( SlopMemory& memory );
30
+    virtual void update( SlopMemory& memory, double dt );
31
+    virtual void draw( SlopMemory& memory, glm::mat4 matrix );
32
+};
33
+
34
+class SlopEndDrag : SlopState {
35
+public:
36
+    virtual void onEnter( SlopMemory& memory );
37
+};
38
+
39
+#endif // N_SLOPSTATES_H_

+ 55
- 0
src/wayland.cpp View File

@@ -0,0 +1,55 @@
1
+#include "wayland.hpp"
2
+
3
+static void global_registry_handler(void *data, wl_registry* registry,
4
+                                    uint32_t id, const char* interface, uint32_t version) {
5
+    //std::cout << "Got register " << interface << " with id " << id << "\n";
6
+    if (std::string(interface) == "wl_compositor") {
7
+        wayland->compositor = (wl_compositor*)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
8
+    } else if(std::string(interface) == "wl_shell") {
9
+        wayland->shell = (wl_shell*)wl_registry_bind(registry, id, &wl_shell_interface, 1);
10
+    } else if(std::string(interface) == "wl_shm") {
11
+        wayland->shm = (wl_shm*)wl_registry_bind(registry, id, &wl_shm_interface, 1);
12
+    } else if(std::string(interface) == "wl_seat") {
13
+        wayland->seat = (wl_seat*)wl_registry_bind(registry, id, &wl_seat_interface, 1);
14
+    } else if(std::string(interface) == "wl_output") {
15
+        wayland->output = (wl_output*)wl_registry_bind(registry, id, &wl_output_interface, 1);
16
+        //wl_list_insert(&output_list, &output->link);
17
+        //wl_output_add_listener(output->output, &output_listener, output);
18
+    }
19
+}
20
+
21
+static void global_registry_remover(void *data, struct wl_registry *registry, uint32_t id) {
22
+}
23
+
24
+static const struct wl_registry_listener registry_listener = {
25
+    global_registry_handler,
26
+    global_registry_remover
27
+};
28
+
29
+Wayland::Wayland() {
30
+    display = wl_display_connect(NULL);
31
+    if (!display) {
32
+        throw new std::runtime_error("Failed to connect to display.");
33
+    }
34
+}
35
+
36
+Wayland::~Wayland() {
37
+    wl_display_disconnect(display);
38
+}
39
+
40
+void Wayland::init() {
41
+    struct wl_registry *registry = wl_display_get_registry(display);
42
+    wl_registry_add_listener(registry, &registry_listener, NULL);
43
+
44
+    wl_display_dispatch(display);
45
+    wl_display_roundtrip(display);
46
+    if (!compositor) {
47
+        throw new std::runtime_error("Can't find compositor.");
48
+    }
49
+
50
+    egl_display = eglGetDisplay( display );
51
+    eglInitialize( egl_display, NULL, NULL );
52
+    if ( !egl_display ) {
53
+        throw new std::runtime_error("Failed to initialize EGL! (Thats the graphics stuff.)");
54
+    }
55
+}

+ 36
- 0
src/wayland.hpp View File

@@ -0,0 +1,36 @@
1
+#ifndef N_WAYLAND_H_
2
+#define N_WAYLAND_H_
3
+
4
+#include <wayland-client.h>
5
+#include <wayland-egl.h>
6
+#include <EGL/egl.h>
7
+#include <string>
8
+#include <iostream>
9
+#include <vector>
10
+#include <glm/glm.hpp>
11
+
12
+//#include <mutter/meta/compositor-mutter.h>
13
+
14
+#ifndef NULL
15
+#define NULL 0
16
+#endif
17
+
18
+class Wayland {
19
+public:
20
+    Wayland();
21
+    ~Wayland();
22
+    void init();
23
+    wl_display* display;
24
+    wl_compositor* compositor;
25
+    wl_seat* seat;
26
+    wl_shell* shell;
27
+    wl_shm* shm;
28
+    wl_output* output;
29
+    EGLDisplay egl_display;
30
+    glm::vec2 mousepos;
31
+    std::vector<glm::vec4> getWindows();
32
+};
33
+
34
+extern Wayland* wayland;
35
+
36
+#endif // N_WAYLAND_H_

+ 80
- 0
src/window.cpp View File

@@ -0,0 +1,80 @@
1
+#include "window.hpp"
2
+
3
+static void shell_surface_ping (void *data, struct wl_shell_surface *shell_surface, uint32_t serial) {
4
+	wl_shell_surface_pong (shell_surface, serial);
5
+}
6
+static void shell_surface_configure (void *data, struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height) {
7
+	Window* window = (Window*)data;
8
+	wl_egl_window_resize (window->egl_window, width, height, 0, 0);
9
+    window->camera = glm::ortho( 0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f);
10
+    window->width = width;
11
+    window->height = height;
12
+    glViewport(0,0,width,height);
13
+    window->framebuffer->resize( width, height );
14
+}
15
+static void shell_surface_popup_done (void *data, struct wl_shell_surface *shell_surface) {
16
+	
17
+}
18
+static struct wl_shell_surface_listener shell_surface_listener = {&shell_surface_ping, &shell_surface_configure, &shell_surface_popup_done};
19
+
20
+Window::Window( unsigned int w, unsigned int h ) {
21
+    eglBindAPI (EGL_OPENGL_API);
22
+	EGLint attributes[] = {
23
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
24
+		EGL_RED_SIZE, 8,
25
+		EGL_GREEN_SIZE, 8,
26
+		EGL_BLUE_SIZE, 8,
27
+		EGL_ALPHA_SIZE, 8,
28
+	EGL_NONE};
29
+    camera = glm::ortho( 0.0f, (float)w, (float)h, 0.0f, -1.0f, 1.0f);
30
+	EGLConfig config;
31
+	EGLint num_config;
32
+	eglChooseConfig (wayland->egl_display, attributes, &config, 1, &num_config);
33
+	egl_context = eglCreateContext (wayland->egl_display, config, EGL_NO_CONTEXT, NULL);
34
+	
35
+	surface = wl_compositor_create_surface (wayland->compositor);
36
+	shell_surface = wl_shell_get_shell_surface (wayland->shell, surface);
37
+	wl_shell_surface_add_listener (shell_surface, &shell_surface_listener, this);
38
+	wl_shell_surface_set_toplevel (shell_surface);
39
+	egl_window = wl_egl_window_create (surface, w, h);
40
+	egl_surface = eglCreateWindowSurface (wayland->egl_display, config, egl_window, NULL);
41
+    if(ogl_LoadFunctions() == ogl_LOAD_FAILED)
42
+    {
43
+        throw new std::runtime_error("Failed to load function pointers for OpenGL.");
44
+    }
45
+    setCurrent();
46
+    framebuffer = new Framebuffer( w, h );
47
+}
48
+
49
+Window::~Window() {
50
+    delete framebuffer;
51
+	eglDestroySurface (wayland->egl_display, egl_surface);
52
+	wl_egl_window_destroy (egl_window);
53
+	wl_surface_destroy (surface);
54
+	wl_shell_surface_destroy (shell_surface);
55
+	eglDestroyContext (wayland->egl_display, egl_context);
56
+}
57
+
58
+void Window::display() {
59
+	if (!eglSwapBuffers(wayland->egl_display, egl_surface)) {
60
+        throw new std::runtime_error("Failed to swap buffers.");
61
+    }
62
+}
63
+
64
+void Window::setFullScreen() {
65
+	wl_shell_surface_set_fullscreen(shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
66
+}
67
+
68
+void Window::setCurrent() {
69
+	if (!eglMakeCurrent (wayland->egl_display, egl_surface, egl_surface, egl_context)) {
70
+        throw new std::runtime_error("Failed set EGL's current surface for rendering.");
71
+    }
72
+}
73
+
74
+void Window::setTitle(std::string title) {
75
+	wl_shell_surface_set_title(shell_surface, title.c_str());
76
+}
77
+
78
+void Window::setClass(std::string title) {
79
+	wl_shell_surface_set_class(shell_surface, title.c_str());
80
+}

+ 36
- 0
src/window.hpp View File

@@ -0,0 +1,36 @@
1
+#ifndef N_WINDOW_H_
2
+#define N_WINDOW_H_
3
+
4
+#include <string>
5
+#include <exception>
6
+
7
+#include "gl_core_3_3.h"
8
+#include "wayland.hpp"
9
+//#include <GL/glew.h>
10
+#include <wayland-egl.h>
11
+#include <EGL/egl.h>
12
+#include <GL/gl.h>
13
+#include <glm/gtc/matrix_transform.hpp>
14
+
15
+#include "framebuffer.hpp"
16
+
17
+class Window {
18
+public:
19
+    Framebuffer* framebuffer;
20
+    int width, height;
21
+    glm::mat4 camera;
22
+    Window( unsigned int w, unsigned int h );
23
+    ~Window();
24
+    void setFullScreen();
25
+    void setCurrent();
26
+    void setTitle( std::string title );
27
+    void setClass( std::string c );
28
+    void display();
29
+    EGLContext egl_context;
30
+    struct wl_surface *surface;
31
+    struct wl_shell_surface *shell_surface;
32
+    struct wl_egl_window *egl_window;
33
+    EGLSurface egl_surface;
34
+};
35
+
36
+#endif // N_WINDOW_H_

+ 0
- 453
src/x.cpp View File

@@ -1,453 +0,0 @@
1
-/* x.cpp: Handles starting and managing X.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-#include "x.hpp"
21
-
22
-slop::XEngine* xengine = new slop::XEngine();
23
-
24
-int slop::XEngineErrorHandler( Display* dpy, XErrorEvent* event ) {
25
-    // Ignore XGrabKeyboard BadAccess errors, we can work without it.
26
-    // 31 = XGrabKeyboard's request code
27
-    if ( event->request_code == 31 && event->error_code == BadAccess ) {
28
-        fprintf( stderr, "_X Error \"BadAccess\" for XGrabKeyboard ignored...\n" );
29
-        return EXIT_SUCCESS;
30
-    }
31
-    // Ignore XQueryKeymap BadValue errors, we can work without it.
32
-    // 128 = XShape request code, not sure why XQueryKeymap generates this?
33
-    if ( event->request_code == 128 && event->error_code == BadValue ) {
34
-        fprintf( stderr, "_X Error \"BadValue\" for XQueryKeymap ignored...\n" );
35
-        return EXIT_SUCCESS;
36
-    }
37
-    // Everything else should be fatal as I don't like undefined behavior.
38
-    char buffer[1024];
39
-    XGetErrorText( dpy, event->error_code, buffer, 1024 );
40
-    fprintf( stderr,
41
-             "_X Error of failed request: %s\n_  Error code of failed request: %3d\n_  Major opcode of failed request: %3d\n_  Minor opcode of failed request: %3d\n_  Serial number of failed request: %5li\n_  Current serial number in output stream:?????\n",
42
-             buffer,
43
-             event->error_code,
44
-             event->request_code,
45
-             event->minor_code,
46
-             event->serial );
47
-    exit(1);
48
-}
49
-
50
-unsigned int slop::XEngine::getWidth() {
51
-    if ( !m_good ) {
52
-        return -1;
53
-    }
54
-    return WidthOfScreen( m_screen );
55
-}
56
-
57
-unsigned int slop::XEngine::getHeight() {
58
-    if ( !m_good ) {
59
-        return -1;
60
-    }
61
-    return HeightOfScreen( m_screen );
62
-}
63
-
64
-slop::XEngine::XEngine() {
65
-    m_keypressed = false;
66
-    m_display = NULL;
67
-    m_visual = NULL;
68
-    m_screen = NULL;
69
-    m_good = false;
70
-    m_mousex = -1;
71
-    m_mousey = -1;
72
-    m_hoverWindow = None;
73
-}
74
-
75
-slop::XEngine::~XEngine() {
76
-    if ( !m_good ) {
77
-        return;
78
-    }
79
-    for ( unsigned int i=0; i<m_cursors.size(); i++ ) {
80
-        if ( m_cursors.at( i ) ) {
81
-            XFreeCursor( m_display, m_cursors[i] );
82
-        }
83
-    }
84
-    XCloseDisplay( m_display );
85
-}
86
-
87
-bool slop::XEngine::mouseDown( unsigned int button ) {
88
-    if ( button >= m_mouse.size() ) {
89
-        return false;
90
-    }
91
-    return m_mouse.at( button );
92
-}
93
-
94
-int slop::XEngine::init( std::string display ) {
95
-    // Initialize display
96
-    m_display = XOpenDisplay( display.c_str() );
97
-    if ( !m_display ) {
98
-        fprintf( stderr, "Error: Failed to open X display %s\n", display.c_str() );
99
-        return EXIT_FAILURE;
100
-    }
101
-    m_screen    = ScreenOfDisplay( m_display, DefaultScreen( m_display ) );
102
-    m_visual    = DefaultVisual  ( m_display, XScreenNumberOfScreen( m_screen ) );
103
-    m_colormap  = DefaultColormap( m_display, XScreenNumberOfScreen( m_screen ) );
104
-    //m_root      = RootWindow     ( m_display, XScreenNumberOfScreen( m_screen ) );
105
-    m_root      = DefaultRootWindow( m_display );
106
-
107
-#ifdef OPENGL_ENABLED
108
-    m_res = XRRGetScreenResourcesCurrent( m_display, m_root);
109
-#endif // OPENGL_ENABLED
110
-
111
-    m_good = true;
112
-    XSetErrorHandler( slop::XEngineErrorHandler );
113
-    selectAllInputs( m_root, EnterWindowMask );
114
-    return EXIT_SUCCESS;
115
-}
116
-
117
-#ifdef OPENGL_ENABLED
118
-std::vector<XRRCrtcInfo*> slop::XEngine::getCRTCS() {
119
-    std::vector<XRRCrtcInfo*> monitors;
120
-    if ( !m_res ) {
121
-        return monitors;
122
-    }
123
-    for ( int i=0;i<m_res->ncrtc;i++ ) {
124
-        monitors.push_back( XRRGetCrtcInfo( m_display, m_res, m_res->crtcs[ i ] ) );
125
-    }
126
-    return monitors;
127
-}
128
-
129
-void slop::XEngine::freeCRTCS( std::vector<XRRCrtcInfo*> monitors ) {
130
-    for ( unsigned int i=0;i<monitors.size();i++ ) {
131
-        XRRFreeCrtcInfo( monitors[ i ] );
132
-    }
133
-}
134
-#endif // OPENGL_ENABLED
135
-
136
-bool slop::XEngine::keyPressed( KeySym key ) {
137
-    KeyCode keycode = XKeysymToKeycode( m_display, key );
138
-    if ( keycode != 0 ) {
139
-        // Get the whole keyboard state
140
-        char keys[32];
141
-        XQueryKeymap( m_display, keys );
142
-        // Check our keycode
143
-        return ( keys[ keycode / 8 ] & ( 1 << ( keycode % 8 ) ) ) != 0;
144
-    } else {
145
-        return false;
146
-    }
147
-}
148
-
149
-bool slop::XEngine::anyKeyPressed() {
150
-    if ( !m_good ) {
151
-        return false;
152
-    }
153
-    // Thanks to SFML for some reliable key state grabbing.
154
-    // Get the whole keyboard state
155
-    char keys[ 32 ];
156
-    XQueryKeymap( m_display, keys );
157
-    // Each bit indicates a different key, 1 for pressed, 0 otherwise.
158
-    // Every bit should be 0 if nothing is pressed.
159
-    for ( unsigned int i = 0; i < 32; i++ ) {
160
-        if ( keys[ i ] != 0 ) {
161
-            return true;
162
-        }
163
-    }
164
-    return false;
165
-}
166
-
167
-int slop::XEngine::grabKeyboard() {
168
-    if ( !m_good ) {
169
-        return EXIT_FAILURE;
170
-    }
171
-    int err = XGrabKeyboard( m_display, m_root, False, GrabModeAsync, GrabModeAsync, CurrentTime );
172
-    if ( err != GrabSuccess ) {
173
-        fprintf( stderr, "Warning: Failed to grab X keyboard.\n" );
174
-        fprintf( stderr, "         This happens when something has already grabbed your keybaord.\n" );
175
-        fprintf( stderr, "         slop should still run properly though.\n" );
176
-        return EXIT_FAILURE;
177
-    }
178
-    return EXIT_SUCCESS;
179
-}
180
-
181
-int slop::XEngine::releaseKeyboard() {
182
-    if ( !m_good ) {
183
-        return EXIT_FAILURE;
184
-    }
185
-    XUngrabKeyboard( m_display, CurrentTime );
186
-    return EXIT_SUCCESS;
187
-}
188
-
189
-void slop::XEngine::selectAllInputs( Window win, long event_mask) {
190
-    Window root, parent;
191
-    Window* children;
192
-    unsigned int nchildren;
193
-    XQueryTree( m_display, win, &root, &parent, &children, &nchildren );
194
-    for ( unsigned int i=0;i<nchildren;i++ ) {
195
-        XSelectInput( m_display, children[ i ], event_mask );
196
-        selectAllInputs( children[ i ], event_mask );
197
-    }
198
-    free( children );
199
-}
200
-
201
-// Grabs the cursor, be wary that setCursor changes the mouse masks.
202
-// waittime is how long grabCursor can repeatedly try to grab the cursor, if it fails to grab.
203
-// This is because tiling window managers like i3 grab the mouse while holding down certain keys,
204
-// while these certain keys also launch slop.
205
-int slop::XEngine::grabCursor( slop::CursorType type, double waittime ) {
206
-    if ( !m_good ) {
207
-        return EXIT_FAILURE;
208
-    }
209
-    int xfontcursor = makeCursor( type );
210
-    int err = XGrabPointer( m_display, m_root, True,
211
-                            PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
212
-                            GrabModeAsync, GrabModeAsync, None, xfontcursor, CurrentTime );
213
-    double accumulationtime = 0;
214
-    int timestep = 10000; // in microseconds
215
-    while ( err != GrabSuccess && accumulationtime < waittime ) {
216
-        err = XGrabPointer( m_display, m_root, True,
217
-                            PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
218
-                            GrabModeAsync, GrabModeAsync, None, xfontcursor, CurrentTime );
219
-        usleep( timestep );
220
-        accumulationtime += double( timestep/1000000.f );
221
-    }
222
-    if ( err != GrabSuccess ) {
223
-        fprintf( stderr, "Error: Failed to grab X cursor.\n" );
224
-        switch( err ) {
225
-            case 1:
226
-                fprintf( stderr, "       The cursor is already grabbed by another application.\n" );
227
-                break;
228
-            case 2:
229
-                fprintf( stderr, "       The cursor grab was initiated at an invalid time (in the past?) .\n" );
230
-                break;
231
-            case 3:
232
-                fprintf( stderr, "       The cursor is not viewable or outside of the bounds of the root window.\n" );
233
-                break;
234
-            case 4:
235
-                fprintf( stderr, "       The grab is frozen already by an active grab by another application.\n" );
236
-                break;
237
-            default:
238
-                break;
239
-        }
240
-        fprintf( stderr, "       This can be caused by launching slop weirdly.\n" );
241
-        return EXIT_FAILURE;
242
-    }
243
-    // Quickly set the mouse position so we don't have to worry about x11 generating an event.
244
-    Window root, child;
245
-    int mx, my;
246
-    int wx, wy;
247
-    unsigned int mask;
248
-    XQueryPointer( m_display, m_root, &root, &child, &mx, &my, &wx, &wy, &mask );
249
-    m_mousex = mx;
250
-    m_mousey = my;
251
-
252
-    // Get the deepest available window.
253
-    Window test = child;
254
-    while( test ) {
255
-        child = test;
256
-        XQueryPointer( m_display, child, &root, &test, &mx, &my, &wx, &wy, &mask );
257
-    }
258
-    m_hoverWindow = child;
259
-    return EXIT_SUCCESS;
260
-}
261
-
262
-int slop::XEngine::releaseCursor() {
263
-    if ( !m_good ) {
264
-        return EXIT_FAILURE;
265
-    }
266
-    XUngrabPointer( m_display, CurrentTime );
267
-    return EXIT_SUCCESS;
268
-}
269
-
270
-void slop::XEngine::tick() {
271
-    if ( !m_good ) {
272
-        return;
273
-    }
274
-    XEvent event;
275
-    while ( XPending( m_display ) ) {
276
-        XNextEvent( m_display, &event );
277
-        switch ( event.type ) {
278
-            case MotionNotify: {
279
-                m_mousex = event.xmotion.x;
280
-                m_mousey = event.xmotion.y;
281
-                break;
282
-            }
283
-            case ButtonPress: {
284
-                // Our pitiful mouse manager--
285
-                if ( m_mouse.size() > event.xbutton.button ) {
286
-                    m_mouse.at( event.xbutton.button ) = true;
287
-                } else {
288
-                    m_mouse.resize( event.xbutton.button+2, false );
289
-                    m_mouse.at( event.xbutton.button ) = true;
290
-                }
291
-                break;
292
-            }
293
-            case EnterNotify: {
294
-                if ( event.xcrossing.subwindow != None ) {
295
-                    m_hoverWindow = event.xcrossing.subwindow;
296
-                } else {
297
-                    m_hoverWindow = event.xcrossing.window;
298
-                }
299
-                break;
300
-            }
301
-            case ButtonRelease: {
302
-                if ( m_mouse.size() > event.xbutton.button ) {
303
-                    m_mouse.at( event.xbutton.button ) = false;
304
-                } else {
305
-                    m_mouse.resize( event.xbutton.button+2, false );
306
-                    m_mouse.at( event.xbutton.button ) = false;
307
-                }
308
-                break;
309
-            }
310
-            default: break;
311
-        }
312
-    }
313
-}
314
-
315
-// This converts an enum into a preallocated cursor, the cursor will automatically deallocate itself on ~XEngine
316
-Cursor slop::XEngine::makeCursor( slop::CursorType type ) {
317
-    int xfontcursor;
318
-    switch ( type ) {
319
-        default:
320
-        case Left:                  xfontcursor = XC_left_ptr; break;
321
-        case Crosshair:             xfontcursor = XC_crosshair; break;
322
-        case Cross:                 xfontcursor = XC_cross; break;
323
-        case UpperLeftCorner:       xfontcursor = XC_ul_angle; break;
324
-        case UpperRightCorner:      xfontcursor = XC_ur_angle; break;
325
-        case LowerLeftCorner:       xfontcursor = XC_ll_angle; break;
326
-        case LowerRightCorner:      xfontcursor = XC_lr_angle; break;
327
-        case Dot:                   xfontcursor = XC_dot; break;
328
-        case Box:                   xfontcursor = 40; break;
329
-    }
330
-    Cursor newcursor = 0;
331
-    if ( m_cursors.size() > (unsigned int)xfontcursor ) {
332
-        newcursor = m_cursors.at( xfontcursor );
333
-    }
334
-    if ( !newcursor ) {
335
-        newcursor = XCreateFontCursor( m_display, xfontcursor );
336
-        m_cursors.resize( xfontcursor+2, 0 );
337
-        m_cursors.at( xfontcursor ) = newcursor;
338
-    }
339
-    return newcursor;
340
-}
341
-
342
-slop::CursorType slop::XEngine::getCursor() {
343
-    if ( m_currentCursor ) {
344
-        return m_currentCursor;
345
-    } else {
346
-        return slop::Left;
347
-    }
348
-}
349
-
350
-// Swaps out the current cursor, bewary that XChangeActivePointerGrab also resets masks, so if you change the mouse masks on grab you need to change them here too.
351
-void slop::XEngine::setCursor( slop::CursorType type ) {
352
-    if ( !m_good ) {
353
-        return;
354
-    }
355
-    m_currentCursor = type;
356
-    Cursor xfontcursor = makeCursor( type );
357
-    XChangeActivePointerGrab( m_display,
358
-                              PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
359
-                              xfontcursor, CurrentTime );
360
-}
361
-
362
-void slop::WindowRectangle::applyPadding( int padding ) {
363
-    if ( (int)m_width + padding*2 >= 0 ) {
364
-        m_x -= padding;
365
-        m_width += padding*2;
366
-    }
367
-    if ( (int)m_height + padding*2 >= 0 ) {
368
-        m_y -= padding;
369
-        m_height += padding*2;
370
-    }
371
-}
372
-
373
-Window slop::WindowRectangle::getWindow() {
374
-    return m_window;
375
-}
376
-
377
-void slop::WindowRectangle::applyMinMaxSize( unsigned int minimumsize, unsigned int maximumsize ) {
378
-    if ( minimumsize > maximumsize && maximumsize > 0 ) {
379
-        fprintf( stderr, "Error: minimumsize is greater than maximumsize.\n" );
380
-        exit( 1 );
381
-    }
382
-    if ( m_width < minimumsize ) {
383
-        int diff = minimumsize - m_width;
384
-        m_width = minimumsize;
385
-        m_x -= diff/2;
386
-    }
387
-    if ( m_height < minimumsize ) {
388
-        int diff = minimumsize - m_height;
389
-        m_height = minimumsize;
390
-        m_y -= diff/2;
391
-    }
392
-    if ( maximumsize > 0 ) {
393
-        if ( m_width > maximumsize ) {
394
-            int diff = m_width;
395
-            m_width = maximumsize;
396
-            // Center in the center of the window
397
-            m_x += diff/2 - maximumsize/2;
398
-        }
399
-        if ( m_height > maximumsize ) {
400
-            int diff = m_height;
401
-            m_height = maximumsize;
402
-            // Center in the center of the window
403
-            m_y += diff/2 - maximumsize/2;
404
-        }
405
-    }
406
-}
407
-
408
-void slop::WindowRectangle::setGeometry( Window win, bool decorations ) {
409
-    if ( decorations ) {
410
-        Window root, parent, test, junk;
411
-        Window* childlist;
412
-        unsigned int ujunk;
413
-        // Try to find the actual decorations.
414
-        test = win;
415
-        int status = XQueryTree( xengine->m_display, test, &root, &parent, &childlist, &ujunk);
416
-        free( childlist );
417
-        while( parent != root ) {
418
-            if ( !parent || !status ) {
419
-                break;
420
-            }
421
-            test = parent;
422
-            status = XQueryTree( xengine->m_display, test, &root, &parent, &childlist, &ujunk);
423
-            free( childlist );
424
-        }
425
-        // test contains the window we're screenshotting.
426
-        m_window = test;
427
-        // Once found, proceed normally.
428
-        if ( test && parent == root && status ) {
429
-            XWindowAttributes attr;
430
-            XGetWindowAttributes( xengine->m_display, test, &attr );
431
-            m_width = attr.width;
432
-            m_height = attr.height;
433
-            m_border = attr.border_width;
434
-            XTranslateCoordinates( xengine->m_display, test, attr.root, -attr.border_width, -attr.border_width, &(m_x), &(m_y), &junk );
435
-            // We make sure we include borders, since we want decorations.
436
-            m_width += m_border * 2;
437
-            m_height += m_border * 2;
438
-        }
439
-        return;
440
-    }
441
-    Window junk;
442
-    // Now here we should be able to just use whatever we get.
443
-    XWindowAttributes attr;
444
-    // We use XGetWindowAttributes to know our root window.
445
-    XGetWindowAttributes( xengine->m_display, win, &attr );
446
-    //m_x = attr.x;
447
-    //m_y = attr.y;
448
-    m_width = attr.width;
449
-    m_height = attr.height;
450
-    m_border = attr.border_width;
451
-    XTranslateCoordinates( xengine->m_display, win, attr.root, -attr.border_width, -attr.border_width, &(m_x), &(m_y), &junk );
452
-    m_window = win;
453
-}

+ 0
- 115
src/x.hpp View File

@@ -1,115 +0,0 @@
1
-/* x.hpp: Handles starting and managing X.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
-#ifndef IS_X_H_
22
-#define IS_X_H_
23
-
24
-#include <unistd.h>
25
-
26
-#include <X11/Xlib.h>
27
-#include <X11/cursorfont.h>
28
-#include <X11/extensions/shape.h>
29
-#include <X11/extensions/Xrandr.h>
30
-
31
-#include <stdlib.h>
32
-#include <cstring>
33
-#include <cstdlib>
34
-#include <cmath>
35
-#include <cstdio>
36
-#include <string>
37
-#include <vector>
38
-
39
-namespace slop {
40
-
41
-enum CursorType {
42
-    Left,
43
-    Crosshair,
44
-    Cross,
45
-    UpperLeftCorner,
46
-    UpperRightCorner,
47
-    LowerRightCorner,
48
-    LowerLeftCorner,
49
-    Dot,
50
-    Box
51
-};
52
-
53
-class WindowRectangle {
54
-public:
55
-    int          m_x;
56
-    int          m_y;
57
-    unsigned int m_width;
58
-    unsigned int m_height;
59
-    unsigned int m_border;
60
-    Window       m_window;
61
-    bool         m_decorations;
62
-    Window       getWindow();
63
-    void         setGeometry( Window win, bool decorations );
64
-    void         applyPadding( int padding );
65
-    void         applyMinMaxSize( unsigned int minimumsize, unsigned int maximumsize );
66
-};
67
-
68
-class XEngine {
69
-public:
70
-                        XEngine();
71
-                        ~XEngine();
72
-    int                 init( std::string display );
73
-    void                tick();
74
-    int                 grabCursor( slop::CursorType type, double waittime );
75
-    int                 grabKeyboard();
76
-    bool                anyKeyPressed();
77
-    bool                keyPressed( KeySym key );
78
-    int                 releaseCursor();
79
-    int                 releaseKeyboard();
80
-    void                setCursor( slop::CursorType type );
81
-    slop::CursorType    getCursor();
82
-    void                drawRect( int x, int y, unsigned int w, unsigned int h );
83
-    unsigned int        getWidth();
84
-    unsigned int        getHeight();
85
-#ifdef OPENGL_ENABLED
86
-    std::vector<XRRCrtcInfo*>        getCRTCS();
87
-    void                freeCRTCS( std::vector<XRRCrtcInfo*> monitors );
88
-#endif // OPENGL_ENABLED
89
-    int                 m_mousex;
90
-    int                 m_mousey;
91
-    Display*            m_display;
92
-    Visual*             m_visual;
93
-    Screen*             m_screen;
94
-    Colormap            m_colormap;
95
-    Window              m_root;
96
-    Window              m_hoverWindow;
97
-    std::vector<bool>   m_mouse;
98
-    bool                mouseDown( unsigned int button );
99
-    bool                m_keypressed;
100
-    XRRScreenResources* m_res;
101
-private:
102
-    slop::CursorType    m_currentCursor;
103
-    bool                m_good;
104
-    std::vector<Cursor> m_cursors;
105
-    Cursor              makeCursor( slop::CursorType type );
106
-    void                selectAllInputs( Window win, long event_mask);
107
-};
108
-
109
-int XEngineErrorHandler( Display* dpy, XErrorEvent* event );
110
-
111
-}
112
-
113
-extern slop::XEngine* xengine;
114
-
115
-#endif // IS_X_H_

+ 0
- 189
src/xselectrectangle.cpp View File

@@ -1,189 +0,0 @@
1
-/* xselectrectangle.cpp: Handles creating rectangles on the screen in pure X11.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-#include "xselectrectangle.hpp"
21
-
22
-static Bool isDestroyNotify( Display* dpy, XEvent* ev, XPointer win ) {
23
-    return ev->type == DestroyNotify && ev->xdestroywindow.window == *((Window*)win);
24
-}
25
-
26
-slop::XSelectRectangle::~XSelectRectangle() {
27
-    if ( m_window == None ) {
28
-        return;
29
-    }
30
-    // Try to erase the window before destroying it.
31
-    XSetWindowBackground( xengine->m_display, m_window, 0 );
32
-    XClearWindow( xengine->m_display, m_window );
33
-    // Sleep for 0.1 seconds in hope that the rectangle was erased.
34
-    usleep( 10000 );
35
-    // Free up our color.
36
-    XFreeColors( xengine->m_display, xengine->m_colormap, &m_color.pixel, 1, 0 );
37
-    XDestroyWindow( xengine->m_display, m_window );
38
-    XEvent event;
39
-    // Block until the window is actually completely removed.
40
-    XIfEvent( xengine->m_display, &event, &isDestroyNotify, (XPointer)&m_window );
41
-    // Sleep for 0.1 seconds in hope that the screen actually cleared the window.
42
-    usleep( 10000 );
43
-}
44
-
45
-slop::XSelectRectangle::XSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a ) {
46
-    m_x = std::min( sx, ex );
47
-    m_y = std::min( sy, ey );
48
-    m_width = std::max( sx, ex ) - m_x;
49
-    m_height = std::max( sy, ey ) - m_y;
50
-    m_border = border;
51
-    m_window = None;
52
-    m_highlight = highlight;
53
-
54
-    // If we don't have a border, we don't exist, so just die.
55
-    if ( m_border == 0 ) {
56
-        return;
57
-    }
58
-
59
-    if ( m_highlight ) {
60
-        m_border = 0;
61
-    }
62
-
63
-    m_color = convertColor( r, g, b );
64
-    XSetWindowAttributes attributes;
65
-    // Set up the window so it's our color 
66
-    attributes.background_pixel = m_color.pixel;
67
-    // Disable window decorations.
68
-    attributes.override_redirect = True;
69
-    // Make sure we know when we've been successfully destroyed later!
70
-    attributes.event_mask = StructureNotifyMask;
71
-    unsigned long valueMask = CWBackPixel | CWOverrideRedirect | CWEventMask;
72
-
73
-    // Create the window
74
-    m_window = XCreateWindow( xengine->m_display, xengine->m_root, 0, 0, xengine->getWidth(), xengine->getHeight(),
75
-                              0, CopyFromParent, InputOutput,
76
-                              CopyFromParent, valueMask, &attributes );
77
-
78
-
79
-    if ( a < 1 ) {
80
-        // Change the window opacity
81
-        unsigned int cardinal_alpha = (unsigned int) (a * (unsigned int)-1) ;
82
-        XChangeProperty( xengine->m_display, m_window, XInternAtom( xengine->m_display, "_NET_WM_WINDOW_OPACITY", 0),
83
-                         XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&cardinal_alpha, 1 );
84
-    }
85
-
86
-    XClassHint classhints;
87
-    char name[] = "slop";
88
-    classhints.res_name = name;
89
-    classhints.res_class = name;
90
-    XSetClassHint( xengine->m_display, m_window, &classhints );
91
-
92
-    // Now punch a hole into it so it looks like a selection rectangle, but only if we're not highlighting.
93
-    if ( !m_highlight ) {
94
-        XRectangle rects[4];
95
-        // Left
96
-        rects[0].x = m_x-m_border;
97
-        rects[0].y = m_y-m_border;
98
-        rects[0].width = m_border;
99
-        rects[0].height = m_height+m_border*2;
100
-        // Top
101
-        rects[1].x = m_x;
102
-        rects[1].y = m_y-m_border;
103
-        rects[1].width = m_width+m_border;
104
-        rects[1].height = m_border;
105
-        // Right
106
-        rects[2].x = m_x+m_width;
107
-        rects[2].y = m_y-m_border;
108
-        rects[2].width = m_border;
109
-        rects[2].height = m_height+m_border*2;
110
-        // Bottom
111
-        rects[3].x = m_x;
112
-        rects[3].y = m_y+m_height;
113
-        rects[3].width = m_width+m_border;
114
-        rects[3].height = m_border;
115
-        XShapeCombineRectangles( xengine->m_display, m_window, ShapeBounding, 0, 0, rects, 4, ShapeSet, 0);
116
-    } else {
117
-        XRectangle rect;
118
-        rect.x = m_x;
119
-        rect.y = m_y;
120
-        rect.width = m_width;
121
-        rect.height = m_height;
122
-        XShapeCombineRectangles( xengine->m_display, m_window, ShapeBounding, 0, 0, &rect, 1, ShapeSet, 0);
123
-    }
124
-    // Make it so all input falls through
125
-    XRectangle rect;
126
-    rect.x = rect.y = rect.width = rect.height = 0;
127
-    XShapeCombineRectangles( xengine->m_display, m_window, ShapeInput, 0, 0, &rect, 1, ShapeSet, 0);
128
-    XMapWindow( xengine->m_display, m_window );
129
-}
130
-
131
-void slop::XSelectRectangle::setGeo( int sx, int sy, int ex, int ey ) {
132
-    int x = std::min( sx, ex );
133
-    int y = std::min( sy, ey );
134
-    int w = std::max( sx, ex ) - x;
135
-    int h = std::max( sy, ey ) - y;
136
-
137
-    // Only resize or move if we have to, because they're oddly expensive.
138
-    m_x = x;
139
-    m_y = y;
140
-    m_width = w;
141
-    m_height = h;
142
-    if ( m_border > 0 ) {
143
-        XRectangle rects[4];
144
-        // Left
145
-        rects[0].x = m_x-m_border;
146
-        rects[0].y = m_y-m_border;
147
-        rects[0].width = m_border;
148
-        rects[0].height = m_height+m_border*2;
149
-        // Top
150
-        rects[1].x = m_x;
151
-        rects[1].y = m_y-m_border;
152
-        rects[1].width = m_width+m_border;
153
-        rects[1].height = m_border;
154
-        // Right
155
-        rects[2].x = m_x+m_width;
156
-        rects[2].y = m_y-m_border;
157
-        rects[2].width = m_border;
158
-        rects[2].height = m_height+m_border*2;
159
-        // Bottom
160
-        rects[3].x = m_x;
161
-        rects[3].y = m_y+m_height;
162
-        rects[3].width = m_width+m_border;
163
-        rects[3].height = m_border;
164
-        XShapeCombineRectangles( xengine->m_display, m_window, ShapeBounding, 0, 0, rects, 4, ShapeSet, 0);
165
-    } else {
166
-        XRectangle rect;
167
-        rect.x = m_x;
168
-        rect.y = m_y;
169
-        rect.width = m_width;
170
-        rect.height = m_height;
171
-        XShapeCombineRectangles( xengine->m_display, m_window, ShapeBounding, 0, 0, &rect, 1, ShapeSet, 0);
172
-    }
173
-}
174
-
175
-XColor slop::XSelectRectangle::convertColor( float r, float g, float b ) {
176
-    // Convert float colors to shorts.
177
-    short red   = short( floor( r * 65535.f ) );
178
-    short green = short( floor( g * 65535.f ) );
179
-    short blue  = short( floor( b * 65535.f ) );
180
-    XColor color;
181
-    color.red = red;
182
-    color.green = green;
183
-    color.blue = blue;
184
-    int err = XAllocColor( xengine->m_display, xengine->m_colormap, &color );
185
-    if ( err == BadColor ) {
186
-        fprintf( stderr, "Couldn't allocate color of value %f,%f,%f!\n", r, g, b );
187
-    }
188
-    return color;
189
-}

+ 0
- 56
src/xselectrectangle.hpp View File

@@ -1,56 +0,0 @@
1
-/* xselectrectangle.hpp: Handles creating rectangles on the screen in pure X11.
2
- *
3
- * Copyright (C) 2014: Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors).
4
- *
5
- * This file is part of Slop.
6
- *
7
- * Slop is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation, either version 3 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * Slop is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with Slop.  If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
-#ifndef IS_X_SELECT_RECTANGLE_H_
22
-#define IS_X_SELECT_RECTANGLE_H_
23
-
24
-#include "x.hpp"
25
-#include "selectrectangle.hpp"
26
-
27
-#include <unistd.h>
28
-
29
-#include <X11/Xlib.h>
30
-#include <X11/extensions/shape.h>
31
-#include <X11/Xatom.h>
32
-
33
-#include <cstdlib>
34
-#include <cmath>
35
-#include <cstdio>
36
-#include <string>
37
-#include <vector>
38
-
39
-namespace slop {
40
-
41
-class XSelectRectangle: public SelectRectangle {
42
-public:
43
-            XSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a );
44
-            ~XSelectRectangle();
45
-    void    setPos( int x, int y );
46
-    void    setDim( int w, int h );
47
-    void    setGeo( int x, int y, int w, int h );
48
-    XColor  m_color;
49
-private:
50
-    XColor  convertColor( float r, float g, float b );
51
-    void    constrain( int w, int h );
52
-};
53
-
54
-}
55
-
56
-#endif // IS_X_SELECT_RECTANGLE_H_