Browse Source

Added an experimental magnifying glass for --opengl only.

Dalton Nell 9 years ago
parent
commit
7f3edc8df3

+ 3
- 0
CMakeLists.txt View File

90
 find_package( OpenGL    REQUIRED )
90
 find_package( OpenGL    REQUIRED )
91
 find_package( GLX       REQUIRED )
91
 find_package( GLX       REQUIRED )
92
 find_package( XRender   REQUIRED )
92
 find_package( XRender   REQUIRED )
93
+find_package( XRandr    REQUIRED )
93
 # This library is needed only for Ubuntu it seems, some platforms don't even
94
 # This library is needed only for Ubuntu it seems, some platforms don't even
94
 # ship with it. I couldn't find a way to do a test compile to check if librt
95
 # ship with it. I couldn't find a way to do a test compile to check if librt
95
 # was needed, so instead I just didn't mark it as REQUIRED.
96
 # was needed, so instead I just didn't mark it as REQUIRED.
102
 if ( RT_INCLUDE_DIR )
103
 if ( RT_INCLUDE_DIR )
103
     include_directories( ${X11_INCLUDE_DIR}
104
     include_directories( ${X11_INCLUDE_DIR}
104
                          ${XEXT_INCLUDE_DIR}
105
                          ${XEXT_INCLUDE_DIR}
106
+                         ${XRANDR_INCLUDE_DIR}
105
                          ${OPENGL_INCLUDE_DIR}
107
                          ${OPENGL_INCLUDE_DIR}
106
                          ${GLX_INCLUDE_DIR}
108
                          ${GLX_INCLUDE_DIR}
107
                          ${XRENDER_INCLUDE_DIRS}
109
                          ${XRENDER_INCLUDE_DIRS}
124
                            ${GLX_LIBRARIES}
126
                            ${GLX_LIBRARIES}
125
                            ${XRENDER_LIBRARIES}
127
                            ${XRENDER_LIBRARIES}
126
                            "${XEXT_LIBRARY}"
128
                            "${XEXT_LIBRARY}"
129
+                           "${XRANDR_LIBRARY}"
127
                            "${RT_LIBRARY}" )
130
                            "${RT_LIBRARY}" )
128
 else()
131
 else()
129
     target_link_libraries( "${BIN_TARGET}"
132
     target_link_libraries( "${BIN_TARGET}"

+ 44
- 0
cmakemodules/FindGLX.cmake View File

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
+)

+ 26
- 0
cmakemodules/FindXRandr.cmake View File

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 )

+ 47
- 0
cmakemodules/FindXRender.cmake View File

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)

+ 71
- 1
src/cmdline.c View File

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')",
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)",
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)",
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')",
52
   "  -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')",
55
   "  -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')",
53
   "\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    $ # 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",
56
   "\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    $ # 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",
54
     0
57
     0
58
   , ARG_FLAG
61
   , ARG_FLAG
59
   , ARG_STRING
62
   , ARG_STRING
60
   , ARG_INT
63
   , ARG_INT
64
+  , ARG_FLOAT
61
 } cmdline_parser_arg_type;
65
 } cmdline_parser_arg_type;
62
 
66
 
63
 static
67
 static
90
   args_info->max_given = 0 ;
94
   args_info->max_given = 0 ;
91
   args_info->highlight_given = 0 ;
95
   args_info->highlight_given = 0 ;
92
   args_info->opengl_given = 0 ;
96
   args_info->opengl_given = 0 ;
97
+  args_info->magnify_given = 0 ;
98
+  args_info->magstrength_given = 0 ;
99
+  args_info->magpixels_given = 0 ;
93
   args_info->format_given = 0 ;
100
   args_info->format_given = 0 ;
94
 }
101
 }
95
 
102
 
117
   args_info->max_orig = NULL;
124
   args_info->max_orig = NULL;
118
   args_info->highlight_flag = 0;
125
   args_info->highlight_flag = 0;
119
   args_info->opengl_flag = 0;
126
   args_info->opengl_flag = 0;
127
+  args_info->magnify_flag = 0;
128
+  args_info->magstrength_arg = 4;
129
+  args_info->magstrength_orig = NULL;
130
+  args_info->magpixels_arg = 64;
131
+  args_info->magpixels_orig = NULL;
120
   args_info->format_arg = gengetopt_strdup ("X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n");
132
   args_info->format_arg = gengetopt_strdup ("X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n");
121
   args_info->format_orig = NULL;
133
   args_info->format_orig = NULL;
122
   
134
   
141
   args_info->max_help = gengetopt_args_info_help[12] ;
153
   args_info->max_help = gengetopt_args_info_help[12] ;
142
   args_info->highlight_help = gengetopt_args_info_help[13] ;
154
   args_info->highlight_help = gengetopt_args_info_help[13] ;
143
   args_info->opengl_help = gengetopt_args_info_help[14] ;
155
   args_info->opengl_help = gengetopt_args_info_help[14] ;
144
-  args_info->format_help = gengetopt_args_info_help[15] ;
156
+  args_info->magnify_help = gengetopt_args_info_help[15] ;
157
+  args_info->magstrength_help = gengetopt_args_info_help[16] ;
158
+  args_info->magpixels_help = gengetopt_args_info_help[17] ;
159
+  args_info->format_help = gengetopt_args_info_help[18] ;
145
   
160
   
146
 }
161
 }
147
 
162
 
236
   free_string_field (&(args_info->color_orig));
251
   free_string_field (&(args_info->color_orig));
237
   free_string_field (&(args_info->min_orig));
252
   free_string_field (&(args_info->min_orig));
238
   free_string_field (&(args_info->max_orig));
253
   free_string_field (&(args_info->max_orig));
254
+  free_string_field (&(args_info->magstrength_orig));
255
+  free_string_field (&(args_info->magpixels_orig));
239
   free_string_field (&(args_info->format_arg));
256
   free_string_field (&(args_info->format_arg));
240
   free_string_field (&(args_info->format_orig));
257
   free_string_field (&(args_info->format_orig));
241
   
258
   
296
     write_into_file(outfile, "highlight", 0, 0 );
313
     write_into_file(outfile, "highlight", 0, 0 );
297
   if (args_info->opengl_given)
314
   if (args_info->opengl_given)
298
     write_into_file(outfile, "opengl", 0, 0 );
315
     write_into_file(outfile, "opengl", 0, 0 );
316
+  if (args_info->magnify_given)
317
+    write_into_file(outfile, "magnify", 0, 0 );
318
+  if (args_info->magstrength_given)
319
+    write_into_file(outfile, "magstrength", args_info->magstrength_orig, 0);
320
+  if (args_info->magpixels_given)
321
+    write_into_file(outfile, "magpixels", args_info->magpixels_orig, 0);
299
   if (args_info->format_given)
322
   if (args_info->format_given)
300
     write_into_file(outfile, "format", args_info->format_orig, 0);
323
     write_into_file(outfile, "format", args_info->format_orig, 0);
301
   
324
   
470
   case ARG_INT:
493
   case ARG_INT:
471
     if (val) *((int *)field) = strtol (val, &stop_char, 0);
494
     if (val) *((int *)field) = strtol (val, &stop_char, 0);
472
     break;
495
     break;
496
+  case ARG_FLOAT:
497
+    if (val) *((float *)field) = (float)strtod (val, &stop_char);
498
+    break;
473
   case ARG_STRING:
499
   case ARG_STRING:
474
     if (val) {
500
     if (val) {
475
       string_field = (char **)field;
501
       string_field = (char **)field;
485
   /* check numeric conversion */
511
   /* check numeric conversion */
486
   switch(arg_type) {
512
   switch(arg_type) {
487
   case ARG_INT:
513
   case ARG_INT:
514
+  case ARG_FLOAT:
488
     if (val && !(stop_char && *stop_char == '\0')) {
515
     if (val && !(stop_char && *stop_char == '\0')) {
489
       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
516
       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
490
       return 1; /* failure */
517
       return 1; /* failure */
566
         { "max",	1, NULL, 0 },
593
         { "max",	1, NULL, 0 },
567
         { "highlight",	0, NULL, 'l' },
594
         { "highlight",	0, NULL, 'l' },
568
         { "opengl",	0, NULL, 0 },
595
         { "opengl",	0, NULL, 0 },
596
+        { "magnify",	0, NULL, 0 },
597
+        { "magstrength",	1, NULL, 0 },
598
+        { "magpixels",	1, NULL, 0 },
569
         { "format",	1, NULL, 'f' },
599
         { "format",	1, NULL, 'f' },
570
         { 0,  0, 0, 0 }
600
         { 0,  0, 0, 0 }
571
       };
601
       };
745
                 additional_error))
775
                 additional_error))
746
               goto failure;
776
               goto failure;
747
           
777
           
778
+          }
779
+          /* Display a magnifying glass when --opengl is also enabled..  */
780
+          else if (strcmp (long_options[option_index].name, "magnify") == 0)
781
+          {
782
+          
783
+          
784
+            if (update_arg((void *)&(args_info->magnify_flag), 0, &(args_info->magnify_given),
785
+                &(local_args_info.magnify_given), optarg, 0, 0, ARG_FLAG,
786
+                check_ambiguity, override, 1, 0, "magnify", '-',
787
+                additional_error))
788
+              goto failure;
789
+          
790
+          }
791
+          /* Sets how many times the magnification window size is multiplied..  */
792
+          else if (strcmp (long_options[option_index].name, "magstrength") == 0)
793
+          {
794
+          
795
+          
796
+            if (update_arg( (void *)&(args_info->magstrength_arg), 
797
+                 &(args_info->magstrength_orig), &(args_info->magstrength_given),
798
+                &(local_args_info.magstrength_given), optarg, 0, "4", ARG_FLOAT,
799
+                check_ambiguity, override, 0, 0,
800
+                "magstrength", '-',
801
+                additional_error))
802
+              goto failure;
803
+          
804
+          }
805
+          /* Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification..  */
806
+          else if (strcmp (long_options[option_index].name, "magpixels") == 0)
807
+          {
808
+          
809
+          
810
+            if (update_arg( (void *)&(args_info->magpixels_arg), 
811
+                 &(args_info->magpixels_orig), &(args_info->magpixels_given),
812
+                &(local_args_info.magpixels_given), optarg, 0, "64", ARG_INT,
813
+                check_ambiguity, override, 0, 0,
814
+                "magpixels", '-',
815
+                additional_error))
816
+              goto failure;
817
+          
748
           }
818
           }
749
           
819
           
750
           break;
820
           break;

+ 11
- 0
src/cmdline.in View File

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.  */
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).  */
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.  */
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.  */
74
   char * format_arg;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. (default='REPLACEME').  */
82
   char * format_arg;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. (default='REPLACEME').  */
75
   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.  */
83
   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.  */
76
   const char *format_help; /**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. help description.  */
84
   const char *format_help; /**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. help description.  */
89
   unsigned int max_given ;	/**< @brief Whether max was given.  */
97
   unsigned int max_given ;	/**< @brief Whether max was given.  */
90
   unsigned int highlight_given ;	/**< @brief Whether highlight was given.  */
98
   unsigned int highlight_given ;	/**< @brief Whether highlight was given.  */
91
   unsigned int opengl_given ;	/**< @brief Whether opengl was given.  */
99
   unsigned int opengl_given ;	/**< @brief Whether opengl was given.  */
100
+  unsigned int magnify_given ;	/**< @brief Whether magnify was given.  */
101
+  unsigned int magstrength_given ;	/**< @brief Whether magstrength was given.  */
102
+  unsigned int magpixels_given ;	/**< @brief Whether magpixels was given.  */
92
   unsigned int format_given ;	/**< @brief Whether format was given.  */
103
   unsigned int format_given ;	/**< @brief Whether format was given.  */
93
 
104
 
94
 } ;
105
 } ;

+ 237
- 4
src/glselectrectangle.cpp View File

41
     usleep( 10000 );
41
     usleep( 10000 );
42
 }
42
 }
43
 
43
 
44
+void slop::GLSelectRectangle::constrainWithinMonitor( int* x, int* y, int* w, int* h ) {
45
+    m_offsetx = 0;
46
+    m_offsety = 0;
47
+    m_offsetw = 0;
48
+    m_offseth = 0;
49
+    for ( unsigned int i=0;i<m_monitors.size();i++ ) {
50
+        XRRCrtcInfo* monitor = m_monitors[ i ];
51
+        if ( !((int)xengine->m_mousex >= (int)monitor->x && (int)xengine->m_mousey >= (int)monitor->y &&
52
+               (int)xengine->m_mousex <= (int)(monitor->x+monitor->width) && (int)xengine->m_mousey <= (int)(monitor->y+monitor->height) ) ) {
53
+            continue;
54
+        }
55
+        if ( (int)*x < (int)monitor->x ) {
56
+            m_offsetx = monitor->x-*x;
57
+            *w += *x-monitor->x;
58
+            *x = monitor->x;
59
+        }
60
+        if ( (int)(*x+*w) >= (int)(monitor->x+monitor->width) ) {
61
+            m_offsetw = (monitor->width-1-(*x-monitor->x+*w));
62
+            *w = monitor->width-1-(*x-monitor->x);
63
+        }
64
+        if ( (int)*y < (int)monitor->y ) {
65
+            m_offsety = monitor->y-*y;
66
+            *h += *y-monitor->y;
67
+            *y = monitor->y;
68
+        }
69
+        if ( (int)(*y+*h) >= (int)(monitor->y+monitor->height) ) {
70
+            m_offseth = (monitor->height-1-(*y-monitor->y+*h));
71
+            *h = monitor->height-1-(*y-monitor->y);
72
+        }
73
+        break;
74
+    }
75
+    m_offsetx *= m_glassSize;
76
+    m_offsety *= m_glassSize;
77
+    m_offsetw *= m_glassSize;
78
+    m_offseth *= m_glassSize;
79
+}
80
+
81
+void slop::GLSelectRectangle::setMagnifySettings( bool on, float magstrength, unsigned int pixels ) {
82
+    m_glassSize = magstrength;
83
+    m_glassPixels = pixels;
84
+    m_glassEnabled = on;
85
+    m_glassx = xengine->m_mousex;
86
+    m_glassy = xengine->m_mousey;
87
+    m_realglassx = xengine->m_mousex;
88
+    m_realglassy = xengine->m_mousey;
89
+}
90
+
91
+void slop::GLSelectRectangle::pushOut( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh ) {
92
+    // AABB to test for collision
93
+    if (!(
94
+          *x < rx + rw &&
95
+          *x + w > rx &&
96
+          *y < ry + rh &&
97
+          h + *y > ry
98
+       )) {
99
+        // No collision, so we do nothing.
100
+        return;
101
+    }
102
+    // Otherwise we find an optimal angle to push ourselves out at.
103
+    int centerx = rx+rw/2;
104
+    int centery = ry+rh/2;
105
+    float ang = -atan2( (float)(*y+(float)h/2.f)-(float)centery, (float)(*x+(float)w/2.f)-(float)centerx );
106
+    float pi = 3.1415926535897;
107
+    float upright = pi/2 - atan( (2.f*float(rx+rw)-2.f*(float)centerx)/(float)rh );
108
+    float upleft = pi/2 - atan( (2.f*(float)rx-2.f*(float)centerx)/(float)rh );
109
+    float downright = -upright;
110
+    float downleft = -upleft;
111
+    if ( ang >= upright && ang <= upleft ) {
112
+        *x = centerx + ((rh*cos(ang))/(2*sin(ang))) - w/2;
113
+        *y = centery - rh/2 - h;
114
+    } else if ( ang <= downright && ang >= downleft) {
115
+        *x = centerx - ((rh*cos(ang))/(2*sin(ang))) - w/2;
116
+        *y = centery + rh/2;
117
+    } else if ( ang < downleft || ang > upleft ) {
118
+        *x = centerx - rw/2 - w;
119
+        *y = centery + (rw*sin(ang))/(2*cos(ang)) - h/2;
120
+    } else {
121
+        *x = centerx + rw/2;
122
+        *y = centery - (rw*sin(ang))/(2*cos(ang)) - h/2;
123
+    }
124
+}
125
+
126
+void slop::GLSelectRectangle::pushIn( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh ) {
127
+    if ( *x > rx && *y > ry &&
128
+         *x+w < rx+rw && *y+h < ry+rh ) {
129
+        // We're already fully contained...
130
+        return;
131
+    }
132
+    // Otherwise we find an optimal angle to push ourselves in at.
133
+    int centerx = rx+rw/2;
134
+    int centery = ry+rh/2;
135
+    float ang = -atan2( (float)(*y+(float)h/2.f)-(float)centery, (float)(*x+(float)w/2.f)-(float)centerx );
136
+    float pi = 3.1415926535897;
137
+    float upright = pi/2 - atan( (2.f*float(rx+rw)-2.f*(float)centerx)/(float)rh );
138
+    float upleft = pi/2 - atan( (2.f*(float)rx-2.f*(float)centerx)/(float)rh );
139
+    float downright = -upright;
140
+    float downleft = -upleft;
141
+    if ( ang >= upright && ang <= upleft ) {
142
+        *x = centerx + ((rh*cos(ang))/(2*sin(ang))) - w/2;
143
+        *y = centery - rh/2;
144
+    } else if ( ang <= downright && ang >= downleft) {
145
+        *x = centerx - ((rh*cos(ang))/(2*sin(ang))) - w/2;
146
+        *y = centery + rh/2 - h;
147
+    } else if ( ang < downleft || ang > upleft ) {
148
+        *x = centerx - rw/2;
149
+        *y = centery + (rw*sin(ang))/(2*cos(ang)) - h/2;
150
+    } else {
151
+        *x = centerx + rw/2 - w;
152
+        *y = centery - (rw*sin(ang))/(2*cos(ang)) - h/2;
153
+    }
154
+    if ( !(*x > rx && *y > ry &&
155
+         *x+w < rx+rw && *y+h < ry+rh) ) {
156
+        if ( *x+w > rx+rw ) {
157
+            *x -= w/2;
158
+        }
159
+        if ( *x < rx ) {
160
+            *x += w/2;
161
+        }
162
+        if ( *y+h > ry+rh ) {
163
+            *y -= h/2;
164
+        }
165
+        if ( *y < ry ) {
166
+            *y += h/2;
167
+        }
168
+    }
169
+}
170
+
171
+void slop::GLSelectRectangle::findOptimalGlassPosition() {
172
+    // Try to move the glass next to the mouse.
173
+    m_glassx = xengine->m_mousex+m_glassPixels/2+5-m_glassBorder;
174
+    m_glassy = xengine->m_mousey+m_glassPixels/2+5-m_glassBorder;
175
+    XRectangle view, selection, combined;
176
+    view.x = xengine->m_mousex-(m_glassPixels+1+m_glassBorder)/2;
177
+    view.y = xengine->m_mousey-(m_glassPixels+1+m_glassBorder)/2;
178
+    view.width = m_glassPixels+1;
179
+    view.height = m_glassPixels+1;
180
+    selection.x = m_x-m_border;
181
+    selection.y = m_y-m_border;
182
+    selection.width = m_width+m_border*2;
183
+    selection.height = m_height+m_border*2;
184
+    combined.x = std::min( selection.x, view.x );
185
+    combined.y = std::min( selection.y, view.y );
186
+    combined.width = selection.width + std::max( selection.x-view.x, (view.x+view.width)-(selection.x+selection.width) );
187
+    combined.height = selection.height + std::max( selection.y-view.y, (view.y+view.height)-(selection.y+selection.height) );
188
+    for ( unsigned int i=0;i<m_monitors.size();i++ ) {
189
+        XRRCrtcInfo* monitor = m_monitors[ i ];
190
+        // Push the glass inside the monitor the mouse is on.
191
+        if ( (int)xengine->m_mousex >= (int)monitor->x && (int)xengine->m_mousex <= (int)(monitor->x + monitor->width) &&
192
+             (int)xengine->m_mousey >= (int)monitor->y && (int)xengine->m_mousey <= (int)(monitor->y + monitor->height) ) {
193
+            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 );
194
+            break;
195
+        }
196
+    }
197
+    // Push the glass outside of the selection, but only if we are left clicking, and always keep it out of the "shot"
198
+    if ( xengine->getCursor() != slop::Left ) {
199
+        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 );
200
+    } else {
201
+        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 );
202
+    }
203
+    m_glassx += m_glassBorder;
204
+    m_glassy += m_glassBorder;
205
+}
206
+
207
+void slop::GLSelectRectangle::generateMagnifyingGlass() {
208
+    int x = xengine->m_mousex-m_glassPixels/2;
209
+    int y = xengine->m_mousey-m_glassPixels/2;
210
+    int w = m_glassPixels;
211
+    int h = m_glassPixels;
212
+    constrainWithinMonitor( &x, &y, &w, &h );
213
+    XImage* image = XGetImage( xengine->m_display, xengine->m_root, x, y, w, h, 0xffffffff, ZPixmap );
214
+    glEnable(GL_TEXTURE_2D);
215
+    glGenTextures(1, &m_texid);
216
+    glBindTexture(GL_TEXTURE_2D, m_texid);
217
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
218
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
219
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
220
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(image->data[0])));
221
+    XDestroyImage( image );
222
+    glDisable(GL_TEXTURE_2D);
223
+}
224
+
44
 slop::GLSelectRectangle::GLSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a ) {
225
 slop::GLSelectRectangle::GLSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a ) {
45
     m_x = std::min( sx, ex );
226
     m_x = std::min( sx, ex );
46
     m_y = std::min( sy, ey );
227
     m_y = std::min( sy, ey );
53
     m_border = border;
234
     m_border = border;
54
     m_window = None;
235
     m_window = None;
55
     m_highlight = highlight;
236
     m_highlight = highlight;
237
+    m_glassPixels = 64;
238
+    m_glassx = xengine->m_mousex;
239
+    m_glassy = xengine->m_mousey;
240
+    m_realglassx = xengine->m_mousex;
241
+    m_realglassy = xengine->m_mousey;
242
+    m_glassSize = 4;
243
+    m_glassBorder = 1;
244
+    m_monitors = xengine->getCRTCS();
56
 
245
 
57
     // If we don't have a border, we don't exist, so just die.
246
     // If we don't have a border, we don't exist, so just die.
58
     if ( m_border == 0 ) {
247
     if ( m_border == 0 ) {
178
     m_y = y;
367
     m_y = y;
179
     m_width = w;
368
     m_width = w;
180
     m_height = h;
369
     m_height = h;
181
-    glDrawBuffer( GL_BACK );
370
+}
371
+
372
+void slop::GLSelectRectangle::update( double dt ) {
182
     glViewport( 0, 0, xengine->getWidth(), xengine->getHeight() );
373
     glViewport( 0, 0, xengine->getWidth(), xengine->getHeight() );
183
 
374
 
184
     glClearColor( 0, 0, 0, 0 );
375
     glClearColor( 0, 0, 0, 0 );
191
     glMatrixMode( GL_MODELVIEW );
382
     glMatrixMode( GL_MODELVIEW );
192
     glLoadIdentity();
383
     glLoadIdentity();
193
 
384
 
194
-    glEnable( GL_BLEND );
195
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
196
-
197
     glColor4f( m_r, m_g, m_b, m_a );
385
     glColor4f( m_r, m_g, m_b, m_a );
198
     glRecti( m_x-m_border, m_y, m_x+m_width+m_border, m_y-m_border );
386
     glRecti( m_x-m_border, m_y, m_x+m_width+m_border, m_y-m_border );
199
     glRecti( m_x-m_border, m_y+m_height, m_x+m_width+m_border, m_y+m_height+m_border );
387
     glRecti( m_x-m_border, m_y+m_height, m_x+m_width+m_border, m_y+m_height+m_border );
200
     glRecti( m_x-m_border, m_y, m_x, m_y+m_height );
388
     glRecti( m_x-m_border, m_y, m_x, m_y+m_height );
201
     glRecti( m_x+m_width, m_y, m_x+m_width+m_border, m_y+m_height );
389
     glRecti( m_x+m_width, m_y, m_x+m_width+m_border, m_y+m_height );
202
 
390
 
391
+    if ( m_glassEnabled ) {
392
+        generateMagnifyingGlass();
393
+        findOptimalGlassPosition();
394
+
395
+        // Takes .1 second to reach the real position. Used for easing.
396
+        m_realglassx -= float(m_realglassx - (float)m_glassx) * dt * 10;
397
+        m_realglassy -= float(m_realglassy - (float)m_glassy) * dt * 10;
398
+
399
+        // Black outline...
400
+
401
+        glColor4f( 0, 0, 0, 1 );
402
+        glBegin( GL_QUADS );
403
+        glTexCoord2f(0.0, 1.0); glVertex3f( m_realglassx+m_offsetx-m_glassBorder,                               m_realglassy+(m_glassSize*m_glassPixels)+m_offseth+m_glassBorder, 0.0);
404
+        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);
405
+        glTexCoord2f(1.0, 0.0); glVertex3f( m_realglassx+(m_glassSize*m_glassPixels)+m_offsetw+m_glassBorder,   m_realglassy+m_offsety-m_glassBorder, 0.0);
406
+        glTexCoord2f(0.0, 0.0); glVertex3f( m_realglassx+m_offsetx-m_glassBorder,                               m_realglassy+m_offsety-m_glassBorder, 0.0);
407
+        glEnd();
408
+
409
+        glEnable( GL_TEXTURE_2D );
410
+        glBindTexture( GL_TEXTURE_2D, m_texid );
411
+        glColor4f( 1, 1, 1, 1 );
412
+        glBegin( GL_QUADS );
413
+        glTexCoord2f(0.0, 1.0); glVertex3f( m_realglassx+m_offsetx,                             m_realglassy+(m_glassSize*m_glassPixels)+m_offseth, 0.0);
414
+        glTexCoord2f(1.0, 1.0); glVertex3f( m_realglassx+(m_glassSize*m_glassPixels)+m_offsetw, m_realglassy+(m_glassSize*m_glassPixels)+m_offseth, 0.0);
415
+        glTexCoord2f(1.0, 0.0); glVertex3f( m_realglassx+(m_glassSize*m_glassPixels)+m_offsetw, m_realglassy+m_offsety, 0.0);
416
+        glTexCoord2f(0.0, 0.0); glVertex3f( m_realglassx+m_offsetx,                             m_realglassy+m_offsety, 0.0);
417
+        glEnd();
418
+        glDisable( GL_TEXTURE_2D );
419
+
420
+        glLogicOp(GL_INVERT);
421
+        glEnable(GL_COLOR_LOGIC_OP);
422
+        glLineWidth( 2 );
423
+        glColor4f( 0, 0, 0, 1 );
424
+        glBegin( GL_LINES );
425
+        float cx = m_realglassx+(m_glassSize*m_glassPixels)/2;
426
+        float cy = m_realglassy+(m_glassSize*m_glassPixels)/2;
427
+        glVertex3f( cx-5, cy, 0 );
428
+        glVertex3f( cx+5, cy, 0 );
429
+        glVertex3f( cx, cy-5, 0 );
430
+        glVertex3f( cx, cy+5, 0 );
431
+        glEnd();
432
+        glLogicOp(GL_NOOP);
433
+        glDisable(GL_COLOR_LOGIC_OP);
434
+    }
435
+
203
     glXSwapBuffers( xengine->m_display, m_glxWindow );
436
     glXSwapBuffers( xengine->m_display, m_glxWindow );
204
 }
437
 }

+ 21
- 0
src/glselectrectangle.hpp View File

47
                         GLSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a );
47
                         GLSelectRectangle( int sx, int sy, int ex, int ey, int border, bool highlight, float r, float g, float b, float a );
48
                         ~GLSelectRectangle();
48
                         ~GLSelectRectangle();
49
     void                setGeo( int x, int y, int w, int h );
49
     void                setGeo( int x, int y, int w, int h );
50
+    void                update( double dt );
51
+    void                generateMagnifyingGlass();
52
+    void                setMagnifySettings( bool on, float magstrength, unsigned int pixels );
53
+    void                pushIn( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh );
54
+    void                pushOut( int* x, int* y, int w, int h, int rx, int ry, int rw, int rh );
55
+    void                findOptimalGlassPosition();
56
+    void                constrainWithinMonitor( int* x, int* y, int* w, int* h );
50
     float               m_r;
57
     float               m_r;
51
     float               m_g;
58
     float               m_g;
52
     float               m_b;
59
     float               m_b;
57
     GLXContext          m_renderContext;
64
     GLXContext          m_renderContext;
58
     GLXWindow           m_glxWindow;
65
     GLXWindow           m_glxWindow;
59
     Colormap            m_cmap;
66
     Colormap            m_cmap;
67
+    unsigned int        m_texid;
68
+    int                 m_offsetx;
69
+    int                 m_offsety;
70
+    int                 m_offsetw;
71
+    int                 m_offseth;
72
+    unsigned int        m_glassPixels;
73
+    float               m_glassSize;
74
+    int                 m_glassBorder;
75
+    float               m_realglassx;
76
+    float               m_realglassy;
77
+    int                 m_glassx;
78
+    int                 m_glassy;
79
+    bool                m_glassEnabled;
80
+    std::vector<XRRCrtcInfo*> m_monitors;
60
 };
81
 };
61
 
82
 
62
 }
83
 }

+ 22
- 2
src/main.cpp View File

266
         pressedTime[ i ] = 0;
266
         pressedTime[ i ] = 0;
267
     }
267
     }
268
     std::string format = options.format_arg;
268
     std::string format = options.format_arg;
269
+    bool magenabled = options.magnify_flag;
270
+    float magstrength = options.magstrength_arg;
271
+    if ( options.magpixels_arg < 0 ) {
272
+        fprintf( stderr, "Error: --magpixels < 0, it's an unsigned integer you twat. Stop trying to underflow me!\n" );
273
+        return EXIT_FAILURE;
274
+    }
275
+    unsigned int magpixels = (unsigned int)options.magpixels_arg;
269
     cmdline_parser_free( &options );
276
     cmdline_parser_free( &options );
270
 
277
 
271
     // First we set up the x interface and grab the mouse,
278
     // First we set up the x interface and grab the mouse,
292
         }
299
         }
293
     }
300
     }
294
     current_utc_time( &start );
301
     current_utc_time( &start );
302
+    double deltatime = 0;
303
+    double curtime = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
295
     while ( running ) {
304
     while ( running ) {
296
         current_utc_time( &time );
305
         current_utc_time( &time );
297
         // "ticking" the xengine makes it process all queued events.
306
         // "ticking" the xengine makes it process all queued events.
298
         xengine->tick();
307
         xengine->tick();
299
         // If the user presses any key on the keyboard, exit the application.
308
         // If the user presses any key on the keyboard, exit the application.
300
         // Make sure at least gracetime has passed before allowing canceling
309
         // Make sure at least gracetime has passed before allowing canceling
301
-        double curtime = double( time.tv_sec*1000000000L + time.tv_nsec )/1000000000.f;
310
+        double newtime = double( time.tv_sec*1000000000L + time.tv_nsec )/1000000000.f;
311
+        deltatime = newtime-curtime;
312
+        curtime = newtime;
302
         double starttime = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
313
         double starttime = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
303
         if ( curtime - starttime > gracetime ) {
314
         if ( curtime - starttime > gracetime ) {
304
             if ( keyRepeat( XK_Up, curtime, 0.5, &pressedTime[ 0 ], &pressedMemory[ 0 ] ) ) {
315
             if ( keyRepeat( XK_Up, curtime, 0.5, &pressedTime[ 0 ], &pressedMemory[ 0 ] ) ) {
356
                                                                      borderSize,
367
                                                                      borderSize,
357
                                                                      highlight,
368
                                                                      highlight,
358
                                                                      r, g, b, a );
369
                                                                      r, g, b, a );
370
+                            // Haha why is this so hard to cast?
371
+                            ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
359
                         } else {
372
                         } else {
360
                             selection = new slop::XSelectRectangle( t.m_x, t.m_y,
373
                             selection = new slop::XSelectRectangle( t.m_x, t.m_y,
361
                                                                     t.m_x + t.m_width,
374
                                                                     t.m_x + t.m_width,
371
                     // Since WindowRectangle can select different windows depending on click location...
384
                     // Since WindowRectangle can select different windows depending on click location...
372
                     window = t.getWindow();
385
                     window = t.getWindow();
373
                 }
386
                 }
387
+                if ( selection ) {
388
+                    selection->update( deltatime );
389
+                }
374
                 // If the user clicked we move on to the next state.
390
                 // If the user clicked we move on to the next state.
375
                 if ( xengine->mouseDown( 1 ) ) {
391
                 if ( xengine->mouseDown( 1 ) ) {
376
                     state++;
392
                     state++;
408
                                                                  borderSize,
424
                                                                  borderSize,
409
                                                                  highlight,
425
                                                                  highlight,
410
                                                                  r, g, b, a );
426
                                                                  r, g, b, a );
427
+                        // Haha why is this so hard to cast?
428
+                        ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
411
                     } else {
429
                     } else {
412
                         selection = new slop::XSelectRectangle( sx, sy,
430
                         selection = new slop::XSelectRectangle( sx, sy,
413
                                                                 ex, ey,
431
                                                                 ex, ey,
429
                 if ( ( std::abs( w ) < tolerance && std::abs( h ) < tolerance ) ) {
447
                 if ( ( std::abs( w ) < tolerance && std::abs( h ) < tolerance ) ) {
430
                     // We make sure the selection rectangle stays on the window we had selected
448
                     // We make sure the selection rectangle stays on the window we had selected
431
                     selection->setGeo( xmem, ymem, xmem + wmem, ymem + hmem );
449
                     selection->setGeo( xmem, ymem, xmem + wmem, ymem + hmem );
450
+                    selection->update( deltatime );
432
                     xengine->setCursor( slop::Left );
451
                     xengine->setCursor( slop::Left );
433
                     // Make sure
452
                     // Make sure
434
                     window = windowmemory;
453
                     window = windowmemory;
455
                 int sx, sy, ex, ey;
474
                 int sx, sy, ex, ey;
456
                 constrain( cx, cy, xengine->m_mousex, xengine->m_mousey, padding, minimumsize, maximumsize, &sx, &sy, &ex, &ey );
475
                 constrain( cx, cy, xengine->m_mousex, xengine->m_mousey, padding, minimumsize, maximumsize, &sx, &sy, &ex, &ey );
457
                 // Set the selection rectangle's dimensions to mouse movement.
476
                 // Set the selection rectangle's dimensions to mouse movement.
458
-                selection->setGeo( sx + xoffset, sy + yoffset, ex, ey );
477
+                selection->setGeo( sx + xoffset, sy + yoffset, ex-1, ey-1 );
478
+                selection->update( deltatime );
459
                 break;
479
                 break;
460
             }
480
             }
461
             case 3: {
481
             case 3: {

+ 14
- 0
src/options.ggo View File

64
     flag
64
     flag
65
     off
65
     off
66
 
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
+
67
 option "format" f "Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c."
81
 option "format" f "Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c."
68
     string
82
     string
69
     default="REPLACEME"
83
     default="REPLACEME"

+ 3
- 0
src/selectrectangle.cpp View File

28
 slop::SelectRectangle::~SelectRectangle() {
28
 slop::SelectRectangle::~SelectRectangle() {
29
 }
29
 }
30
 
30
 
31
+void slop::SelectRectangle::update( double dt ) {
32
+}
33
+
31
 void slop::SelectRectangle::setGeo( int sx, int sy, int ex, int ey ) {
34
 void slop::SelectRectangle::setGeo( int sx, int sy, int ex, int ey ) {
32
     fprintf( stderr, "Tried to use a class function that's meant to be overridden!\n");
35
     fprintf( stderr, "Tried to use a class function that's meant to be overridden!\n");
33
 }
36
 }

+ 1
- 0
src/selectrectangle.hpp View File

42
 public:
42
 public:
43
     virtual ~SelectRectangle();
43
     virtual ~SelectRectangle();
44
     virtual void    setGeo( int x, int y, int w, int h );
44
     virtual void    setGeo( int x, int y, int w, int h );
45
+    virtual void    update( double dt );
45
     Window          m_window;
46
     Window          m_window;
46
     int             m_x;
47
     int             m_x;
47
     int             m_y;
48
     int             m_y;

+ 25
- 3
src/x.cpp View File

104
     //m_root      = RootWindow     ( m_display, XScreenNumberOfScreen( m_screen ) );
104
     //m_root      = RootWindow     ( m_display, XScreenNumberOfScreen( m_screen ) );
105
     m_root      = DefaultRootWindow( m_display );
105
     m_root      = DefaultRootWindow( m_display );
106
 
106
 
107
+    m_res = XRRGetScreenResourcesCurrent( m_display, m_root);
108
+
107
     m_good = true;
109
     m_good = true;
108
     XSetErrorHandler( slop::XEngineErrorHandler );
110
     XSetErrorHandler( slop::XEngineErrorHandler );
109
     selectAllInputs( m_root, EnterWindowMask );
111
     selectAllInputs( m_root, EnterWindowMask );
110
     return EXIT_SUCCESS;
112
     return EXIT_SUCCESS;
111
 }
113
 }
112
 
114
 
115
+std::vector<XRRCrtcInfo*> slop::XEngine::getCRTCS() {
116
+    std::vector<XRRCrtcInfo*> monitors;
117
+    if ( !m_res ) {
118
+        return monitors;
119
+    }
120
+    for ( int i=0;i<m_res->ncrtc;i++ ) {
121
+        monitors.push_back( XRRGetCrtcInfo( m_display, m_res, m_res->crtcs[ i ] ) );
122
+    }
123
+    return monitors;
124
+}
125
+
113
 bool slop::XEngine::keyPressed( KeySym key ) {
126
 bool slop::XEngine::keyPressed( KeySym key ) {
114
     KeyCode keycode = XKeysymToKeycode( m_display, key );
127
     KeyCode keycode = XKeysymToKeycode( m_display, key );
115
     if ( keycode != 0 ) {
128
     if ( keycode != 0 ) {
183
     if ( !m_good ) {
196
     if ( !m_good ) {
184
         return EXIT_FAILURE;
197
         return EXIT_FAILURE;
185
     }
198
     }
186
-    int xfontcursor = getCursor( type );
199
+    int xfontcursor = makeCursor( type );
187
     int err = XGrabPointer( m_display, m_root, True,
200
     int err = XGrabPointer( m_display, m_root, True,
188
                             PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
201
                             PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
189
                             GrabModeAsync, GrabModeAsync, None, xfontcursor, CurrentTime );
202
                             GrabModeAsync, GrabModeAsync, None, xfontcursor, CurrentTime );
290
 }
303
 }
291
 
304
 
292
 // This converts an enum into a preallocated cursor, the cursor will automatically deallocate itself on ~XEngine
305
 // This converts an enum into a preallocated cursor, the cursor will automatically deallocate itself on ~XEngine
293
-Cursor slop::XEngine::getCursor( slop::CursorType type ) {
306
+Cursor slop::XEngine::makeCursor( slop::CursorType type ) {
294
     int xfontcursor;
307
     int xfontcursor;
295
     switch ( type ) {
308
     switch ( type ) {
296
         default:
309
         default:
316
     return newcursor;
329
     return newcursor;
317
 }
330
 }
318
 
331
 
332
+slop::CursorType slop::XEngine::getCursor() {
333
+    if ( m_currentCursor ) {
334
+        return m_currentCursor;
335
+    } else {
336
+        return slop::Left;
337
+    }
338
+}
339
+
319
 // 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.
340
 // 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.
320
 void slop::XEngine::setCursor( slop::CursorType type ) {
341
 void slop::XEngine::setCursor( slop::CursorType type ) {
321
     if ( !m_good ) {
342
     if ( !m_good ) {
322
         return;
343
         return;
323
     }
344
     }
324
-    Cursor xfontcursor = getCursor( type );
345
+    m_currentCursor = type;
346
+    Cursor xfontcursor = makeCursor( type );
325
     XChangeActivePointerGrab( m_display,
347
     XChangeActivePointerGrab( m_display,
326
                               PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
348
                               PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
327
                               xfontcursor, CurrentTime );
349
                               xfontcursor, CurrentTime );

+ 7
- 1
src/x.hpp View File

26
 #include <X11/Xlib.h>
26
 #include <X11/Xlib.h>
27
 #include <X11/cursorfont.h>
27
 #include <X11/cursorfont.h>
28
 #include <X11/extensions/shape.h>
28
 #include <X11/extensions/shape.h>
29
+#include <X11/extensions/Xrandr.h>
29
 
30
 
30
 #include <stdlib.h>
31
 #include <stdlib.h>
31
 #include <cstring>
32
 #include <cstring>
77
     int                 releaseCursor();
78
     int                 releaseCursor();
78
     int                 releaseKeyboard();
79
     int                 releaseKeyboard();
79
     void                setCursor( slop::CursorType type );
80
     void                setCursor( slop::CursorType type );
81
+    slop::CursorType    getCursor();
80
     void                drawRect( int x, int y, unsigned int w, unsigned int h );
82
     void                drawRect( int x, int y, unsigned int w, unsigned int h );
81
     unsigned int        getWidth();
83
     unsigned int        getWidth();
82
     unsigned int        getHeight();
84
     unsigned int        getHeight();
85
+    std::vector<XRRCrtcInfo*>        getCRTCS();
86
+    void                freeCRTCS( std::vector<XRRCrtcInfo*> monitors );
83
     int                 m_mousex;
87
     int                 m_mousex;
84
     int                 m_mousey;
88
     int                 m_mousey;
85
     Display*            m_display;
89
     Display*            m_display;
91
     std::vector<bool>   m_mouse;
95
     std::vector<bool>   m_mouse;
92
     bool                mouseDown( unsigned int button );
96
     bool                mouseDown( unsigned int button );
93
     bool                m_keypressed;
97
     bool                m_keypressed;
98
+    XRRScreenResources* m_res;
94
 private:
99
 private:
100
+    slop::CursorType    m_currentCursor;
95
     bool                m_good;
101
     bool                m_good;
96
     std::vector<Cursor> m_cursors;
102
     std::vector<Cursor> m_cursors;
97
-    Cursor              getCursor( slop::CursorType type );
103
+    Cursor              makeCursor( slop::CursorType type );
98
     void                selectAllInputs( Window win, long event_mask);
104
     void                selectAllInputs( Window win, long event_mask);
99
 };
105
 };
100
 
106