diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..57948c31 --- /dev/null +++ b/.clang-format @@ -0,0 +1,11 @@ +BasedOnStyle: google +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortBlocksOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: false +IndentWidth: 4 +PointerBindsToType: false +ColumnLimit: 0 +ForEachMacros: [ TAILQ_FOREACH, TAILQ_FOREACH_REVERSE, SLIST_FOREACH, CIRCLEQ_FOREACH, CIRCLEQ_FOREACH_REVERSE, NODES_FOREACH, NODES_FOREACH_REVERSE ] +SpaceBeforeParens: ControlStatements diff --git a/DEPENDS b/DEPENDS index 083372c7..8a9f9dca 100644 --- a/DEPENDS +++ b/DEPENDS @@ -12,7 +12,7 @@ │ xcb-util │ 0.3.3 │ 0.3.8 │ http://xcb.freedesktop.org/dist/ │ │ util-cursor³│ 0.0.99 │ 0.0.99 │ http://xcb.freedesktop.org/dist/ │ │ libev │ 4.0 │ 4.11 │ http://libev.schmorp.de/ │ -│ yajl │ 1.0.8 │ 2.0.1 │ http://lloyd.github.com/yajl/ │ +│ yajl │ 2.0.1 │ 2.0.4 │ http://lloyd.github.com/yajl/ │ │ asciidoc │ 8.3.0 │ 8.6.4 │ http://www.methods.co.nz/asciidoc/ │ │ xmlto │ 0.0.23 │ 0.0.23 │ http://www.methods.co.nz/asciidoc/ │ │ Pod::Simple²│ 3.22 │ 3.22 │ http://search.cpan.org/~dwheeler/Pod-Simple-3.23/ @@ -32,5 +32,9 @@ i3bar, i3-msg, i3-input, i3-nagbar and i3-config-wizard do not introduce any new dependencies. - i3-migrate-config-to-v4 is implemented in Perl, but it has no dependencies - besides Perl 5.10. + i3-migrate-config-to-v4 and i3-dmenu-desktop are implemented in Perl, but have + no dependencies besides Perl 5.10. + + i3-save-tree is also implemented in Perl and needs AnyEvent::I3 and JSON::XS. + While i3-save-tree is not required for running i3 itself, it is strongly + recommended to provide it in distribution packages. diff --git a/Makefile b/Makefile index ff10dcb5..1fed4df1 100644 --- a/Makefile +++ b/Makefile @@ -30,8 +30,8 @@ dist: distclean [ ! -d i3-${VERSION} ] || rm -rf i3-${VERSION} [ ! -e i3-${VERSION}.tar.bz2 ] || rm i3-${VERSION}.tar.bz2 mkdir i3-${VERSION} - cp i3-migrate-config-to-v4 generate-command-parser.pl i3-sensible-* i3-dmenu-desktop i3.config.keycodes DEPENDS LICENSE PACKAGE-MAINTAINER RELEASE-NOTES-${VERSION} i3.config i3.xsession.desktop i3-with-shmlog.xsession.desktop i3.applications.desktop pseudo-doc.doxygen common.mk Makefile i3-${VERSION} - cp -r src libi3 i3-msg i3-nagbar i3-config-wizard i3bar i3-dump-log yajl-fallback include man parser-specs testcases i3-${VERSION} + cp i3-migrate-config-to-v4 i3-save-tree generate-command-parser.pl i3-sensible-* i3-dmenu-desktop i3.config.keycodes DEPENDS LICENSE PACKAGE-MAINTAINER RELEASE-NOTES-${VERSION} i3.config i3.xsession.desktop i3-with-shmlog.xsession.desktop i3.applications.desktop pseudo-doc.doxygen common.mk Makefile i3-${VERSION} + cp -r src libi3 i3-msg i3-nagbar i3-config-wizard i3bar i3-dump-log include man parser-specs testcases i3-${VERSION} # Only copy toplevel documentation (important stuff) mkdir i3-${VERSION}/docs # Pre-generate documentation diff --git a/RELEASE-NOTES-4.2 b/RELEASE-NOTES-4.2 deleted file mode 100644 index b6759ce5..00000000 --- a/RELEASE-NOTES-4.2 +++ /dev/null @@ -1,100 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.2 │ - └──────────────────────────────┘ - -This is the second release of the new major version of i3, v4.2. It is -considered stable. All users of i3 are strongly encouraged to upgrade. - -A big change with this release is (again) a new parser for commands. You might -get the impression that we like rewriting parsers, but check the commit message -of commit a532f5a for rationale on this decision. - -A more visible change to users is the introduction of a scratchpad command: -This is useful to have a permanent editor session ready whenever you need it. -Or your music player. Or email client? Or $programming-language REPL? Give it a -try! - -Also, you are finally able to move workspaces between the different outputs if -you are using multiple monitors. You can rename workspaces on the fly and -identify named workspaces by their number. So you can rename "1: www" to "1: -code" with one simple rename command and all your keybindings will still work. - -A subtle indicator of the split state of containers has been introduced: In -case you are in a split container with precisely one window (a situation which -you could not recognize by looking at your screen previously), i3 will -highlight the bottom/right border of the split container in a lighter blue. -This should reduce confusion about whether you are dealing with a split -container or not. - -And finally, i3bar now supports a JSON input protocol, so that with a -subsequent release of i3status, you will be able to use colors in your bar! - - ┌────────────────────────────┐ - │ Changes in v4.2 │ - └────────────────────────────┘ - - • i3-sensible-*: don’t call which without parameters - • i3-config-wizard: Mark the currently selected modifier with an arrow - • i3bar: kick tray clients after output configuration changed - • i3bar: kill child processes when exit()ing (they might be stopped) - • i3bar now supports a JSON input format to provide colors and more (later) - • Support different modifier keys for showing i3bar in hide mode - • bar config: add i3bar_command for non-standard setups - • Implement scratchpad functionality - • Implement 'focus output left|right|up|down' - • Implement 'workspace next_on_output|prev_on_output' - • Implement 'move workspace to output ' - • Implement a new parser for commands - • Implement 'workspace number ' to switch to named workspaces - • Implement 'move [container|window] to workspace number ' - • Implement 'rename workspace to ' - • Re-implement borders in the workspace bar - • Draw a separator line after each tab in tabbed mode - • Ignore aspect ratio during fullscreen mode (fixes MPlayer subtitles) - • Correctly restore focus after in-place restarts - • Highlight the right/bottom border of split windows ("indicator") - • Install /usr/share/applications/i3.desktop so that you can select i3 as a - window manager in GNOME - • Don’t migrate unfocused empty workspaces when disabling an output - • randr: Skip workspaces which are assigned to a different output when - creating a new workspace - • Implement an urgency flag criterion - • Render only once for all matching assignments - • Implement support for user configuration of constraints on floating window - dimensions - • Extend move command for floating windows - • Added option to select primary display on tray_output - • Implement resize , use it in the default config - • Replace the old fullscreen container when requesting fullscreen - • Prevent changing focus outside a container when scrolling on the - decorations - • Only resize when the left/right mouse button is used, not when scrolling - • docs: replace the refcard with an HTML version - • cfgparse: accept force-xinerama as a synonym of force_xinerama - • Implement support for 32 bit visuals (necessary for transparency) - • X11: only copy the requested region from buffer pixmaps in ExposeEvents - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • Bugfix: Don’t leak IPC file descriptors - • Bugfix: fix empty tray icon areas in i3bar - • Bugfix: properly handle workspace names with double quotes - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - Aaron Small, ablepharus, aksr, alexander, badboy, B-con, beauby, ben, biiter, - binzter, cg, cradle, darkraven, dbp, dcoppa, Don, dothebart, D Thompson, - eeemsi, f8l, Fandekasp, fernandotcl, gamo, garga, gregkh, Han, helgikrs, - Jeremy O'Brien, jjfoerch, joepd, Jose Pereira, Jure Ziberna, MasterofJOKers, - Merovius, mhcerri, migueldvb, moemoe, mseed, mxf, nh2, noxxun, Paul, Pavel - Löbl, Peter Bui, Phlogistique, phnom, piroko, rami, SardemFF7, xeen, xpt, - zeus - --- Michael Stapelberg, 2012-04-25 diff --git a/RELEASE-NOTES-4.3 b/RELEASE-NOTES-4.3 deleted file mode 100644 index 68fce10a..00000000 --- a/RELEASE-NOTES-4.3 +++ /dev/null @@ -1,186 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.3 │ - └──────────────────────────────┘ - -This is the i3 v4.3. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -One rather visible change is that commands which could not be parsed properly - will now spawn i3-nagbar. In case you used "bindsym $mod+x firefox" (and - forgot the "exec" keyword) or you made a typo in your config, you will now - notice that :). - - -We also made the orientation (horizontal/vertical) part of the layout - mechanism: Before, we got the default layout and you could change - orientation. Now, there are two new layouts "splitv" and "splith", which - replace the default layout. The "split h" and "split v" commands continue to - work as before, they split the current container and you will end up in a - split container with layout splith (after "split h") or splitv (after - "split v"). - - To change a splith container into a splitv container, use either "layout - splitv" or "layout toggle split". The latter command is used in the - default config as mod+e (formerly "layout default"). In case you have - "layout default" in your config file, it is recommended to just replace - it by "layout toggle split", which will work as "layout default" did - before when pressing it once, but toggle between horizontal/vertical - when pressing it repeatedly. - - The rationale behind this change is that it’s cleaner to have all - parameters that influence how windows are rendered in the layout itself - rather than having one special layout in combination with an additional - orientation. This enables us to change existing split containers in all - cases without breaking existing features (see ticket #464). Also, users - should feel more confident about whether they are actually splitting or - just changing an existing split container now. - - As a nice side-effect, this commit brings back the "layout toggle" - feature we once had in i3 v3 (see the userguide). - - -Another very important change is that we now support pango for rendering text. - The default is still to use misc-fixed (X core fonts), but you can use a font - specification starting with "xft:" now, such as "xft:DejaVu Sans Mono 10" and - i3 will use pango. The sole motivation for this is NOT to have fancier window - decorations, but to support fonts which have more glyphs (think Japanese for - example) and to support right-to-left rendering (open http://www.ftpal.net/ - for an example). Supporting users from all over the planet is important, and - as such I would strongly advise distribution packagers to leave pango support - enabled. In case you are working on a very low-spec embedded device, it is - easy enough to disable pango support, see common.mk. - - -Also, the 'layout' command now always works on the parent split container. This - allows you to do things like this: - - for_window [class="XTerm"] layout tabbed - - When you now open XTerm on an empty workspace, the whole workspace will be - set to tabbed. In case you want to open XTerm in its own tabbed split - container, you need to split before: - - for_window [class="XTerm"] split v, layout tabbed - - -Furthermore, we decided to entirely ignore resize increment size hints for - tiling windows. These are set by terminal emulators (such as urxvt, - gnome-terminal, …) and specify that the window may only be resized in - multiples of the specified size. All terminal emulators cope with the window - manager ignoring these hints and by doing so, they can decide what to do with - the lost space (that is, pseudo-transparency now works without black bars in - urxvt). - - ┌────────────────────────────┐ - │ Changes in v4.3 │ - └────────────────────────────┘ - - • docs: there now is documentation about lib::i3test and lib::i3test::Test, - the main Perl modules used by our testsuite. - • docs/refcard: update for v4 - • docs/userguide: clarify the default for focus_follows_mouse and new_window - • docs/userguide: add section about implicit containers - • docs/userguide: give 'move to output' its own section - • docs/ipc: document the 'window' field in the GET_TREE reply - • docs/ipc: update links to ipc libraries - • docs/ipc: make the reply sections consistent - • docs/i3bar-protocol: add example (illustration-only!) shell script - • man/i3bar.man: reference i3bar-protocol - • IPC: Commands now lead to proper error messages in general. If we forgot - about a specific one, please open a ticket. - • IPC: implement GET_VERSION to find out the i3 version - • i3-dump-log now comes with a massively more helpful error message that - should cover all the use cases. - • 'workspace number ' now opens a new workspace - • 'workspace number ' now works with the back_and_forth option - • Allow focus with target (criteria) when in fullscreen mode in some cases - • Allow focus child/parent when in fullscreen mode - • Restrict directional focus when in fullscreen mode - • Prevent moving out of fullscreen containers - • Add 'move to workspace current' (useful when used with criteria) - • replace loglevels by a global debug logging - • make: new makefile layout - • make: canonicalize path when compiling. This leads to sth like - ../i3-4.2/src/main.c in backtraces, clearly identifying i3 code. - • automatically hide i3bar when it’s unneeded (after urgency hints) - • i3-config-wizard: use the level 0 keysym whenever it’s unambiguous - • i3-nagbar: use custom scripts to work around different terminal emulators - using different ways of interpreting the arguments to -e - • i3-sensible-terminal: add xfce4-terminal - • default config: require confirmation when exiting i3 - • Display i3-nagbar when a command leads to an error. - • testcases: complete-run now supports --xtrace - • testcases: handle EAGAIN (fixes hangs) - • testcases: handle test bailouts - • Introduce splith/splitv layouts, remove orientation - • Implement hide_edge_borders option - • Support _NET_ACTIVE_WINDOW ClientMessages - • Set I3_PID atom on the X11 root window - • Implement i3 --moreversion, handy for figuring out whether you run the - latest binary which is installed. - • i3bar: be less strict about the {"version":1} JSON header - • shm-logging: implement i3-dump-log -f (follow) - • Implement pango support - • 'move workspace number n' will now create the workspace if it doesn’t exist - • Accept slashes in RandR output names - • Keep startup-notification sequences around for 30s after completion - • Introduce bindsym --release, which will trigger the binding not on the - KeyPress event, but on the KeyRelease event (useful for import(1) or - xdotool(1)). - • The signalhandler does not offer you to exit i3 anymore. Instead, there is - 'b' for writing a backtrace to a file in /tmp (if gdb is installed) - • Remove support for resize increment hints for tiling windows - • Exit fullscreen mode when 'scratchpad show' is executed while in fullscreen - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • Fix floating precision bug when floating windows are moved between outputs. - • i3bar won’t crash when full_text is missing or null in the JSON input - • When having "workspace number 1" in your config, there will no longer be a - stray workspace "number 1". - • i3.config.keycodes used bindsym instead of bindcode for the arrow key - resizing bindings by mistake - • Fix 'move to workspace' when used with criteria - • Handle clicks to the very left edge of i3bar - • When using i3 -C, don’t send remaining arguments as an IPC command - • Fix reload crashes in rare cases - • i3bar: inform all clients of new tray selection owner (fixes tray problems - with X-Chat and possibly others) - • resizing: traverse containers up properly (fixes non-working resizing when - having a h-split within a h-split for example) - • Fix floating coordinates when moving assigned workspaces - • Properly fix floating coordinates when disabling outputs - • floating_fix_coordinates: properly deal with negative positions - • floating windows: add deco_height only when in normal border mode (fixes - initial floating window position/size when using a different default border - setting). - • Fix moving scratchpad window - • Cleanup zero-byte logfile on immediate exit (they are created by i3 - --get-socketpath for example). - • Fix resizing floating windows by height - • Fix back_and_forth in 'workspace number' for named workspaces - • Grab server and process pending events before managing existing windows - (fixes problems with GIMP windows not being managed after an in-place - restart) - • Don’t allow ConfigureRequests while in fullscreen (fixes a compatibility - issue with gnome-terminal and xfce’s terminal) - • Fix flickering with 1pixel border tabbed layouts - • Use _exit() instead of exit() when i3 utility programs cannot be executed - • Don’t focus the wrong workspace when moving to scratchpad - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - aksr, Axel Wagner, darkraven, David Coppa, eeemsi, Felicitus, Fernando Tarlá - Cardoso Lemos, Iakov Davydov, jh, Joel Stemmer, Julius Plenz, loblik, Marcel - Hellwig, Marcus, mloskot, Moritz Bandemer, oblique, Ondrej Grover, Pavel - Löbl, Philipp Middendorf, prg, Quentin Glidic, Sebastian Ullrich, Simon - Elsbrock, somelauw, stfn, tucos, TunnelWicht, Valentin Haenel - --- Michael Stapelberg, 2012-09-19 diff --git a/RELEASE-NOTES-4.4 b/RELEASE-NOTES-4.4 deleted file mode 100644 index ea872619..00000000 --- a/RELEASE-NOTES-4.4 +++ /dev/null @@ -1,107 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.4 │ - └──────────────────────────────┘ - -This is the i3 v4.4. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -An important under-the-hood change is that we now use the same parser - infrastructure for the configuration file as we do for the commands. This - makes maintenance and contributions easier and lets us finally escape the - insanity that is bison/flex. - - In case there is a bug and your existing config does not work as expected - anymore, try using the --force-old-config-parser-v4.4-only flag when starting - i3 and please report a bug. This option will only be present in v4.4, so if - you don’t report a bug, you are willingly breaking your own config file. - -Apart from that, there have been several little fixes and additions which make - i3 pay more attention to detail, particularly in the floating window area of - the code. See the changes/bugfixes list for more information. - - ┌────────────────────────────┐ - │ Changes in v4.4 │ - └────────────────────────────┘ - - • add i3-dmenu-desktop, a dmenu wrapper which parses application .desktop - files and executes them. - • also use a custom parser for the config file - • i3.xsession.desktop is now standards-compliant - • ipc: you can now subscribe to an event called 'mode' (for binding modes) - • implement "move container to workspace back_and_forth" - • implement delayed urgency hint reset - • make "move workspace number" accept a default workspace name after the - number - • i3bar: allow child to specify start/stop signals to use in hide mode - • i3bar: add "urgent" to protocol, it unhides i3bar when in hide mode - • make parent of urgent containers also urgent - • add descriptive title to split containers (no more "another container") - • click to focus: clicking the root window focuses the relevant workspace - • display appropriate cursors when resizing or moving floating windows - • implement variable border widths for pixel/normal - • Implement moving workspaces as if they’re regular containers - • Maintain relative positioning when moving floating windows between outputs - • Focus the relevant workspace when clicking any container - • docs/ipc: remove unnecessary newline - • docs/ipc: add a warning to use an existing library - • shmlog: remove O_TRUNC flag for shm_open, we truncate on our own - • un-fullscreen as needed when moving fullscreen containers - • improve startup sequence termination conditions - • allow floating cons to be reached using 'focus parent' - • grab keys with all permutations of lock and numlock - • allow workspace contents to be moved if there are only floating children - • allow 'focus ' to move out of non-global fullscreen containers - • exit with a proper error message when there are no outputs available - • skip floating cons in focus and stop them from being split - • focus windows when middle-clicking - • skip floating windows in the focus stack when moving through the tree - • docs/userguide: use $mod consistently - • keycode default config: s/bindcode/bindsym/ - • implement smart popup_during_fullscreen mode - • docs/testsuite: add "installing the dependencies" section - • introduce new command to rename focused workspace - • libi3: use "pango:" prefix instead of "xft:" to avoid confusion - • ipc: add "current" and "old" containers to workspace events - • i3bar: add current binding mode indicator - • resizing floating windows now obeys the minimum/maximum size - • docs/userguide: document new_float option - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • Bugfix: get_output_next() now works with non-aligned RandR setups - • Bugfix: close empty workspaces after cross-output move - • Bugfix: fix bottom line of tabbed decoration not continuous - • Bugfix: use correct coordinates for windows which are opened on a newly - created workspace due to assignments - • Bugfix: properly react to windows being unmapped before we can reparent - • Bugfix: send non-floating window with floating parent to scratchpad - • docs/userguide: document how to "un-scratchpad" a window - • Bugfix: don’t crash when dragged floating window closes - • Bugfix: draw h-split indicator at the correct position - • make the resize command honor criteria - • Bugfix: with one ws per output, don’t crash on cross-output moves - • Bugfix: correctly move floating windows to invisible workspaces - cross-output - • Bugfix: set workspace_layout in create_workspace_on_output - • fix fullscreen focus bug and corresponding test flaw - • i3bar: bugfix: don’t send workspace command when at beginning/end of workspace - • Bugfix: force rendering when the parent’s orientation changed - • Bugfix: fix workspace back_and_forth after displaying a scratchpad window - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - Adrien Schildknecht, aksr, bitonic, chrysn, Conley Moorhous, darkraven, Deiz, - Emil Mikulic, Feh, flo, Francesco Mazzoli, hax404, joepd, Kacper Kowalik, - Markus, meaneye, Merovius, Michael Walle, moju, Moritz, noxxun, Oliver - Kiddle, Pauli Ervi, Pavel Löbl, Piotr, pkordy, Quentin Glidic, Sascha Kruse, - Sebastian Ullrich, Simon Elsbrock, slowpoke, strcat, Tblue, Tim, whitequark, - xeen, Yaroslav Molochko - --- Michael Stapelberg, 2012-12-12 diff --git a/RELEASE-NOTES-4.5 b/RELEASE-NOTES-4.5 deleted file mode 100644 index 1e59a174..00000000 --- a/RELEASE-NOTES-4.5 +++ /dev/null @@ -1,103 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.5 │ - └──────────────────────────────┘ - -This is the i3 v4.5. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -Most of the changes are cleanups and bugfixes. Due to cleanups, i3 no longer - depends on flex/bison at all. Furthermore, libev ≥ 4 is now a hard dependency - (libev < 4 is not supported anymore). - -One important change to note is that moving windows to a different output will - no longer move focus to that output. If you want to have the old behavior, - modify the keybindings for moving in your configfile like this: - - bindsym $mod+Shift+1 move workspace 1; workspace 1 - - ┌────────────────────────────┐ - │ Changes in v4.5 │ - └────────────────────────────┘ - - • docs/hacking-howto: refer people to cr.i3wm.org - • docs/ipc: Adds Go IPC lib to the docs. - • docs/userguide: remove obsolete sentence about client.background - • docs/userguide: be explicit about assignment processing order - • docs/userguide: be more clear about the resize command arguments - • docs/userguide: fix typo: s/11x/11px/ - • i3-dmenu-desktop: don’t add “geany” if “Geany” is already present - • i3-dmenu-desktop: strip newlines from dmenu ≥ 4.4 - • i3-dmenu-desktop: skip files with broken utf8 but warn about it - • i3-dmenu-desktop: skip broken files (no/empty Exec=) but warn about them - • i3-dmenu-desktop: List filenames of .desktop files - • i3-dmenu-desktop: remove %i from commandline - • i3-nagbar: Work around terminals not supporting -e with quoted arguments - • i3-nagbar: use the same font as configured for i3 - • i3bar: set _NET_SYSTEM_TRAY_COLORS for symbolic icons (gtk3+) - • i3bar: don’t use X11 borders to avoid overlapping in hide mode - • i3bar: separator color via config; separator width and on/off via ipc - • i3bar: Allow min_width of a block in i3bar to be a string - • i3-msg: parse command replies and display errors nicely if there were - errors - • Draw 1px tab separators left/right instead of 2px on the right only - • Render tree before destroying X11 containers upon unmap - • scratchpad show: move visible scratchpad window from another workspace to - focused workspace instead of doing nothing - • ignore MotionNotify events generated while warping the pointer - • Allow X11 servers which do not support the XKB extension. - • remove the urgency indicator when a window is closed - • wrap when moving containers to outputs with direction - • scratchpad_show: focus unfocused scratchpad window - • Split workspace instead of changing orientation - • scratchpad: always auto center on 'scratchpad show' if window hasn't been - repositioned by the user - • Add a new IPC event for changes on windows. - • config: accept “smart” as popup_during_fullscreen parameter - • Add support for _NET_WM_STATE_DEMANDS_ATTENTION. - • Obey WM_SIZE_HINTS's resize increments in floating mode - • Do not move focus if a container is moved across outputs - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • Ignore ConfigureRequests for scratchpad windows - • Correctly parse `move ... workspace *_on_output` - • i3bar: Set separator color properly when drawing - • Properly parse commands like “move workspace torrent” - • Handle nested transient popups properly - • Fix decoration rect size for windows without border - • parse outputs as "word", not "string", to ignore trailing whitespace - • fix crash when disabling output without any windows - • scratchpad: fix crash when moving last window of an invisible workspace - • fix coordinates of scratchpad windows on output changes - • call scratchpad_show() when focusing scratchpad windows via criteria - • fix continuous resize bug in floating mode, e.g. with xbmc - • fix “overlapping” --release key bindings - • fix IPC messages writes with low buffer sizes - • unregister as window manager before restarting (fixes a race condition) - • Fix bind[code|sym] --release - • remove superfluous #include - • Makefile: Repect AR environment variable - • i3-input: restore input focus on exit() - • Also draw right tab border for split containers - • Fix scrolling on a tabbed titlebar which contains split cons - • Correctly close floating windows - • handle MapRequests sent between i3 registering as a wm and handling events - • i3bar: fake DestroyNotify and send MANAGER ClientMessages to fix tray restarts - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - Adrien Schildknecht, alex, András Mohari, Artem Shinkarov, badboy, bafain, - cradle, dcoppa, Donald, dRbiG, eeemsi, else, emias, f8l, Francesco Mazzoli, - jasper, joepd, Kacper Kowalik, Kai, knopwob, Marcos, Marius Muja, Mats, - MeanEYE, Merovius, oblique, paolo, phlux, Piotr S. Staszewski, pnutzh4x0r, - rasi, saurabhgeek92, Sebastian Rachuj, Sebastian Ullrich, slowpoke, Steven - Allen, supplantr, Tai-Lin Chu, Tucos, Vivien Didelot, xeen - --- Michael Stapelberg, 2013-03-12 diff --git a/RELEASE-NOTES-4.5.1 b/RELEASE-NOTES-4.5.1 deleted file mode 100644 index b834255f..00000000 --- a/RELEASE-NOTES-4.5.1 +++ /dev/null @@ -1,24 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.5.1 │ - └──────────────────────────────┘ - -This is the i3 v4.5.1, a bugfix release. This version is considered stable. All -users of i3 are strongly encouraged to upgrade. - -This release fixes an i3 lockup when dragging floating windows from one monitor - to another. - -Furthermore, in the release process for v4.5, there was a human error leading - to i3 thinking that v4.5 is a debug version, therefore allocating 25 MB of - shared memory logging ringbuffer by default. - - ┌────────────────────────────┐ - │ Changes in v4.5.1 │ - └────────────────────────────┘ - - • Bugfix: Don’t warp the pointer when dragging floating windows - • i3-dmenu-desktop: improve error message when dmenu cannot be found - • Add YAJL_CFLAGS to i3-msg.mk - --- Michael Stapelberg, 2013-03-18 diff --git a/RELEASE-NOTES-4.6 b/RELEASE-NOTES-4.6 deleted file mode 100644 index 4928c1b7..00000000 --- a/RELEASE-NOTES-4.6 +++ /dev/null @@ -1,99 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.6 │ - └──────────────────────────────┘ - -This is the i3 v4.6. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -The main improvement of this release is increased compatibility. We made a few -tiny code changes and hope that Mathematica and Java applications will work -better with i3 now. i3-nagbar should work with more terminal emulators than -before. - -For debugging, the shmlog and debuglog commands can be sent via IPC to enable -shared memory logging while i3 is running. For the large number of users using -a release version (i.e. a version without shared memory logging by default), -this will make debugging their issues much simpler. - -i3bar now supports click events and can be hidden/shown via an i3 IPC command. - - ┌────────────────────────────┐ - │ Changes in v4.6 │ - └────────────────────────────┘ - - • docs/userguide: mention forgotten layout splitv/splith - • docs/multi-monitor: nVidia ≥ 302.17 works just fine - • docs/wsbar: update (we have i3bar now, i3-wsbar is just an example) - • docs/testsuite: Document fixes and workarounds for test failures - • man/i3-msg.man: updated man page to include all options - • lib/i3test: clarify how to identify open_window() windows in i3 commands - • Use a saner sanity check for floating_reposition - • tabbed: floor(), put extra pixels into the last tab - • raise fullscreen windows on top of all other X11 windows - • Draw indicator border only for split layouts - • re-shuffle struct members to save a bit of memory - • Add 'NoDisplay=true' to i3.application.desktop - • Store aspect_ratio instead of weird proportional_{width,height} - • Implement shmlog command - • Implement debuglog command - • Implement unmark command - • actively delete _NET_WORKAREA on startup - • Handle the _NET_REQUEST_FRAME_EXTENTS ClientMessage (java compat) - • i3bar: add click events - • i3bar: fix -b parameter, fix usage description - • i3bar: restore compatibility with libyajl version 1 - • i3bar: unhide hidden i3bar when mode is active - • i3bar: fix font display height in i3bar - • i3bar: introduced i3 command for changing the hidden state and mode - • i3bar: fix wrong placement of i3bar when connecting/disconnecting outputs - • i3bar: draw workspace buttons at x=0 instead of x=1 - • i3-nagbar: take our terminal execution kludge to the next level - • i3-nagbar: Bugfix: -m requires an argument (crashes if none specified) - • i3-dmenu-desktop: run commands when they don’t match a .desktop file - (e.g. enter “i3 layout stacking”) - • i3-dmenu-desktop: honor Path= key - • contrib/dump-asy.pl: Fix $ and & in window titles - • contrib/dump-asy.pl: Display nicer double-quotes - • contrib/gtk-tree-watch.pl: Remove bogus default socket path - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • Bugfix: ipc: use correct workspace in workspace change event - • Bugfix: fix floating window size with hide_edge_borders - • Bugfix: Fix parsing of comments in the config file - • Bugfix: Fix error messages for the debug log - • Bugfix: shm_unlink the correct file when handling errors - • Bugfix: Fix shm logging on FreeBSD - • Bugfix: Fix restarting with 32 bit depth windows - • Bugfix: Fix scratchpad_show on non-scratchpad windows - • Bugfix: i3bar: mark IPC fd CLOEXEC - • Bugfix: fix crash when not having tray_output configured - • Bugfix: make sure that resize will take place even if pixel is smaller - than size increments. - • Bugfix: render_con: fix height rounding in aspect ratio computation - • Bugfix: fix problem when moving fullscreen window to scratchpad - • Bugfix: Unmap windows before reparenting them to the root window - (fixes Mathematica) - • Bugfix: update parent urgency hint if a child is removed. - • Bugfix: fix bus error on OpenBSD/sparc64 - • Bugfix: fix focus handling in 'floating disable' on non-visible windows - • Bugfix: ignore spaces in front of default workspace name - • Bugfix: call i3-nagbar correctly for configfiles without the font directive - • Bugfix: resize and center a scratchpad even when a criteria is used. - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - Alexander, Alexander Berntsen, Arun Persaud, badboy, Baptiste Daroussin, - Clément Bœsch, Diego Ongaro, Eelis van der Weegen, Eika Enge, enkore, Eric S. - Raymond, Franck Michea, haptix, HedgeMage, koebi, Layus, Mayhem, Merovius, - necoro, oblique, Philippe Virouleau, phillip, psychon, Simon Elsbrock, Simon - Wesp, Thomas Adam, tobiasu, vandannen, xeen, Yuxuan Shui - --- Michael Stapelberg, 2013-08-07 diff --git a/RELEASE-NOTES-4.7 b/RELEASE-NOTES-4.7 deleted file mode 100644 index 99c3dc1d..00000000 --- a/RELEASE-NOTES-4.7 +++ /dev/null @@ -1,82 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.7 │ - └──────────────────────────────┘ - -This is the i3 v4.7. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -This release features a number of documentation improvements, better error -messages in various places, better tray compatibility in i3bar, and a number of -bugfixes. - -Relevant from a packaging point of view is that we have switched to the new -xcb-util-cursor library to get rid of libXcursor. The last remaining big piece -of Xlib code now is XKB, which we may be able to tackle in upcoming releases -thanks to the just released libxcb 1.10. - - ┌────────────────────────────┐ - │ Changes in v4.7 │ - └────────────────────────────┘ - - • docs/userguide: clarify variable parsing - • docs/userguide: clarify urgent_workspace - • docs/userguide: add proper quoting for rename sample command - • docs/userguide: clarify multiple criteria - • docs/userguide: userguide: explain the difference between comma and semicolon for command chaining - • docs/hacking-howto: update to reflect parser changes - • man/i3-dump-log: document -f - • switch from libXcursor to xcb-util-cursor - • Respect workspace numbers when looking for a free workspace name - • Revert "raise fullscreen windows on top of all other X11 windows" - • i3bar: Create pixmaps using the real bar height, rather than screen height - • Add scratchpad bindings to the default config - • Close all children when closing a workspace - • i3bar: Add new bar.binding_mode_indicator configuration - • Improve error message when $XDG_RUNTIME_DIR is not writable - • libi3/font: Draw the text at the expected place - • libi3/font: Set DPI for the pango context - • Add ability to escape out of a mouse-resize operation - • Do not resize/reposition floating containers when moving them to scratchpad - • i3-nagbar: Set button inner-width to the width of the label - • Assigned windows open urgent when not visible - • i3bar: Only configure tray on own outputs - • Command 'move ' moves across outputs - • i3bar: Handle DestroyNotify events - • i3bar: Realign tray clients on map/unmap notify - • i3bar: Group child processes for signalling - • i3bar: Print error message when status_command fails - • Remove references to PATH_MAX macro for GNU/Hurd - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • update root geometry on output changes for “fullscreen global” - • don’t flatten tabbed/stacked containers - • Fix handling of new windows with WM_STATE_FULLSCREEN - • correctly recognize assigned windows as urgent - • Fix keyboard and mouse resize in nested containers - • Reply to _NET_REQUEST_FRAME_EXTENTS correctly - • Fix command parser: resizing tiling windows - • Fix output retrieval for floating cons - • Use _PATH_BSHELL to ensure using a bourne shell - • Instead of crashing, return DRAG_ABORT on UnmapNotify from drag_pointer - • Remove-child callback skips output content cons - • ignore _NET_ACTIVE_WINDOW for scratchpad windows - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - -Alexander Neumann, badboy, Baptiste Daroussin, Bas Pape, Deiz, Franck Michea, -Jean-Philippe Ouellet, jj, jookia, kaersten, Lancelot SIX, Leo Gaspard, -mistnim, Peter Maatman, Quentin Glidic, Sebastian Ullrich, Slava, syl20bnr, -Tony Crisci, Trung Ngo, Vivien Didelot, Xarthisius - -I want to specifically thank Tony Crisci for the very valuable help with -responding to bugreports in our bugtracker. Thank you! - --- Michael Stapelberg, 2013-12-22 diff --git a/RELEASE-NOTES-4.7.1 b/RELEASE-NOTES-4.7.1 deleted file mode 100644 index 211f813f..00000000 --- a/RELEASE-NOTES-4.7.1 +++ /dev/null @@ -1,36 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.7.1 │ - └──────────────────────────────┘ - -This is the i3 v4.7.1. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -This is a bugfix release for v4.7. - - ┌────────────────────────────┐ - │ Changes in v4.7.1 │ - └────────────────────────────┘ - - • docs/debugging: explain how to enable logging on the fly - • docs/debugging: small cleanups (versions, bzip2) - • add i3-with-shmlog.xsession.desktop - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • only LOG() the DPI when it changes, DLOG() it otherwise - • make “move ” properly send workspace focus event - • i3bar: set mapped flag on trayclient creation - • i3bar: don’t show EOF status line error in favor of exit code - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - lkraav, TonyC - --- Michael Stapelberg, 2014-01-21 diff --git a/RELEASE-NOTES-4.7.2 b/RELEASE-NOTES-4.7.2 deleted file mode 100644 index c8371ba3..00000000 --- a/RELEASE-NOTES-4.7.2 +++ /dev/null @@ -1,26 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.7.2 │ - └──────────────────────────────┘ - -This is the i3 v4.7.2. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -This is a bugfix release for v4.7. - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • install i3-with-shmlog.xsession.desktop to the correct location - • OpenBSD currently lacks posix_fallocate() - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - David Coppa - --- Michael Stapelberg, 2014-01-23 diff --git a/RELEASE-NOTES-4.8 b/RELEASE-NOTES-4.8 new file mode 100644 index 00000000..f0f5923f --- /dev/null +++ b/RELEASE-NOTES-4.8 @@ -0,0 +1,138 @@ + + ┌──────────────────────────────┐ + │ Release notes for i3 v4.8 │ + └──────────────────────────────┘ + +This is i3 v4.8. This version is considered stable. All users of i3 are +strongly encouraged to upgrade. + +The biggest new feature certainly is layout saving/restoring. See +http://i3wm.org/docs/layout-saving.html for more details. tl;dr: export your +current layout as JSON file, load it into new i3 sessions, get placeholder +windows that will be replaced by the actual apps once you start them. + +Also very important for owners of HiDPI/“retina” displays is that i3 will now +respect your configured DPI and scale up its UI elements accordingly. Use +“xrandr --dpi 184” to set your dpi to 184, in case your setup does not figure +it out automatically. To get properly scaling fonts, we also changed the +default font from a bitmap font to a pango font (“DejaVu Sans Mono 8”). + +Multiple changes improve the compatibility of i3 with other software, e.g. +java-based software (focus handling, once again) or external pagers (we now +provide _NET_CLIENT_LIST and let pager applications change workspaces). + +For packagers, another change is that yajl ≥ 2.0 is now required for compiling +i3. This should not be a problem for anyone, as that version is pretty old by +now. + +For contributors, note that we have starting formatting the source code with +clang-format-3.5. This means that there will no longer be a need to argue about +coding style when discussing patches :). + + ┌────────────────────────────┐ + │ Changes in v4.8 │ + └────────────────────────────┘ + + • docs/ipc: reformat/update list of ipc libraries + • docs/ipc: fix current_workspace outputs reply member + • docs/ipc: update ipc COMMAND reply docs + • docs/userguide: fix multiple typos + • docs/debugging: use bzip2 + • docs/debugging: explain how to enable logging on the fly + • docs/debugging: merge the debug symbols/backtrace section + • docs/debugging: recommend i3 --moreversion + • man/i3-nagbar.man: update manpage to document all options + • i3bar: Amend status line error 127 message + • i3bar: don’t kill watcher on EOF, leads to better error messages + • i3bar: send mouse wheel events to child too + • i3bar: do click handling and tray padding retina-correctly + • i3bar: render separators render-correctly + • i3bar: reinit colors on barconfig update + • i3bar: Don't start child unless status_command + • i3bar: implement custom workspace numbers config + • resize floating windows when right-clicking the decoration + • enable shmlog when invoked as i3-with-shmlog + • Disable pointer warps when focus_follows_mouse is disabled + • Movement into a branch considers movement direction + • set ewmh desktop properties on startup + • handle ButtonPress events with child != XCB_NONE + • implement layout restoring + • only LOG() the DPI when it changes, DLOG() it otherwise + • send IPC window events for focus and title changes + • these types of windows are now floating by default: + dialog, utility, toolbar and splash windows, modal windows, windows with an + equal minimum and maximum size + • send last event timestamp with WM_TAKE_FOCUS message + • maintain the _NET_CLIENT_LIST property + • don’t set input focus _and_ send WM_TAKE_FOCUS + • respect CFLAGS in linking command + • fix parallel make + • reset SIGPIPE handler before executing a command + • render default window border width retina-correctly + • draw workspace buttons and padded text blocks retina-correctly + • render resize windows retina-correctly + • delegate click handling to dock clients + • send complete config on barconfig_update + • implement the window::fullscreen_mode ipc event + • make all workspaces starting with "__" internal + • improve error messages for i3-internal workspace names + • allow _NET_ACTIVE_WINDOW requests to switch workspaces if they indicate + that they are a pager (following the spec) + • workspace assignments by number + • add configuration option for disabling mouse warping + • set _NET_ACTIVE_WINDOW to None when none has focus + • set X-LightDM-DesktopName in i3.xsession.desktop to fix autostart on Ubuntu + • don’t ELOG ipc EOF + • replace all printf()s with D?LOG + • delete ipc socket when exiting, cleanup tmpdir + • default config: switch to DejaVu Sans Mono 8 as default font + • cleanup tmpdir when restarting and not using XDG_RUNTIME_DIR + • Snap pointer to resize bar on drag resize + • Size resizebar according to container size + • Fix clang -Wextra except -Wunused-parameter + • Respect Motif hint for window decorations + + ┌────────────────────────────┐ + │ Bugfixes │ + └────────────────────────────┘ + + • create con pixmaps when not needed + • i3bar: fix resource leak: statusline_ctx needs to be freed first + • tree_split should not split floating cons + • fix memory leak with ipc_receive_message + • fix invalid reads by setting con->window to NULL in tree_close + • fix memory leak when closing windows + • fix memory leak when matching window by criteria + • fix memory leak when matching window by con_id + • ignore dock clients in the resize command + • clear wm_size_hints if they are not set + • resize window check should check for NULL + • fix window event crash with no window + • i3-dmenu-desktop: also quote the %c field code + • new_window and new_float can now be used simultaneously with different + border widths + • fix crash when using multiple for_window statements that move windows + • Set input focus with last timestamp + • handle windows whose WM_TRANSIENT_FOR points to themselve + • don’t overwrite the original size of floating windows when changing border + • don’t errnously render floating fullscreen windows during restart + • ensure floating windows don’t drop out of fullscreen when restarting + • don’t overwrite the window’s geometry after restartingnext + • i3bar: Set `mapped` flag on trayclient creation + • i3bar: don't show "EOF" status line error + + ┌────────────────────────────┐ + │ Thanks! │ + └────────────────────────────┘ + +Thanks for testing, bugfixes, discussions and everything I forgot go out to: + +Aleksi Blinnikka, Alexander Berntsen, Alexander Kedrik, Antonio, Arun +Persaud, Atte Peltomaki, bo, Campbell Barton, chris, David Coppa, eeemsi, +Holger Langenau, Jean-Philippe Ouellet, Jens, jeroentbt, Jonas Maaskola, +Julian Ospald, Kernc, Koston, lasers, lkraav, Marcin, Marco Hunsicker, +Marcus Crestani, Matthias Thubauville, Maxime, Michael Stapelberg, Peter +Boström, Petr Písař, Quentin Glidic, Steve Jones, TonyC, Tony Crisci, +Vivien Didelot, Wieland Hoffmann, x33a, xeen + +-- Michael Stapelberg, 2014-06-15 diff --git a/common.mk b/common.mk index b946206d..b086bc85 100644 --- a/common.mk +++ b/common.mk @@ -115,9 +115,6 @@ XCURSOR_LIBS := $(call ldflags_for_lib, xcb-cursor,xcb-cursor) # yajl YAJL_CFLAGS := $(call cflags_for_lib, yajl) -# Fallback for libyajl 1 which did not include yajl_version.h. We need -# YAJL_MAJOR from that file to decide which code path should be used. -YAJL_CFLAGS += -idirafter $(TOPDIR)/yajl-fallback YAJL_LIBS := $(call ldflags_for_lib, yajl,yajl) #libev @@ -171,8 +168,8 @@ endif ifeq ($(UNAME),Darwin) LIBS += -liconv -else -# Darwin (Mac OS X) doesn’t have librt +else ifneq ($(UNAME),OpenBSD) +# Darwin (Mac OS X) and OpenBSD do not have librt LIBS += -lrt endif diff --git a/contrib/per-workspace-layout.pl b/contrib/per-workspace-layout.pl new file mode 100644 index 00000000..9304b6fd --- /dev/null +++ b/contrib/per-workspace-layout.pl @@ -0,0 +1,55 @@ +#!/usr/bin/env perl +# vim:ts=4:sw=4:expandtab +# © 2012 Michael Stapelberg +# Licensed under BSD license, see http://code.i3wm.org/i3/tree/LICENSE +# +# Append this line to your i3 config file: +# exec_always ~/per-workspace-layout.pl +# +# Then, change the %layouts hash like you want your workspaces to be set up. +# This script requires i3 >= v4.4 for the extended workspace event. + +use strict; +use warnings; +use AnyEvent; +use AnyEvent::I3; +use v5.10; + +my %layouts = ( + '4' => 'tabbed', + '5' => 'stacked', +); + +my $i3 = i3(); + +die "Could not connect to i3: $!" unless $i3->connect->recv(); + +die "Could not subscribe to the workspace event: $!" unless + $i3->subscribe({ + workspace => sub { + my ($msg) = @_; + return unless $msg->{change} eq 'focus'; + die "Your version of i3 is too old. You need >= v4.4" + unless exists($msg->{current}); + my $ws = $msg->{current}; + + # If the workspace already has children, don’t change the layout. + return unless scalar @{$ws->{nodes}} == 0; + + my $name = $ws->{name}; + my $con_id = $ws->{id}; + + return unless exists $layouts{$name}; + + $i3->command(qq|[con_id="$con_id"] layout | . $layouts{$name}); + }, + _error => sub { + my ($msg) = @_; + say "AnyEvent::I3 error: $msg"; + say "Exiting."; + exit 1; + }, + })->recv->{success}; + +# Run forever. +AnyEvent->condvar->recv diff --git a/contrib/sticker-7x5cm-stickma.tif.lzma b/contrib/sticker-7x5cm-stickma.tif.lzma new file mode 100644 index 00000000..591360ce Binary files /dev/null and b/contrib/sticker-7x5cm-stickma.tif.lzma differ diff --git a/debian/changelog b/debian/changelog index f3855363..ac79c8bb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,26 @@ -i3-wm (4.6.1-1) unstable; urgency=low +i3-wm (4.7.3-1) unstable; urgency=low - * NOT YET RELEASED. + * NOT YET RELEASED - -- Michael Stapelberg Wed, 07 Aug 2013 20:53:26 +0200 + -- Michael Stapelberg Thu, 23 Jan 2014 23:11:48 +0100 + +i3-wm (4.7.2-1) unstable; urgency=low + + * New upstream release. (Closes: #736396) + + -- Michael Stapelberg Thu, 23 Jan 2014 23:03:03 +0100 + +i3-wm (4.7.1-1) unstable; urgency=low + + * New upstream release. + + -- Michael Stapelberg Tue, 21 Jan 2014 19:29:34 +0100 + +i3-wm (4.7-1) unstable; urgency=low + + * New upstream release. + + -- Michael Stapelberg Sun, 22 Dec 2013 21:19:02 +0100 i3-wm (4.6-1) unstable; urgency=low diff --git a/debian/control b/debian/control index 558b0127..97b11a5e 100644 --- a/debian/control +++ b/debian/control @@ -15,7 +15,7 @@ Build-Depends: debhelper (>= 7.0.50~), docbook-xml, pkg-config, libev-dev (>= 1:4.04), - libyajl-dev, + libyajl-dev (>= 2.0.4), libpcre3-dev, libstartup-notification0-dev (>= 0.10), libcairo2-dev, @@ -38,7 +38,7 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, x11-utils Provides: x-window-manager Suggests: rxvt-unicode | x-terminal-emulator -Recommends: xfonts-base +Recommends: xfonts-base, fonts-dejavu-core, libanyevent-i3-perl, libjson-xs-perl Description: improved dynamic tiling window manager Key features of i3 are good documentation, reasonable defaults (changeable in a simple configuration file) and good multi-monitor support. The user diff --git a/debian/i3-wm.docs b/debian/i3-wm.docs index b83b8da7..11a695ba 100644 --- a/debian/i3-wm.docs +++ b/debian/i3-wm.docs @@ -29,3 +29,5 @@ docs/refcard_style.css docs/logo-30.png docs/lib-i3test.html docs/lib-i3test-test.html +docs/layout-saving.html +docs/layout-saving-1.png diff --git a/debian/i3-wm.links b/debian/i3-wm.links new file mode 100644 index 00000000..376018bd --- /dev/null +++ b/debian/i3-wm.links @@ -0,0 +1 @@ +usr/share/man/man1/i3.1.gz usr/share/man/man1/i3-with-shmlog.1.gz diff --git a/debian/rules b/debian/rules index 55c72b51..7036b90d 100755 --- a/debian/rules +++ b/debian/rules @@ -38,7 +38,7 @@ override_dh_auto_build: $(MAKE) -C docs override_dh_installchangelogs: - dh_installchangelogs RELEASE-NOTES-4.6 + dh_installchangelogs RELEASE-NOTES-* override_dh_install: $(MAKE) DESTDIR=$(CURDIR)/debian/i3-wm/ install diff --git a/docs/NoName-2009-03-12/screenshot.png b/docs/NoName-2009-03-12/screenshot.png new file mode 100644 index 00000000..15a5c7f6 Binary files /dev/null and b/docs/NoName-2009-03-12/screenshot.png differ diff --git a/docs/asciidoc-git.conf b/docs/asciidoc-git.conf index cc135ae9..3d42bca8 100644 --- a/docs/asciidoc-git.conf +++ b/docs/asciidoc-git.conf @@ -560,7 +560,7 @@ ifdef::linkcss[] @@ -569,7 +569,7 @@ ifndef::linkcss[] @@ -647,7 +647,7 @@ endif::doctype-manpage[] {disable-javascript%

} diff --git a/docs/docs.mk b/docs/docs.mk index 8a522cce..050df97d 100644 --- a/docs/docs.mk +++ b/docs/docs.mk @@ -14,7 +14,8 @@ ASCIIDOC_TOC_TARGETS = \ docs/multi-monitor.html \ docs/wsbar.html \ docs/testsuite.html \ - docs/i3bar-protocol.html + docs/i3bar-protocol.html \ + docs/layout-saving.html ASCIIDOC_TARGETS = \ $(ASCIIDOC_TOC_TARGETS) \ diff --git a/docs/hacking-howto b/docs/hacking-howto index bc59eaeb..f4e3f031 100644 --- a/docs/hacking-howto +++ b/docs/hacking-howto @@ -172,6 +172,10 @@ values will later be pushed to X11 in +src/x.c+. src/resize.c:: Contains the functions to resize containers. +src/restore_layout.c:: +Everything for restored containers that is not pure state parsing (which can be +found in load_layout.c). + src/sighandler.c:: Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed. You can chose to let it dump core, to restart it in-place or to restart it diff --git a/docs/i3bar-protocol b/docs/i3bar-protocol index bd8ea536..92763154 100644 --- a/docs/i3bar-protocol +++ b/docs/i3bar-protocol @@ -225,7 +225,7 @@ instance:: Instance of the block, if set x, y:: X11 root window coordinates where the click occured -button: +button:: X11 button ID (for example 1 to 3 for left/middle/right mouse button) *Example*: diff --git a/docs/ipc b/docs/ipc index 85e5e77e..c9768705 100644 --- a/docs/ipc +++ b/docs/ipc @@ -1,7 +1,7 @@ IPC interface (interprocess communication) ========================================== Michael Stapelberg -October 2012 +February 2014 This document describes how to interface with i3 from a separate process. This is useful for example to remote-control i3 (to write test cases for example) or @@ -140,12 +140,13 @@ VERSION (7):: === COMMAND reply -The reply consists of a single serialized map. At the moment, the only -property is +success (bool)+, but this will be expanded in future versions. +The reply consists of a list of serialized maps for each command that was +parsed. Each has the property +success (bool)+ and may also include a +human-readable error message in the property +error (string)+. *Example:* ------------------- -{ "success": true } +[{ "success": true }] ------------------- === WORKSPACES reply @@ -227,9 +228,9 @@ name (string):: The name of this output (as seen in +xrandr(1)+). Encoded in UTF-8. active (boolean):: Whether this output is currently active (has a valid mode). -current_workspace (integer):: - The current workspace which is visible on this output. +null+ if the - output is not active. +current_workspace (string):: + The name of the current workspace that is visible on this output. +null+ if + the output is not active. rect (map):: The rectangle of this output (equals the rect of the output it is on), consists of x, y, width, height. @@ -240,7 +241,7 @@ rect (map):: { "name": "LVDS1", "active": true, - "current_workspace": 4, + "current_workspace": "4", "rect": { "x": 0, "y": 0, @@ -251,7 +252,7 @@ rect (map):: { "name": "VGA1", "active": true, - "current_workspace": 1, + "current_workspace": "1", "rect": { "x": 1280, "y": 0, @@ -277,7 +278,12 @@ name (string):: The internal name of this container. For all containers which are part of the tree structure down to the workspace contents, this is set to a nice human-readable name of the container. + For containers that have an X11 window, the content is the title + (_NET_WM_NAME property) of that window. For all other containers, the content is not defined (yet). +type (string):: + Type of this container. Can be one of "root", "output", "con", + "floating_con", "workspace" or "dockarea". border (string):: Can be either "normal", "none" or "1pixel", dependending on the container’s border style. @@ -627,10 +633,11 @@ mode (2):: Sent whenever i3 changes its binding mode. window (3):: Sent when a client's window is successfully reparented (that is when i3 - has finished fitting it into a container). + has finished fitting it into a container), when a window received input + focus or when certain properties of the window have changed. barconfig_update (4):: Sent when the hidden_state or mode field in the barconfig of any bar - instance was updated. + instance was updated and when the config is reloaded. *Example:* -------------------------------------------------------------------- @@ -670,12 +677,12 @@ but will still be present in the "old" property. "change": "focus", "current": { "id": 28489712, - "type":4, + "type": "workspace", ... } "old": { "id": 28489715, - "type": 4, + "type": "workspace", ... } } @@ -707,14 +714,18 @@ mode is simply named default. === window event This event consists of a single serialized map containing a property -+change (string)+ which currently can indicate only that a new window -has been successfully reparented (the value will be "new"). ++change (string)+ which indicates the type of the change + +* +new+ - the window has become managed by i3 +* +focus+ - the window has received input focus +* +title+ - the window's title has changed +* +fullscreen_mode+ - the window has entered or exited fullscreen mode Additionally a +container (object)+ field will be present, which consists -of the window's parent container. Be aware that the container will hold -the initial name of the newly reparented window (e.g. if you run urxvt -with a shell that changes the title, you will still at this point get the -window title as "urxvt"). +of the window's parent container. Be aware that for the "new" event, the +container will hold the initial name of the newly reparented window (e.g. +if you run urxvt with a shell that changes the title, you will still at +this point get the window title as "urxvt"). *Example:* --------------------------- @@ -722,7 +733,7 @@ window title as "urxvt"). "change": "new", "container": { "id": 35569536, - "type": 2, + "type": "con", ... } } @@ -731,20 +742,8 @@ window title as "urxvt"). === barconfig_update event This event consists of a single serialized map reporting on options from the -barconfig of the specified bar_id that were updated in i3. The map always -consists of a property +id (string)+, which specifies to which bar instance the -sent config update belongs, a property +hidden_state (string)+, which indicates -the hidden_state of an i3bar instance, and a property +mode (string)+, which -corresponds to the current mode. - -*Example:* ---------------------------- -{ - "id": "bar-0", - "hidden_state": "hide" - "mode": "hide" -} ---------------------------- +barconfig of the specified bar_id that were updated in i3. This event is the +same as a +GET_BAR_CONFIG+ reply for the bar with the given id. == See also (existing libraries) @@ -756,13 +755,19 @@ know): C:: i3 includes a headerfile +i3/ipc.h+ which provides you all constants. - However, there is no library yet. -Ruby:: - http://github.com/badboy/i3-ipc -Perl:: - https://metacpan.org/module/AnyEvent::I3 -Python:: - * https://github.com/whitelynx/i3ipc - * https://github.com/ziberna/i3-py (includes higher-level features) + + https://github.com/acrisci/i3ipc-glib Go:: * https://github.com/proxypoke/i3ipc +JavaScript:: + * https://github.com/acrisci/i3ipc-gjs +Lua:: + * https:/github.com/acrisci/i3ipc-lua +Perl:: + * https://metacpan.org/module/AnyEvent::I3 +Python:: + * https://github.com/acrisci/i3ipc-python + * https://github.com/whitelynx/i3ipc (not maintained) + * https://github.com/ziberna/i3-py (not maintained) +Ruby:: + http://github.com/badboy/i3-ipc diff --git a/docs/layout-saving b/docs/layout-saving new file mode 100644 index 00000000..2b798df5 --- /dev/null +++ b/docs/layout-saving @@ -0,0 +1,233 @@ +Layout saving in i3 +=================== +Michael Stapelberg +April 2014 + +Layout saving/restoring is a feature that was introduced in i3 v4.8. + +Layout saving/restoring allows you to load a JSON layout file so that you can +have a base layout to start working with after powering on your computer. +Dynamic use-cases also come to mind: if you frequently (but not always!) need a +grid layout of terminals with ping/traceroute commands to diagnose network +issues, you can easily automate opening these windows in just the right layout. + +== Saving the layout + +You can save the layout of either a single workspace or an entire output (e.g. +LVDS1). Of course, you can repeat this step multiple times if you want to +save/restore multiple workspaces/outputs. + ++i3-save-tree(1)+ is a tool to save the layout. It will print a JSON +representation of i3’s internal layout data structures to stdout. Typically, +you may want to take a quick look at the output, then save it to a file and +tweak it a little bit: + +--------------------------------------------------- +i3-save-tree --workspace 1 > ~/.i3/workspace-1.json +--------------------------------------------------- + +Please note that the output of +i3-save-tree(1)+ is *NOT useful* until you +manually modify it — you need to tell i3 how to match/distinguish windows (for +example based on their WM_CLASS, title, etc.). By default, all the different +window properties are included in the output, but commented out. This is partly +to avoid relying on heuristics and partly to make you aware how i3 works so +that you can easily solve layout restoring problems. + +How to modify the file manually is described in <>. + +== Restoring the layout + +After restoring the example layout from <>, i3 will open +placeholder windows for all the windows that were specified in the layout file. +You can recognize the placeholder windows by the watch symbol +footnote:[Depending on the font you are using, a placeholder symbol may show up +instead of the watch symbol.] in the center of the window, and by the swallow +criteria specification at the top of the window: + +image:layout-saving-1.png["Restored layout",width=400,link="layout-saving-1.png"] + +When an application opens a window that matches the specified swallow criteria, +it will be placed in the corresponding placeholder window. We say it gets +*swallowed* by the placeholder container, hence the term. + +Note: Swallowing windows into unsatisfied placeholder windows takes precedence +over +link:http://i3wm.org/docs/userguide.html#_automatically_putting_clients_on_specific_workspaces[assignment +rules]. For example, if you assign all Emacs windows to workspace 1 in your i3 +configuration file, but there is a placeholder window on workspace 2 which +matches Emacs as well, your newly started Emacs window will end up in the +placeholder window on workspace 2. + +The placeholder windows are just regular windows, so feel free to move them +around or close them, for example. + +=== append_layout command + +The +append_layout+ command is used to load a layout file into i3. It accepts a +path (relative to i3’s current working directory or absolute) to a JSON file. + +*Syntax*: +-------------------------------------------------------------------------------- +append_layout +-------------------------------------------------------------------------------- + +*Examples*: +-------------------------------------------------------------------------------- +# From a terminal or script: +i3-msg "workspace 1; append_layout /home/michael/.i3/workspace-1.json" + +# In your i3 configuration file, you can autostart i3-msg like this: +# (Note that those lines will quickly become long, so typically you would store +# them in a script with proper indentation.) +exec --no-startup-id "i3-msg 'workspace 1; append_layout /home/michael/.i3/workspace-1.json'" +-------------------------------------------------------------------------------- + +== Editing layout files + +[[EditingLayoutFiles]] + +=== Anatomy of a layout file + +Here is an example layout file that we’ll discuss: + +-------------------------------------------------------------------------------- +{ + // splitv split container with 2 children + "layout": "splitv", + "percent": 0.4, + "type": "con", + "nodes": [ + { + "border": "none", + "name": "irssi", + "percent": 0.5, + "type": "con", + "swallows": [ + { + "class": "^URxvt$", + "instance": "^irssi$" + } + ] + }, + { + // stacked split container with 2 children + "layout": "stacked", + "percent": 0.5, + "type": "con", + "nodes": [ + { + "name": "notmuch", + "percent": 0.5, + "type": "con", + "swallows": [ + { + "class": "^Emacs$", + "instance": "^notmuch$" + } + ] + }, + { + "name": "midna: ~", + "percent": 0.5, + "type": "con" + } + ] + } + ] +} + +{ + // stacked split container with 1 children + "layout": "stacked", + "percent": 0.6, + "type": "con", + "nodes": [ + { + "name": "chrome", + "type": "con", + "swallows": [ + { + "class": "^Google-chrome$" + } + ] + } + ] +} +-------------------------------------------------------------------------------- + +In this layout, the screen is divided into two columns. In the left column, +which covers 40% of the screen, there is a terminal emulator running irssi on +the top, and a stacked split container with an Emacs window and a terminal +emulator on the bottom. In the right column, there is a stacked container with +a Chrome window: + +image:layout-saving-1.png["Restored layout",width=400,link="layout-saving-1.png"] + +The structure of this JSON file looks a lot like the +TREE+ reply, see +http://build.i3wm.org/docs/ipc.html#_tree_reply for documentation on that. Some +properties are excluded because they are not relevant when restoring a layout. + +Most importantly, look at the "swallows" section of each window. This is where +you need to be more or less specific. As an example, remember the section about +the Emacs window: + +-------------------------------------------------------------------------------- +"swallows": [ + { + "class": "^Emacs$", + "instance": "^notmuch$" + } +] +-------------------------------------------------------------------------------- + +Here you can see that i3 will require both the class and the instance to match. +Therefore, if you just start Emacs via dmenu, it will not get swallowed by that +container. Only if you start Emacs with the proper instance name (+emacs24 +--name notmuch+), it will get swallowed. + +You can match on "class", "instance", "window_role" and "title". All values are +case-sensitive regular expressions (PCRE). Use +xprop(1)+ and click into a +window to see its properties: + +-------------------------------------------------------------------------------- +$ xprop +WM_WINDOW_ROLE(STRING) = "gimp-toolbox-color-dialog" +WM_CLASS(STRING) = "gimp-2.8", "Gimp-2.8" +_NET_WM_NAME(UTF8_STRING) = "Change Foreground Color" +-------------------------------------------------------------------------------- + +The first part of +WM_CLASS+ is the "instance" (gimp-2.8 in this case), the +second part is the "class" (Gimp-2.8 in this case). "title" matches against ++_NET_WM_NAME+ and "window_role" matches against +WM_WINDOW_ROLE+. + +In general, you should try to be as specific as possible in your swallow +criteria. Try to use criteria that match one window and only one window, to +have a reliable startup procedure. + +If you specify multiple swallow criteria, the placeholder will be replaced by +the window which matches any of the criteria. As an example: + +-------------------------------------------------------------------------------- +// Matches either Emacs or Gvim, whichever one is started first. +"swallows": [ + {"class": "^Emacs$"}, + {"class": "^Gvim$"} +] +-------------------------------------------------------------------------------- + +=== JSON standard non-compliance + +A layout file as generated by +i3-save-tree(1)+ is not strictly valid JSON: + +1. Layout files contain multiple “JSON documents” on the top level, whereas the + JSON standard only allows precisely one “document” (array or hash). + +2. Layout files contain comments which are not standardized, but understood by + many parsers. + +Both deviations from the JSON standard are to make manual editing by humans +easier. In case you are writing a more elaborate tool for manipulating these +layouts, you can either use a JSON parser that supports these deviations (for +example libyajl), transform the layout file to a JSON-conforming file, or +link:http://cr.i3wm.org/[submit a patch] to make +i3-save-tree(1)+ optionally +output standard-conforming JSON. diff --git a/docs/layout-saving-1.png b/docs/layout-saving-1.png new file mode 100644 index 00000000..a49f042a Binary files /dev/null and b/docs/layout-saving-1.png differ diff --git a/docs/userguide b/docs/userguide index acf8192a..ff46d62f 100644 --- a/docs/userguide +++ b/docs/userguide @@ -166,7 +166,8 @@ hint and are opened in floating mode by default. You can toggle floating mode for a window by pressing +$mod+Shift+Space+. By dragging the window’s titlebar with your mouse you can move the window around. By grabbing the borders and moving them you can resize the window. You -can also do that by using the <>. +can also do that by using the <>. Another way to resize +floating windows using the mouse is to right-click on the titlebar and drag. For resizing floating windows with your keyboard, see <>. @@ -203,7 +204,7 @@ orientation (horizontal, vertical or unspecified) and the orientation depends on the layout the container is in (vertical for splitv and stacking, horizontal for splith and tabbed). So, in our example with the workspace, the default layout of the workspace +Container+ is splith (most monitors are widescreen -nowadays). If you change the layout to splitv (+$mod+l+ in the default config) +nowadays). If you change the layout to splitv (+$mod+v+ in the default config) and *then* open two terminals, i3 will configure your windows like this: image::tree-shot2.png["shot2",title="Vertical Workspace Orientation"] @@ -249,13 +250,13 @@ single workspace on which you open three terminal windows. All these terminal windows are directly attached to one node inside i3’s layout tree, the workspace node. By default, the workspace node’s orientation is +horizontal+. -Now you move one of these terminals down (+$mod+k+ by default). The workspace -node’s orientation will be changed to +vertical+. The terminal window you moved -down is directly attached to the workspace and appears on the bottom of the -screen. A new (horizontal) container was created to accommodate the other two -terminal windows. You will notice this when switching to tabbed mode (for -example). You would end up having one tab called "another container" and the -other one being the terminal window you moved down. +Now you move one of these terminals down (+$mod+Shift+k+ by default). The +workspace node’s orientation will be changed to +vertical+. The terminal window +you moved down is directly attached to the workspace and appears on the bottom +of the screen. A new (horizontal) container was created to accommodate the +other two terminal windows. You will notice this when switching to tabbed mode +(for example). You would end up having one tab called "another container" and +the other one being the terminal window you moved down. [[configuring]] == Configuring i3 @@ -727,6 +728,9 @@ client.unfocused:: A client which is not the focused one of its container. client.urgent:: A client which has its urgency hint activated. +client.placeholder:: + Background and text color are used to draw placeholder window contents + (when restoring layouts). Border and indicator are ignored. You can also specify the color to be used to paint the background of the client windows. This color will be used to paint the window on top of which the client @@ -749,6 +753,7 @@ client.focused #4c7899 #285577 #ffffff #2e9ef4 client.focused_inactive #333333 #5f676a #ffffff #484e50 client.unfocused #333333 #222222 #888888 #292d2e client.urgent #2f343a #900000 #ffffff #900000 +client.placeholder #000000 #0c0c0c #ffffff #000000 --------------------------------------------------------- Note that for the window decorations, the color around the child window is the @@ -805,6 +810,26 @@ focus_follows_mouse focus_follows_mouse no ---------------------- +=== Mouse warping + +By default, when switching focus to a window on a different output (e.g. +focusing a window on workspace 3 on output VGA-1, coming from workspace 2 on +LVDS-1), the mouse cursor is warped to the center of that window. + +With the +mouse_warping+ option, you can control when the mouse cursor should +be warped. +none+ disables warping entirely, whereas +output+ is the default +behavior described above. + +*Syntax*: +--------------------------- +mouse_warping +--------------------------- + +*Example*: +------------------ +mouse_warping none +------------------ + === Popups during fullscreen mode When you are in fullscreen mode, some applications still open popup windows @@ -861,7 +886,7 @@ inferior Xinerama API explicitly and therefore don’t provide support for reconfiguring your screens on the fly (they are read only once on startup and that’s it). -For people who do cannot modify their +~/.xsession+ to add the +For people who cannot modify their +~/.xsession+ to add the +--force-xinerama+ commandline parameter, a configuration option is provided: *Syntax*: @@ -1186,6 +1211,31 @@ bar { } ------------------------ +=== Strip workspace numbers + +Specifies whether workspace numbers should be displayed within the workspace +buttons. This is useful if you want to have a named workspace that stays in +order on the bar according to its number without displaying the number prefix. + +When +strip_workspace_numbers+ is set to +yes+, any workspace that has a name of +the form "[n]:[NAME]" will display only the name. You could use this, for +instance, to display Roman numerals rather than digits by naming your +workspaces to "1:I", "2:II", "3:III", "4:IV", ... + +The default is to display the full name within the workspace button. + +*Syntax*: +---------------------------------- +strip_workspace_numbers +---------------------------------- + +*Example*: +---------------------------- +bar { + strip_workspace_numbers yes +} +---------------------------- + === Binding Mode indicator Specifies whether the current binding mode indicator should be shown or not. diff --git a/generate-command-parser.pl b/generate-command-parser.pl index b76d5e55..9b5ef562 100755 --- a/generate-command-parser.pl +++ b/generate-command-parser.pl @@ -131,7 +131,7 @@ close($enumfh); # Third step: Generate the call function. open(my $callfh, '>', "GENERATED_${prefix}_call.h"); -my $resultname = uc(substr($prefix, 0, 1)) . substr($prefix, 1) . 'Result'; +my $resultname = uc(substr($prefix, 0, 1)) . substr($prefix, 1) . 'ResultIR'; say $callfh "static void GENERATED_call(const int call_identifier, struct $resultname *result) {"; say $callfh ' switch (call_identifier) {'; my $call_id = 0; diff --git a/i3-config-wizard/main.c b/i3-config-wizard/main.c index 09b94841..a76c211e 100644 --- a/i3-config-wizard/main.c +++ b/i3-config-wizard/main.c @@ -53,19 +53,21 @@ #error "SYSCONFDIR not defined" #endif -#define FREE(pointer) do { \ - if (pointer != NULL) { \ - free(pointer); \ - pointer = NULL; \ - } \ -} \ -while (0) +#define FREE(pointer) \ + do { \ + if (pointer != NULL) { \ + free(pointer); \ + pointer = NULL; \ + } \ + } while (0) #include "xcb.h" #include "libi3.h" -enum { STEP_WELCOME, STEP_GENERATE } current_step = STEP_WELCOME; -enum { MOD_Mod1, MOD_Mod4 } modifier = MOD_Mod4; +enum { STEP_WELCOME, + STEP_GENERATE } current_step = STEP_WELCOME; +enum { MOD_Mod1, + MOD_Mod4 } modifier = MOD_Mod4; static char *config_path; static uint32_t xcb_numlock_mask; @@ -102,7 +104,6 @@ typedef struct tokenptr { int n; } cmdp_token_ptr; - #include "GENERATED_config_tokens.h" static cmdp_state state; @@ -111,7 +112,7 @@ static cmdp_state state; * When jumping back to INITIAL, statelist_idx will simply be set to 1 * (likewise for other states, e.g. MODE or BAR). * This list is used to process the nearest error token. */ -static cmdp_state statelist[10] = { INITIAL }; +static cmdp_state statelist[10] = {INITIAL}; /* NB: statelist_idx points to where the next entry will be inserted */ static int statelist_idx = 1; @@ -182,7 +183,6 @@ static void push_long(const char *identifier, long num) { "in the code, or a new command which contains more than " "10 identified tokens.\n"); exit(1); - } static const char *get_string(const char *identifier) { @@ -195,7 +195,6 @@ static const char *get_string(const char *identifier) { return NULL; } - static void clear_stack(void) { for (int c = 0; c < 10; c++) { if (stack[c].type == STACK_STR && stack[c].val.str != NULL) @@ -213,8 +212,8 @@ static void clear_stack(void) { */ static bool keysym_used_on_other_key(KeySym sym, xcb_keycode_t except_keycode) { xcb_keycode_t i, - min_keycode = xcb_get_setup(conn)->min_keycode, - max_keycode = xcb_get_setup(conn)->max_keycode; + min_keycode = xcb_get_setup(conn)->min_keycode, + max_keycode = xcb_get_setup(conn)->max_keycode; for (i = min_keycode; i && i <= max_keycode; i++) { if (i == except_keycode) @@ -228,7 +227,6 @@ static bool keysym_used_on_other_key(KeySym sym, xcb_keycode_t except_keycode) { return false; } - static char *next_state(const cmdp_token *token) { cmdp_state _next_state = token->next_state; @@ -277,7 +275,7 @@ static char *next_state(const cmdp_token *token) { for (int i = 0; i < statelist_idx; i++) { if (statelist[i] != _next_state) continue; - statelist_idx = i+1; + statelist_idx = i + 1; return NULL; } @@ -286,7 +284,6 @@ static char *next_state(const cmdp_token *token) { return NULL; } - static char *rewrite_binding(const char *input) { state = INITIAL; statelist_idx = 1; @@ -299,13 +296,13 @@ static char *rewrite_binding(const char *input) { /* The "<=" operator is intentional: We also handle the terminating 0-byte * explicitly by looking for an 'end' token. */ - while ((walk - input) <= len) { + while ((size_t)(walk - input) <= len) { /* Skip whitespace before every token, newlines are relevant since they * separate configuration directives. */ while ((*walk == ' ' || *walk == '\t') && *walk != '\0') walk++; - //printf("remaining input: %s\n", walk); + //printf("remaining input: %s\n", walk); cmdp_token_ptr *ptr = &(tokens[state]); for (c = 0; c < ptr->n; c++) { @@ -354,7 +351,7 @@ static char *rewrite_binding(const char *input) { if (*walk == '"') { beginning++; walk++; - while (*walk != '\0' && (*walk != '"' || *(walk-1) == '\\')) + while (*walk != '\0' && (*walk != '"' || *(walk - 1) == '\\')) walk++; } else { if (token->name[0] == 's') { @@ -366,22 +363,22 @@ static char *rewrite_binding(const char *input) { * semicolon (;). */ while (*walk != ' ' && *walk != '\t' && *walk != ']' && *walk != ',' && - *walk != ';' && *walk != '\r' && + *walk != ';' && *walk != '\r' && *walk != '\n' && *walk != '\0') walk++; } } if (walk != beginning) { - char *str = scalloc(walk-beginning + 1); + char *str = scalloc(walk - beginning + 1); /* We copy manually to handle escaping of characters. */ int inpos, outpos; for (inpos = 0, outpos = 0; - inpos < (walk-beginning); + inpos < (walk - beginning); inpos++, outpos++) { /* We only handle escaped double quotes to not break * backwards compatibility with people using \w in * regular expressions etc. */ - if (beginning[inpos] == '\\' && beginning[inpos+1] == '"') + if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"') inpos++; str[outpos] = beginning[inpos]; } @@ -410,15 +407,14 @@ static char *rewrite_binding(const char *input) { // TODO: make this testable walk++; break; - } - } + } + } } } return NULL; } - /* * Having verboselog(), errorlog() and debuglog() is necessary when using libi3. * @@ -453,7 +449,7 @@ static char *resolve_tilde(const char *path) { char *head, *tail, *result; tail = strchr(path, '/'); - head = strndup(path, tail ? tail - path : strlen(path)); + head = strndup(path, tail ? (size_t)(tail - path) : strlen(path)); int res = glob(head, GLOB_TILDE, NULL, &globbuf); free(head); @@ -481,14 +477,14 @@ static char *resolve_tilde(const char *path) { static int handle_expose() { /* re-draw the background */ xcb_rectangle_t border = {0, 0, 300, (15 * font.height) + 8}; - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {get_colorpixel("#000000")}); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border); set_font(&font); -#define txt(x, row, text) \ - draw_text_ascii(text, pixmap, pixmap_gc,\ - x, (row - 1) * font.height + 4, 300 - x * 2) +#define txt(x, row, text) \ + draw_text_ascii(text, pixmap, pixmap_gc, \ + x, (row - 1) * font.height + 4, 300 - x * 2) if (current_step == STEP_WELCOME) { /* restore font color */ @@ -521,14 +517,16 @@ static int handle_expose() { /* the not-selected modifier */ if (modifier == MOD_Mod4) txt(31, 5, ""); - else txt(31, 4, ""); + else + txt(31, 4, ""); /* the selected modifier */ set_font(&bold_font); set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); if (modifier == MOD_Mod4) txt(10, 4, "-> "); - else txt(10, 5, "-> "); + else + txt(10, 5, "-> "); /* green */ set_font(&font); @@ -565,16 +563,16 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press current_step = STEP_GENERATE; /* Set window title */ xcb_change_property(conn, - XCB_PROP_MODE_REPLACE, - win, - A__NET_WM_NAME, - A_UTF8_STRING, - 8, - strlen("i3: generate config"), - "i3: generate config"); + XCB_PROP_MODE_REPLACE, + win, + A__NET_WM_NAME, + A_UTF8_STRING, + 8, + strlen("i3: generate config"), + "i3: generate config"); xcb_flush(conn); - } - else finish(); + } else + finish(); } /* cancel any time */ @@ -618,7 +616,7 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press * Handle button presses to make clicking on "" and "" work * */ -static void handle_button_press(xcb_button_press_event_t* event) { +static void handle_button_press(xcb_button_press_event_t *event) { if (current_step != STEP_GENERATE) return; @@ -667,7 +665,7 @@ static void finish() { fputs("# This file has been auto-generated by i3-config-wizard(1).\n", ks_config); fputs("# It will not be overwritten, so edit it as you like.\n", ks_config); fputs("#\n", ks_config); - fputs("# Should you change your keyboard layout somewhen, delete\n", ks_config); + fputs("# Should you change your keyboard layout some time, delete\n", ks_config); fputs("# this file and re-run i3-config-wizard(1).\n", ks_config); fputs("#\n", ks_config); @@ -701,7 +699,8 @@ static void finish() { if (strncmp(walk, "set $mod ", strlen("set $mod ")) == 0) { if (modifier == MOD_Mod1) fputs("set $mod Mod1\n", ks_config); - else fputs("set $mod Mod4\n", ks_config); + else + fputs("set $mod Mod4\n", ks_config); continue; } @@ -729,7 +728,7 @@ static void finish() { /* tell i3 to reload the config file */ int sockfd = ipc_connect(socket_path); - ipc_send_message(sockfd, strlen("reload"), 0, (uint8_t*)"reload"); + ipc_send_message(sockfd, strlen("reload"), 0, (uint8_t *)"reload"); close(sockfd); exit(0); @@ -750,8 +749,7 @@ int main(int argc, char *argv[]) { {"prefix", required_argument, 0, 'p'}, {"font", required_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} - }; + {0, 0, 0, 0}}; char *options_string = "s:vh"; @@ -810,11 +808,11 @@ int main(int argc, char *argv[]) { modmap_cookie = xcb_get_modifier_mapping(conn); symbols = xcb_key_symbols_alloc(conn); - /* Place requests for the atoms we need as soon as possible */ - #define xmacro(atom) \ - xcb_intern_atom_cookie_t atom ## _cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom); - #include "atoms.xmacro" - #undef xmacro +/* Place requests for the atoms we need as soon as possible */ +#define xmacro(atom) \ + xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom); +#include "atoms.xmacro" +#undef xmacro root_screen = xcb_aux_get_screen(conn, screen); root = root_screen->root; @@ -832,54 +830,53 @@ int main(int argc, char *argv[]) { xcb_create_window( conn, XCB_COPY_FROM_PARENT, - win, /* the window id */ - root, /* parent == root */ + win, /* the window id */ + root, /* parent == root */ 490, 297, 300, 205, /* dimensions */ - 0, /* X11 border = 0, we draw our own */ + 0, /* X11 border = 0, we draw our own */ XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */ XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, - (uint32_t[]){ + (uint32_t[]) { 0, /* back pixel: black */ XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_BUTTON_PRESS - }); + XCB_EVENT_MASK_BUTTON_PRESS}); /* Map the window (make it visible) */ xcb_map_window(conn, win); - /* Setup NetWM atoms */ - #define xmacro(name) \ - do { \ - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name ## _cookie, NULL); \ - if (!reply) \ - errx(EXIT_FAILURE, "Could not get atom " # name "\n"); \ - \ - A_ ## name = reply->atom; \ - free(reply); \ - } while (0); - #include "atoms.xmacro" - #undef xmacro +/* Setup NetWM atoms */ +#define xmacro(name) \ + do { \ + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \ + if (!reply) \ + errx(EXIT_FAILURE, "Could not get atom " #name "\n"); \ + \ + A_##name = reply->atom; \ + free(reply); \ + } while (0); +#include "atoms.xmacro" +#undef xmacro /* Set dock mode */ xcb_change_property(conn, - XCB_PROP_MODE_REPLACE, - win, - A__NET_WM_WINDOW_TYPE, - A_ATOM, - 32, - 1, - (unsigned char*) &A__NET_WM_WINDOW_TYPE_DIALOG); + XCB_PROP_MODE_REPLACE, + win, + A__NET_WM_WINDOW_TYPE, + A_ATOM, + 32, + 1, + (unsigned char *)&A__NET_WM_WINDOW_TYPE_DIALOG); /* Set window title */ xcb_change_property(conn, - XCB_PROP_MODE_REPLACE, - win, - A__NET_WM_NAME, - A_UTF8_STRING, - 8, - strlen("i3: first configuration"), - "i3: first configuration"); + XCB_PROP_MODE_REPLACE, + win, + A__NET_WM_NAME, + A_UTF8_STRING, + 8, + strlen("i3: first configuration"), + "i3: first configuration"); /* Create pixmap */ pixmap = xcb_generate_id(conn); @@ -922,13 +919,13 @@ int main(int argc, char *argv[]) { switch (type) { case XCB_KEY_PRESS: - handle_key_press(NULL, conn, (xcb_key_press_event_t*)event); + handle_key_press(NULL, conn, (xcb_key_press_event_t *)event); break; /* TODO: handle mappingnotify */ case XCB_BUTTON_PRESS: - handle_button_press((xcb_button_press_event_t*)event); + handle_button_press((xcb_button_press_event_t *)event); break; case XCB_EXPOSE: diff --git a/i3-config-wizard/xcb.h b/i3-config-wizard/xcb.h index 372ed161..d51f979a 100644 --- a/i3-config-wizard/xcb.h +++ b/i3-config-wizard/xcb.h @@ -1,5 +1,4 @@ -#ifndef I3_XCB_H -#define I3_XCB_H +#pragma once /* from X11/keysymdef.h */ #define XCB_NUM_LOCK 0xff7f @@ -7,5 +6,3 @@ #define xmacro(atom) xcb_atom_t A_ ## atom; #include "atoms.xmacro" #undef xmacro - -#endif diff --git a/i3-dmenu-desktop b/i3-dmenu-desktop index cccc1dc5..4a2371e2 100755 --- a/i3-dmenu-desktop +++ b/i3-dmenu-desktop @@ -1,7 +1,7 @@ #!/usr/bin/env perl # vim:ts=4:sw=4:expandtab # -# © 2012-2013 Michael Stapelberg +# © 2012-2014 Michael Stapelberg # # No dependencies except for perl ≥ v5.10 @@ -55,8 +55,12 @@ my $result = GetOptions( die "Could not parse command line options" unless $result; # Filter entry types and set default type(s) if none selected -my @valid_types = ('name', 'command', 'filename'); -@entry_types = grep { $_ ~~ @valid_types } @entry_types; +my $valid_types = { + name => 1, + command => 1, + filename => 1, +}; +@entry_types = grep { exists($valid_types->{$_}) } @entry_types; @entry_types = ('name', 'command') unless @entry_types; # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ @@ -257,7 +261,7 @@ for my $app (keys %apps) { } } - if ('name' ~~ @entry_types) { + if ((scalar grep { $_ eq 'name' } @entry_types) > 0) { if (exists($choices{$name})) { # There are two .desktop files which contain the same “Name” value. # I’m not sure if that is allowed to happen, but we disambiguate the @@ -273,22 +277,22 @@ for my $app (keys %apps) { $choices{$name} = $app; } - if ('command' ~~ @entry_types) { + if ((scalar grep { $_ eq 'command' } @entry_types) > 0) { my ($command) = split(' ', $apps{$app}->{Exec}); # Don’t add “geany” if “Geany” is already present. my @keys = map { lc } keys %choices; - next if lc(basename($command)) ~~ @keys; + next if (scalar grep { $_ eq lc(basename($command)) } @keys) > 0; $choices{basename($command)} = $app; } - if ('filename' ~~ @entry_types) { + if ((scalar grep { $_ eq 'filename' } @entry_types) > 0) { my $filename = basename($app, '.desktop'); # Don’t add “geany” if “Geany” is already present. my @keys = map { lc } keys %choices; - next if lc($filename) ~~ @keys; + next if (scalar grep { $_ eq lc($filename) } @keys) > 0; $choices{$filename} = $app; } @@ -376,6 +380,7 @@ sub quote { $choice = quote($choice); $location = quote($location); +$name = quote($name); # Remove deprecated field codes, as the spec dictates. $exec =~ s/%[dDnNvm]//g; diff --git a/i3-dump-log/main.c b/i3-dump-log/main.c index acb7fcb1..86b39338 100644 --- a/i3-dump-log/main.c +++ b/i3-dump-log/main.c @@ -29,11 +29,11 @@ #include static uint32_t offset_next_write, - wrap_count; + wrap_count; static i3_shmlog_header *header; static char *logbuffer, - *walk; + *walk; static int check_for_wrap(void) { if (wrap_count == header->wrap_count) @@ -70,8 +70,7 @@ int main(int argc, char *argv[]) { {"verbose", no_argument, 0, 'V'}, {"follow", no_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} - }; + {0, 0, 0, 0}}; char *options_string = "s:vfVh"; @@ -139,7 +138,7 @@ int main(int argc, char *argv[]) { if (logbuffer == MAP_FAILED) err(EXIT_FAILURE, "Could not mmap SHM segment for the i3 log"); - header = (i3_shmlog_header*)logbuffer; + header = (i3_shmlog_header *)logbuffer; if (verbose) printf("next_write = %d, last_wrap = %d, logbuffer_size = %d, shmname = %s\n", diff --git a/i3-input/i3-input.h b/i3-input/i3-input.h index f1d5f077..104296cf 100644 --- a/i3-input/i3-input.h +++ b/i3-input/i3-input.h @@ -1,5 +1,4 @@ -#ifndef I3_INPUT -#define I3_INPUT +#pragma once #include @@ -13,5 +12,3 @@ while (0) extern xcb_window_t root; - -#endif diff --git a/i3-input/keysym2ucs.c b/i3-input/keysym2ucs.c index 3da51edd..b8e45a14 100644 --- a/i3-input/keysym2ucs.c +++ b/i3-input/keysym2ucs.c @@ -35,787 +35,786 @@ #include "keysym2ucs.h" struct codepair { - unsigned short keysym; - unsigned short ucs; + unsigned short keysym; + unsigned short ucs; } keysymtab[] = { - { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ - { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ - { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ - { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ - { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ - { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ - { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ - { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ - { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ - { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ - { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ - { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ - { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ - { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ - { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ - { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ - { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ - { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ - { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ - { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ - { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ - { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ - { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ - { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ - { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ - { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ - { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ - { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ - { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ - { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ - { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ - { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ - { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ - { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ - { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ - { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ - { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ - { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ - { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ - { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ - { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ - { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ - { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ - { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ - { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ - { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ - { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ - { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ - { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ - { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ - { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ - { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ - { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ - { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ - { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ - { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ - { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ - { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ - { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ - { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ - { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ - { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ - { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ - { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ - { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ - { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ - { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ - { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ - { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ - { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ - { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ - { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ - { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ - { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ - { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ - { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ - { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ - { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ - { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ - { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ - { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ - { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ - { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ - { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ - { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ - { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ - { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ - { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ - { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ - { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ - { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ - { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ - { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ - { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ - { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ - { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ - { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ - { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ - { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ - { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ - { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ - { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ - { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ - { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ - { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ - { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ - { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ - { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ - { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ - { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ - { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ - { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ - { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ - { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ - { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ - { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ - { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ - { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ - { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ - { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ - { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ - { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ - { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ - { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ - { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ - { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ - { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ - { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ - { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ - { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ - { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ - { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ - { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ - { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ - { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ - { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ - { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ - { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ - { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ - { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ - { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ - { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ - { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ - { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ - { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ - { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ - { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ - { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ - { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ - { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ - { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ - { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ - { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ - { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ - { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ - { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ - { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ - { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ - { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ - { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ - { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ - { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ - { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ - { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ - { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ - { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ - { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ - { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ - { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ - { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ - { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ - { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ - { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ - { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ - { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ - { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ - { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ - { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ - { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ - { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ - { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ - { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ - { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ - { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ - { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ - { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ - { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ - { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ - { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ - { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ - { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ - { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ - { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ - { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ - { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ - { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ - { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ - { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ - { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ - { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ - { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ - { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ - { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ - { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ - { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ - { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ - { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ - { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ - { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ - { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ - { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ - { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ - { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ - { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ - { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ - { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ - { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ - { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ - { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ - { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ - { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ - { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ - { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ - { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ - { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ - { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ - { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ - { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ - { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ - { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ - { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ - { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ - { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ - { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ - { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ - { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ - { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ -/* 0x06ad Ukrainian_ghe_with_upturn ? ??? */ - { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ - { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ - { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ - { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ - { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ - { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ - { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ - { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ - { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ - { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ - { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ - { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ - { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ - { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ -/* 0x06bd Ukrainian_GHE_WITH_UPTURN ? ??? */ - { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ - { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ - { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ - { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ - { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ - { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ - { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ - { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ - { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ - { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ - { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ - { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ - { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ - { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ - { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ - { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ - { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ - { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ - { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ - { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ - { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ - { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ - { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ - { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ - { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ - { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ - { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ - { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ - { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ - { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ - { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ - { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ - { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ - { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ - { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ - { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ - { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ - { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ - { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ - { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ - { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ - { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ - { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ - { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ - { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ - { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ - { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ - { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ - { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ - { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ - { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ - { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ - { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ - { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ - { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ - { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ - { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ - { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ - { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ - { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ - { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ - { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ - { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ - { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ - { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ - { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ - { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ - { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ - { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ - { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ - { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ - { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ - { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ - { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ - { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ - { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ - { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ - { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ - { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ - { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ - { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ - { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ - { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ - { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ - { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ - { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ - { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ - { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ - { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ - { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ - { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ - { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ - { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ - { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ - { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ - { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ - { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ - { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ - { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ - { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ - { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ - { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ - { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ - { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ - { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ - { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ - { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ - { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ - { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ - { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ - { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ - { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ - { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ - { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ - { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ - { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ - { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ - { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ - { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ - { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ - { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ - { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ - { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ - { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ - { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ - { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ - { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ - { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ - { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ - { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ - { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ - { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ - { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ - { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ - { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ -/* 0x08a1 leftradical ? ??? */ -/* 0x08a2 topleftradical ? ??? */ -/* 0x08a3 horizconnector ? ??? */ - { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ - { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ - { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ -/* 0x08a7 topleftsqbracket ? ??? */ -/* 0x08a8 botleftsqbracket ? ??? */ -/* 0x08a9 toprightsqbracket ? ??? */ -/* 0x08aa botrightsqbracket ? ??? */ -/* 0x08ab topleftparens ? ??? */ -/* 0x08ac botleftparens ? ??? */ -/* 0x08ad toprightparens ? ??? */ -/* 0x08ae botrightparens ? ??? */ -/* 0x08af leftmiddlecurlybrace ? ??? */ -/* 0x08b0 rightmiddlecurlybrace ? ??? */ -/* 0x08b1 topleftsummation ? ??? */ -/* 0x08b2 botleftsummation ? ??? */ -/* 0x08b3 topvertsummationconnector ? ??? */ -/* 0x08b4 botvertsummationconnector ? ??? */ -/* 0x08b5 toprightsummation ? ??? */ -/* 0x08b6 botrightsummation ? ??? */ -/* 0x08b7 rightmiddlesummation ? ??? */ - { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ - { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ - { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ - { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ - { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ - { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ - { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ - { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ - { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ -/* 0x08c9 similarequal ? ??? */ - { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ - { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ - { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ - { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ - { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ - { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ - { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ - { 0x08dd, 0x222a }, /* union ∪ UNION */ - { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ - { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ - { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ - { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ - { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ - { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ - { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ - { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ - { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ - { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ - { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ - { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ - { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ - { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ - { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ - { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ - { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ - { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ - { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ - { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ - { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ - { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ -/* 0x09ef horizlinescan1 ? ??? */ -/* 0x09f0 horizlinescan3 ? ??? */ - { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ -/* 0x09f2 horizlinescan7 ? ??? */ -/* 0x09f3 horizlinescan9 ? ??? */ - { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ - { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ - { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ - { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ - { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ - { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ - { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ - { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ - { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ - { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ - { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ - { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ - { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ - { 0x0aaa, 0x2013 }, /* endash – EN DASH */ -/* 0x0aac signifblank ? ??? */ - { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ -/* 0x0aaf doubbaselinedot ? ??? */ - { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ - { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ - { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ - { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ - { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ - { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ - { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ - { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ - { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ - { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ - { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ - { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ - { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ -/* 0x0abf marker ? ??? */ - { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ - { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ - { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ - { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ - { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ - { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ -/* 0x0acb trademarkincircle ? ??? */ - { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ - { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ - { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ - { 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */ - { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ - { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ - { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ - { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ - { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ - { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ - { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ - { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ -/* 0x0ada hexagram ? ??? */ - { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ - { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ - { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ - { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ - { 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */ - { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ - { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ - { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ - { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ - { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ - { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ - { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ - { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ - { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ - { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ - { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ - { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ - { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ - { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ - { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ - { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ - { 0x0af1, 0x2020 }, /* dagger † DAGGER */ - { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ - { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ - { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ - { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ - { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ - { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ - { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ - { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ - { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ - { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ - { 0x0afc, 0x2038 }, /* caret ‸ CARET */ - { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ - { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ -/* 0x0aff cursor ? ??? */ - { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ - { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ - { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ - { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ - { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ - { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ - { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ - { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ - { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ - { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ - { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ - { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ - { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ - { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ - { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ - { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ - { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ - { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ - { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ - { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ - { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ - { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ - { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ - { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ - { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ - { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ - { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ - { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ - { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ - { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ - { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ - { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ - { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ - { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ - { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ - { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ - { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ - { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ - { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ - { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ - { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ - { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ - { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ - { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ - { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ - { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ - { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ - { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ - { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ - { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ - { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ - { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ - { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ - { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ - { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ - { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ - { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ - { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ - { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ - { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ - { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ - { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ - { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ - { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ - { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ - { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ - { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ - { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ - { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ - { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ - { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ - { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ - { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ - { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ - { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ - { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ - { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ - { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ - { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ - { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ - { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ - { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ - { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ - { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ - { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ - { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ - { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ - { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ - { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ - { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ - { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ - { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ - { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ - { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ - { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ - { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ - { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ - { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ - { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ - { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ - { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ - { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ - { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ - { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ - { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ - { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ - { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ - { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ - { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ - { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ - { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ - { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ - { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ - { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ - { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ - { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ - { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ - { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ - { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ - { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ - { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ - { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ - { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ - { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ - { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ - { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ - { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ - { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ - { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ - { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ - { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ - { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ - { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ - { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ - { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ - { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ - { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ - { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ - { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ - { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ - { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ - { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ - { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ - { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ - { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ - { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ - { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ - { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ - { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ - { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ - { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ - { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ - { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ - { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ - { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ - { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ - { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ - { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ - { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ - { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ - { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ - { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ - { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ - { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ - { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ - { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ - { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ - { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ - { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ - { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ - { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ - { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ - { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ - { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ - { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ - { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ - { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ - { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ - { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ - { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ - { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ - { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ - { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ - { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ - { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ - { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ - { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ - { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ - { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ - { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ - { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ - { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ - { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ - { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ - { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ - { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ - { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ - { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ - { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ - { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ - { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ - { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ - { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ - { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ - { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ - { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ - { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ - { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ - { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ - { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ - { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ - { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ - { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ -/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ - { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ - { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ - { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ - { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ - { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ -/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */ - { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ - { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ - { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ - { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ - { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ - { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ + {0x01a1, 0x0104}, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ + {0x01a2, 0x02d8}, /* breve ˘ BREVE */ + {0x01a3, 0x0141}, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ + {0x01a5, 0x013d}, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + {0x01a6, 0x015a}, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ + {0x01a9, 0x0160}, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ + {0x01aa, 0x015e}, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ + {0x01ab, 0x0164}, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + {0x01ac, 0x0179}, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + {0x01ae, 0x017d}, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + {0x01af, 0x017b}, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + {0x01b1, 0x0105}, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ + {0x01b2, 0x02db}, /* ogonek ˛ OGONEK */ + {0x01b3, 0x0142}, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ + {0x01b5, 0x013e}, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + {0x01b6, 0x015b}, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ + {0x01b7, 0x02c7}, /* caron ˇ CARON */ + {0x01b9, 0x0161}, /* scaron š LATIN SMALL LETTER S WITH CARON */ + {0x01ba, 0x015f}, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ + {0x01bb, 0x0165}, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ + {0x01bc, 0x017a}, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + {0x01bd, 0x02dd}, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ + {0x01be, 0x017e}, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + {0x01bf, 0x017c}, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + {0x01c0, 0x0154}, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ + {0x01c3, 0x0102}, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ + {0x01c5, 0x0139}, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + {0x01c6, 0x0106}, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + {0x01c8, 0x010c}, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ + {0x01ca, 0x0118}, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + {0x01cc, 0x011a}, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ + {0x01cf, 0x010e}, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ + {0x01d0, 0x0110}, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ + {0x01d1, 0x0143}, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + {0x01d2, 0x0147}, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + {0x01d5, 0x0150}, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + {0x01d8, 0x0158}, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + {0x01d9, 0x016e}, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ + {0x01db, 0x0170}, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + {0x01de, 0x0162}, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ + {0x01e0, 0x0155}, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ + {0x01e3, 0x0103}, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + {0x01e5, 0x013a}, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + {0x01e6, 0x0107}, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + {0x01e8, 0x010d}, /* ccaron č LATIN SMALL LETTER C WITH CARON */ + {0x01ea, 0x0119}, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ + {0x01ec, 0x011b}, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ + {0x01ef, 0x010f}, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ + {0x01f0, 0x0111}, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ + {0x01f1, 0x0144}, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ + {0x01f2, 0x0148}, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + {0x01f5, 0x0151}, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + {0x01f8, 0x0159}, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ + {0x01f9, 0x016f}, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + {0x01fb, 0x0171}, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + {0x01fe, 0x0163}, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ + {0x01ff, 0x02d9}, /* abovedot ˙ DOT ABOVE */ + {0x02a1, 0x0126}, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + {0x02a6, 0x0124}, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + {0x02a9, 0x0130}, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ + {0x02ab, 0x011e}, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ + {0x02ac, 0x0134}, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + {0x02b1, 0x0127}, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + {0x02b6, 0x0125}, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + {0x02b9, 0x0131}, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + {0x02bb, 0x011f}, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ + {0x02bc, 0x0135}, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + {0x02c5, 0x010a}, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + {0x02c6, 0x0108}, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + {0x02d5, 0x0120}, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ + {0x02d8, 0x011c}, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + {0x02dd, 0x016c}, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + {0x02de, 0x015c}, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + {0x02e5, 0x010b}, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ + {0x02e6, 0x0109}, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + {0x02f5, 0x0121}, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ + {0x02f8, 0x011d}, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ + {0x02fd, 0x016d}, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ + {0x02fe, 0x015d}, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ + {0x03a2, 0x0138}, /* kra ĸ LATIN SMALL LETTER KRA */ + {0x03a3, 0x0156}, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ + {0x03a5, 0x0128}, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + {0x03a6, 0x013b}, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ + {0x03aa, 0x0112}, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ + {0x03ab, 0x0122}, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ + {0x03ac, 0x0166}, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + {0x03b3, 0x0157}, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ + {0x03b5, 0x0129}, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ + {0x03b6, 0x013c}, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + {0x03ba, 0x0113}, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ + {0x03bb, 0x0123}, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ + {0x03bc, 0x0167}, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + {0x03bd, 0x014a}, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ + {0x03bf, 0x014b}, /* eng ŋ LATIN SMALL LETTER ENG */ + {0x03c0, 0x0100}, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ + {0x03c7, 0x012e}, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ + {0x03cc, 0x0116}, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ + {0x03cf, 0x012a}, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + {0x03d1, 0x0145}, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ + {0x03d2, 0x014c}, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ + {0x03d3, 0x0136}, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + {0x03d9, 0x0172}, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + {0x03dd, 0x0168}, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + {0x03de, 0x016a}, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + {0x03e0, 0x0101}, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ + {0x03e7, 0x012f}, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + {0x03ec, 0x0117}, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ + {0x03ef, 0x012b}, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ + {0x03f1, 0x0146}, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + {0x03f2, 0x014d}, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ + {0x03f3, 0x0137}, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ + {0x03f9, 0x0173}, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + {0x03fd, 0x0169}, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ + {0x03fe, 0x016b}, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ + {0x047e, 0x203e}, /* overline ‾ OVERLINE */ + {0x04a1, 0x3002}, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + {0x04a2, 0x300c}, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + {0x04a3, 0x300d}, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ + {0x04a4, 0x3001}, /* kana_comma 、 IDEOGRAPHIC COMMA */ + {0x04a5, 0x30fb}, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + {0x04a6, 0x30f2}, /* kana_WO ヲ KATAKANA LETTER WO */ + {0x04a7, 0x30a1}, /* kana_a ァ KATAKANA LETTER SMALL A */ + {0x04a8, 0x30a3}, /* kana_i ィ KATAKANA LETTER SMALL I */ + {0x04a9, 0x30a5}, /* kana_u ゥ KATAKANA LETTER SMALL U */ + {0x04aa, 0x30a7}, /* kana_e ェ KATAKANA LETTER SMALL E */ + {0x04ab, 0x30a9}, /* kana_o ォ KATAKANA LETTER SMALL O */ + {0x04ac, 0x30e3}, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + {0x04ad, 0x30e5}, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + {0x04ae, 0x30e7}, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + {0x04af, 0x30c3}, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + {0x04b0, 0x30fc}, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + {0x04b1, 0x30a2}, /* kana_A ア KATAKANA LETTER A */ + {0x04b2, 0x30a4}, /* kana_I イ KATAKANA LETTER I */ + {0x04b3, 0x30a6}, /* kana_U ウ KATAKANA LETTER U */ + {0x04b4, 0x30a8}, /* kana_E エ KATAKANA LETTER E */ + {0x04b5, 0x30aa}, /* kana_O オ KATAKANA LETTER O */ + {0x04b6, 0x30ab}, /* kana_KA カ KATAKANA LETTER KA */ + {0x04b7, 0x30ad}, /* kana_KI キ KATAKANA LETTER KI */ + {0x04b8, 0x30af}, /* kana_KU ク KATAKANA LETTER KU */ + {0x04b9, 0x30b1}, /* kana_KE ケ KATAKANA LETTER KE */ + {0x04ba, 0x30b3}, /* kana_KO コ KATAKANA LETTER KO */ + {0x04bb, 0x30b5}, /* kana_SA サ KATAKANA LETTER SA */ + {0x04bc, 0x30b7}, /* kana_SHI シ KATAKANA LETTER SI */ + {0x04bd, 0x30b9}, /* kana_SU ス KATAKANA LETTER SU */ + {0x04be, 0x30bb}, /* kana_SE セ KATAKANA LETTER SE */ + {0x04bf, 0x30bd}, /* kana_SO ソ KATAKANA LETTER SO */ + {0x04c0, 0x30bf}, /* kana_TA タ KATAKANA LETTER TA */ + {0x04c1, 0x30c1}, /* kana_CHI チ KATAKANA LETTER TI */ + {0x04c2, 0x30c4}, /* kana_TSU ツ KATAKANA LETTER TU */ + {0x04c3, 0x30c6}, /* kana_TE テ KATAKANA LETTER TE */ + {0x04c4, 0x30c8}, /* kana_TO ト KATAKANA LETTER TO */ + {0x04c5, 0x30ca}, /* kana_NA ナ KATAKANA LETTER NA */ + {0x04c6, 0x30cb}, /* kana_NI ニ KATAKANA LETTER NI */ + {0x04c7, 0x30cc}, /* kana_NU ヌ KATAKANA LETTER NU */ + {0x04c8, 0x30cd}, /* kana_NE ネ KATAKANA LETTER NE */ + {0x04c9, 0x30ce}, /* kana_NO ノ KATAKANA LETTER NO */ + {0x04ca, 0x30cf}, /* kana_HA ハ KATAKANA LETTER HA */ + {0x04cb, 0x30d2}, /* kana_HI ヒ KATAKANA LETTER HI */ + {0x04cc, 0x30d5}, /* kana_FU フ KATAKANA LETTER HU */ + {0x04cd, 0x30d8}, /* kana_HE ヘ KATAKANA LETTER HE */ + {0x04ce, 0x30db}, /* kana_HO ホ KATAKANA LETTER HO */ + {0x04cf, 0x30de}, /* kana_MA マ KATAKANA LETTER MA */ + {0x04d0, 0x30df}, /* kana_MI ミ KATAKANA LETTER MI */ + {0x04d1, 0x30e0}, /* kana_MU ム KATAKANA LETTER MU */ + {0x04d2, 0x30e1}, /* kana_ME メ KATAKANA LETTER ME */ + {0x04d3, 0x30e2}, /* kana_MO モ KATAKANA LETTER MO */ + {0x04d4, 0x30e4}, /* kana_YA ヤ KATAKANA LETTER YA */ + {0x04d5, 0x30e6}, /* kana_YU ユ KATAKANA LETTER YU */ + {0x04d6, 0x30e8}, /* kana_YO ヨ KATAKANA LETTER YO */ + {0x04d7, 0x30e9}, /* kana_RA ラ KATAKANA LETTER RA */ + {0x04d8, 0x30ea}, /* kana_RI リ KATAKANA LETTER RI */ + {0x04d9, 0x30eb}, /* kana_RU ル KATAKANA LETTER RU */ + {0x04da, 0x30ec}, /* kana_RE レ KATAKANA LETTER RE */ + {0x04db, 0x30ed}, /* kana_RO ロ KATAKANA LETTER RO */ + {0x04dc, 0x30ef}, /* kana_WA ワ KATAKANA LETTER WA */ + {0x04dd, 0x30f3}, /* kana_N ン KATAKANA LETTER N */ + {0x04de, 0x309b}, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ + {0x04df, 0x309c}, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + {0x05ac, 0x060c}, /* Arabic_comma ، ARABIC COMMA */ + {0x05bb, 0x061b}, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ + {0x05bf, 0x061f}, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ + {0x05c1, 0x0621}, /* Arabic_hamza ء ARABIC LETTER HAMZA */ + {0x05c2, 0x0622}, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ + {0x05c3, 0x0623}, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + {0x05c4, 0x0624}, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + {0x05c5, 0x0625}, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ + {0x05c6, 0x0626}, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + {0x05c7, 0x0627}, /* Arabic_alef ا ARABIC LETTER ALEF */ + {0x05c8, 0x0628}, /* Arabic_beh ب ARABIC LETTER BEH */ + {0x05c9, 0x0629}, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ + {0x05ca, 0x062a}, /* Arabic_teh ت ARABIC LETTER TEH */ + {0x05cb, 0x062b}, /* Arabic_theh ث ARABIC LETTER THEH */ + {0x05cc, 0x062c}, /* Arabic_jeem ج ARABIC LETTER JEEM */ + {0x05cd, 0x062d}, /* Arabic_hah ح ARABIC LETTER HAH */ + {0x05ce, 0x062e}, /* Arabic_khah خ ARABIC LETTER KHAH */ + {0x05cf, 0x062f}, /* Arabic_dal د ARABIC LETTER DAL */ + {0x05d0, 0x0630}, /* Arabic_thal ذ ARABIC LETTER THAL */ + {0x05d1, 0x0631}, /* Arabic_ra ر ARABIC LETTER REH */ + {0x05d2, 0x0632}, /* Arabic_zain ز ARABIC LETTER ZAIN */ + {0x05d3, 0x0633}, /* Arabic_seen س ARABIC LETTER SEEN */ + {0x05d4, 0x0634}, /* Arabic_sheen ش ARABIC LETTER SHEEN */ + {0x05d5, 0x0635}, /* Arabic_sad ص ARABIC LETTER SAD */ + {0x05d6, 0x0636}, /* Arabic_dad ض ARABIC LETTER DAD */ + {0x05d7, 0x0637}, /* Arabic_tah ط ARABIC LETTER TAH */ + {0x05d8, 0x0638}, /* Arabic_zah ظ ARABIC LETTER ZAH */ + {0x05d9, 0x0639}, /* Arabic_ain ع ARABIC LETTER AIN */ + {0x05da, 0x063a}, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + {0x05e0, 0x0640}, /* Arabic_tatweel ـ ARABIC TATWEEL */ + {0x05e1, 0x0641}, /* Arabic_feh ف ARABIC LETTER FEH */ + {0x05e2, 0x0642}, /* Arabic_qaf ق ARABIC LETTER QAF */ + {0x05e3, 0x0643}, /* Arabic_kaf ك ARABIC LETTER KAF */ + {0x05e4, 0x0644}, /* Arabic_lam ل ARABIC LETTER LAM */ + {0x05e5, 0x0645}, /* Arabic_meem م ARABIC LETTER MEEM */ + {0x05e6, 0x0646}, /* Arabic_noon ن ARABIC LETTER NOON */ + {0x05e7, 0x0647}, /* Arabic_ha ه ARABIC LETTER HEH */ + {0x05e8, 0x0648}, /* Arabic_waw و ARABIC LETTER WAW */ + {0x05e9, 0x0649}, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ + {0x05ea, 0x064a}, /* Arabic_yeh ي ARABIC LETTER YEH */ + {0x05eb, 0x064b}, /* Arabic_fathatan ً ARABIC FATHATAN */ + {0x05ec, 0x064c}, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ + {0x05ed, 0x064d}, /* Arabic_kasratan ٍ ARABIC KASRATAN */ + {0x05ee, 0x064e}, /* Arabic_fatha َ ARABIC FATHA */ + {0x05ef, 0x064f}, /* Arabic_damma ُ ARABIC DAMMA */ + {0x05f0, 0x0650}, /* Arabic_kasra ِ ARABIC KASRA */ + {0x05f1, 0x0651}, /* Arabic_shadda ّ ARABIC SHADDA */ + {0x05f2, 0x0652}, /* Arabic_sukun ْ ARABIC SUKUN */ + {0x06a1, 0x0452}, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ + {0x06a2, 0x0453}, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ + {0x06a3, 0x0451}, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ + {0x06a4, 0x0454}, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ + {0x06a5, 0x0455}, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ + {0x06a6, 0x0456}, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + {0x06a7, 0x0457}, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ + {0x06a8, 0x0458}, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + {0x06a9, 0x0459}, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ + {0x06aa, 0x045a}, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ + {0x06ab, 0x045b}, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ + {0x06ac, 0x045c}, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ + /* 0x06ad Ukrainian_ghe_with_upturn ? ??? */ + {0x06ae, 0x045e}, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ + {0x06af, 0x045f}, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ + {0x06b0, 0x2116}, /* numerosign № NUMERO SIGN */ + {0x06b1, 0x0402}, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + {0x06b2, 0x0403}, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + {0x06b3, 0x0401}, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ + {0x06b4, 0x0404}, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + {0x06b5, 0x0405}, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ + {0x06b6, 0x0406}, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + {0x06b7, 0x0407}, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + {0x06b8, 0x0408}, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + {0x06b9, 0x0409}, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + {0x06ba, 0x040a}, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + {0x06bb, 0x040b}, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + {0x06bc, 0x040c}, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ + /* 0x06bd Ukrainian_GHE_WITH_UPTURN ? ??? */ + {0x06be, 0x040e}, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ + {0x06bf, 0x040f}, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ + {0x06c0, 0x044e}, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ + {0x06c1, 0x0430}, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + {0x06c2, 0x0431}, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + {0x06c3, 0x0446}, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + {0x06c4, 0x0434}, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + {0x06c5, 0x0435}, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + {0x06c6, 0x0444}, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ + {0x06c7, 0x0433}, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + {0x06c8, 0x0445}, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ + {0x06c9, 0x0438}, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + {0x06ca, 0x0439}, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + {0x06cb, 0x043a}, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + {0x06cc, 0x043b}, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + {0x06cd, 0x043c}, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + {0x06ce, 0x043d}, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + {0x06cf, 0x043e}, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + {0x06d0, 0x043f}, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + {0x06d1, 0x044f}, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ + {0x06d2, 0x0440}, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ + {0x06d3, 0x0441}, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ + {0x06d4, 0x0442}, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ + {0x06d5, 0x0443}, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + {0x06d6, 0x0436}, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + {0x06d7, 0x0432}, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + {0x06d8, 0x044c}, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ + {0x06d9, 0x044b}, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ + {0x06da, 0x0437}, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + {0x06db, 0x0448}, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + {0x06dc, 0x044d}, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ + {0x06dd, 0x0449}, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + {0x06de, 0x0447}, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + {0x06df, 0x044a}, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ + {0x06e0, 0x042e}, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + {0x06e1, 0x0410}, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ + {0x06e2, 0x0411}, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + {0x06e3, 0x0426}, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + {0x06e4, 0x0414}, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + {0x06e5, 0x0415}, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + {0x06e6, 0x0424}, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + {0x06e7, 0x0413}, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + {0x06e8, 0x0425}, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ + {0x06e9, 0x0418}, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + {0x06ea, 0x0419}, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + {0x06eb, 0x041a}, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + {0x06ec, 0x041b}, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + {0x06ed, 0x041c}, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ + {0x06ee, 0x041d}, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ + {0x06ef, 0x041e}, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + {0x06f0, 0x041f}, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + {0x06f1, 0x042f}, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + {0x06f2, 0x0420}, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ + {0x06f3, 0x0421}, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + {0x06f4, 0x0422}, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + {0x06f5, 0x0423}, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + {0x06f6, 0x0416}, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + {0x06f7, 0x0412}, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ + {0x06f8, 0x042c}, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + {0x06f9, 0x042b}, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + {0x06fa, 0x0417}, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + {0x06fb, 0x0428}, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + {0x06fc, 0x042d}, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ + {0x06fd, 0x0429}, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + {0x06fe, 0x0427}, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + {0x06ff, 0x042a}, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + {0x07a1, 0x0386}, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + {0x07a2, 0x0388}, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + {0x07a3, 0x0389}, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + {0x07a4, 0x038a}, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + {0x07a5, 0x03aa}, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + {0x07a7, 0x038c}, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ + {0x07a8, 0x038e}, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + {0x07a9, 0x03ab}, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + {0x07ab, 0x038f}, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ + {0x07ae, 0x0385}, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ + {0x07af, 0x2015}, /* Greek_horizbar ― HORIZONTAL BAR */ + {0x07b1, 0x03ac}, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + {0x07b2, 0x03ad}, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ + {0x07b3, 0x03ae}, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + {0x07b4, 0x03af}, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + {0x07b5, 0x03ca}, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + {0x07b6, 0x0390}, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + {0x07b7, 0x03cc}, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ + {0x07b8, 0x03cd}, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ + {0x07b9, 0x03cb}, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + {0x07ba, 0x03b0}, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + {0x07bb, 0x03ce}, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ + {0x07c1, 0x0391}, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + {0x07c2, 0x0392}, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ + {0x07c3, 0x0393}, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + {0x07c4, 0x0394}, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + {0x07c5, 0x0395}, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + {0x07c6, 0x0396}, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + {0x07c7, 0x0397}, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + {0x07c8, 0x0398}, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + {0x07c9, 0x0399}, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + {0x07ca, 0x039a}, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + {0x07cb, 0x039b}, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + {0x07cc, 0x039c}, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ + {0x07cd, 0x039d}, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ + {0x07ce, 0x039e}, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + {0x07cf, 0x039f}, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + {0x07d0, 0x03a0}, /* Greek_PI Π GREEK CAPITAL LETTER PI */ + {0x07d1, 0x03a1}, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + {0x07d2, 0x03a3}, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + {0x07d4, 0x03a4}, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + {0x07d5, 0x03a5}, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ + {0x07d6, 0x03a6}, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + {0x07d7, 0x03a7}, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + {0x07d8, 0x03a8}, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + {0x07d9, 0x03a9}, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + {0x07e1, 0x03b1}, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + {0x07e2, 0x03b2}, /* Greek_beta β GREEK SMALL LETTER BETA */ + {0x07e3, 0x03b3}, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + {0x07e4, 0x03b4}, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + {0x07e5, 0x03b5}, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + {0x07e6, 0x03b6}, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + {0x07e7, 0x03b7}, /* Greek_eta η GREEK SMALL LETTER ETA */ + {0x07e8, 0x03b8}, /* Greek_theta θ GREEK SMALL LETTER THETA */ + {0x07e9, 0x03b9}, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + {0x07ea, 0x03ba}, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + {0x07eb, 0x03bb}, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + {0x07ec, 0x03bc}, /* Greek_mu μ GREEK SMALL LETTER MU */ + {0x07ed, 0x03bd}, /* Greek_nu ν GREEK SMALL LETTER NU */ + {0x07ee, 0x03be}, /* Greek_xi ξ GREEK SMALL LETTER XI */ + {0x07ef, 0x03bf}, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + {0x07f0, 0x03c0}, /* Greek_pi π GREEK SMALL LETTER PI */ + {0x07f1, 0x03c1}, /* Greek_rho ρ GREEK SMALL LETTER RHO */ + {0x07f2, 0x03c3}, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + {0x07f3, 0x03c2}, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ + {0x07f4, 0x03c4}, /* Greek_tau τ GREEK SMALL LETTER TAU */ + {0x07f5, 0x03c5}, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ + {0x07f6, 0x03c6}, /* Greek_phi φ GREEK SMALL LETTER PHI */ + {0x07f7, 0x03c7}, /* Greek_chi χ GREEK SMALL LETTER CHI */ + {0x07f8, 0x03c8}, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + {0x07f9, 0x03c9}, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ + /* 0x08a1 leftradical ? ??? */ + /* 0x08a2 topleftradical ? ??? */ + /* 0x08a3 horizconnector ? ??? */ + {0x08a4, 0x2320}, /* topintegral ⌠ TOP HALF INTEGRAL */ + {0x08a5, 0x2321}, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + {0x08a6, 0x2502}, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ + /* 0x08a7 topleftsqbracket ? ??? */ + /* 0x08a8 botleftsqbracket ? ??? */ + /* 0x08a9 toprightsqbracket ? ??? */ + /* 0x08aa botrightsqbracket ? ??? */ + /* 0x08ab topleftparens ? ??? */ + /* 0x08ac botleftparens ? ??? */ + /* 0x08ad toprightparens ? ??? */ + /* 0x08ae botrightparens ? ??? */ + /* 0x08af leftmiddlecurlybrace ? ??? */ + /* 0x08b0 rightmiddlecurlybrace ? ??? */ + /* 0x08b1 topleftsummation ? ??? */ + /* 0x08b2 botleftsummation ? ??? */ + /* 0x08b3 topvertsummationconnector ? ??? */ + /* 0x08b4 botvertsummationconnector ? ??? */ + /* 0x08b5 toprightsummation ? ??? */ + /* 0x08b6 botrightsummation ? ??? */ + /* 0x08b7 rightmiddlesummation ? ??? */ + {0x08bc, 0x2264}, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + {0x08bd, 0x2260}, /* notequal ≠ NOT EQUAL TO */ + {0x08be, 0x2265}, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + {0x08bf, 0x222b}, /* integral ∫ INTEGRAL */ + {0x08c0, 0x2234}, /* therefore ∴ THEREFORE */ + {0x08c1, 0x221d}, /* variation ∝ PROPORTIONAL TO */ + {0x08c2, 0x221e}, /* infinity ∞ INFINITY */ + {0x08c5, 0x2207}, /* nabla ∇ NABLA */ + {0x08c8, 0x2245}, /* approximate ≅ APPROXIMATELY EQUAL TO */ + /* 0x08c9 similarequal ? ??? */ + {0x08cd, 0x21d4}, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + {0x08ce, 0x21d2}, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + {0x08cf, 0x2261}, /* identical ≡ IDENTICAL TO */ + {0x08d6, 0x221a}, /* radical √ SQUARE ROOT */ + {0x08da, 0x2282}, /* includedin ⊂ SUBSET OF */ + {0x08db, 0x2283}, /* includes ⊃ SUPERSET OF */ + {0x08dc, 0x2229}, /* intersection ∩ INTERSECTION */ + {0x08dd, 0x222a}, /* union ∪ UNION */ + {0x08de, 0x2227}, /* logicaland ∧ LOGICAL AND */ + {0x08df, 0x2228}, /* logicalor ∨ LOGICAL OR */ + {0x08ef, 0x2202}, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + {0x08f6, 0x0192}, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ + {0x08fb, 0x2190}, /* leftarrow ← LEFTWARDS ARROW */ + {0x08fc, 0x2191}, /* uparrow ↑ UPWARDS ARROW */ + {0x08fd, 0x2192}, /* rightarrow → RIGHTWARDS ARROW */ + {0x08fe, 0x2193}, /* downarrow ↓ DOWNWARDS ARROW */ + {0x09df, 0x2422}, /* blank ␢ BLANK SYMBOL */ + {0x09e0, 0x25c6}, /* soliddiamond ◆ BLACK DIAMOND */ + {0x09e1, 0x2592}, /* checkerboard ▒ MEDIUM SHADE */ + {0x09e2, 0x2409}, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ + {0x09e3, 0x240c}, /* ff ␌ SYMBOL FOR FORM FEED */ + {0x09e4, 0x240d}, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ + {0x09e5, 0x240a}, /* lf ␊ SYMBOL FOR LINE FEED */ + {0x09e8, 0x2424}, /* nl ␤ SYMBOL FOR NEWLINE */ + {0x09e9, 0x240b}, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ + {0x09ea, 0x2518}, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + {0x09eb, 0x2510}, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ + {0x09ec, 0x250c}, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + {0x09ed, 0x2514}, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ + {0x09ee, 0x253c}, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ + /* 0x09ef horizlinescan1 ? ??? */ + /* 0x09f0 horizlinescan3 ? ??? */ + {0x09f1, 0x2500}, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ + /* 0x09f2 horizlinescan7 ? ??? */ + /* 0x09f3 horizlinescan9 ? ??? */ + {0x09f4, 0x251c}, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + {0x09f5, 0x2524}, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + {0x09f6, 0x2534}, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + {0x09f7, 0x252c}, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + {0x09f8, 0x2502}, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + {0x0aa1, 0x2003}, /* emspace   EM SPACE */ + {0x0aa2, 0x2002}, /* enspace   EN SPACE */ + {0x0aa3, 0x2004}, /* em3space   THREE-PER-EM SPACE */ + {0x0aa4, 0x2005}, /* em4space   FOUR-PER-EM SPACE */ + {0x0aa5, 0x2007}, /* digitspace   FIGURE SPACE */ + {0x0aa6, 0x2008}, /* punctspace   PUNCTUATION SPACE */ + {0x0aa7, 0x2009}, /* thinspace   THIN SPACE */ + {0x0aa8, 0x200a}, /* hairspace   HAIR SPACE */ + {0x0aa9, 0x2014}, /* emdash — EM DASH */ + {0x0aaa, 0x2013}, /* endash – EN DASH */ + /* 0x0aac signifblank ? ??? */ + {0x0aae, 0x2026}, /* ellipsis … HORIZONTAL ELLIPSIS */ + /* 0x0aaf doubbaselinedot ? ??? */ + {0x0ab0, 0x2153}, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ + {0x0ab1, 0x2154}, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ + {0x0ab2, 0x2155}, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ + {0x0ab3, 0x2156}, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ + {0x0ab4, 0x2157}, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ + {0x0ab5, 0x2158}, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ + {0x0ab6, 0x2159}, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ + {0x0ab7, 0x215a}, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ + {0x0ab8, 0x2105}, /* careof ℅ CARE OF */ + {0x0abb, 0x2012}, /* figdash ‒ FIGURE DASH */ + {0x0abc, 0x2329}, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + {0x0abd, 0x002e}, /* decimalpoint . FULL STOP */ + {0x0abe, 0x232a}, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ + /* 0x0abf marker ? ??? */ + {0x0ac3, 0x215b}, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ + {0x0ac4, 0x215c}, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ + {0x0ac5, 0x215d}, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ + {0x0ac6, 0x215e}, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ + {0x0ac9, 0x2122}, /* trademark ™ TRADE MARK SIGN */ + {0x0aca, 0x2613}, /* signaturemark ☓ SALTIRE */ + /* 0x0acb trademarkincircle ? ??? */ + {0x0acc, 0x25c1}, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ + {0x0acd, 0x25b7}, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ + {0x0ace, 0x25cb}, /* emopencircle ○ WHITE CIRCLE */ + {0x0acf, 0x25a1}, /* emopenrectangle □ WHITE SQUARE */ + {0x0ad0, 0x2018}, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + {0x0ad1, 0x2019}, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + {0x0ad2, 0x201c}, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + {0x0ad3, 0x201d}, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ + {0x0ad4, 0x211e}, /* prescription ℞ PRESCRIPTION TAKE */ + {0x0ad6, 0x2032}, /* minutes ′ PRIME */ + {0x0ad7, 0x2033}, /* seconds ″ DOUBLE PRIME */ + {0x0ad9, 0x271d}, /* latincross ✝ LATIN CROSS */ + /* 0x0ada hexagram ? ??? */ + {0x0adb, 0x25ac}, /* filledrectbullet ▬ BLACK RECTANGLE */ + {0x0adc, 0x25c0}, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ + {0x0add, 0x25b6}, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ + {0x0ade, 0x25cf}, /* emfilledcircle ● BLACK CIRCLE */ + {0x0adf, 0x25a0}, /* emfilledrect ■ BLACK SQUARE */ + {0x0ae0, 0x25e6}, /* enopencircbullet ◦ WHITE BULLET */ + {0x0ae1, 0x25ab}, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ + {0x0ae2, 0x25ad}, /* openrectbullet ▭ WHITE RECTANGLE */ + {0x0ae3, 0x25b3}, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ + {0x0ae4, 0x25bd}, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ + {0x0ae5, 0x2606}, /* openstar ☆ WHITE STAR */ + {0x0ae6, 0x2022}, /* enfilledcircbullet • BULLET */ + {0x0ae7, 0x25aa}, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ + {0x0ae8, 0x25b2}, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ + {0x0ae9, 0x25bc}, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ + {0x0aea, 0x261c}, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + {0x0aeb, 0x261e}, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + {0x0aec, 0x2663}, /* club ♣ BLACK CLUB SUIT */ + {0x0aed, 0x2666}, /* diamond ♦ BLACK DIAMOND SUIT */ + {0x0aee, 0x2665}, /* heart ♥ BLACK HEART SUIT */ + {0x0af0, 0x2720}, /* maltesecross ✠ MALTESE CROSS */ + {0x0af1, 0x2020}, /* dagger † DAGGER */ + {0x0af2, 0x2021}, /* doubledagger ‡ DOUBLE DAGGER */ + {0x0af3, 0x2713}, /* checkmark ✓ CHECK MARK */ + {0x0af4, 0x2717}, /* ballotcross ✗ BALLOT X */ + {0x0af5, 0x266f}, /* musicalsharp ♯ MUSIC SHARP SIGN */ + {0x0af6, 0x266d}, /* musicalflat ♭ MUSIC FLAT SIGN */ + {0x0af7, 0x2642}, /* malesymbol ♂ MALE SIGN */ + {0x0af8, 0x2640}, /* femalesymbol ♀ FEMALE SIGN */ + {0x0af9, 0x260e}, /* telephone ☎ BLACK TELEPHONE */ + {0x0afa, 0x2315}, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + {0x0afb, 0x2117}, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ + {0x0afc, 0x2038}, /* caret ‸ CARET */ + {0x0afd, 0x201a}, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + {0x0afe, 0x201e}, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ + /* 0x0aff cursor ? ??? */ + {0x0ba3, 0x003c}, /* leftcaret < LESS-THAN SIGN */ + {0x0ba6, 0x003e}, /* rightcaret > GREATER-THAN SIGN */ + {0x0ba8, 0x2228}, /* downcaret ∨ LOGICAL OR */ + {0x0ba9, 0x2227}, /* upcaret ∧ LOGICAL AND */ + {0x0bc0, 0x00af}, /* overbar ¯ MACRON */ + {0x0bc2, 0x22a4}, /* downtack ⊤ DOWN TACK */ + {0x0bc3, 0x2229}, /* upshoe ∩ INTERSECTION */ + {0x0bc4, 0x230a}, /* downstile ⌊ LEFT FLOOR */ + {0x0bc6, 0x005f}, /* underbar _ LOW LINE */ + {0x0bca, 0x2218}, /* jot ∘ RING OPERATOR */ + {0x0bcc, 0x2395}, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ + {0x0bce, 0x22a5}, /* uptack ⊥ UP TACK */ + {0x0bcf, 0x25cb}, /* circle ○ WHITE CIRCLE */ + {0x0bd3, 0x2308}, /* upstile ⌈ LEFT CEILING */ + {0x0bd6, 0x222a}, /* downshoe ∪ UNION */ + {0x0bd8, 0x2283}, /* rightshoe ⊃ SUPERSET OF */ + {0x0bda, 0x2282}, /* leftshoe ⊂ SUBSET OF */ + {0x0bdc, 0x22a3}, /* lefttack ⊣ LEFT TACK */ + {0x0bfc, 0x22a2}, /* righttack ⊢ RIGHT TACK */ + {0x0cdf, 0x2017}, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + {0x0ce0, 0x05d0}, /* hebrew_aleph א HEBREW LETTER ALEF */ + {0x0ce1, 0x05d1}, /* hebrew_bet ב HEBREW LETTER BET */ + {0x0ce2, 0x05d2}, /* hebrew_gimel ג HEBREW LETTER GIMEL */ + {0x0ce3, 0x05d3}, /* hebrew_dalet ד HEBREW LETTER DALET */ + {0x0ce4, 0x05d4}, /* hebrew_he ה HEBREW LETTER HE */ + {0x0ce5, 0x05d5}, /* hebrew_waw ו HEBREW LETTER VAV */ + {0x0ce6, 0x05d6}, /* hebrew_zain ז HEBREW LETTER ZAYIN */ + {0x0ce7, 0x05d7}, /* hebrew_chet ח HEBREW LETTER HET */ + {0x0ce8, 0x05d8}, /* hebrew_tet ט HEBREW LETTER TET */ + {0x0ce9, 0x05d9}, /* hebrew_yod י HEBREW LETTER YOD */ + {0x0cea, 0x05da}, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + {0x0ceb, 0x05db}, /* hebrew_kaph כ HEBREW LETTER KAF */ + {0x0cec, 0x05dc}, /* hebrew_lamed ל HEBREW LETTER LAMED */ + {0x0ced, 0x05dd}, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ + {0x0cee, 0x05de}, /* hebrew_mem מ HEBREW LETTER MEM */ + {0x0cef, 0x05df}, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + {0x0cf0, 0x05e0}, /* hebrew_nun נ HEBREW LETTER NUN */ + {0x0cf1, 0x05e1}, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + {0x0cf2, 0x05e2}, /* hebrew_ayin ע HEBREW LETTER AYIN */ + {0x0cf3, 0x05e3}, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ + {0x0cf4, 0x05e4}, /* hebrew_pe פ HEBREW LETTER PE */ + {0x0cf5, 0x05e5}, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ + {0x0cf6, 0x05e6}, /* hebrew_zade צ HEBREW LETTER TSADI */ + {0x0cf7, 0x05e7}, /* hebrew_qoph ק HEBREW LETTER QOF */ + {0x0cf8, 0x05e8}, /* hebrew_resh ר HEBREW LETTER RESH */ + {0x0cf9, 0x05e9}, /* hebrew_shin ש HEBREW LETTER SHIN */ + {0x0cfa, 0x05ea}, /* hebrew_taw ת HEBREW LETTER TAV */ + {0x0da1, 0x0e01}, /* Thai_kokai ก THAI CHARACTER KO KAI */ + {0x0da2, 0x0e02}, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + {0x0da3, 0x0e03}, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + {0x0da4, 0x0e04}, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + {0x0da5, 0x0e05}, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + {0x0da6, 0x0e06}, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + {0x0da7, 0x0e07}, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + {0x0da8, 0x0e08}, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + {0x0da9, 0x0e09}, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + {0x0daa, 0x0e0a}, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + {0x0dab, 0x0e0b}, /* Thai_soso ซ THAI CHARACTER SO SO */ + {0x0dac, 0x0e0c}, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + {0x0dad, 0x0e0d}, /* Thai_yoying ญ THAI CHARACTER YO YING */ + {0x0dae, 0x0e0e}, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + {0x0daf, 0x0e0f}, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ + {0x0db0, 0x0e10}, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ + {0x0db1, 0x0e11}, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + {0x0db2, 0x0e12}, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + {0x0db3, 0x0e13}, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + {0x0db4, 0x0e14}, /* Thai_dodek ด THAI CHARACTER DO DEK */ + {0x0db5, 0x0e15}, /* Thai_totao ต THAI CHARACTER TO TAO */ + {0x0db6, 0x0e16}, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + {0x0db7, 0x0e17}, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + {0x0db8, 0x0e18}, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + {0x0db9, 0x0e19}, /* Thai_nonu น THAI CHARACTER NO NU */ + {0x0dba, 0x0e1a}, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + {0x0dbb, 0x0e1b}, /* Thai_popla ป THAI CHARACTER PO PLA */ + {0x0dbc, 0x0e1c}, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + {0x0dbd, 0x0e1d}, /* Thai_fofa ฝ THAI CHARACTER FO FA */ + {0x0dbe, 0x0e1e}, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + {0x0dbf, 0x0e1f}, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + {0x0dc0, 0x0e20}, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ + {0x0dc1, 0x0e21}, /* Thai_moma ม THAI CHARACTER MO MA */ + {0x0dc2, 0x0e22}, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + {0x0dc3, 0x0e23}, /* Thai_rorua ร THAI CHARACTER RO RUA */ + {0x0dc4, 0x0e24}, /* Thai_ru ฤ THAI CHARACTER RU */ + {0x0dc5, 0x0e25}, /* Thai_loling ล THAI CHARACTER LO LING */ + {0x0dc6, 0x0e26}, /* Thai_lu ฦ THAI CHARACTER LU */ + {0x0dc7, 0x0e27}, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + {0x0dc8, 0x0e28}, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + {0x0dc9, 0x0e29}, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + {0x0dca, 0x0e2a}, /* Thai_sosua ส THAI CHARACTER SO SUA */ + {0x0dcb, 0x0e2b}, /* Thai_hohip ห THAI CHARACTER HO HIP */ + {0x0dcc, 0x0e2c}, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + {0x0dcd, 0x0e2d}, /* Thai_oang อ THAI CHARACTER O ANG */ + {0x0dce, 0x0e2e}, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + {0x0dcf, 0x0e2f}, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + {0x0dd0, 0x0e30}, /* Thai_saraa ะ THAI CHARACTER SARA A */ + {0x0dd1, 0x0e31}, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + {0x0dd2, 0x0e32}, /* Thai_saraaa า THAI CHARACTER SARA AA */ + {0x0dd3, 0x0e33}, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + {0x0dd4, 0x0e34}, /* Thai_sarai ิ THAI CHARACTER SARA I */ + {0x0dd5, 0x0e35}, /* Thai_saraii ี THAI CHARACTER SARA II */ + {0x0dd6, 0x0e36}, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + {0x0dd7, 0x0e37}, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + {0x0dd8, 0x0e38}, /* Thai_sarau ุ THAI CHARACTER SARA U */ + {0x0dd9, 0x0e39}, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + {0x0dda, 0x0e3a}, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + {0x0dde, 0x0e3e}, /* Thai_maihanakat_maitho ฾ ??? */ + {0x0ddf, 0x0e3f}, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + {0x0de0, 0x0e40}, /* Thai_sarae เ THAI CHARACTER SARA E */ + {0x0de1, 0x0e41}, /* Thai_saraae แ THAI CHARACTER SARA AE */ + {0x0de2, 0x0e42}, /* Thai_sarao โ THAI CHARACTER SARA O */ + {0x0de3, 0x0e43}, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + {0x0de4, 0x0e44}, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + {0x0de5, 0x0e45}, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + {0x0de6, 0x0e46}, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + {0x0de7, 0x0e47}, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + {0x0de8, 0x0e48}, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + {0x0de9, 0x0e49}, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + {0x0dea, 0x0e4a}, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + {0x0deb, 0x0e4b}, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + {0x0dec, 0x0e4c}, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + {0x0ded, 0x0e4d}, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ + {0x0df0, 0x0e50}, /* Thai_leksun ๐ THAI DIGIT ZERO */ + {0x0df1, 0x0e51}, /* Thai_leknung ๑ THAI DIGIT ONE */ + {0x0df2, 0x0e52}, /* Thai_leksong ๒ THAI DIGIT TWO */ + {0x0df3, 0x0e53}, /* Thai_leksam ๓ THAI DIGIT THREE */ + {0x0df4, 0x0e54}, /* Thai_leksi ๔ THAI DIGIT FOUR */ + {0x0df5, 0x0e55}, /* Thai_lekha ๕ THAI DIGIT FIVE */ + {0x0df6, 0x0e56}, /* Thai_lekhok ๖ THAI DIGIT SIX */ + {0x0df7, 0x0e57}, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + {0x0df8, 0x0e58}, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + {0x0df9, 0x0e59}, /* Thai_lekkao ๙ THAI DIGIT NINE */ + {0x0ea1, 0x3131}, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + {0x0ea2, 0x3132}, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + {0x0ea3, 0x3133}, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + {0x0ea4, 0x3134}, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ + {0x0ea5, 0x3135}, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + {0x0ea6, 0x3136}, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ + {0x0ea7, 0x3137}, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ + {0x0ea8, 0x3138}, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + {0x0ea9, 0x3139}, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + {0x0eaa, 0x313a}, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + {0x0eab, 0x313b}, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ + {0x0eac, 0x313c}, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + {0x0ead, 0x313d}, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + {0x0eae, 0x313e}, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + {0x0eaf, 0x313f}, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ + {0x0eb0, 0x3140}, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ + {0x0eb1, 0x3141}, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ + {0x0eb2, 0x3142}, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ + {0x0eb3, 0x3143}, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ + {0x0eb4, 0x3144}, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ + {0x0eb5, 0x3145}, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ + {0x0eb6, 0x3146}, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ + {0x0eb7, 0x3147}, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ + {0x0eb8, 0x3148}, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ + {0x0eb9, 0x3149}, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ + {0x0eba, 0x314a}, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ + {0x0ebb, 0x314b}, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ + {0x0ebc, 0x314c}, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ + {0x0ebd, 0x314d}, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ + {0x0ebe, 0x314e}, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ + {0x0ebf, 0x314f}, /* Hangul_A ㅏ HANGUL LETTER A */ + {0x0ec0, 0x3150}, /* Hangul_AE ㅐ HANGUL LETTER AE */ + {0x0ec1, 0x3151}, /* Hangul_YA ㅑ HANGUL LETTER YA */ + {0x0ec2, 0x3152}, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ + {0x0ec3, 0x3153}, /* Hangul_EO ㅓ HANGUL LETTER EO */ + {0x0ec4, 0x3154}, /* Hangul_E ㅔ HANGUL LETTER E */ + {0x0ec5, 0x3155}, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ + {0x0ec6, 0x3156}, /* Hangul_YE ㅖ HANGUL LETTER YE */ + {0x0ec7, 0x3157}, /* Hangul_O ㅗ HANGUL LETTER O */ + {0x0ec8, 0x3158}, /* Hangul_WA ㅘ HANGUL LETTER WA */ + {0x0ec9, 0x3159}, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ + {0x0eca, 0x315a}, /* Hangul_OE ㅚ HANGUL LETTER OE */ + {0x0ecb, 0x315b}, /* Hangul_YO ㅛ HANGUL LETTER YO */ + {0x0ecc, 0x315c}, /* Hangul_U ㅜ HANGUL LETTER U */ + {0x0ecd, 0x315d}, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ + {0x0ece, 0x315e}, /* Hangul_WE ㅞ HANGUL LETTER WE */ + {0x0ecf, 0x315f}, /* Hangul_WI ㅟ HANGUL LETTER WI */ + {0x0ed0, 0x3160}, /* Hangul_YU ㅠ HANGUL LETTER YU */ + {0x0ed1, 0x3161}, /* Hangul_EU ㅡ HANGUL LETTER EU */ + {0x0ed2, 0x3162}, /* Hangul_YI ㅢ HANGUL LETTER YI */ + {0x0ed3, 0x3163}, /* Hangul_I ㅣ HANGUL LETTER I */ + {0x0ed4, 0x11a8}, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + {0x0ed5, 0x11a9}, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + {0x0ed6, 0x11aa}, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + {0x0ed7, 0x11ab}, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + {0x0ed8, 0x11ac}, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + {0x0ed9, 0x11ad}, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ + {0x0eda, 0x11ae}, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + {0x0edb, 0x11af}, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + {0x0edc, 0x11b0}, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + {0x0edd, 0x11b1}, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + {0x0ede, 0x11b2}, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + {0x0edf, 0x11b3}, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + {0x0ee0, 0x11b4}, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + {0x0ee1, 0x11b5}, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + {0x0ee2, 0x11b6}, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + {0x0ee3, 0x11b7}, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + {0x0ee4, 0x11b8}, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + {0x0ee5, 0x11b9}, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + {0x0ee6, 0x11ba}, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + {0x0ee7, 0x11bb}, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + {0x0ee8, 0x11bc}, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + {0x0ee9, 0x11bd}, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + {0x0eea, 0x11be}, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + {0x0eeb, 0x11bf}, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + {0x0eec, 0x11c0}, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + {0x0eed, 0x11c1}, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ + {0x0eee, 0x11c2}, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + {0x0eef, 0x316d}, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ + {0x0ef0, 0x3171}, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ + {0x0ef1, 0x3178}, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ + {0x0ef2, 0x317f}, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ + /* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ + {0x0ef4, 0x3184}, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + {0x0ef5, 0x3186}, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + {0x0ef6, 0x318d}, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ + {0x0ef7, 0x318e}, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ + {0x0ef8, 0x11eb}, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ + /* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */ + {0x0efa, 0x11f9}, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + {0x0eff, 0x20a9}, /* Korean_Won ₩ WON SIGN */ + {0x13bc, 0x0152}, /* OE Œ LATIN CAPITAL LIGATURE OE */ + {0x13bd, 0x0153}, /* oe œ LATIN SMALL LIGATURE OE */ + {0x13be, 0x0178}, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + {0x20ac, 0x20ac}, /* EuroSign € EURO SIGN */ }; -long keysym2ucs(xcb_keysym_t keysym) -{ +long keysym2ucs(xcb_keysym_t keysym) { int min = 0; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; int mid; @@ -827,19 +826,19 @@ long keysym2ucs(xcb_keysym_t keysym) /* also check for directly encoded 24-bit UCS characters */ if ((keysym & 0xff000000) == 0x01000000) - return keysym & 0x00ffffff; + return keysym & 0x00ffffff; /* binary search in table */ while (max >= min) { - mid = (min + max) / 2; - if (keysymtab[mid].keysym < keysym) - min = mid + 1; - else if (keysymtab[mid].keysym > keysym) - max = mid - 1; - else { - /* found it */ - return keysymtab[mid].ucs; - } + mid = (min + max) / 2; + if (keysymtab[mid].keysym < keysym) + min = mid + 1; + else if (keysymtab[mid].keysym > keysym) + max = mid - 1; + else { + /* found it */ + return keysymtab[mid].ucs; + } } /* no matching Unicode value found */ diff --git a/i3-input/main.c b/i3-input/main.c index 1c0d6856..9f3ff174 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -103,7 +103,7 @@ static void restore_input_focus(void) { * */ static uint8_t *concat_strings(char **glyphs, int max) { - uint8_t *output = calloc(max+1, 4); + uint8_t *output = calloc(max + 1, 4); uint8_t *walk = output; for (int c = 0; c < max; c++) { printf("at %c\n", glyphs[c][0]); @@ -112,7 +112,7 @@ static uint8_t *concat_strings(char **glyphs, int max) { memcpy(walk, glyphs[c], 2); walk += 2; } else { - strcpy((char*)walk, glyphs[c]); + strcpy((char *)walk, glyphs[c]); walk += strlen(glyphs[c]); } } @@ -130,9 +130,9 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t /* re-draw the background */ xcb_rectangle_t border = {0, 0, 500, font.height + 8}, inner = {2, 2, 496, font.height + 8 - 4}; - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FF0000") }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {get_colorpixel("#FF0000")}); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border); - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {get_colorpixel("#000000")}); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &inner); /* restore font color */ @@ -143,8 +143,7 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t draw_text(prompt, pixmap, pixmap_gc, 4, 4, 492); } /* … and the text */ - if (input_position > 0) - { + if (input_position > 0) { i3String *input = i3string_from_ucs2(glyphs_ucs, input_position); draw_text(input, pixmap, pixmap_gc, prompt_offset + 4, 4, 492); i3string_free(input); @@ -174,14 +173,14 @@ static int handle_key_release(void *ignored, xcb_connection_t *conn, xcb_key_rel } static void finish_input() { - char *command = (char*)concat_strings(glyphs_utf8, input_position); + char *command = (char *)concat_strings(glyphs_utf8, input_position); /* count the occurences of %s in the string */ int c; int len = strlen(format); int cnt = 0; - for (c = 0; c < (len-1); c++) - if (format[c] == '%' && format[c+1] == 's') + for (c = 0; c < (len - 1); c++) + if (format[c] == '%' && format[c + 1] == 's') cnt++; printf("occurences = %d\n", cnt); @@ -189,13 +188,13 @@ static void finish_input() { int inputlen = strlen(command); char *full = calloc(1, strlen(format) - (2 * cnt) /* format without all %s */ - + (inputlen * cnt) /* replaced %s */ - + 1); /* trailing NUL */ + + (inputlen * cnt) /* replaced %s */ + + 1); /* trailing NUL */ char *dest = full; for (c = 0; c < len; c++) { /* if this is not % or it is % but without a following 's', * just copy the character */ - if (format[c] != '%' || (c == (len-1)) || format[c+1] != 's') + if (format[c] != '%' || (c == (len - 1)) || format[c + 1] != 's') *(dest++) = format[c]; else { strncat(dest, command, inputlen); @@ -212,7 +211,9 @@ static void finish_input() { xcb_aux_sync(conn); - ipc_send_message(sockfd, strlen(full), 0, (uint8_t*)full); + ipc_send_message(sockfd, strlen(full), 0, (uint8_t *)full); + + free(full); #if 0 free(command); @@ -290,8 +291,8 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press } xcb_char2b_t inp; - inp.byte1 = ( ucs & 0xff00 ) >> 2; - inp.byte2 = ( ucs & 0x00ff ) >> 0; + inp.byte1 = (ucs & 0xff00) >> 2; + inp.byte2 = (ucs & 0x00ff) >> 0; printf("inp.byte1 = %02x, inp.byte2 = %02x\n", inp.byte1, inp.byte2); /* convert it to UTF-8 */ @@ -324,8 +325,7 @@ int main(int argc, char *argv[]) { {"format", required_argument, 0, 'F'}, {"font", required_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} - }; + {0, 0, 0, 0}}; char *options_string = "s:p:P:f:l:F:vh"; @@ -403,18 +403,17 @@ int main(int argc, char *argv[]) { xcb_create_window( conn, XCB_COPY_FROM_PARENT, - win, /* the window id */ - root, /* parent == root */ + win, /* the window id */ + root, /* parent == root */ 50, 50, 500, font.height + 8, /* dimensions */ - 0, /* X11 border = 0, we draw our own */ + 0, /* X11 border = 0, we draw our own */ XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */ XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, - (uint32_t[]){ + (uint32_t[]) { 0, /* back pixel: black */ 1, /* override redirect: don’t manage this window */ - XCB_EVENT_MASK_EXPOSURE - }); + XCB_EVENT_MASK_EXPOSURE}); /* Map the window (make it visible) */ xcb_map_window(conn, win); @@ -465,15 +464,15 @@ int main(int argc, char *argv[]) { switch (type) { case XCB_KEY_PRESS: - handle_key_press(NULL, conn, (xcb_key_press_event_t*)event); + handle_key_press(NULL, conn, (xcb_key_press_event_t *)event); break; case XCB_KEY_RELEASE: - handle_key_release(NULL, conn, (xcb_key_release_event_t*)event); + handle_key_release(NULL, conn, (xcb_key_release_event_t *)event); break; case XCB_EXPOSE: - handle_expose(NULL, conn, (xcb_expose_event_t*)event); + handle_expose(NULL, conn, (xcb_expose_event_t *)event); break; } diff --git a/i3-msg/main.c b/i3-msg/main.c index 935edc04..354e8af9 100644 --- a/i3-msg/main.c +++ b/i3-msg/main.c @@ -76,20 +76,17 @@ static int reply_boolean_cb(void *params, int val) { return 1; } -#if YAJL_MAJOR >= 2 static int reply_string_cb(void *params, const unsigned char *val, size_t len) { -#else -static int reply_string_cb(void *params, const unsigned char *val, unsigned int len) { -#endif char *str = scalloc(len + 1); - strncpy(str, (const char*)val, len); + strncpy(str, (const char *)val, len); if (strcmp(last_key, "error") == 0) last_reply.error = str; else if (strcmp(last_key, "input") == 0) last_reply.input = str; else if (strcmp(last_key, "errorposition") == 0) last_reply.errorposition = str; - else free(str); + else + free(str); return 1; } @@ -106,36 +103,25 @@ static int reply_end_map_cb(void *params) { return 1; } - -#if YAJL_MAJOR >= 2 static int reply_map_key_cb(void *params, const unsigned char *keyVal, size_t keyLen) { -#else -static int reply_map_key_cb(void *params, const unsigned char *keyVal, unsigned keyLen) { -#endif free(last_key); last_key = scalloc(keyLen + 1); - strncpy(last_key, (const char*)keyVal, keyLen); + strncpy(last_key, (const char *)keyVal, keyLen); return 1; } -yajl_callbacks reply_callbacks = { - NULL, - &reply_boolean_cb, - NULL, - NULL, - NULL, - &reply_string_cb, - &reply_start_map_cb, - &reply_map_key_cb, - &reply_end_map_cb, - NULL, - NULL +static yajl_callbacks reply_callbacks = { + .yajl_boolean = reply_boolean_cb, + .yajl_string = reply_string_cb, + .yajl_start_map = reply_start_map_cb, + .yajl_map_key = reply_map_key_cb, + .yajl_end_map = reply_end_map_cb, }; int main(int argc, char *argv[]) { socket_path = getenv("I3SOCK"); int o, option_index = 0; - int message_type = I3_IPC_MESSAGE_TYPE_COMMAND; + uint32_t message_type = I3_IPC_MESSAGE_TYPE_COMMAND; char *payload = NULL; bool quiet = false; @@ -145,8 +131,7 @@ int main(int argc, char *argv[]) { {"version", no_argument, 0, 'v'}, {"quiet", no_argument, 0, 'q'}, {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} - }; + {0, 0, 0, 0}}; char *options_string = "s:t:vhq"; @@ -221,10 +206,10 @@ int main(int argc, char *argv[]) { memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_LOCAL; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); - if (connect(sockfd, (const struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0) + if (connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) err(EXIT_FAILURE, "Could not connect to i3 on socket \"%s\"", socket_path); - if (ipc_send_message(sockfd, strlen(payload), message_type, (uint8_t*)payload) == -1) + if (ipc_send_message(sockfd, strlen(payload), message_type, (uint8_t *)payload) == -1) err(EXIT_FAILURE, "IPC: write()"); if (quiet) @@ -245,21 +230,12 @@ int main(int argc, char *argv[]) { * If not, nicely format the error message. */ if (reply_type == I3_IPC_MESSAGE_TYPE_COMMAND) { yajl_handle handle; -#if YAJL_MAJOR < 2 - yajl_parser_config parse_conf = { 0, 0 }; - - handle = yajl_alloc(&reply_callbacks, &parse_conf, NULL, NULL); -#else handle = yajl_alloc(&reply_callbacks, NULL, NULL); -#endif - yajl_status state = yajl_parse(handle, (const unsigned char*)reply, reply_length); + yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length); switch (state) { case yajl_status_ok: break; case yajl_status_client_canceled: -#if YAJL_MAJOR < 2 - case yajl_status_insufficient_data: -#endif case yajl_status_error: errx(EXIT_FAILURE, "IPC: Could not parse JSON reply."); } diff --git a/i3-nagbar/i3-nagbar.h b/i3-nagbar/i3-nagbar.h index 379a7f6f..9aac709b 100644 --- a/i3-nagbar/i3-nagbar.h +++ b/i3-nagbar/i3-nagbar.h @@ -1,5 +1,4 @@ -#ifndef I3_NAGBAR -#define I3_NAGBAR +#pragma once #include @@ -17,5 +16,3 @@ while (0) #undef xmacro extern xcb_window_t root; - -#endif diff --git a/i3-nagbar/main.c b/i3-nagbar/main.c index 791da97b..8dbc4a76 100644 --- a/i3-nagbar/main.c +++ b/i3-nagbar/main.c @@ -43,7 +43,7 @@ typedef struct { static xcb_window_t win; static xcb_pixmap_t pixmap; static xcb_gcontext_t pixmap_gc; -static xcb_rectangle_t rect = { 0, 0, 600, 20 }; +static xcb_rectangle_t rect = {0, 0, 600, 20}; static i3Font font; static i3String *prompt; static button_t *buttons; @@ -100,7 +100,7 @@ static void start_application(const char *command) { setsid(); if (fork() == 0) { /* This is the child */ - execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (void*)NULL); + execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (void *)NULL); /* not reached */ } exit(0); @@ -118,7 +118,7 @@ static button_t *get_button_at(int16_t x, int16_t y) { static void handle_button_press(xcb_connection_t *conn, xcb_button_press_event_t *event) { printf("button pressed on x = %d, y = %d\n", - event->event_x, event->event_y); + event->event_x, event->event_y); /* TODO: set a flag for the button, re-render */ } @@ -129,7 +129,7 @@ static void handle_button_press(xcb_connection_t *conn, xcb_button_press_event_t */ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_event_t *event) { printf("button released on x = %d, y = %d\n", - event->event_x, event->event_y); + event->event_x, event->event_y); /* If the user hits the close button, we exit(0) */ if (event->event_x >= (rect.width - 32)) exit(0); @@ -188,13 +188,13 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve */ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { /* re-draw the background */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ color_background }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {color_background}); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &rect); /* restore font color */ set_font_colors(pixmap_gc, color_text, color_background); draw_text(prompt, pixmap, pixmap_gc, - 4 + 4, 4 + 4, rect.width - 4 - 4); + 4 + 4, 4 + 4, rect.width - 4 - 4); /* render close button */ const char *close_button_label = "X"; @@ -209,24 +209,23 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { values[1] = line_width; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH, values); - xcb_rectangle_t close = { y - w - (2 * line_width), 0, w + (2 * line_width), rect.height }; + xcb_rectangle_t close = {y - w - (2 * line_width), 0, w + (2 * line_width), rect.height}; xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &close); - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ color_border }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {color_border}); xcb_point_t points[] = { - { y - w - (2 * line_width), line_width / 2 }, - { y - (line_width / 2), line_width / 2 }, - { y - (line_width / 2), (rect.height - (line_width / 2)) - 2 }, - { y - w - (2 * line_width), (rect.height - (line_width / 2)) - 2 }, - { y - w - (2 * line_width), line_width / 2 } - }; + {y - w - (2 * line_width), line_width / 2}, + {y - (line_width / 2), line_width / 2}, + {y - (line_width / 2), (rect.height - (line_width / 2)) - 2}, + {y - w - (2 * line_width), (rect.height - (line_width / 2)) - 2}, + {y - w - (2 * line_width), line_width / 2}}; xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, pixmap, pixmap_gc, 5, points); values[0] = 1; set_font_colors(pixmap_gc, color_text, color_button_background); /* the x term here seems to set left/right padding */ draw_text_ascii(close_button_label, pixmap, pixmap_gc, y - w - line_width + w / 2 - 4, - 4 + 4 - 1, rect.width - y + w + line_width - w / 2 + 4); + 4 + 4 - 1, rect.width - y + w + line_width - w / 2 + 4); y -= w; y -= 20; @@ -239,20 +238,19 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { /* account for left/right padding, which seems to be set to 12px (total) below */ w += 12; y -= 30; - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ color_button_background }); - close = (xcb_rectangle_t){ y - w - (2 * line_width), 2, w + (2 * line_width), rect.height - 6 }; + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {color_button_background}); + close = (xcb_rectangle_t) {y - w - (2 * line_width), 2, w + (2 * line_width), rect.height - 6}; xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &close); - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ color_border }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {color_border}); buttons[c].x = y - w - (2 * line_width); buttons[c].width = w; xcb_point_t points2[] = { - { y - w - (2 * line_width), (line_width / 2) + 2 }, - { y - (line_width / 2), (line_width / 2) + 2 }, - { y - (line_width / 2), (rect.height - 4 - (line_width / 2)) }, - { y - w - (2 * line_width), (rect.height - 4 - (line_width / 2)) }, - { y - w - (2 * line_width), (line_width / 2) + 2 } - }; + {y - w - (2 * line_width), (line_width / 2) + 2}, + {y - (line_width / 2), (line_width / 2) + 2}, + {y - (line_width / 2), (rect.height - 4 - (line_width / 2))}, + {y - w - (2 * line_width), (rect.height - 4 - (line_width / 2))}, + {y - w - (2 * line_width), (line_width / 2) + 2}}; xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, pixmap, pixmap_gc, 5, points2); values[0] = color_text; @@ -260,7 +258,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { set_font_colors(pixmap_gc, color_text, color_button_background); /* the x term seems to set left/right padding */ draw_text(buttons[c].label, pixmap, pixmap_gc, - y - w - line_width + 6, 4 + 3, rect.width - y + w + line_width - 6); + y - w - line_width + 6, 4 + 3, rect.width - y + w + line_width - 6); y -= w; } @@ -271,12 +269,10 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { values[1] = line_width; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH, values); xcb_point_t bottom[] = { - { 0, rect.height - 0 }, - { rect.width, rect.height - 0 } - }; + {0, rect.height - 0}, + {rect.width, rect.height - 0}}; xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, pixmap, pixmap_gc, 2, bottom); - /* Copy the contents of the pixmap to the real window */ xcb_copy_area(conn, pixmap, win, pixmap_gc, 0, 0, 0, 0, rect.width, rect.height); xcb_flush(conn); @@ -322,7 +318,8 @@ int main(int argc, char *argv[]) { char *pattern = sstrdup("-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1"); int o, option_index = 0; - enum { TYPE_ERROR = 0, TYPE_WARNING = 1 } bar_type = TYPE_ERROR; + enum { TYPE_ERROR = 0, + TYPE_WARNING = 1 } bar_type = TYPE_ERROR; static struct option long_options[] = { {"version", no_argument, 0, 'v'}, @@ -331,8 +328,7 @@ int main(int argc, char *argv[]) { {"help", no_argument, 0, 'h'}, {"message", required_argument, 0, 'm'}, {"type", required_argument, 0, 't'}, - {0, 0, 0, 0} - }; + {0, 0, 0, 0}}; char *options_string = "b:f:m:t:vh"; @@ -341,7 +337,7 @@ int main(int argc, char *argv[]) { while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) { switch (o) { case 'v': - printf("i3-nagbar " I3_VERSION); + printf("i3-nagbar " I3_VERSION "\n"); return 0; case 'f': FREE(pattern); @@ -363,8 +359,8 @@ int main(int argc, char *argv[]) { buttons[buttoncnt].label = i3string_from_utf8(optarg); buttons[buttoncnt].action = argv[optind]; printf("button with label *%s* and action *%s*\n", - i3string_as_utf8(buttons[buttoncnt].label), - buttons[buttoncnt].action); + i3string_as_utf8(buttons[buttoncnt].label), + buttons[buttoncnt].action); buttoncnt++; printf("now %d buttons\n", buttoncnt); if (optind < argc) @@ -378,11 +374,11 @@ int main(int argc, char *argv[]) { xcb_connection_has_error(conn)) die("Cannot open display\n"); - /* Place requests for the atoms we need as soon as possible */ - #define xmacro(atom) \ - xcb_intern_atom_cookie_t atom ## _cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom); - #include "atoms.xmacro" - #undef xmacro +/* Place requests for the atoms we need as soon as possible */ +#define xmacro(atom) \ + xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom); +#include "atoms.xmacro" +#undef xmacro root_screen = xcb_aux_get_screen(conn, screens); root = root_screen->root; @@ -412,46 +408,45 @@ int main(int argc, char *argv[]) { xcb_create_window( conn, XCB_COPY_FROM_PARENT, - win, /* the window id */ - root, /* parent == root */ + win, /* the window id */ + root, /* parent == root */ 50, 50, 500, font.height + 8 + 8 /* 8 px padding */, /* dimensions */ - 0, /* x11 border = 0, we draw our own */ + 0, /* x11 border = 0, we draw our own */ XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */ XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, - (uint32_t[]){ + (uint32_t[]) { 0, /* back pixel: black */ XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE - }); + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE}); /* Map the window (make it visible) */ xcb_map_window(conn, win); - /* Setup NetWM atoms */ - #define xmacro(name) \ - do { \ - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name ## _cookie, NULL); \ - if (!reply) \ - die("Could not get atom " # name "\n"); \ - \ - A_ ## name = reply->atom; \ - free(reply); \ - } while (0); - #include "atoms.xmacro" - #undef xmacro +/* Setup NetWM atoms */ +#define xmacro(name) \ + do { \ + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \ + if (!reply) \ + die("Could not get atom " #name "\n"); \ + \ + A_##name = reply->atom; \ + free(reply); \ + } while (0); +#include "atoms.xmacro" +#undef xmacro /* Set dock mode */ xcb_change_property(conn, - XCB_PROP_MODE_REPLACE, - win, - A__NET_WM_WINDOW_TYPE, - A_ATOM, - 32, - 1, - (unsigned char*) &A__NET_WM_WINDOW_TYPE_DOCK); + XCB_PROP_MODE_REPLACE, + win, + A__NET_WM_WINDOW_TYPE, + A_ATOM, + 32, + 1, + (unsigned char *)&A__NET_WM_WINDOW_TYPE_DOCK); /* Reserve some space at the top of the screen */ struct { @@ -467,20 +462,21 @@ int main(int argc, char *argv[]) { uint32_t top_end_x; uint32_t bottom_start_x; uint32_t bottom_end_x; - } __attribute__((__packed__)) strut_partial = {0,}; + } __attribute__((__packed__)) strut_partial; + memset(&strut_partial, 0, sizeof(strut_partial)); strut_partial.top = font.height + 6; strut_partial.top_start_x = 0; strut_partial.top_end_x = 800; xcb_change_property(conn, - XCB_PROP_MODE_REPLACE, - win, - A__NET_WM_STRUT_PARTIAL, - A_CARDINAL, - 32, - 12, - &strut_partial); + XCB_PROP_MODE_REPLACE, + win, + A__NET_WM_STRUT_PARTIAL, + A_CARDINAL, + 32, + 12, + &strut_partial); /* Create pixmap */ pixmap = xcb_generate_id(conn); @@ -503,25 +499,24 @@ int main(int argc, char *argv[]) { switch (type) { case XCB_EXPOSE: - handle_expose(conn, (xcb_expose_event_t*)event); + handle_expose(conn, (xcb_expose_event_t *)event); break; case XCB_BUTTON_PRESS: - handle_button_press(conn, (xcb_button_press_event_t*)event); + handle_button_press(conn, (xcb_button_press_event_t *)event); break; case XCB_BUTTON_RELEASE: - handle_button_release(conn, (xcb_button_release_event_t*)event); + handle_button_release(conn, (xcb_button_release_event_t *)event); break; case XCB_CONFIGURE_NOTIFY: { - xcb_configure_notify_event_t *configure_notify = (xcb_configure_notify_event_t*)event; - rect = (xcb_rectangle_t){ + xcb_configure_notify_event_t *configure_notify = (xcb_configure_notify_event_t *)event; + rect = (xcb_rectangle_t) { configure_notify->x, configure_notify->y, configure_notify->width, - configure_notify->height - }; + configure_notify->height}; /* Recreate the pixmap / gc */ xcb_free_pixmap(conn, pixmap); diff --git a/i3-save-tree b/i3-save-tree new file mode 100755 index 00000000..53d67e99 --- /dev/null +++ b/i3-save-tree @@ -0,0 +1,288 @@ +#!/usr/bin/env perl +# vim:ts=4:sw=4:expandtab +# +# © 2013-2014 Michael Stapelberg +# +# Requires perl ≥ v5.10, AnyEvent::I3 and JSON::XS + +use strict; +use warnings qw(FATAL utf8); +use Data::Dumper; +use IPC::Open2; +use POSIX qw(locale_h); +use File::Find; +use File::Basename qw(basename); +use File::Temp qw(tempfile); +use Getopt::Long; +use Pod::Usage; +use AnyEvent::I3; +use JSON::XS; +use List::Util qw(first); +use v5.10; +use utf8; +use open ':encoding(UTF-8)'; + +binmode STDOUT, ':utf8'; +binmode STDERR, ':utf8'; + +my $workspace; +my $output; +my $result = GetOptions( + 'workspace=s' => \$workspace, + 'output=s' => \$output, + 'version' => sub { + say "i3-save-tree 0.1 © 2013 Michael Stapelberg"; + exit 0; + }, + 'help' => sub { + pod2usage(-exitval => 0); + }); + +die "Could not parse command line options" unless $result; + +if (!defined($workspace) && !defined($output)) { + die "One of --workspace or --output need to be specified"; +} + +unless (defined($workspace) ^ defined($output)) { + die "Only one of --workspace or --output can be specified"; +} + +my $i3 = i3(); +if (!$i3->connect->recv) { + die "Could not connect to i3"; +} + +sub filter_containers { + my ($tree, $pred) = @_; + + $_ = $tree; + return $tree if $pred->(); + + for my $child (@{$tree->{nodes}}, @{$tree->{floating_nodes}}) { + my $result = filter_containers($child, $pred); + return $result if defined($result); + } + + return undef; +} + +sub leaf_node { + my ($tree) = @_; + + return $tree->{type} eq 'con' && + @{$tree->{nodes}} == 0 && + @{$tree->{floating_nodes}} == 0; +} + +my %allowed_keys = map { ($_, 1) } qw( + type + fullscreen_mode + layout + border + current_border_width + floating + percent + nodes + floating_nodes + name + geometry + window_properties +); + +sub strip_containers { + my ($tree) = @_; + + # layout is not relevant for a leaf container + delete $tree->{layout} if leaf_node($tree); + + # fullscreen_mode conveys no state at all, it can either be 0 or 1 and the + # default is _always_ 0, so skip noop entries. + delete $tree->{fullscreen_mode} if $tree->{fullscreen_mode} == 0; + + # names for non-leafs are auto-generated and useful only for i3 debugging + delete $tree->{name} unless leaf_node($tree); + + delete $tree->{geometry} if zero_rect($tree->{geometry}); + + delete $tree->{current_border_width} if $tree->{current_border_width} == -1; + + for my $key (keys %$tree) { + next if exists($allowed_keys{$key}); + + delete $tree->{$key}; + } + + for my $key (qw(nodes floating_nodes)) { + $tree->{$key} = [ map { strip_containers($_) } @{$tree->{$key}} ]; + } + + return $tree; +} + +my $json_xs = JSON::XS->new->pretty(1)->allow_nonref->space_before(0)->canonical(1); + +sub zero_rect { + my ($rect) = @_; + return $rect->{x} == 0 && + $rect->{y} == 0 && + $rect->{width} == 0 && + $rect->{height} == 0; +} + +# Dumps the containers in JSON, but with comments to explain the user what she +# needs to fix. +sub dump_containers { + my ($tree, $ws, $last) = @_; + + $ws //= ""; + + say $ws . '{'; + + $ws .= (' ' x 4); + + if (!leaf_node($tree)) { + my $desc = $tree->{layout} . ' split container'; + if ($tree->{type} ne 'con') { + $desc = $tree->{type}; + } + say "$ws// $desc with " . @{$tree->{nodes}} . " children"; + } + + # Turn “window_properties” into “swallows” expressions, but only for leaf + # nodes. It only makes sense for leaf nodes to swallow anything. + if (leaf_node($tree)) { + my $swallows = {}; + for my $property (keys %{$tree->{window_properties}}) { + $swallows->{$property} = '^' . quotemeta($tree->{window_properties}->{$property}) . '$'; + } + $tree->{swallows} = [ $swallows ]; + } + delete $tree->{window_properties}; + + my @keys = sort keys %$tree; + for (0 .. (@keys-1)) { + my $key = $keys[$_]; + # Those are handled recursively, not printed. + next if $key eq 'nodes' || $key eq 'floating_nodes'; + + # JSON::XS’s encode appends a newline + chomp(my $val = $json_xs->encode($tree->{$key})); + + # Fix indentation. Keep in mind we are producing output to be + # read/modified by a human. + $val =~ s/^/$ws/mg; + $val =~ s/^\s+//; + + # Comment out all swallows criteria, they are just suggestions. + if ($key eq 'swallows') { + $val =~ s,^(\s*)\s{3}",\1// ",gm; + } + + # Append a comma unless this is the last value. + # Ugly, but necessary so that we can print all values before recursing. + my $comma = ($_ == (@keys-1) && + @{$tree->{nodes}} == 0 && + @{$tree->{floating_nodes}} == 0 ? '' : ','); + say qq#$ws"$key": $val$comma#; + } + + for my $key (qw(nodes floating_nodes)) { + my $num = scalar @{$tree->{$key}}; + next if !$num; + + say qq#$ws"$key": [#; + for (0 .. ($num-1)) { + dump_containers( + $tree->{$key}->[$_], + $ws . (' ' x 4), + ($_ == ($num-1))); + } + say qq#$ws]#; + } + + $ws =~ s/\s{4}$//; + + say $ws . ($last ? '}' : '},'); +} + +my $tree = $i3->get_tree->recv; + +my $dump; +if (defined($workspace)) { + $dump = filter_containers($tree, sub { + $_->{type} eq 'workspace' && $_->{name} eq $workspace + }); +} else { + $dump = filter_containers($tree, sub { + $_->{type} eq 'output' && $_->{name} eq $output + }); + # Get the output’s content container (living beneath dockarea containers). + $dump = first { $_->{type} eq 'con' } @{$dump->{nodes}}; +} + +$dump = strip_containers($dump); + +say "// vim:ts=4:sw=4:et"; +for my $key (qw(nodes floating_nodes)) { + for (0 .. (@{$dump->{$key}} - 1)) { + dump_containers($dump->{$key}->[$_], undef, 1); + # Newlines separate containers so that one can use { and } in vim to + # jump out of the current container. + say ''; + } +} + +=encoding utf-8 + +=head1 NAME + + i3-save-tree - save (parts of) the layout tree for restoring + +=head1 SYNOPSIS + + i3-save-tree [--workspace=name] [--output=name] + +=head1 DESCRIPTION + +Dumps a workspace (or an entire output) to stdout. The data is supposed to be +edited a bit by a human, then later fed to i3 via the append_layout command. + +The append_layout command will create placeholder windows, arranged in the +layout the input file specifies. Each container should have a swallows +specification. When a window is mapped (made visible on the screen) that +matches the specification, i3 will put it into that place and kill the +placeholder. + +=head1 OPTIONS + +=over + +=item B<--workspace=name> + +Specifies the workspace that should be dumped, e.g. 1. Either this or --output +need to be specified. + +=item B<--output=name> + +Specifies the output that should be dumped, e.g. LVDS-1. Either this or +--workspace need to be specified. + +=back + +=head1 VERSION + +Version 0.1 + +=head1 AUTHOR + +Michael Stapelberg, C<< >> + +=head1 LICENSE AND COPYRIGHT + +Copyright 2013 Michael Stapelberg. + +This program is free software; you can redistribute it and/or modify it +under the terms of the BSD license. + +=cut diff --git a/i3.config b/i3.config index de7e1fec..30b3f6a8 100644 --- a/i3.config +++ b/i3.config @@ -10,13 +10,23 @@ # # Font for window titles. Will also be used by the bar unless a different font -# is used in the bar {} block below. ISO 10646 = Unicode -font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +# is used in the bar {} block below. +# This font is widely installed, provides lots of unicode glyphs, right-to-left +# text rendering and scalability on retina/hidpi displays (thanks to pango). +font pango:DejaVu Sans Mono 8 +# Before i3 v4.8, we used to recommend this one as the default: +# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 # The font above is very space-efficient, that is, it looks good, sharp and -# clear in small sizes. However, if you need a lot of unicode glyphs or -# right-to-left text rendering, you should instead use pango for rendering and -# chose a FreeType font, such as: -# font pango:DejaVu Sans Mono 10 +# clear in small sizes. However, its unicode glyph coverage is limited, the old +# X core fonts rendering does not support right-to-left and this being a bitmap +# font, it doesn’t scale on retina/hidpi displays. + +# use these keys for focus, movement, and resize directions when reaching for +# the arrows is not convenient +set $up l +set $down k +set $left j +set $right semicolon # use Mouse+Mod1 to drag floating windows to their wanted position floating_modifier Mod1 @@ -35,10 +45,10 @@ bindsym Mod1+d exec dmenu_run # bindsym Mod1+d exec --no-startup-id i3-dmenu-desktop # change focus -bindsym Mod1+j focus left -bindsym Mod1+k focus down -bindsym Mod1+l focus up -bindsym Mod1+semicolon focus right +bindsym Mod1+$left focus left +bindsym Mod1+$down focus down +bindsym Mod1+$up focus up +bindsym Mod1+$right focus right # alternatively, you can use the cursor keys: bindsym Mod1+Left focus left @@ -47,10 +57,10 @@ bindsym Mod1+Up focus up bindsym Mod1+Right focus right # move focused window -bindsym Mod1+Shift+j move left -bindsym Mod1+Shift+k move down -bindsym Mod1+Shift+l move up -bindsym Mod1+Shift+semicolon move right +bindsym Mod1+Shift+$left move left +bindsym Mod1+Shift+$down move down +bindsym Mod1+Shift+$up move up +bindsym Mod1+Shift+$right move right # alternatively, you can use the cursor keys: bindsym Mod1+Shift+Left move left @@ -130,10 +140,10 @@ mode "resize" { # Pressing right will grow the window’s width. # Pressing up will shrink the window’s height. # Pressing down will grow the window’s height. - bindsym j resize shrink width 10 px or 10 ppt - bindsym k resize grow height 10 px or 10 ppt - bindsym l resize shrink height 10 px or 10 ppt - bindsym semicolon resize grow width 10 px or 10 ppt + bindsym $left resize shrink width 10 px or 10 ppt + bindsym $down resize grow height 10 px or 10 ppt + bindsym $up resize shrink height 10 px or 10 ppt + bindsym $right resize grow width 10 px or 10 ppt # same bindings, but for the arrow keys bindsym Left resize shrink width 10 px or 10 ppt diff --git a/i3.config.keycodes b/i3.config.keycodes index 0da3d77a..27398515 100644 --- a/i3.config.keycodes +++ b/i3.config.keycodes @@ -11,13 +11,16 @@ set $mod Mod1 # Font for window titles. Will also be used by the bar unless a different font -# is used in the bar {} block below. ISO 10646 = Unicode -font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +# is used in the bar {} block below. +# This font is widely installed, provides lots of unicode glyphs, right-to-left +# text rendering and scalability on retina/hidpi displays (thanks to pango). +font pango:DejaVu Sans Mono 8 +# Before i3 v4.8, we used to recommend this one as the default: +# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 # The font above is very space-efficient, that is, it looks good, sharp and -# clear in small sizes. However, if you need a lot of unicode glyphs or -# right-to-left text rendering, you should instead use pango for rendering and -# chose a FreeType font, such as: -# font pango:DejaVu Sans Mono 10 +# clear in small sizes. However, its unicode glyph coverage is limited, the old +# X core fonts rendering does not support right-to-left and this being a bitmap +# font, it doesn’t scale on retina/hidpi displays. # Use Mouse+$mod to drag floating windows to their wanted position floating_modifier $mod diff --git a/i3.xsession.desktop b/i3.xsession.desktop index ff698f20..d1e3dc2d 100644 --- a/i3.xsession.desktop +++ b/i3.xsession.desktop @@ -2,4 +2,6 @@ Name=i3 Comment=improved dynamic tiling window manager Exec=i3 +TryExec=i3 Type=Application +X-LightDM-DesktopName=i3 diff --git a/i3bar/include/child.h b/i3bar/include/child.h index dc244bef..72272b24 100644 --- a/i3bar/include/child.h +++ b/i3bar/include/child.h @@ -7,8 +7,7 @@ * child.c: Getting Input for the statusline * */ -#ifndef CHILD_H_ -#define CHILD_H_ +#pragma once #include @@ -74,10 +73,14 @@ void stop_child(void); */ void cont_child(void); +/* + * Whether or not the child want click events + * + */ +bool child_want_click_events(void); + /* * Generates a click event, if enabled. * */ void send_block_clicked(int button, const char *name, const char *instance, int x, int y); - -#endif diff --git a/i3bar/include/common.h b/i3bar/include/common.h index cb55e0d6..d63780dc 100644 --- a/i3bar/include/common.h +++ b/i3bar/include/common.h @@ -5,8 +5,7 @@ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE) * */ -#ifndef COMMON_H_ -#define COMMON_H_ +#pragma once #include #include @@ -74,5 +73,3 @@ TAILQ_HEAD(statusline_head, status_block) statusline_head; #include "config.h" #include "libi3.h" #include "parse_json_header.h" - -#endif diff --git a/i3bar/include/config.h b/i3bar/include/config.h index c6486712..a2c16887 100644 --- a/i3bar/include/config.h +++ b/i3bar/include/config.h @@ -7,8 +7,7 @@ * config.c: Parses the configuration (received from i3). * */ -#ifndef CONFIG_H_ -#define CONFIG_H_ +#pragma once #include "common.h" @@ -18,6 +17,9 @@ typedef enum { POS_BOT } position_t; +/* Bar display mode (hide unless modifier is pressed or show in dock mode or always hide in invisible mode) */ +typedef enum { M_DOCK = 0, M_HIDE = 1, M_INVISIBLE = 2 } bar_display_mode_t; + typedef struct config_t { int modifier; position_t position; @@ -25,6 +27,7 @@ typedef struct config_t { struct xcb_color_strings_t colors; bool disable_binding_mode_indicator; bool disable_ws; + bool strip_ws_numbers; char *bar_id; char *command; char *fontname; @@ -32,8 +35,7 @@ typedef struct config_t { int num_outputs; char **outputs; - /* Bar display mode (hide unless modifier is pressed or show in dock mode or always hide in invisible mode) */ - enum { M_DOCK = 0, M_HIDE = 1, M_INVISIBLE = 2 } hide_on_modifier; + bar_display_mode_t hide_on_modifier; /* The current hidden_state of the bar, which indicates whether it is hidden or shown */ enum { S_HIDE = 0, S_SHOW = 1 } hidden_state; @@ -52,5 +54,3 @@ void parse_config_json(char *json); * */ void free_colors(struct xcb_color_strings_t *colors); - -#endif diff --git a/i3bar/include/ipc.h b/i3bar/include/ipc.h index f20d45f0..5de23878 100644 --- a/i3bar/include/ipc.h +++ b/i3bar/include/ipc.h @@ -7,8 +7,7 @@ * ipc.c: Communicating with i3 * */ -#ifndef IPC_H_ -#define IPC_H_ +#pragma once #include @@ -37,5 +36,3 @@ int i3_send_msg(uint32_t type, const char* payload); * */ void subscribe_events(void); - -#endif diff --git a/i3bar/include/mode.h b/i3bar/include/mode.h index a8491aa9..6c3833f4 100644 --- a/i3bar/include/mode.h +++ b/i3bar/include/mode.h @@ -7,8 +7,7 @@ * mode.c: Handle mode-event and show current binding mode in the bar * */ -#ifndef MODE_H_ -#define MODE_H_ +#pragma once #include @@ -27,5 +26,3 @@ typedef struct mode mode; * */ void parse_mode_json(char *json); - -#endif diff --git a/i3bar/include/outputs.h b/i3bar/include/outputs.h index ad249786..9f6add11 100644 --- a/i3bar/include/outputs.h +++ b/i3bar/include/outputs.h @@ -7,8 +7,7 @@ * outputs.c: Maintaining the output-list * */ -#ifndef OUTPUTS_H_ -#define OUTPUTS_H_ +#pragma once #include @@ -53,5 +52,3 @@ struct i3_output { SLIST_ENTRY(i3_output) slist; /* Pointer for the SLIST-Macro */ }; - -#endif diff --git a/i3bar/include/parse_json_header.h b/i3bar/include/parse_json_header.h index 79efddc6..ef13cf78 100644 --- a/i3bar/include/parse_json_header.h +++ b/i3bar/include/parse_json_header.h @@ -8,8 +8,7 @@ * protocol version and features. * */ -#ifndef PARSE_JSON_HEADER_H_ -#define PARSE_JSON_HEADER_H_ +#pragma once #include @@ -22,5 +21,3 @@ * */ void parse_json_header(i3bar_child *child, const unsigned char *buffer, int length, unsigned int *consumed); - -#endif diff --git a/i3bar/include/trayclients.h b/i3bar/include/trayclients.h index e1e795fa..7a7e537e 100644 --- a/i3bar/include/trayclients.h +++ b/i3bar/include/trayclients.h @@ -5,8 +5,7 @@ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE) * */ -#ifndef TRAYCLIENT_H_ -#define TRAYCLIENT_H_ +#pragma once #include "common.h" @@ -21,5 +20,3 @@ struct trayclient { TAILQ_ENTRY(trayclient) tailq; /* Pointer for the TAILQ-Macro */ }; - -#endif diff --git a/i3bar/include/util.h b/i3bar/include/util.h index 468eff3e..9ffd4467 100644 --- a/i3bar/include/util.h +++ b/i3bar/include/util.h @@ -5,8 +5,7 @@ * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) * */ -#ifndef UTIL_H_ -#define UTIL_H_ +#pragma once #include "queue.h" @@ -36,8 +35,6 @@ } \ } while (0) -#endif - /* Securely fee tail-queues */ #define FREE_TAILQ(l, type) do { \ type *walk = TAILQ_FIRST(l); \ diff --git a/i3bar/include/workspaces.h b/i3bar/include/workspaces.h index 5fe1ba1e..d3d23c84 100644 --- a/i3bar/include/workspaces.h +++ b/i3bar/include/workspaces.h @@ -7,8 +7,7 @@ * workspaces.c: Maintaining the workspace-lists * */ -#ifndef WORKSPACES_H_ -#define WORKSPACES_H_ +#pragma once #include @@ -32,7 +31,8 @@ void free_workspaces(void); struct i3_ws { int num; /* The internal number of the ws */ - i3String *name; /* The name of the ws */ + char *canonical_name; /* The true name of the ws according to the ipc */ + i3String *name; /* The name of the ws that is displayed on the bar */ int name_width; /* The rendered width of the name */ bool visible; /* If the ws is currently visible on an output */ bool focused; /* If the ws is currently focused */ @@ -42,5 +42,3 @@ struct i3_ws { TAILQ_ENTRY(i3_ws) tailq; /* Pointer for the TAILQ-Macro */ }; - -#endif diff --git a/i3bar/include/xcb.h b/i3bar/include/xcb.h index e1654a34..2740f330 100644 --- a/i3bar/include/xcb.h +++ b/i3bar/include/xcb.h @@ -7,8 +7,7 @@ * xcb.c: Communicating with X * */ -#ifndef XCB_H_ -#define XCB_H_ +#pragma once #include //#include "outputs.h" @@ -133,5 +132,3 @@ void redraw_bars(void); * */ void set_current_mode(struct mode *mode); - -#endif diff --git a/i3bar/src/child.c b/i3bar/src/child.c index 52e99b40..5867ce4a 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -28,14 +28,13 @@ #include "common.h" /* Global variables for child_*() */ -i3bar_child child = { 0 }; +i3bar_child child; /* stdin- and sigchild-watchers */ -ev_io *stdin_io; +ev_io *stdin_io; ev_child *child_sig; /* JSON parser for stdin */ -yajl_callbacks callbacks; yajl_handle parser; /* JSON generator for stdout */ @@ -81,12 +80,7 @@ static void clear_status_blocks() { * `draw_bars' is called, the error message text will be drawn on the bar in * the space allocated for the statusline. */ - -/* forward function declaration is needed to add __attribute__ mechanism which - * helps the compiler understand we are defining a printf wrapper */ -static void set_statusline_error(const char *format, ...) __attribute__ ((format (printf, 1, 2))); - -static void set_statusline_error(const char *format, ...) { +__attribute__((format(printf, 1, 2))) static void set_statusline_error(const char *format, ...) { clear_status_blocks(); char *message; @@ -162,16 +156,12 @@ static int stdin_start_map(void *context) { memset(&(ctx->block), '\0', sizeof(struct status_block)); /* Default width of the separator block. */ - ctx->block.sep_block_width = 9; + ctx->block.sep_block_width = logical_px(9); return 1; } -#if YAJL_MAJOR >= 2 static int stdin_map_key(void *context, const unsigned char *key, size_t len) { -#else -static int stdin_map_key(void *context, const unsigned char *key, unsigned int len) { -#endif parser_ctx *ctx = context; FREE(ctx->last_map_key); sasprintf(&(ctx->last_map_key), "%.*s", len, key); @@ -189,11 +179,7 @@ static int stdin_boolean(void *context, int val) { return 1; } -#if YAJL_MAJOR >= 2 static int stdin_string(void *context, const unsigned char *val, size_t len) { -#else -static int stdin_string(void *context, const unsigned char *val, unsigned int len) { -#endif parser_ctx *ctx = context; if (strcasecmp(ctx->last_map_key, "full_text") == 0) { ctx->block.full_text = i3string_from_utf8_with_length((const char *)val, len); @@ -202,9 +188,9 @@ static int stdin_string(void *context, const unsigned char *val, unsigned int le sasprintf(&(ctx->block.color), "%.*s", len, val); } if (strcasecmp(ctx->last_map_key, "align") == 0) { - if (len == strlen("left") && !strncmp((const char*)val, "left", strlen("left"))) { + if (len == strlen("left") && !strncmp((const char *)val, "left", strlen("left"))) { ctx->block.align = ALIGN_LEFT; - } else if (len == strlen("right") && !strncmp((const char*)val, "right", strlen("right"))) { + } else if (len == strlen("right") && !strncmp((const char *)val, "right", strlen("right"))) { ctx->block.align = ALIGN_RIGHT; } else { ctx->block.align = ALIGN_CENTER; @@ -215,13 +201,13 @@ static int stdin_string(void *context, const unsigned char *val, unsigned int le i3string_free(text); } if (strcasecmp(ctx->last_map_key, "name") == 0) { - char *copy = (char*)malloc(len+1); + char *copy = (char *)malloc(len + 1); strncpy(copy, (const char *)val, len); copy[len] = 0; ctx->block.name = copy; } if (strcasecmp(ctx->last_map_key, "instance") == 0) { - char *copy = (char*)malloc(len+1); + char *copy = (char *)malloc(len + 1); strncpy(copy, (const char *)val, len); copy[len] = 0; ctx->block.instance = copy; @@ -229,11 +215,7 @@ static int stdin_string(void *context, const unsigned char *val, unsigned int le return 1; } -#if YAJL_MAJOR >= 2 static int stdin_integer(void *context, long long val) { -#else -static int stdin_integer(void *context, long val) { -#endif parser_ctx *ctx = context; if (strcasecmp(ctx->last_map_key, "min_width") == 0) { ctx->block.min_width = (uint32_t)val; @@ -261,7 +243,7 @@ static int stdin_end_map(void *context) { static int stdin_end_array(void *context) { DLOG("dumping statusline:\n"); struct status_block *current; - TAILQ_FOREACH(current, &statusline_head, blocks) { + TAILQ_FOREACH (current, &statusline_head, blocks) { DLOG("full_text = %s\n", i3string_as_utf8(current->full_text)); DLOG("color = %s\n", current->color); } @@ -272,15 +254,17 @@ static int stdin_end_array(void *context) { /* * Helper function to read stdin * + * Returns NULL on EOF. + * */ static unsigned char *get_buffer(ev_io *watcher, int *ret_buffer_len) { int fd = watcher->fd; int n = 0; int rec = 0; int buffer_len = STDIN_CHUNK_SIZE; - unsigned char *buffer = smalloc(buffer_len+1); + unsigned char *buffer = smalloc(buffer_len + 1); buffer[0] = '\0'; - while(1) { + while (1) { n = read(fd, buffer + rec, buffer_len - rec); if (n == -1) { if (errno == EAGAIN) { @@ -291,9 +275,7 @@ static unsigned char *get_buffer(ev_io *watcher, int *ret_buffer_len) { exit(EXIT_FAILURE); } if (n == 0) { - /* end of file, kill the watcher */ ELOG("stdin: received EOF\n"); - cleanup(); *ret_buffer_len = -1; return NULL; } @@ -318,20 +300,17 @@ static void read_flat_input(char *buffer, int length) { I3STRING_FREE(first->full_text); /* Remove the trailing newline and terminate the string at the same * time. */ - if (buffer[length-1] == '\n' || buffer[length-1] == '\r') - buffer[length-1] = '\0'; - else buffer[length] = '\0'; + if (buffer[length - 1] == '\n' || buffer[length - 1] == '\r') + buffer[length - 1] = '\0'; + else + buffer[length] = '\0'; first->full_text = i3string_from_utf8(buffer); } static bool read_json_input(unsigned char *input, int length) { yajl_status status = yajl_parse(parser, input, length); bool has_urgent = false; -#if YAJL_MAJOR >= 2 if (status != yajl_status_ok) { -#else - if (status != yajl_status_ok && status != yajl_status_insufficient_data) { -#endif char *message = (char *)yajl_get_error(parser, 0, input, length); /* strip the newline yajl adds to the error message */ @@ -342,7 +321,7 @@ static bool read_json_input(unsigned char *input, int length) { status, message, length, input); set_statusline_error("Could not parse JSON (%s)", message); - yajl_free_error(parser, (unsigned char*)message); + yajl_free_error(parser, (unsigned char *)message); draw_bars(false); } else if (parser_context.has_urgent) { has_urgent = true; @@ -364,7 +343,7 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) { if (child.version > 0) { has_urgent = read_json_input(buffer, rec); } else { - read_flat_input((char*)buffer, rec); + read_flat_input((char *)buffer, rec); } free(buffer); draw_bars(has_urgent); @@ -398,7 +377,7 @@ void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) { * full_text pointer later. */ struct status_block *new_block = scalloc(sizeof(struct status_block)); TAILQ_INSERT_TAIL(&statusline_head, new_block, blocks); - read_flat_input((char*)buffer, rec); + read_flat_input((char *)buffer, rec); } free(buffer); ev_io_stop(main_loop, stdin_io); @@ -416,15 +395,15 @@ void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) { int exit_status = WEXITSTATUS(watcher->rstatus); ELOG("Child (pid: %d) unexpectedly exited with status %d\n", - child.pid, - exit_status); + child.pid, + exit_status); /* this error is most likely caused by a user giving a nonexecutable or * nonexistent file, so we will handle those cases separately. */ if (exit_status == 126) set_statusline_error("status_command is not executable (exit %d)", exit_status); else if (exit_status == 127) - set_statusline_error("status_command not found (exit %d)", exit_status); + set_statusline_error("status_command not found or is missing a library dependency (exit %d)", exit_status); else set_statusline_error("status_command process exited unexpectedly (exit %d)", exit_status); @@ -435,11 +414,8 @@ void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) { void child_write_output(void) { if (child.click_events) { const unsigned char *output; -#if YAJL_MAJOR < 2 - unsigned int size; -#else size_t size; -#endif + yajl_gen_get_buf(gen, &output, &size); write(child_stdin, output, size); write(child_stdin, "\n", 1); @@ -450,69 +426,66 @@ void child_write_output(void) { /* * Start a child-process with the specified command and reroute stdin. * We actually start a $SHELL to execute the command so we don't have to care - * about arguments and such + * about arguments and such. + * + * If `command' is NULL, such as in the case when no `status_command' is given + * in the bar config, no child will be started. * */ void start_child(char *command) { + if (command == NULL) + return; + /* Allocate a yajl parser which will be used to parse stdin. */ - memset(&callbacks, '\0', sizeof(yajl_callbacks)); - callbacks.yajl_map_key = stdin_map_key; - callbacks.yajl_boolean = stdin_boolean; - callbacks.yajl_string = stdin_string; - callbacks.yajl_integer = stdin_integer; - callbacks.yajl_start_array = stdin_start_array; - callbacks.yajl_end_array = stdin_end_array; - callbacks.yajl_start_map = stdin_start_map; - callbacks.yajl_end_map = stdin_end_map; -#if YAJL_MAJOR < 2 - yajl_parser_config parse_conf = { 0, 0 }; - - parser = yajl_alloc(&callbacks, &parse_conf, NULL, (void*)&parser_context); - - gen = yajl_gen_alloc(NULL, NULL); -#else + static yajl_callbacks callbacks = { + .yajl_boolean = stdin_boolean, + .yajl_integer = stdin_integer, + .yajl_string = stdin_string, + .yajl_start_map = stdin_start_map, + .yajl_map_key = stdin_map_key, + .yajl_end_map = stdin_end_map, + .yajl_start_array = stdin_start_array, + .yajl_end_array = stdin_end_array, + }; parser = yajl_alloc(&callbacks, NULL, &parser_context); gen = yajl_gen_alloc(NULL); -#endif - if (command != NULL) { - int pipe_in[2]; /* pipe we read from */ - int pipe_out[2]; /* pipe we write to */ + int pipe_in[2]; /* pipe we read from */ + int pipe_out[2]; /* pipe we write to */ - if (pipe(pipe_in) == -1) - err(EXIT_FAILURE, "pipe(pipe_in)"); - if (pipe(pipe_out) == -1) - err(EXIT_FAILURE, "pipe(pipe_out)"); + if (pipe(pipe_in) == -1) + err(EXIT_FAILURE, "pipe(pipe_in)"); + if (pipe(pipe_out) == -1) + err(EXIT_FAILURE, "pipe(pipe_out)"); - child.pid = fork(); - switch (child.pid) { - case -1: - ELOG("Couldn't fork(): %s\n", strerror(errno)); - exit(EXIT_FAILURE); - case 0: - /* Child-process. Reroute streams and start shell */ + child.pid = fork(); + switch (child.pid) { + case -1: + ELOG("Couldn't fork(): %s\n", strerror(errno)); + exit(EXIT_FAILURE); + case 0: + /* Child-process. Reroute streams and start shell */ - close(pipe_in[0]); - close(pipe_out[1]); + close(pipe_in[0]); + close(pipe_out[1]); - dup2(pipe_in[1], STDOUT_FILENO); - dup2(pipe_out[0], STDIN_FILENO); + dup2(pipe_in[1], STDOUT_FILENO); + dup2(pipe_out[0], STDIN_FILENO); - setpgid(child.pid, 0); - execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (char*) NULL); - return; - default: - /* Parent-process. Reroute streams */ + setpgid(child.pid, 0); + execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (char *)NULL); + return; + default: + /* Parent-process. Reroute streams */ - close(pipe_in[1]); - close(pipe_out[0]); + close(pipe_in[1]); + close(pipe_out[0]); - dup2(pipe_in[0], STDIN_FILENO); - child_stdin = pipe_out[1]; + dup2(pipe_in[0], STDIN_FILENO); + child_stdin = pipe_out[1]; - break; - } + break; } /* We set O_NONBLOCK because blocking is evil in event-driven software */ @@ -625,3 +598,11 @@ void cont_child(void) { killpg(child.pid, child.cont_signal); } } + +/* + * Whether or not the child want click events + * + */ +bool child_want_click_events(void) { + return child.click_events; +} diff --git a/i3bar/src/config.c b/i3bar/src/config.c index 5ac31b1f..1f0c2a8e 100644 --- a/i3bar/src/config.c +++ b/i3bar/src/config.c @@ -27,15 +27,11 @@ static char *cur_key; * Essentially we just save it in cur_key. * */ -#if YAJL_MAJOR >= 2 static int config_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) { -#else -static int config_map_key_cb(void *params_, const unsigned char *keyVal, unsigned keyLen) { -#endif FREE(cur_key); cur_key = smalloc(sizeof(unsigned char) * (keyLen + 1)); - strncpy(cur_key, (const char*) keyVal, keyLen); + strncpy(cur_key, (const char *)keyVal, keyLen); cur_key[keyLen] = '\0'; return 1; @@ -61,11 +57,7 @@ static int config_null_cb(void *params_) { * Parse a string * */ -#if YAJL_MAJOR >= 2 static int config_string_cb(void *params_, const unsigned char *val, size_t _len) { -#else -static int config_string_cb(void *params_, const unsigned char *val, unsigned int _len) { -#endif int len = (int)_len; /* The id and socket_path are ignored, we already know them. */ if (!strcmp(cur_key, "id") || !strcmp(cur_key, "socket_path")) @@ -73,29 +65,29 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in if (!strcmp(cur_key, "mode")) { DLOG("mode = %.*s, len = %d\n", len, val, len); - config.hide_on_modifier = (len == 4 && !strncmp((const char*)val, "dock", strlen("dock")) ? M_DOCK - : (len == 4 && !strncmp((const char*)val, "hide", strlen("hide")) ? M_HIDE - : M_INVISIBLE)); + config.hide_on_modifier = (len == 4 && !strncmp((const char *)val, "dock", strlen("dock")) ? M_DOCK + : (len == 4 && !strncmp((const char *)val, "hide", strlen("hide")) ? M_HIDE + : M_INVISIBLE)); return 1; } if (!strcmp(cur_key, "hidden_state")) { DLOG("hidden_state = %.*s, len = %d\n", len, val, len); - config.hidden_state = (len == 4 && !strncmp((const char*)val, "hide", strlen("hide")) ? S_HIDE : S_SHOW); + config.hidden_state = (len == 4 && !strncmp((const char *)val, "hide", strlen("hide")) ? S_HIDE : S_SHOW); return 1; } if (!strcmp(cur_key, "modifier")) { DLOG("modifier = %.*s\n", len, val); - if (len == 5 && !strncmp((const char*)val, "shift", strlen("shift"))) { + if (len == 5 && !strncmp((const char *)val, "shift", strlen("shift"))) { config.modifier = ShiftMask; return 1; } - if (len == 4 && !strncmp((const char*)val, "ctrl", strlen("ctrl"))) { + if (len == 4 && !strncmp((const char *)val, "ctrl", strlen("ctrl"))) { config.modifier = ControlMask; return 1; } - if (len == 4 && !strncmp((const char*)val, "Mod", strlen("Mod"))) { + if (len == 4 && !strncmp((const char *)val, "Mod", strlen("Mod"))) { switch (val[3]) { case '1': config.modifier = Mod1Mask; @@ -122,15 +114,11 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in if (!strcmp(cur_key, "position")) { DLOG("position = %.*s\n", len, val); - config.position = (len == 3 && !strncmp((const char*)val, "top", strlen("top")) ? POS_TOP : POS_BOT); + config.position = (len == 3 && !strncmp((const char *)val, "top", strlen("top")) ? POS_TOP : POS_BOT); return 1; } if (!strcmp(cur_key, "status_command")) { - /* We cannot directly start the child here, because start_child() also - * needs to be run when no command was specified (to setup stdin). - * Therefore we save the command in 'config' and access it later in - * got_bar_config() */ DLOG("command = %.*s\n", len, val); sasprintf(&config.command, "%.*s", len, val); return 1; @@ -145,7 +133,7 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in if (!strcmp(cur_key, "outputs")) { DLOG("+output %.*s\n", len, val); int new_num_outputs = config.num_outputs + 1; - config.outputs = srealloc(config.outputs, sizeof(char*) * new_num_outputs); + config.outputs = srealloc(config.outputs, sizeof(char *) * new_num_outputs); sasprintf(&config.outputs[config.num_outputs], "%.*s", len, val); config.num_outputs = new_num_outputs; return 1; @@ -158,13 +146,13 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in return 1; } -#define COLOR(json_name, struct_name) \ - do { \ - if (!strcmp(cur_key, #json_name)) { \ +#define COLOR(json_name, struct_name) \ + do { \ + if (!strcmp(cur_key, #json_name)) { \ DLOG(#json_name " = " #struct_name " = %.*s\n", len, val); \ sasprintf(&(config.colors.struct_name), "%.*s", len, val); \ - return 1; \ - } \ + return 1; \ + } \ } while (0) COLOR(statusline, bar_fg); @@ -205,6 +193,12 @@ static int config_boolean_cb(void *params_, int val) { return 1; } + if (!strcmp(cur_key, "strip_workspace_numbers")) { + DLOG("strip_workspace_numbers = %d\n", val); + config.strip_ws_numbers = val; + return 1; + } + if (!strcmp(cur_key, "verbose")) { DLOG("verbose = %d\n", val); config.verbose = val; @@ -216,17 +210,10 @@ static int config_boolean_cb(void *params_, int val) { /* A datastructure to pass all these callbacks to yajl */ static yajl_callbacks outputs_callbacks = { - &config_null_cb, - &config_boolean_cb, - NULL, - NULL, - NULL, - &config_string_cb, - NULL, - &config_map_key_cb, - NULL, - NULL, - NULL + .yajl_null = config_null_cb, + .yajl_boolean = config_boolean_cb, + .yajl_string = config_string_cb, + .yajl_map_key = config_map_key_cb, }; /* @@ -236,24 +223,15 @@ static yajl_callbacks outputs_callbacks = { void parse_config_json(char *json) { yajl_handle handle; yajl_status state; -#if YAJL_MAJOR < 2 - yajl_parser_config parse_conf = { 0, 0 }; - - handle = yajl_alloc(&outputs_callbacks, &parse_conf, NULL, NULL); -#else handle = yajl_alloc(&outputs_callbacks, NULL, NULL); -#endif - state = yajl_parse(handle, (const unsigned char*) json, strlen(json)); + state = yajl_parse(handle, (const unsigned char *)json, strlen(json)); /* FIXME: Proper errorhandling for JSON-parsing */ switch (state) { case yajl_status_ok: break; case yajl_status_client_canceled: -#if YAJL_MAJOR < 2 - case yajl_status_insufficient_data: -#endif case yajl_status_error: ELOG("Could not parse config-reply!\n"); exit(EXIT_FAILURE); @@ -268,9 +246,9 @@ void parse_config_json(char *json) { * */ void free_colors(struct xcb_color_strings_t *colors) { -#define FREE_COLOR(x) \ - do { \ - if (colors->x) \ +#define FREE_COLOR(x) \ + do { \ + if (colors->x) \ free(colors->x); \ } while (0) FREE_COLOR(bar_fg); @@ -290,4 +268,3 @@ void free_colors(struct xcb_color_strings_t *colors) { FREE_COLOR(focus_ws_border); #undef FREE_COLOR } - diff --git a/i3bar/src/ipc.c b/i3bar/src/ipc.c index 3536b7dc..6ff83979 100644 --- a/i3bar/src/ipc.c +++ b/i3bar/src/ipc.c @@ -20,11 +20,11 @@ #include "common.h" -ev_io *i3_connection; +ev_io *i3_connection; const char *sock_path; -typedef void(*handler_t)(char*); +typedef void (*handler_t)(char *); /* * Called, when we get a reply to a command from i3. @@ -67,7 +67,7 @@ void got_output_reply(char *reply) { reconfig_windows(false); i3_output *o_walk; - SLIST_FOREACH(o_walk, outputs, slist) { + SLIST_FOREACH (o_walk, outputs, slist) { kick_tray_clients(o_walk); } @@ -100,9 +100,6 @@ void got_bar_config(char *reply) { /* Resolve color strings to colorpixels and save them, then free the strings. */ init_colors(&(config.colors)); - /* The name of this function is actually misleading. Even if no command is - * specified, this function initiates the watchers to listen on stdin and - * react accordingly */ start_child(config.command); FREE(config.command); } @@ -160,16 +157,21 @@ void got_bar_config_update(char *event) { char *found_id = strstr(event, expected_id); FREE(expected_id); if (found_id == NULL) - return; + return; + + free_colors(&(config.colors)); /* update the configuration with the received settings */ DLOG("Received bar config update \"%s\"\n", event); - int old_mode = config.hide_on_modifier; + bar_display_mode_t old_mode = config.hide_on_modifier; parse_config_json(event); if (old_mode != config.hide_on_modifier) { reconfig_windows(true); } + init_colors(&(config.colors)); + realloc_sl_buffer(); + draw_bars(false); } @@ -191,7 +193,7 @@ void got_data(struct ev_loop *loop, ev_io *watcher, int events) { int fd = watcher->fd; /* First we only read the header, because we know its length */ - uint32_t header_len = strlen(I3_IPC_MAGIC) + sizeof(uint32_t)*2; + uint32_t header_len = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) * 2; char *header = smalloc(header_len); /* We first parse the fixed-length IPC-header, to know, how much data @@ -215,7 +217,7 @@ void got_data(struct ev_loop *loop, ev_io *watcher, int events) { if (strncmp(header, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC))) { ELOG("Wrong magic code: %.*s\n Expected: %s\n", - (int) strlen(I3_IPC_MAGIC), + (int)strlen(I3_IPC_MAGIC), header, I3_IPC_MAGIC); exit(EXIT_FAILURE); @@ -223,10 +225,10 @@ void got_data(struct ev_loop *loop, ev_io *watcher, int events) { char *walk = header + strlen(I3_IPC_MAGIC); uint32_t size; - memcpy(&size, (uint32_t*)walk, sizeof(uint32_t)); + memcpy(&size, (uint32_t *)walk, sizeof(uint32_t)); walk += sizeof(uint32_t); uint32_t type; - memcpy(&type, (uint32_t*)walk, sizeof(uint32_t)); + memcpy(&type, (uint32_t *)walk, sizeof(uint32_t)); /* Now that we know, what to expect, we can start read()ing the rest * of the message */ @@ -272,7 +274,7 @@ int i3_send_msg(uint32_t type, const char *payload) { } /* We are a wellbehaved client and send a proper header first */ - uint32_t to_write = strlen (I3_IPC_MAGIC) + sizeof(uint32_t)*2 + len; + uint32_t to_write = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) * 2 + len; /* TODO: I'm not entirely sure if this buffer really has to contain more * than the pure header (why not just write() the payload from *payload?), * but we leave it for now */ diff --git a/i3bar/src/main.c b/i3bar/src/main.c index 9ae69e3c..371aeec9 100644 --- a/i3bar/src/main.c +++ b/i3bar/src/main.c @@ -99,12 +99,11 @@ int main(int argc, char **argv) { memset(&config, '\0', sizeof(config_t)); static struct option long_opt[] = { - { "socket", required_argument, 0, 's' }, - { "bar_id", required_argument, 0, 'b' }, - { "help", no_argument, 0, 'h' }, - { "version", no_argument, 0, 'v' }, - { NULL, 0, 0, 0} - }; + {"socket", required_argument, 0, 's'}, + {"bar_id", required_argument, 0, 'b'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {NULL, 0, 0, 0}}; while ((opt = getopt_long(argc, argv, "b:s:hv", long_opt, &option_index)) != -1) { switch (opt) { @@ -112,7 +111,7 @@ int main(int argc, char **argv) { socket_path = expand_path(optarg); break; case 'v': - printf("i3bar version " I3_VERSION " © 2010-2011 Axel Wagner and contributors\n"); + printf("i3bar version " I3_VERSION " © 2010-2014 Axel Wagner and contributors\n"); exit(EXIT_SUCCESS); break; case 'b': diff --git a/i3bar/src/mode.c b/i3bar/src/mode.c index 7363971a..813d4aab 100644 --- a/i3bar/src/mode.c +++ b/i3bar/src/mode.c @@ -18,36 +18,31 @@ /* A datatype to pass through the callbacks to save the state */ struct mode_json_params { - char *json; - char *cur_key; - mode *mode; + char *json; + char *cur_key; + mode *mode; }; /* * Parse a string (change) * */ -#if YAJL_MAJOR >= 2 static int mode_string_cb(void *params_, const unsigned char *val, size_t len) { -#else -static int mode_string_cb(void *params_, const unsigned char *val, unsigned int len) { -#endif - struct mode_json_params *params = (struct mode_json_params*) params_; + struct mode_json_params *params = (struct mode_json_params *)params_; - if (!strcmp(params->cur_key, "change")) { + if (!strcmp(params->cur_key, "change")) { + /* Save the name */ + params->mode->name = i3string_from_utf8_with_length((const char *)val, len); + /* Save its rendered width */ + params->mode->width = predict_text_width(params->mode->name); - /* Save the name */ - params->mode->name = i3string_from_utf8_with_length((const char *)val, len); - /* Save its rendered width */ - params->mode->width = predict_text_width(params->mode->name); + DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name)); + FREE(params->cur_key); - DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name)); - FREE(params->cur_key); + return 1; + } - return 1; - } - - return 0; + return 0; } /* @@ -56,34 +51,21 @@ static int mode_string_cb(void *params_, const unsigned char *val, unsigned int * Essentially we just save it in the parsing-state * */ -#if YAJL_MAJOR >= 2 static int mode_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) { -#else -static int mode_map_key_cb(void *params_, const unsigned char *keyVal, unsigned int keyLen) { -#endif - struct mode_json_params *params = (struct mode_json_params*) params_; + struct mode_json_params *params = (struct mode_json_params *)params_; FREE(params->cur_key); params->cur_key = smalloc(sizeof(unsigned char) * (keyLen + 1)); - strncpy(params->cur_key, (const char*) keyVal, keyLen); + strncpy(params->cur_key, (const char *)keyVal, keyLen); params->cur_key[keyLen] = '\0'; return 1; } /* A datastructure to pass all these callbacks to yajl */ -yajl_callbacks mode_callbacks = { - NULL, - NULL, - NULL, - NULL, - NULL, - &mode_string_cb, - NULL, - &mode_map_key_cb, - NULL, - NULL, - NULL +static yajl_callbacks mode_callbacks = { + .yajl_string = mode_string_cb, + .yajl_map_key = mode_map_key_cb, }; /* @@ -104,24 +86,15 @@ void parse_mode_json(char *json) { yajl_handle handle; yajl_status state; -#if YAJL_MAJOR < 2 - yajl_parser_config parse_conf = { 0, 0 }; + handle = yajl_alloc(&mode_callbacks, NULL, (void *)¶ms); - handle = yajl_alloc(&mode_callbacks, &parse_conf, NULL, (void*) ¶ms); -#else - handle = yajl_alloc(&mode_callbacks, NULL, (void*) ¶ms); -#endif - - state = yajl_parse(handle, (const unsigned char*) json, strlen(json)); + state = yajl_parse(handle, (const unsigned char *)json, strlen(json)); /* FIXME: Propper errorhandling for JSON-parsing */ switch (state) { case yajl_status_ok: break; case yajl_status_client_canceled: -#if YAJL_MAJOR < 2 - case yajl_status_insufficient_data: -#endif case yajl_status_error: ELOG("Could not parse mode-event!\n"); exit(EXIT_FAILURE); diff --git a/i3bar/src/outputs.c b/i3bar/src/outputs.c index db986702..5508a5a2 100644 --- a/i3bar/src/outputs.c +++ b/i3bar/src/outputs.c @@ -20,10 +20,10 @@ /* A datatype to pass through the callbacks to save the state */ struct outputs_json_params { struct outputs_head *outputs; - i3_output *outputs_walk; - char *cur_key; - char *json; - bool in_rect; + i3_output *outputs_walk; + char *cur_key; + char *json; + bool in_rect; }; /* @@ -31,7 +31,7 @@ struct outputs_json_params { * */ static int outputs_null_cb(void *params_) { - struct outputs_json_params *params = (struct outputs_json_params*) params_; + struct outputs_json_params *params = (struct outputs_json_params *)params_; FREE(params->cur_key); @@ -43,7 +43,7 @@ static int outputs_null_cb(void *params_) { * */ static int outputs_boolean_cb(void *params_, int val) { - struct outputs_json_params *params = (struct outputs_json_params*) params_; + struct outputs_json_params *params = (struct outputs_json_params *)params_; if (!strcmp(params->cur_key, "active")) { params->outputs_walk->active = val; @@ -64,39 +64,35 @@ static int outputs_boolean_cb(void *params_, int val) { * Parse an integer (current_workspace or the rect) * */ -#if YAJL_MAJOR >= 2 static int outputs_integer_cb(void *params_, long long val) { -#else -static int outputs_integer_cb(void *params_, long val) { -#endif - struct outputs_json_params *params = (struct outputs_json_params*) params_; + struct outputs_json_params *params = (struct outputs_json_params *)params_; if (!strcmp(params->cur_key, "current_workspace")) { - params->outputs_walk->ws = (int) val; + params->outputs_walk->ws = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "x")) { - params->outputs_walk->rect.x = (int) val; + params->outputs_walk->rect.x = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "y")) { - params->outputs_walk->rect.y = (int) val; + params->outputs_walk->rect.y = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "width")) { - params->outputs_walk->rect.w = (int) val; + params->outputs_walk->rect.w = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "height")) { - params->outputs_walk->rect.h = (int) val; + params->outputs_walk->rect.h = (int)val; FREE(params->cur_key); return 1; } @@ -108,16 +104,12 @@ static int outputs_integer_cb(void *params_, long val) { * Parse a string (name) * */ -#if YAJL_MAJOR >= 2 static int outputs_string_cb(void *params_, const unsigned char *val, size_t len) { -#else -static int outputs_string_cb(void *params_, const unsigned char *val, unsigned int len) { -#endif - struct outputs_json_params *params = (struct outputs_json_params*) params_; + struct outputs_json_params *params = (struct outputs_json_params *)params_; if (!strcmp(params->cur_key, "current_workspace")) { char *copy = smalloc(sizeof(const unsigned char) * (len + 1)); - strncpy(copy, (const char*) val, len); + strncpy(copy, (const char *)val, len); copy[len] = '\0'; char *end; @@ -136,7 +128,7 @@ static int outputs_string_cb(void *params_, const unsigned char *val, unsigned i } char *name = smalloc(sizeof(const unsigned char) * (len + 1)); - strncpy(name, (const char*) val, len); + strncpy(name, (const char *)val, len); name[len] = '\0'; params->outputs_walk->name = name; @@ -151,7 +143,7 @@ static int outputs_string_cb(void *params_, const unsigned char *val, unsigned i * */ static int outputs_start_map_cb(void *params_) { - struct outputs_json_params *params = (struct outputs_json_params*) params_; + struct outputs_json_params *params = (struct outputs_json_params *)params_; i3_output *new_output = NULL; if (params->cur_key == NULL) { @@ -184,7 +176,7 @@ static int outputs_start_map_cb(void *params_) { * */ static int outputs_end_map_cb(void *params_) { - struct outputs_json_params *params = (struct outputs_json_params*) params_; + struct outputs_json_params *params = (struct outputs_json_params *)params_; if (params->in_rect) { params->in_rect = false; /* Ignore the end of a rect */ @@ -232,34 +224,26 @@ static int outputs_end_map_cb(void *params_) { * Essentially we just save it in the parsing-state * */ -#if YAJL_MAJOR >= 2 static int outputs_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) { -#else -static int outputs_map_key_cb(void *params_, const unsigned char *keyVal, unsigned keyLen) { -#endif - struct outputs_json_params *params = (struct outputs_json_params*) params_; + struct outputs_json_params *params = (struct outputs_json_params *)params_; FREE(params->cur_key); params->cur_key = smalloc(sizeof(unsigned char) * (keyLen + 1)); - strncpy(params->cur_key, (const char*) keyVal, keyLen); + strncpy(params->cur_key, (const char *)keyVal, keyLen); params->cur_key[keyLen] = '\0'; return 1; } /* A datastructure to pass all these callbacks to yajl */ -yajl_callbacks outputs_callbacks = { - &outputs_null_cb, - &outputs_boolean_cb, - &outputs_integer_cb, - NULL, - NULL, - &outputs_string_cb, - &outputs_start_map_cb, - &outputs_map_key_cb, - &outputs_end_map_cb, - NULL, - NULL +static yajl_callbacks outputs_callbacks = { + .yajl_null = outputs_null_cb, + .yajl_boolean = outputs_boolean_cb, + .yajl_integer = outputs_integer_cb, + .yajl_string = outputs_string_cb, + .yajl_start_map = outputs_start_map_cb, + .yajl_map_key = outputs_map_key_cb, + .yajl_end_map = outputs_end_map_cb, }; /* @@ -285,24 +269,15 @@ void parse_outputs_json(char *json) { yajl_handle handle; yajl_status state; -#if YAJL_MAJOR < 2 - yajl_parser_config parse_conf = { 0, 0 }; + handle = yajl_alloc(&outputs_callbacks, NULL, (void *)¶ms); - handle = yajl_alloc(&outputs_callbacks, &parse_conf, NULL, (void*) ¶ms); -#else - handle = yajl_alloc(&outputs_callbacks, NULL, (void*) ¶ms); -#endif - - state = yajl_parse(handle, (const unsigned char*) json, strlen(json)); + state = yajl_parse(handle, (const unsigned char *)json, strlen(json)); /* FIXME: Propper errorhandling for JSON-parsing */ switch (state) { case yajl_status_ok: break; case yajl_status_client_canceled: -#if YAJL_MAJOR < 2 - case yajl_status_insufficient_data: -#endif case yajl_status_error: ELOG("Could not parse outputs-reply!\n"); exit(EXIT_FAILURE); @@ -321,7 +296,7 @@ i3_output *get_output_by_name(char *name) { if (name == NULL) { return NULL; } - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!strcmp(walk->name, name)) { break; } diff --git a/i3bar/src/parse_json_header.c b/i3bar/src/parse_json_header.c index c09e0f49..f5fb84ab 100644 --- a/i3bar/src/parse_json_header.c +++ b/i3bar/src/parse_json_header.c @@ -35,11 +35,7 @@ static enum { NO_KEY } current_key; -#if YAJL_MAJOR >= 2 static int header_integer(void *ctx, long long val) { -#else -static int header_integer(void *ctx, long val) { -#endif i3bar_child *child = ctx; switch (current_key) { @@ -74,13 +70,9 @@ static int header_boolean(void *ctx, int val) { } #define CHECK_KEY(name) (stringlen == strlen(name) && \ - STARTS_WITH((const char*)stringval, stringlen, name)) + STARTS_WITH((const char *)stringval, stringlen, name)) -#if YAJL_MAJOR >= 2 static int header_map_key(void *ctx, const unsigned char *stringval, size_t stringlen) { -#else -static int header_map_key(void *ctx, const unsigned char *stringval, unsigned int stringlen) { -#endif if (CHECK_KEY("version")) { current_key = KEY_VERSION; } else if (CHECK_KEY("stop_signal")) { @@ -93,20 +85,6 @@ static int header_map_key(void *ctx, const unsigned char *stringval, unsigned in return 1; } -static yajl_callbacks version_callbacks = { - NULL, /* null */ - &header_boolean, /* boolean */ - &header_integer, - NULL, /* double */ - NULL, /* number */ - NULL, /* string */ - NULL, /* start_map */ - &header_map_key, - NULL, /* end_map */ - NULL, /* start_array */ - NULL /* end_array */ -}; - static void child_init(i3bar_child *child) { child->version = 0; child->stop_signal = SIGSTOP; @@ -122,20 +100,20 @@ static void child_init(i3bar_child *child) { * */ void parse_json_header(i3bar_child *child, const unsigned char *buffer, int length, unsigned int *consumed) { + static yajl_callbacks version_callbacks = { + .yajl_boolean = header_boolean, + .yajl_integer = header_integer, + .yajl_map_key = &header_map_key, + }; + child_init(child); current_key = NO_KEY; -#if YAJL_MAJOR >= 2 yajl_handle handle = yajl_alloc(&version_callbacks, NULL, child); /* Allow trailing garbage. yajl 1 always behaves that way anyways, but for * yajl 2, we need to be explicit. */ yajl_config(handle, yajl_allow_trailing_garbage, 1); -#else - yajl_parser_config parse_conf = { 0, 0 }; - - yajl_handle handle = yajl_alloc(&version_callbacks, &parse_conf, NULL, child); -#endif yajl_status state = yajl_parse(handle, buffer, length); if (state != yajl_status_ok) { diff --git a/i3bar/src/workspaces.c b/i3bar/src/workspaces.c index 5e01b98d..91307b0c 100644 --- a/i3bar/src/workspaces.c +++ b/i3bar/src/workspaces.c @@ -19,9 +19,9 @@ /* A datatype to pass through the callbacks to save the state */ struct workspaces_json_params { struct ws_head *workspaces; - i3_ws *workspaces_walk; - char *cur_key; - char *json; + i3_ws *workspaces_walk; + char *cur_key; + char *json; }; /* @@ -29,7 +29,7 @@ struct workspaces_json_params { * */ static int workspaces_boolean_cb(void *params_, int val) { - struct workspaces_json_params *params = (struct workspaces_json_params*) params_; + struct workspaces_json_params *params = (struct workspaces_json_params *)params_; if (!strcmp(params->cur_key, "visible")) { params->workspaces_walk->visible = val; @@ -58,39 +58,35 @@ static int workspaces_boolean_cb(void *params_, int val) { * Parse an integer (num or the rect) * */ -#if YAJL_MAJOR >= 2 static int workspaces_integer_cb(void *params_, long long val) { -#else -static int workspaces_integer_cb(void *params_, long val) { -#endif - struct workspaces_json_params *params = (struct workspaces_json_params*) params_; + struct workspaces_json_params *params = (struct workspaces_json_params *)params_; if (!strcmp(params->cur_key, "num")) { - params->workspaces_walk->num = (int) val; + params->workspaces_walk->num = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "x")) { - params->workspaces_walk->rect.x = (int) val; + params->workspaces_walk->rect.x = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "y")) { - params->workspaces_walk->rect.y = (int) val; + params->workspaces_walk->rect.y = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "width")) { - params->workspaces_walk->rect.w = (int) val; + params->workspaces_walk->rect.w = (int)val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "height")) { - params->workspaces_walk->rect.h = (int) val; + params->workspaces_walk->rect.h = (int)val; FREE(params->cur_key); return 1; } @@ -103,51 +99,71 @@ static int workspaces_integer_cb(void *params_, long val) { * Parse a string (name, output) * */ -#if YAJL_MAJOR >= 2 static int workspaces_string_cb(void *params_, const unsigned char *val, size_t len) { -#else -static int workspaces_string_cb(void *params_, const unsigned char *val, unsigned int len) { -#endif - struct workspaces_json_params *params = (struct workspaces_json_params*) params_; + struct workspaces_json_params *params = (struct workspaces_json_params *)params_; - char *output_name; + char *output_name; - if (!strcmp(params->cur_key, "name")) { - /* Save the name */ - params->workspaces_walk->name = i3string_from_utf8_with_length((const char *)val, len); + if (!strcmp(params->cur_key, "name")) { + const char *ws_name = (const char *)val; + params->workspaces_walk->canonical_name = strndup(ws_name, len); - /* Save its rendered width */ - params->workspaces_walk->name_width = - predict_text_width(params->workspaces_walk->name); + if (config.strip_ws_numbers && params->workspaces_walk->num >= 0) { + /* Special case: strip off the workspace number */ + static char ws_num[10]; - DLOG("Got Workspace %s, name_width: %d, glyphs: %zu\n", - i3string_as_utf8(params->workspaces_walk->name), - params->workspaces_walk->name_width, - i3string_get_num_glyphs(params->workspaces_walk->name)); - FREE(params->cur_key); + snprintf(ws_num, sizeof(ws_num), "%d", params->workspaces_walk->num); - return 1; + /* Calculate the length of the number str in the name */ + size_t offset = strspn(ws_name, ws_num); + + /* Also strip off the conventional ws name delimiter */ + if (offset && ws_name[offset] == ':') + offset += 1; + + /* Offset may be equal to length, in which case display the number */ + params->workspaces_walk->name = (offset < len + ? i3string_from_utf8_with_length(ws_name + offset, len - offset) + : i3string_from_utf8(ws_num)); + + } else { + /* Default case: just save the name */ + params->workspaces_walk->name = i3string_from_utf8_with_length(ws_name, len); } - if (!strcmp(params->cur_key, "output")) { - /* We add the ws to the TAILQ of the output, it belongs to */ - output_name = smalloc(sizeof(const unsigned char) * (len + 1)); - strncpy(output_name, (const char*) val, len); - output_name[len] = '\0'; - i3_output *target = get_output_by_name(output_name); - if (target) { - params->workspaces_walk->output = target; + /* Save its rendered width */ + params->workspaces_walk->name_width = + predict_text_width(params->workspaces_walk->name); - TAILQ_INSERT_TAIL(params->workspaces_walk->output->workspaces, - params->workspaces_walk, - tailq); - } + DLOG("Got Workspace canonical: %s, name: '%s', name_width: %d, glyphs: %zu\n", + params->workspaces_walk->canonical_name, + i3string_as_utf8(params->workspaces_walk->name), + params->workspaces_walk->name_width, + i3string_get_num_glyphs(params->workspaces_walk->name)); + FREE(params->cur_key); - FREE(output_name); - return 1; + return 1; + } + + if (!strcmp(params->cur_key, "output")) { + /* We add the ws to the TAILQ of the output, it belongs to */ + output_name = smalloc(sizeof(const unsigned char) * (len + 1)); + strncpy(output_name, (const char *)val, len); + output_name[len] = '\0'; + i3_output *target = get_output_by_name(output_name); + if (target) { + params->workspaces_walk->output = target; + + TAILQ_INSERT_TAIL(params->workspaces_walk->output->workspaces, + params->workspaces_walk, + tailq); } - return 0; + FREE(output_name); + return 1; + } + + return 0; } /* @@ -155,7 +171,7 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, unsigne * */ static int workspaces_start_map_cb(void *params_) { - struct workspaces_json_params *params = (struct workspaces_json_params*) params_; + struct workspaces_json_params *params = (struct workspaces_json_params *)params_; i3_ws *new_workspace = NULL; @@ -182,34 +198,24 @@ static int workspaces_start_map_cb(void *params_) { * Essentially we just save it in the parsing-state * */ -#if YAJL_MAJOR >= 2 static int workspaces_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) { -#else -static int workspaces_map_key_cb(void *params_, const unsigned char *keyVal, unsigned int keyLen) { -#endif - struct workspaces_json_params *params = (struct workspaces_json_params*) params_; + struct workspaces_json_params *params = (struct workspaces_json_params *)params_; FREE(params->cur_key); params->cur_key = smalloc(sizeof(unsigned char) * (keyLen + 1)); - strncpy(params->cur_key, (const char*) keyVal, keyLen); + strncpy(params->cur_key, (const char *)keyVal, keyLen); params->cur_key[keyLen] = '\0'; return 1; } /* A datastructure to pass all these callbacks to yajl */ -yajl_callbacks workspaces_callbacks = { - NULL, - &workspaces_boolean_cb, - &workspaces_integer_cb, - NULL, - NULL, - &workspaces_string_cb, - &workspaces_start_map_cb, - &workspaces_map_key_cb, - NULL, - NULL, - NULL +static yajl_callbacks workspaces_callbacks = { + .yajl_boolean = workspaces_boolean_cb, + .yajl_integer = workspaces_integer_cb, + .yajl_string = workspaces_string_cb, + .yajl_start_map = workspaces_start_map_cb, + .yajl_map_key = workspaces_map_key_cb, }; /* @@ -229,24 +235,15 @@ void parse_workspaces_json(char *json) { yajl_handle handle; yajl_status state; -#if YAJL_MAJOR < 2 - yajl_parser_config parse_conf = { 0, 0 }; + handle = yajl_alloc(&workspaces_callbacks, NULL, (void *)¶ms); - handle = yajl_alloc(&workspaces_callbacks, &parse_conf, NULL, (void*) ¶ms); -#else - handle = yajl_alloc(&workspaces_callbacks, NULL, (void*) ¶ms); -#endif - - state = yajl_parse(handle, (const unsigned char*) json, strlen(json)); + state = yajl_parse(handle, (const unsigned char *)json, strlen(json)); /* FIXME: Propper errorhandling for JSON-parsing */ switch (state) { case yajl_status_ok: break; case yajl_status_client_canceled: -#if YAJL_MAJOR < 2 - case yajl_status_insufficient_data: -#endif case yajl_status_error: ELOG("Could not parse workspaces-reply!\n"); exit(EXIT_FAILURE); @@ -267,12 +264,13 @@ void free_workspaces(void) { if (outputs == NULL) { return; } - i3_ws *ws_walk; + i3_ws *ws_walk; - SLIST_FOREACH(outputs_walk, outputs, slist) { + SLIST_FOREACH (outputs_walk, outputs, slist) { if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) { - TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) { + TAILQ_FOREACH (ws_walk, outputs_walk->workspaces, tailq) { I3STRING_FREE(ws_walk->name); + FREE(ws_walk->canonical_name); } FREE_TAILQ(outputs_walk->workspaces, i3_ws); } diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 3a9c061b..a29f9094 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -35,19 +35,19 @@ /* We save the Atoms in an easy to access array, indexed by an enum */ enum { - #define ATOM_DO(name) name, - #include "xcb_atoms.def" +#define ATOM_DO(name) name, +#include "xcb_atoms.def" NUM_ATOMS }; xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS]; -xcb_atom_t atoms[NUM_ATOMS]; +xcb_atom_t atoms[NUM_ATOMS]; /* Variables, that are the same for all functions at all times */ xcb_connection_t *xcb_connection; -int screen; -xcb_screen_t *root_screen; -xcb_window_t xcb_root; +int screen; +xcb_screen_t *root_screen; +xcb_window_t xcb_root; /* selection window for tray support */ static xcb_window_t selwin = XCB_NONE; @@ -63,22 +63,22 @@ static i3Font font; int bar_height; /* These are only relevant for XKB, which we only need for grabbing modifiers */ -Display *xkb_dpy; -int xkb_event_base; -int mod_pressed = 0; +Display *xkb_dpy; +int xkb_event_base; +int mod_pressed = 0; /* Because the statusline is the same on all outputs, we have * global buffer to render it on */ -xcb_gcontext_t statusline_ctx; -xcb_gcontext_t statusline_clear; -xcb_pixmap_t statusline_pm; -uint32_t statusline_width; +xcb_gcontext_t statusline_ctx; +xcb_gcontext_t statusline_clear; +xcb_pixmap_t statusline_pm; +uint32_t statusline_width; /* Event-Watchers, to interact with the user */ ev_prepare *xcb_prep; -ev_check *xcb_chk; -ev_io *xcb_io; -ev_io *xkb_io; +ev_check *xcb_chk; +ev_io *xcb_io; +ev_io *xkb_io; /* The name of current binding mode */ static mode binding; @@ -128,7 +128,7 @@ void refresh_statusline(void) { statusline_width = 0; /* Predict the text width of all blocks (in pixels). */ - TAILQ_FOREACH(block, &statusline_head, blocks) { + TAILQ_FOREACH (block, &statusline_head, blocks) { if (i3string_get_num_bytes(block->full_text) == 0) continue; @@ -148,8 +148,8 @@ void refresh_statusline(void) { block->x_offset = padding_width; break; case ALIGN_CENTER: - block->x_offset = padding_width / 2; - block->x_append = padding_width / 2 + padding_width % 2; + block->x_offset = padding_width / logical_px(2); + block->x_append = padding_width / logical_px(2) + padding_width % logical_px(2); break; } } @@ -168,12 +168,12 @@ void refresh_statusline(void) { realloc_sl_buffer(); /* Clear the statusline pixmap. */ - xcb_rectangle_t rect = { 0, 0, root_screen->width_in_pixels, font.height + 2 }; + xcb_rectangle_t rect = {0, 0, root_screen->width_in_pixels, font.height + logical_px(5)}; xcb_poly_fill_rectangle(xcb_connection, statusline_pm, statusline_clear, 1, &rect); /* Draw the text of each block. */ uint32_t x = 0; - TAILQ_FOREACH(block, &statusline_head, blocks) { + TAILQ_FOREACH (block, &statusline_head, blocks) { if (i3string_get_num_bytes(block->full_text) == 0) continue; @@ -184,14 +184,14 @@ void refresh_statusline(void) { if (TAILQ_NEXT(block, blocks) != NULL && !block->no_separator && block->sep_block_width > 0) { /* This is not the last block, draw a separator. */ - uint32_t sep_offset = block->sep_block_width/2 + block->sep_block_width % 2; - uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; - uint32_t values[] = { colors.sep_fg, colors.bar_bg }; + uint32_t sep_offset = block->sep_block_width / 2 + block->sep_block_width % 2; + uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_LINE_WIDTH; + uint32_t values[] = {colors.sep_fg, colors.bar_bg, logical_px(1)}; xcb_change_gc(xcb_connection, statusline_ctx, mask, values); xcb_poly_line(xcb_connection, XCB_COORD_MODE_ORIGIN, statusline_pm, statusline_ctx, 2, - (xcb_point_t[]){ { x - sep_offset, 2 }, - { x - sep_offset, font.height - 2 } }); + (xcb_point_t[]) {{x - sep_offset, 2}, + {x - sep_offset, font.height - 2}}); } } } @@ -206,7 +206,7 @@ void hide_bars(void) { } i3_output *walk; - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!walk->active) { continue; } @@ -224,14 +224,14 @@ void unhide_bars(void) { return; } - i3_output *walk; - xcb_void_cookie_t cookie; - uint32_t mask; - uint32_t values[5]; + i3_output *walk; + xcb_void_cookie_t cookie; + uint32_t mask; + uint32_t values[5]; cont_child(); - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (walk->bar == XCB_NONE) { continue; } @@ -243,7 +243,8 @@ void unhide_bars(void) { values[0] = walk->rect.x; if (config.position == POS_TOP) values[1] = walk->rect.y; - else values[1] = walk->rect.y + walk->rect.h - bar_height; + else + values[1] = walk->rect.y + walk->rect.h - bar_height; values[2] = walk->rect.w; values[3] = bar_height; values[4] = XCB_STACK_MODE_ABOVE; @@ -265,10 +266,10 @@ void unhide_bars(void) { * */ void init_colors(const struct xcb_color_strings_t *new_colors) { -#define PARSE_COLOR(name, def) \ - do { \ +#define PARSE_COLOR(name, def) \ + do { \ colors.name = get_colorpixel(new_colors->name ? new_colors->name : def); \ - } while (0) + } while (0) PARSE_COLOR(bar_fg, "#FFFFFF"); PARSE_COLOR(bar_bg, "#000000"); PARSE_COLOR(sep_fg, "#666666"); @@ -302,7 +303,7 @@ void handle_button(xcb_button_press_event_t *event) { /* Determine, which bar was clicked */ i3_output *walk; xcb_window_t bar = event->event; - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (walk->bar == bar) { break; } @@ -314,7 +315,7 @@ void handle_button(xcb_button_press_event_t *event) { } /* TODO: Move this to extern get_ws_for_output() */ - TAILQ_FOREACH(cur_ws, walk->workspaces, tailq) { + TAILQ_FOREACH (cur_ws, walk->workspaces, tailq) { if (cur_ws->visible) { break; } @@ -330,6 +331,39 @@ void handle_button(xcb_button_press_event_t *event) { DLOG("Got Button %d\n", event->detail); + if (child_want_click_events()) { + /* If the child asked for click events, + * check if a status block has been clicked. */ + + /* First calculate width of tray area */ + trayclient *trayclient; + int tray_width = 0; + TAILQ_FOREACH_REVERSE (trayclient, walk->trayclients, tc_head, tailq) { + if (!trayclient->mapped) + continue; + tray_width += (font.height + logical_px(2)); + } + + int block_x = 0, last_block_x; + int offset = (walk->rect.w - (statusline_width + tray_width)) - logical_px(10); + + x = original_x - offset; + if (x >= 0) { + struct status_block *block; + + TAILQ_FOREACH (block, &statusline_head, blocks) { + last_block_x = block_x; + block_x += block->width + block->x_offset + block->x_append; + + if (x <= block_x && x >= last_block_x) { + send_block_clicked(event->detail, block->name, block->instance, event->root_x, event->root_y); + return; + } + } + } + x = original_x; + } + switch (event->detail) { case 4: /* Mouse wheel up. We select the previous ws, if any. @@ -351,52 +385,32 @@ void handle_button(xcb_button_press_event_t *event) { cur_ws = TAILQ_NEXT(cur_ws, tailq); break; - default: + case 1: /* Check if this event regards a workspace button */ - TAILQ_FOREACH(cur_ws, walk->workspaces, tailq) { + TAILQ_FOREACH (cur_ws, walk->workspaces, tailq) { DLOG("x = %d\n", x); - if (x >= 0 && x < cur_ws->name_width + 10) { + if (x >= 0 && x < cur_ws->name_width + logical_px(10)) { break; } - x -= cur_ws->name_width + 11; + x -= cur_ws->name_width + logical_px(11); } + + /* Otherwise, focus our currently visible workspace if it is not + * already focused */ if (cur_ws == NULL) { - /* No workspace button was pressed. - * Check if a status block has been clicked. - * This of course only has an effect, - * if the child reported bidirectional protocol usage. */ - - /* First calculate width of tray area */ - trayclient *trayclient; - int tray_width = 0; - TAILQ_FOREACH_REVERSE(trayclient, walk->trayclients, tc_head, tailq) { - if (!trayclient->mapped) - continue; - tray_width += (font.height + 2); + TAILQ_FOREACH (cur_ws, walk->workspaces, tailq) { + if (cur_ws->visible && !cur_ws->focused) + break; } - - int block_x = 0, last_block_x; - int offset = (walk->rect.w - (statusline_width + tray_width)) - 10; - - x = original_x - offset; - if (x < 0) - return; - - struct status_block *block; - - TAILQ_FOREACH(block, &statusline_head, blocks) { - last_block_x = block_x; - block_x += block->width + block->x_offset + block->x_append; - - if (x <= block_x && x >= last_block_x) { - send_block_clicked(event->detail, block->name, block->instance, event->root_x, event->root_y); - return; - } - } - return; } - if (event->detail != 1) + + /* if there is nothing to focus, we are done */ + if (cur_ws == NULL) return; + + break; + default: + return; } /* To properly handle workspace names with double quotes in them, we need @@ -405,7 +419,7 @@ void handle_button(xcb_button_press_event_t *event) { * buffer, then we copy character by character. */ int num_quotes = 0; size_t namelen = 0; - const char *utf8_name = i3string_as_utf8(cur_ws->name); + const char *utf8_name = cur_ws->canonical_name; for (const char *walk = utf8_name; *walk != '\0'; walk++) { if (*walk == '"') num_quotes++; @@ -415,9 +429,9 @@ void handle_button(xcb_button_press_event_t *event) { } const size_t len = namelen + strlen("workspace \"\"") + 1; - char *buffer = scalloc(len+num_quotes); + char *buffer = scalloc(len + num_quotes); strncpy(buffer, "workspace \"", strlen("workspace \"")); - int inpos, outpos; + size_t inpos, outpos; for (inpos = 0, outpos = strlen("workspace \""); inpos < namelen; inpos++, outpos++) { @@ -441,19 +455,19 @@ void handle_button(xcb_button_press_event_t *event) { static void configure_trayclients(void) { trayclient *trayclient; i3_output *output; - SLIST_FOREACH(output, outputs, slist) { + SLIST_FOREACH (output, outputs, slist) { if (!output->active) continue; int clients = 0; - TAILQ_FOREACH_REVERSE(trayclient, output->trayclients, tc_head, tailq) { + TAILQ_FOREACH_REVERSE (trayclient, output->trayclients, tc_head, tailq) { if (!trayclient->mapped) continue; clients++; DLOG("Configuring tray window %08x to x=%d\n", - trayclient->win, output->rect.w - (clients * (font.height + 2))); - uint32_t x = output->rect.w - (clients * (font.height + 2)); + trayclient->win, output->rect.w - (clients * (font.height + logical_px(2)))); + uint32_t x = output->rect.w - (clients * (font.height + logical_px(2))); xcb_configure_window(xcb_connection, trayclient->win, XCB_CONFIG_WINDOW_X, @@ -469,7 +483,7 @@ static void configure_trayclients(void) { * supported client messages currently are _NET_SYSTEM_TRAY_OPCODE. * */ -static void handle_client_message(xcb_client_message_event_t* event) { +static void handle_client_message(xcb_client_message_event_t *event) { if (event->type == atoms[_NET_SYSTEM_TRAY_OPCODE] && event->format == 32) { DLOG("_NET_SYSTEM_TRAY_OPCODE received\n"); @@ -530,7 +544,7 @@ static void handle_client_message(xcb_client_message_event_t* event) { DLOG("X window %08x requested docking\n", client); i3_output *walk, *output = NULL; - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!walk->active) continue; if (config.tray_output) { @@ -548,7 +562,7 @@ static void handle_client_message(xcb_client_message_event_t* event) { if (output == NULL && config.tray_output && strcasecmp("primary", config.tray_output) == 0) { - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!walk->active) continue; DLOG("Falling back to output %s because no primary output is configured\n", walk->name); @@ -593,7 +607,7 @@ static void handle_client_message(xcb_client_message_event_t* event) { 0, client, XCB_EVENT_MASK_NO_EVENT, - (char*)ev); + (char *)ev); free(event); /* Put the client inside the save set. Upon termination (whether @@ -632,16 +646,16 @@ static void handle_client_message(xcb_client_message_event_t* event) { * See: http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html * */ -static void handle_destroy_notify(xcb_destroy_notify_event_t* event) { +static void handle_destroy_notify(xcb_destroy_notify_event_t *event) { DLOG("DestroyNotify for window = %08x, event = %08x\n", event->window, event->event); i3_output *walk; - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!walk->active) continue; DLOG("checking output %s\n", walk->name); trayclient *trayclient; - TAILQ_FOREACH(trayclient, walk->trayclients, tailq) { + TAILQ_FOREACH (trayclient, walk->trayclients, tailq) { if (trayclient->win != event->window) continue; @@ -661,16 +675,16 @@ static void handle_destroy_notify(xcb_destroy_notify_event_t* event) { * window. We respond by realigning the tray clients. * */ -static void handle_map_notify(xcb_map_notify_event_t* event) { +static void handle_map_notify(xcb_map_notify_event_t *event) { DLOG("MapNotify for window = %08x, event = %08x\n", event->window, event->event); i3_output *walk; - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!walk->active) continue; DLOG("checking output %s\n", walk->name); trayclient *trayclient; - TAILQ_FOREACH(trayclient, walk->trayclients, tailq) { + TAILQ_FOREACH (trayclient, walk->trayclients, tailq) { if (trayclient->win != event->window) continue; @@ -689,16 +703,16 @@ static void handle_map_notify(xcb_map_notify_event_t* event) { * window. We respond by realigning the tray clients. * */ -static void handle_unmap_notify(xcb_unmap_notify_event_t* event) { +static void handle_unmap_notify(xcb_unmap_notify_event_t *event) { DLOG("UnmapNotify for window = %08x, event = %08x\n", event->window, event->event); i3_output *walk; - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!walk->active) continue; DLOG("checking output %s\n", walk->name); trayclient *trayclient; - TAILQ_FOREACH(trayclient, walk->trayclients, tailq) { + TAILQ_FOREACH (trayclient, walk->trayclients, tailq) { if (trayclient->win != event->window) continue; @@ -725,11 +739,11 @@ static void handle_property_notify(xcb_property_notify_event_t *event) { DLOG("xembed_info updated\n"); trayclient *trayclient = NULL, *walk; i3_output *o_walk; - SLIST_FOREACH(o_walk, outputs, slist) { + SLIST_FOREACH (o_walk, outputs, slist) { if (!o_walk->active) continue; - TAILQ_FOREACH(walk, o_walk->trayclients, tailq) { + TAILQ_FOREACH (walk, o_walk->trayclients, tailq) { if (walk->win != event->window) continue; trayclient = walk; @@ -788,12 +802,12 @@ static void handle_configure_request(xcb_configure_request_event_t *event) { trayclient *trayclient; i3_output *output; - SLIST_FOREACH(output, outputs, slist) { + SLIST_FOREACH (output, outputs, slist) { if (!output->active) continue; int clients = 0; - TAILQ_FOREACH_REVERSE(trayclient, output->trayclients, tc_head, tailq) { + TAILQ_FOREACH_REVERSE (trayclient, output->trayclients, tc_head, tailq) { if (!trayclient->mapped) continue; clients++; @@ -847,31 +861,31 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) { break; case XCB_BUTTON_PRESS: /* Button-press-events are mouse-buttons clicked on one of our bars */ - handle_button((xcb_button_press_event_t*) event); + handle_button((xcb_button_press_event_t *)event); break; case XCB_CLIENT_MESSAGE: /* Client messages are used for client-to-client communication, for * example system tray widgets talk to us directly via client messages. */ - handle_client_message((xcb_client_message_event_t*) event); + handle_client_message((xcb_client_message_event_t *)event); break; case XCB_DESTROY_NOTIFY: /* DestroyNotify signifies the end of the XEmbed protocol */ - handle_destroy_notify((xcb_destroy_notify_event_t*) event); + handle_destroy_notify((xcb_destroy_notify_event_t *)event); break; case XCB_UNMAP_NOTIFY: /* UnmapNotify is received when a tray client hides its window. */ - handle_unmap_notify((xcb_unmap_notify_event_t*) event); + handle_unmap_notify((xcb_unmap_notify_event_t *)event); break; case XCB_MAP_NOTIFY: - handle_map_notify((xcb_map_notify_event_t*) event); + handle_map_notify((xcb_map_notify_event_t *)event); break; case XCB_PROPERTY_NOTIFY: /* PropertyNotify */ - handle_property_notify((xcb_property_notify_event_t*) event); + handle_property_notify((xcb_property_notify_event_t *)event); break; case XCB_CONFIGURE_REQUEST: /* ConfigureRequest, sent by a tray child */ - handle_configure_request((xcb_configure_request_event_t*) event); + handle_configure_request((xcb_configure_request_event_t *)event); break; } free(event); @@ -897,7 +911,7 @@ void xkb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) { DLOG("Got XKB-Event!\n"); while (XPending(xkb_dpy)) { - XNextEvent(xkb_dpy, (XEvent*)&ev); + XNextEvent(xkb_dpy, (XEvent *)&ev); if (ev.type != xkb_event_base) { ELOG("No Xkb-Event!\n"); @@ -913,31 +927,31 @@ void xkb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) { modstate = mods & config.modifier; } -#define DLOGMOD(modmask, status) \ - do { \ - switch (modmask) { \ - case ShiftMask: \ - DLOG("ShiftMask got " #status "!\n"); \ - break; \ - case ControlMask: \ +#define DLOGMOD(modmask, status) \ + do { \ + switch (modmask) { \ + case ShiftMask: \ + DLOG("ShiftMask got " #status "!\n"); \ + break; \ + case ControlMask: \ DLOG("ControlMask got " #status "!\n"); \ - break; \ - case Mod1Mask: \ - DLOG("Mod1Mask got " #status "!\n"); \ - break; \ - case Mod2Mask: \ - DLOG("Mod2Mask got " #status "!\n"); \ - break; \ - case Mod3Mask: \ - DLOG("Mod3Mask got " #status "!\n"); \ - break; \ - case Mod4Mask: \ - DLOG("Mod4Mask got " #status "!\n"); \ - break; \ - case Mod5Mask: \ - DLOG("Mod5Mask got " #status "!\n"); \ - break; \ - } \ + break; \ + case Mod1Mask: \ + DLOG("Mod1Mask got " #status "!\n"); \ + break; \ + case Mod2Mask: \ + DLOG("Mod2Mask got " #status "!\n"); \ + break; \ + case Mod3Mask: \ + DLOG("Mod3Mask got " #status "!\n"); \ + break; \ + case Mod4Mask: \ + DLOG("Mod4Mask got " #status "!\n"); \ + break; \ + case Mod5Mask: \ + DLOG("Mod5Mask got " #status "!\n"); \ + break; \ + } \ } while (0) if (modstate != mod_pressed) { @@ -971,9 +985,9 @@ char *init_xcb_early() { conn = xcb_connection; DLOG("Connected to xcb\n"); - /* We have to request the atoms we need */ - #define ATOM_DO(name) atom_cookies[name] = xcb_intern_atom(xcb_connection, 0, strlen(#name), #name); - #include "xcb_atoms.def" +/* We have to request the atoms we need */ +#define ATOM_DO(name) atom_cookies[name] = xcb_intern_atom(xcb_connection, 0, strlen(#name), #name); +#include "xcb_atoms.def" root_screen = xcb_aux_get_screen(xcb_connection, screen); xcb_root = root_screen->root; @@ -981,7 +995,7 @@ char *init_xcb_early() { /* We draw the statusline to a seperate pixmap, because it looks the same on all bars and * this way, we can choose to crop it */ uint32_t mask = XCB_GC_FOREGROUND; - uint32_t vals[] = { colors.bar_bg, colors.bar_bg }; + uint32_t vals[] = {colors.bar_bg, colors.bar_bg}; statusline_clear = xcb_generate_id(xcb_connection); xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection, @@ -1005,7 +1019,6 @@ char *init_xcb_early() { root_screen->width_in_pixels, root_screen->height_in_pixels); - /* The various Watchers to communicate with xcb */ xcb_io = smalloc(sizeof(ev_io)); xcb_prep = smalloc(sizeof(ev_prepare)); @@ -1086,7 +1099,7 @@ void register_xkb_keyevents() { */ void deregister_xkb_keyevents() { if (xkb_dpy != NULL) { - ev_io_stop (main_loop, xkb_io); + ev_io_stop(main_loop, xkb_io); XCloseDisplay(xkb_dpy); close(xkb_io->fd); FREE(xkb_io); @@ -1107,7 +1120,7 @@ void init_xcb_late(char *fontname) { font = load_font(fontname, true); set_font(&font); DLOG("Calculated Font-height: %d\n", font.height); - bar_height = font.height + 6; + bar_height = font.height + logical_px(6); xcb_flush(xcb_connection); @@ -1121,8 +1134,8 @@ void init_xcb_late(char *fontname) { * */ static void send_tray_clientmessage(void) { - uint8_t buffer[32] = { 0 }; - xcb_client_message_event_t *ev = (xcb_client_message_event_t*)buffer; + uint8_t buffer[32] = {0}; + xcb_client_message_event_t *ev = (xcb_client_message_event_t *)buffer; ev->response_type = XCB_CLIENT_MESSAGE; ev->window = xcb_root; @@ -1136,10 +1149,9 @@ static void send_tray_clientmessage(void) { 0, xcb_root, 0xFFFFFF, - (char*)buffer); + (char *)buffer); } - /* * Initializes tray support by requesting the appropriate _NET_SYSTEM_TRAY atom * for the X11 display we are running on, then acquiring the selection for this @@ -1158,7 +1170,7 @@ void init_tray(void) { /* tray support: we need a window to own the selection */ selwin = xcb_generate_id(xcb_connection); uint32_t selmask = XCB_CW_OVERRIDE_REDIRECT; - uint32_t selval[] = { 1 }; + uint32_t selval[] = {1}; xcb_create_window(xcb_connection, root_screen->root_depth, selwin, @@ -1207,8 +1219,9 @@ void init_tray(void) { } if (selreply->owner != selwin) { - ELOG("Could not set the %s selection. " \ - "Maybe another tray is already running?\n", atomname); + ELOG("Could not set the %s selection. " + "Maybe another tray is already running?\n", + atomname); /* NOTE that this error is not fatal. We just can’t provide tray * functionality */ free(selreply); @@ -1267,7 +1280,7 @@ void init_tray_colors(void) { void clean_xcb(void) { i3_output *o_walk; free_workspaces(); - SLIST_FOREACH(o_walk, outputs, slist) { + SLIST_FOREACH (o_walk, outputs, slist) { destroy_window(o_walk); FREE(o_walk->trayclients); FREE(o_walk->workspaces); @@ -1294,15 +1307,16 @@ void clean_xcb(void) { */ void get_atoms(void) { xcb_intern_atom_reply_t *reply; - #define ATOM_DO(name) reply = xcb_intern_atom_reply(xcb_connection, atom_cookies[name], NULL); \ - if (reply == NULL) { \ - ELOG("Could not get atom %s\n", #name); \ - exit(EXIT_FAILURE); \ - } \ - atoms[name] = reply->atom; \ - free(reply); +#define ATOM_DO(name) \ + reply = xcb_intern_atom_reply(xcb_connection, atom_cookies[name], NULL); \ + if (reply == NULL) { \ + ELOG("Could not get atom %s\n", #name); \ + exit(EXIT_FAILURE); \ + } \ + atoms[name] = reply->atom; \ + free(reply); - #include "xcb_atoms.def" +#include "xcb_atoms.def" DLOG("Got Atoms\n"); } @@ -1338,14 +1352,14 @@ void kick_tray_clients(i3_output *output) { /* Fake a DestroyNotify so that Qt re-adds tray icons. * We cannot actually destroy the window because then Qt will not restore * its event mask on the new window. */ - uint8_t buffer[32] = { 0 }; - xcb_destroy_notify_event_t *event = (xcb_destroy_notify_event_t*)buffer; + uint8_t buffer[32] = {0}; + xcb_destroy_notify_event_t *event = (xcb_destroy_notify_event_t *)buffer; event->response_type = XCB_DESTROY_NOTIFY; event->event = selwin; event->window = selwin; - xcb_send_event(conn, false, selwin, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char*)event); + xcb_send_event(conn, false, selwin, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *)event); send_tray_clientmessage(); } @@ -1384,7 +1398,7 @@ void realloc_sl_buffer(void) { bar_height); uint32_t mask = XCB_GC_FOREGROUND; - uint32_t vals[2] = { colors.bar_bg, colors.bar_bg }; + uint32_t vals[2] = {colors.bar_bg, colors.bar_bg}; xcb_free_gc(xcb_connection, statusline_clear); statusline_clear = xcb_generate_id(xcb_connection); xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection, @@ -1408,7 +1422,6 @@ void realloc_sl_buffer(void) { xcb_request_failed(sl_ctx_cookie, "Could not allocate statusline-buffer-context")) { exit(EXIT_FAILURE); } - } /* @@ -1421,7 +1434,7 @@ void reconfig_windows(bool redraw_bars) { static bool tray_configured = false; i3_output *walk; - SLIST_FOREACH(walk, outputs, slist) { + SLIST_FOREACH (walk, outputs, slist) { if (!walk->active) { /* If an output is not active, we destroy its bar */ /* FIXME: Maybe we rather want to unmap? */ @@ -1504,7 +1517,7 @@ void reconfig_windows(bool redraw_bars) { XCB_ATOM_ATOM, 32, 1, - (unsigned char*) &atoms[_NET_WM_WINDOW_TYPE_DOCK]); + (unsigned char *)&atoms[_NET_WM_WINDOW_TYPE_DOCK]); /* We need to tell i3, where to reserve space for i3bar */ /* left, right, top, bottom, left_start_y, left_end_y, @@ -1524,7 +1537,9 @@ void reconfig_windows(bool redraw_bars) { uint32_t top_end_x; uint32_t bottom_start_x; uint32_t bottom_end_x; - } __attribute__((__packed__)) strut_partial = {0,}; + } __attribute__((__packed__)) strut_partial; + memset(&strut_partial, 0, sizeof(strut_partial)); + switch (config.position) { case POS_NONE: break; @@ -1563,13 +1578,13 @@ void reconfig_windows(bool redraw_bars) { map_cookie = xcb_map_window_checked(xcb_connection, walk->bar); } - if (xcb_request_failed(win_cookie, "Could not create window") || - xcb_request_failed(pm_cookie, "Could not create pixmap") || - xcb_request_failed(dock_cookie, "Could not set dock mode") || - xcb_request_failed(class_cookie, "Could not set WM_CLASS") || - xcb_request_failed(name_cookie, "Could not set WM_NAME") || - xcb_request_failed(strut_cookie, "Could not set strut") || - xcb_request_failed(gc_cookie, "Could not create graphical context") || + if (xcb_request_failed(win_cookie, "Could not create window") || + xcb_request_failed(pm_cookie, "Could not create pixmap") || + xcb_request_failed(dock_cookie, "Could not set dock mode") || + xcb_request_failed(class_cookie, "Could not set WM_CLASS") || + xcb_request_failed(name_cookie, "Could not set WM_NAME") || + xcb_request_failed(strut_cookie, "Could not set strut") || + xcb_request_failed(gc_cookie, "Could not create graphical context") || ((config.hide_on_modifier == M_DOCK) && xcb_request_failed(map_cookie, "Could not map window"))) { exit(EXIT_FAILURE); } @@ -1581,9 +1596,9 @@ void reconfig_windows(bool redraw_bars) { * VGA-1 but output == [HDMI-1]). */ i3_output *output; - SLIST_FOREACH(output, outputs, slist) { + SLIST_FOREACH (output, outputs, slist) { if (strcasecmp(output->name, tray_output) == 0 || - (strcasecmp(tray_output, "primary") == 0 && output->primary)) { + (strcasecmp(tray_output, "primary") == 0 && output->primary)) { init_tray(); break; } @@ -1650,9 +1665,9 @@ void reconfig_windows(bool redraw_bars) { if (xcb_request_failed(cfg_cookie, "Could not reconfigure window") || xcb_request_failed(chg_cookie, "Could not change window") || - xcb_request_failed(pm_cookie, "Could not create pixmap") || - (redraw_bars && (xcb_request_failed(umap_cookie, "Could not unmap window") || - (config.hide_on_modifier == M_DOCK && xcb_request_failed(map_cookie, "Could not map window"))))) { + xcb_request_failed(pm_cookie, "Could not create pixmap") || + (redraw_bars && (xcb_request_failed(umap_cookie, "Could not unmap window") || + (config.hide_on_modifier == M_DOCK && xcb_request_failed(map_cookie, "Could not map window"))))) { exit(EXIT_FAILURE); } } @@ -1670,7 +1685,7 @@ void draw_bars(bool unhide) { refresh_statusline(); i3_output *outputs_walk; - SLIST_FOREACH(outputs_walk, outputs, slist) { + SLIST_FOREACH (outputs_walk, outputs, slist) { if (!outputs_walk->active) { DLOG("Output %s inactive, skipping...\n", outputs_walk->name); continue; @@ -1685,7 +1700,7 @@ void draw_bars(bool unhide) { outputs_walk->bargc, XCB_GC_FOREGROUND, &color); - xcb_rectangle_t rect = { 0, 0, outputs_walk->rect.w, bar_height }; + xcb_rectangle_t rect = {0, 0, outputs_walk->rect.w, bar_height}; xcb_poly_fill_rectangle(xcb_connection, outputs_walk->buffer, outputs_walk->bargc, @@ -1700,7 +1715,7 @@ void draw_bars(bool unhide) { * position */ trayclient *trayclient; int traypx = 0; - TAILQ_FOREACH(trayclient, outputs_walk->trayclients, tailq) { + TAILQ_FOREACH (trayclient, outputs_walk->trayclients, tailq) { if (!trayclient->mapped) continue; /* We assume the tray icons are quadratic (we use the font @@ -1717,12 +1732,12 @@ void draw_bars(bool unhide) { outputs_walk->bargc, MAX(0, (int16_t)(statusline_width - outputs_walk->rect.w + 4)), 0, MAX(0, (int16_t)(outputs_walk->rect.w - statusline_width - traypx - 4)), 3, - MIN(outputs_walk->rect.w - traypx - 4, statusline_width), font.height + 2); + MIN(outputs_walk->rect.w - traypx - 4, (int)statusline_width), font.height + 2); } if (!config.disable_ws) { i3_ws *ws_walk; - TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) { + TAILQ_FOREACH (ws_walk, outputs_walk->workspaces, tailq) { DLOG("Drawing Button for WS %s at x = %d, len = %d\n", i3string_as_utf8(ws_walk->name), i, ws_walk->name_width); uint32_t fg_color = colors.inactive_ws_fg; @@ -1747,23 +1762,29 @@ void draw_bars(bool unhide) { unhide = true; } uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; - uint32_t vals_border[] = { border_color, border_color }; + uint32_t vals_border[] = {border_color, border_color}; xcb_change_gc(xcb_connection, outputs_walk->bargc, mask, vals_border); - xcb_rectangle_t rect_border = { i, 1, ws_walk->name_width + 10, font.height + 4 }; + xcb_rectangle_t rect_border = {i, + logical_px(1), + ws_walk->name_width + logical_px(10), + font.height + logical_px(4)}; xcb_poly_fill_rectangle(xcb_connection, outputs_walk->buffer, outputs_walk->bargc, 1, &rect_border); - uint32_t vals[] = { bg_color, bg_color }; + uint32_t vals[] = {bg_color, bg_color}; xcb_change_gc(xcb_connection, outputs_walk->bargc, mask, vals); - xcb_rectangle_t rect = { i + 1, 2, ws_walk->name_width + 8, font.height + 2 }; + xcb_rectangle_t rect = {i + logical_px(1), + 2 * logical_px(1), + ws_walk->name_width + logical_px(8), + font.height + logical_px(2)}; xcb_poly_fill_rectangle(xcb_connection, outputs_walk->buffer, outputs_walk->bargc, @@ -1771,9 +1792,8 @@ void draw_bars(bool unhide) { &rect); set_font_colors(outputs_walk->bargc, fg_color, bg_color); draw_text(ws_walk->name, outputs_walk->buffer, outputs_walk->bargc, - i + 5, 3, ws_walk->name_width); - i += 10 + ws_walk->name_width + 1; - + i + logical_px(5), 3 * logical_px(1), ws_walk->name_width); + i += logical_px(10) + ws_walk->name_width + logical_px(1); } } @@ -1782,24 +1802,24 @@ void draw_bars(bool unhide) { uint32_t bg_color = colors.urgent_ws_bg; uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; - uint32_t vals_border[] = { colors.urgent_ws_border, colors.urgent_ws_border }; + uint32_t vals_border[] = {colors.urgent_ws_border, colors.urgent_ws_border}; xcb_change_gc(xcb_connection, outputs_walk->bargc, mask, vals_border); - xcb_rectangle_t rect_border = { i, 1, binding.width + 10, font.height + 4 }; + xcb_rectangle_t rect_border = {i, 1, binding.width + 10, font.height + 4}; xcb_poly_fill_rectangle(xcb_connection, outputs_walk->buffer, outputs_walk->bargc, 1, &rect_border); - uint32_t vals[] = { bg_color, bg_color }; + uint32_t vals[] = {bg_color, bg_color}; xcb_change_gc(xcb_connection, outputs_walk->bargc, mask, vals); - xcb_rectangle_t rect = { i + 1, 2, binding.width + 8, font.height + 2 }; + xcb_rectangle_t rect = {i + 1, 2, binding.width + 8, font.height + 2}; xcb_poly_fill_rectangle(xcb_connection, outputs_walk->buffer, outputs_walk->bargc, @@ -1817,8 +1837,8 @@ void draw_bars(bool unhide) { /* Assure the bar is hidden/unhidden according to the specified hidden_state and mode */ if (mod_pressed || - config.hidden_state == S_SHOW || - unhide) { + config.hidden_state == S_SHOW || + unhide) { unhide_bars(); } else if (config.hide_on_modifier == M_HIDE) { hide_bars(); @@ -1833,7 +1853,7 @@ void draw_bars(bool unhide) { */ void redraw_bars(void) { i3_output *outputs_walk; - SLIST_FOREACH(outputs_walk, outputs, slist) { + SLIST_FOREACH (outputs_walk, outputs, slist) { if (!outputs_walk->active) { continue; } diff --git a/include/all.h b/include/all.h index c9c4bbbe..a355d3d2 100644 --- a/include/all.h +++ b/include/all.h @@ -79,9 +79,12 @@ #include "scratchpad.h" #include "commands.h" #include "commands_parser.h" +#include "bindings.h" #include "config_directives.h" #include "config_parser.h" #include "fake_outputs.h" #include "display_version.h" +#include "restore_layout.h" +#include "main.h" #endif diff --git a/include/assignments.h b/include/assignments.h index 570375cf..b83ee03f 100644 --- a/include/assignments.h +++ b/include/assignments.h @@ -7,8 +7,7 @@ * assignments.c: Assignments for specific windows (for_window). * */ -#ifndef I3_ASSIGNMENTS_H -#define I3_ASSIGNMENTS_H +#pragma once /** * Checks the list of assignments for the given window and runs all matching @@ -22,5 +21,3 @@ void run_assignments(i3Window *window); * */ Assignment *assignment_for(i3Window *window, int type); - -#endif diff --git a/include/atoms.xmacro b/include/atoms.xmacro index 41889eb1..90b02616 100644 --- a/include/atoms.xmacro +++ b/include/atoms.xmacro @@ -3,6 +3,7 @@ xmacro(_NET_SUPPORTING_WM_CHECK) xmacro(_NET_WM_NAME) xmacro(_NET_WM_STATE_FULLSCREEN) xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) +xmacro(_NET_WM_STATE_MODAL) xmacro(_NET_WM_STATE) xmacro(_NET_WM_WINDOW_TYPE) xmacro(_NET_WM_WINDOW_TYPE_DOCK) @@ -12,6 +13,7 @@ xmacro(_NET_WM_WINDOW_TYPE_TOOLBAR) xmacro(_NET_WM_WINDOW_TYPE_SPLASH) xmacro(_NET_WM_DESKTOP) xmacro(_NET_WM_STRUT_PARTIAL) +xmacro(_NET_CLIENT_LIST) xmacro(_NET_CLIENT_LIST_STACKING) xmacro(_NET_CURRENT_DESKTOP) xmacro(_NET_ACTIVE_WINDOW) @@ -31,3 +33,4 @@ xmacro(I3_SHMLOG_PATH) xmacro(I3_PID) xmacro(_NET_REQUEST_FRAME_EXTENTS) xmacro(_NET_FRAME_EXTENTS) +xmacro(_MOTIF_WM_HINTS) diff --git a/include/bindings.h b/include/bindings.h new file mode 100644 index 00000000..e51f5e99 --- /dev/null +++ b/include/bindings.h @@ -0,0 +1,69 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * i3 - an improved dynamic tiling window manager + * © 2009-2014 Michael Stapelberg and contributors (see also: LICENSE) + * + * bindings.h: Functions for configuring, finding, and running bindings. + * + */ +#pragma once + +extern pid_t command_error_nagbar_pid; + +/** + * The name of the default mode. + * + */ +const char *DEFAULT_BINDING_MODE; + +/** + * Adds a binding from config parameters given as strings and returns a + * pointer to the binding structure. Returns NULL if the input code could not + * be parsed. + * + */ +Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code, + const char *release, const char *command, const char *mode); + +/** + * Grab the bound keys (tell X to send us keypress events for those keycodes) + * + */ +void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch); + +/** + * Returns a pointer to the Binding that matches the given xcb event or NULL if + * no such binding exists. + * + */ +Binding *get_binding_from_xcb_event(xcb_generic_event_t *event); + +/** + * Translates keysymbols to keycodes for all bindings which use keysyms. + * + */ +void translate_keysyms(void); + +/** + * Switches the key bindings to the given mode, if the mode exists + * + */ +void switch_mode(const char *new_mode); + +/** + * Checks for duplicate key bindings (the same keycode or keysym is configured + * more than once). If a duplicate binding is found, a message is printed to + * stderr and the has_errors variable is set to true, which will start + * i3-nagbar. + * + */ +void check_for_duplicate_bindings(struct context *context); + +/** + * Runs the given binding and handles parse errors. Returns a CommandResult for + * running the binding's command. Caller should render tree if + * needs_tree_render is true. Free with command_result_free(). + * + */ +CommandResult *run_binding(Binding *bind); diff --git a/include/click.h b/include/click.h index 3c4d5288..c63672a7 100644 --- a/include/click.h +++ b/include/click.h @@ -7,8 +7,7 @@ * click.c: Button press (mouse click) events. * */ -#ifndef I3_CLICK_H -#define I3_CLICK_H +#pragma once /** * The button press X callback. This function determines whether the floating @@ -19,5 +18,3 @@ * */ int handle_button_press(xcb_button_press_event_t *event); - -#endif diff --git a/include/cmdparse.h b/include/cmdparse.h index 4a87c39c..263801f6 100644 --- a/include/cmdparse.h +++ b/include/cmdparse.h @@ -7,9 +7,6 @@ * cmdparse.y: the parser for commands you send to i3 (or bind on keys) * */ -#ifndef I3_CMDPARSE_H -#define I3_CMDPARSE_H +#pragma once char *parse_cmd(const char *new); - -#endif diff --git a/include/commands.h b/include/commands.h index bbf45ba9..cb687890 100644 --- a/include/commands.h +++ b/include/commands.h @@ -7,13 +7,12 @@ * commands.c: all command functions (see commands_parser.c) * */ -#ifndef I3_COMMANDS_H -#define I3_COMMANDS_H +#pragma once #include "commands_parser.h" /** The beginning of the prototype for every cmd_ function. */ -#define I3_CMD Match *current_match, struct CommandResult *cmd_output +#define I3_CMD Match *current_match, struct CommandResultIR *cmd_output /** * Initializes the specified 'Match' data structure and the initial state of @@ -288,5 +287,3 @@ void cmd_shmlog(I3_CMD, char *argument); * */ void cmd_debuglog(I3_CMD, char *argument); - -#endif diff --git a/include/commands_parser.h b/include/commands_parser.h index 37c4d4b1..6e531e9b 100644 --- a/include/commands_parser.h +++ b/include/commands_parser.h @@ -7,22 +7,17 @@ * commands.c: all command functions (see commands_parser.c) * */ -#ifndef I3_COMMANDS_PARSER_H -#define I3_COMMANDS_PARSER_H +#pragma once #include /* - * Holds the result of a call to any command. When calling - * parse_command("floating enable, border none"), the parser will internally - * use a struct CommandResult when calling cmd_floating and cmd_border. - * parse_command will also return another struct CommandResult, whose - * json_output is set to a map of individual json_outputs and whose - * needs_tree_trender is true if any individual needs_tree_render was true. - * + * Holds an intermediate represenation of the result of a call to any command. + * When calling parse_command("floating enable, border none"), the parser will + * internally use this struct when calling cmd_floating and cmd_border. */ -struct CommandResult { - /* The JSON generator to append a reply to. */ +struct CommandResultIR { + /* The JSON generator to append a reply to (may be NULL). */ yajl_gen json_gen; /* The next state to transition to. Passed to the function so that we can @@ -34,6 +29,31 @@ struct CommandResult { bool needs_tree_render; }; -struct CommandResult *parse_command(const char *input); +typedef struct CommandResult CommandResult; -#endif +/** + * A struct that contains useful information about the result of a command as a + * whole (e.g. a compound command like "floating enable, border none"). + * needs_tree_render is true if needs_tree_render of any individual command was + * true. + */ +struct CommandResult { + bool parse_error; + /* the error_message is currently only set for parse errors */ + char *error_message; + bool needs_tree_render; +}; + +/** + * Parses and executes the given command. If a caller-allocated yajl_gen is + * passed, a json reply will be generated in the format specified by the ipc + * protocol. Pass NULL if no json reply is required. + * + * Free the returned CommandResult with command_result_free(). + */ +CommandResult *parse_command(const char *input, yajl_gen gen); + +/** + * Frees a CommandResult + */ +void command_result_free(CommandResult *result); diff --git a/include/con.h b/include/con.h index ec4ae352..b8fd60ad 100644 --- a/include/con.h +++ b/include/con.h @@ -9,8 +9,7 @@ * …). * */ -#ifndef I3_CON_H -#define I3_CON_H +#pragma once /** * Create a new container (and attach it to the given parent, if not NULL). @@ -38,6 +37,12 @@ void con_focus(Con *con); */ bool con_is_leaf(Con *con); +/** + * Returns true when this con is a leaf node with a managed X11 window (e.g., + * excluding dock containers) + */ +bool con_has_managed_window(Con *con); + /* * Returns true if a container should be considered split. * @@ -81,7 +86,7 @@ Con *con_parent_with_orientation(Con *con, orientation_t orientation); * Returns the first fullscreen node below this node. * */ -Con *con_get_fullscreen_con(Con *con, int fullscreen_mode); +Con *con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode); /** * Returns true if the container is internal, such as __i3_scratch @@ -193,7 +198,7 @@ void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool * container). * */ -int con_orientation(Con *con); +orientation_t con_orientation(Con *con); /** * Returns the container which will be focused next when the given container @@ -340,5 +345,3 @@ void con_set_urgency(Con *con, bool urgent); * */ char *con_get_tree_representation(Con *con); - -#endif diff --git a/include/config.h b/include/config.h index 4267dcfe..71b37a80 100644 --- a/include/config.h +++ b/include/config.h @@ -10,8 +10,7 @@ * bindings mode). * */ -#ifndef I3_CONFIG_H -#define I3_CONFIG_H +#pragma once #include #include "queue.h" @@ -99,6 +98,7 @@ struct Config { int container_stack_limit; int container_stack_limit_value; int default_border_width; + int default_floating_border_width; /** Default orientation for new containers */ int default_orientation; @@ -109,6 +109,16 @@ struct Config { * It is not planned to add any different focus models. */ bool disable_focus_follows_mouse; + /** By default, when switching focus to a window on a different output + * (e.g. focusing a window on workspace 3 on output VGA-1, coming from + * workspace 2 on LVDS-1), the mouse cursor is warped to the center of + * that window. + * + * With the mouse_warping option, you can control when the mouse cursor + * should be warped. "none" disables warping entirely, whereas "output" + * is the default behavior described above. */ + warping_t mouse_warping; + /** Remove borders if they are adjacent to the screen edge. * This is useful if you are reaching scrollbar on the edge of the * screen or do not want to waste a single pixel of displayspace. @@ -180,6 +190,7 @@ struct Config { struct Colortriple focused_inactive; struct Colortriple unfocused; struct Colortriple urgent; + struct Colortriple placeholder; } client; struct config_bar { struct Colortriple focused; @@ -267,6 +278,10 @@ struct Barconfig { * zero. */ bool hide_workspace_buttons; + /** Strip workspace numbers? Configuration option is + * 'strip_workspace_numbers yes'. */ + bool strip_workspace_numbers; + /** Hide mode button? Configuration option is 'binding_mode_indicator no' * but we invert the bool for the same reason as hide_workspace_buttons.*/ bool hide_binding_mode_indicator; @@ -308,12 +323,6 @@ struct Barconfig { */ void load_configuration(xcb_connection_t *conn, const char *override_configfile, bool reload); -/** - * Translates keysymbols to keycodes for all bindings which use keysyms. - * - */ -void translate_keysyms(void); - /** * Ungrabs all keys, to be called before re-grabbing the keys because of a * mapping_notify event or a configuration file reload @@ -321,30 +330,11 @@ void translate_keysyms(void); */ void ungrab_all_keys(xcb_connection_t *conn); -/** - * Grab the bound keys (tell X to send us keypress events for those keycodes) - * - */ -void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch); - -/** - * Switches the key bindings to the given mode, if the mode exists - * - */ -void switch_mode(const char *new_mode); - /** * Sends the current bar configuration as an event to all barconfig_update listeners. - * This update mechnism currently only includes the hidden_state and the mode in the config. - * - */void update_barconfig(); - -/** - * Returns a pointer to the Binding with the specified modifiers and keycode - * or NULL if no such binding exists. * */ -Binding *get_binding(uint16_t modifiers, bool key_release, xcb_keycode_t keycode); +void update_barconfig(); /** * Kills the configerror i3-nagbar process, if any. @@ -356,5 +346,3 @@ Binding *get_binding(uint16_t modifiers, bool key_release, xcb_keycode_t keycode * */ void kill_configerror_nagbar(bool wait_for_it); - -#endif diff --git a/include/config_directives.h b/include/config_directives.h index 9569a7b0..9dedad15 100644 --- a/include/config_directives.h +++ b/include/config_directives.h @@ -7,13 +7,18 @@ * config_directives.h: all config storing functions (see config_parser.c) * */ -#ifndef I3_CONFIG_DIRECTIVES_H -#define I3_CONFIG_DIRECTIVES_H +#pragma once #include "config_parser.h" +/** + * A utility function to convert a string of modifiers to the corresponding bit + * mask. + */ +uint32_t modifiers_from_str(const char *str); + /** The beginning of the prototype for every cfg_ function. */ -#define I3_CFG Match *current_match, struct ConfigResult *result +#define I3_CFG Match *current_match, struct ConfigResultIR *result /* Defines a configuration function, that is, anything that can be called by * using 'call cfg_foo()' in parser-specs/.*.spec. Useful so that we don’t need @@ -41,6 +46,7 @@ CFGFUN(default_orientation, const char *orientation); CFGFUN(workspace_layout, const char *layout); CFGFUN(workspace_back_and_forth, const char *value); CFGFUN(focus_follows_mouse, const char *value); +CFGFUN(mouse_warping, const char *value); CFGFUN(force_focus_wrapping, const char *value); CFGFUN(force_xinerama, const char *value); CFGFUN(fake_outputs, const char *outputs); @@ -76,6 +82,5 @@ CFGFUN(bar_color_single, const char *colorclass, const char *color); CFGFUN(bar_status_command, const char *command); CFGFUN(bar_binding_mode_indicator, const char *value); CFGFUN(bar_workspace_buttons, const char *value); +CFGFUN(bar_strip_workspace_numbers, const char *value); CFGFUN(bar_finish); - -#endif diff --git a/include/config_parser.h b/include/config_parser.h index fb863f3b..e18e5cf2 100644 --- a/include/config_parser.h +++ b/include/config_parser.h @@ -7,19 +7,19 @@ * config_parser.h: config parser-related definitions * */ -#ifndef I3_CONFIG_PARSER_H -#define I3_CONFIG_PARSER_H +#pragma once #include extern pid_t config_error_nagbar_pid; /* - * The result of a parse_config call. Currently unused, but the JSON output - * will be useful in the future when we implement a config parsing IPC command. + * An intermediate reprsentation of the result of a parse_config call. + * Currently unused, but the JSON output will be useful in the future when we + * implement a config parsing IPC command. * */ -struct ConfigResult { +struct ConfigResultIR { /* The JSON generator to append a reply to. */ yajl_gen json_gen; @@ -29,7 +29,7 @@ struct ConfigResult { int next_state; }; -struct ConfigResult *parse_config(const char *input, struct context *context); +struct ConfigResultIR *parse_config(const char *input, struct context *context); /** * Parses the given file by first replacing the variables, then calling @@ -37,5 +37,3 @@ struct ConfigResult *parse_config(const char *input, struct context *context); * */ void parse_file(const char *f); - -#endif diff --git a/include/data.h b/include/data.h index ea1d3240..6ac228ec 100644 --- a/include/data.h +++ b/include/data.h @@ -7,8 +7,7 @@ * include/data.h: This file defines all data structures used by i3 * */ -#ifndef I3_DATA_H -#define I3_DATA_H +#pragma once #define SN_API_NOT_YET_FROZEN 1 #include @@ -92,6 +91,22 @@ typedef enum { L_SPLITH = 6 } layout_t; +/** + * Binding input types. See Binding::input_type. + */ +typedef enum { + B_KEYBOARD = 0, + B_MOUSE = 1 +} input_type_t; + +/** + * Mouse pointer warping modes. + */ +typedef enum { + POINTER_WARPING_OUTPUT = 0, + POINTER_WARPING_NONE = 1 +} warping_t; + /** * Stores a rectangle, for example the size of a window, the child window etc. * It needs to be packed so that the compiler will not add any padding bytes. @@ -151,7 +166,7 @@ struct deco_render_params { }; /** - * Stores which workspace (by name) goes to which output. + * Stores which workspace (by name or number) goes to which output. * */ struct Workspace_Assignment { @@ -214,6 +229,10 @@ struct regex { * */ struct Binding { + /* The type of input this binding is for. (Mouse bindings are not yet + * implemented. All bindings are currently assumed to be keyboard bindings.) */ + input_type_t input_type; + /** If true, the binding should be executed upon a KeyRelease event, not a * KeyPress (the default). */ enum { @@ -374,7 +393,7 @@ struct Match { struct regex *class; struct regex *instance; struct regex *mark; - struct regex *role; + struct regex *window_role; enum { U_DONTCHECK = -1, U_LATEST = 0, @@ -450,6 +469,9 @@ struct Assignment { TAILQ_ENTRY(Assignment) assignments; }; +/** Fullscreen modes. Used by Con.fullscreen_mode. */ +typedef enum { CF_NONE = 0, CF_OUTPUT = 1, CF_GLOBAL = 2 } fullscreen_mode_t; + /** * A 'Con' represents everything from the X11 root window down to a single X11 window. * @@ -538,7 +560,7 @@ struct Con { TAILQ_HEAD(swallow_head, Match) swallow_head; - enum { CF_NONE = 0, CF_OUTPUT = 1, CF_GLOBAL = 2 } fullscreen_mode; + fullscreen_mode_t fullscreen_mode; /* layout is the layout of this container: one of split[v|h], stacked or * tabbed. Special containers in the tree (above workspaces) have special * layouts like dockarea or output. @@ -595,5 +617,3 @@ struct Con { /* Depth of the container window */ uint16_t depth; }; - -#endif diff --git a/include/debug.h b/include/debug.h index 44c95c6d..3e65c35e 100644 --- a/include/debug.h +++ b/include/debug.h @@ -8,9 +8,6 @@ * events. This code is from xcb-util. * */ -#ifndef I3_DEBUG_H -#define I3_DEBUG_H +#pragma once int handle_event(void *ignored, xcb_connection_t *c, xcb_generic_event_t *e); - -#endif diff --git a/include/display_version.h b/include/display_version.h index 88a1abc1..6f88ae97 100644 --- a/include/display_version.h +++ b/include/display_version.h @@ -7,8 +7,7 @@ * display_version.c: displays the running i3 version, runs as part of * i3 --moreversion. */ -#ifndef I3_DISPLAY_VERSION_H -#define I3_DISPLAY_VERSION_H +#pragma once /** * Connects to i3 to find out the currently running version. Useful since it @@ -23,5 +22,3 @@ * */ void display_running_version(void); - -#endif diff --git a/include/ewmh.h b/include/ewmh.h index c36eaeb0..46d6c985 100644 --- a/include/ewmh.h +++ b/include/ewmh.h @@ -7,8 +7,7 @@ * ewmh.c: Get/set certain EWMH properties easily. * */ -#ifndef I3_EWMH_C -#define I3_EWMH_C +#pragma once /** * Updates _NET_CURRENT_DESKTOP with the current desktop number. @@ -28,6 +27,11 @@ void ewmh_update_current_desktop(void); */ void ewmh_update_active_window(xcb_window_t window); +/** + * Updates the _NET_CLIENT_LIST hint. Used for window listers. + */ +void ewmh_update_client_list(xcb_window_t *list, int num_windows); + /** * Updates the _NET_CLIENT_LIST_STACKING hint. Necessary to move tabs in * Chromium correctly. @@ -62,5 +66,3 @@ void ewmh_setup_hints(void); * */ void ewmh_update_workarea(void); - -#endif diff --git a/include/fake_outputs.h b/include/fake_outputs.h index bfeba292..75ef77ba 100644 --- a/include/fake_outputs.h +++ b/include/fake_outputs.h @@ -8,8 +8,7 @@ * which don’t support multi-monitor in a useful way) and for our testsuite. * */ -#ifndef I3_FAKE_OUTPUTS_H -#define I3_FAKE_OUTPUTS_H +#pragma once /** * Creates outputs according to the given specification. @@ -19,5 +18,3 @@ * */ void fake_outputs_init(const char *output_spec); - -#endif diff --git a/include/floating.h b/include/floating.h index 43600187..fa3bdcc3 100644 --- a/include/floating.h +++ b/include/floating.h @@ -7,8 +7,7 @@ * floating.c: Floating windows. * */ -#ifndef I3_FLOATING_H -#define I3_FLOATING_H +#pragma once #include "tree.h" @@ -183,5 +182,3 @@ void floating_reposition(Con *con, Rect newrect); * */ void floating_fix_coordinates(Con *con, Rect *old_rect, Rect *new_rect); - -#endif diff --git a/include/handlers.h b/include/handlers.h index b2e7ce2e..db7d06b5 100644 --- a/include/handlers.h +++ b/include/handlers.h @@ -8,8 +8,7 @@ * …). * */ -#ifndef I3_HANDLERS_H -#define I3_HANDLERS_H +#pragma once #include @@ -63,5 +62,3 @@ int handle_window_type(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *property); #endif - -#endif diff --git a/include/i3.h b/include/i3.h index 1bc8b55d..4ed0d8d5 100644 --- a/include/i3.h +++ b/include/i3.h @@ -7,8 +7,7 @@ * i3.h: global variables that are used all over i3. * */ -#ifndef I3_I3_H -#define I3_I3_H +#pragma once #include #include @@ -62,5 +61,3 @@ extern bool xcursor_supported, xkb_supported; extern xcb_window_t root; extern struct ev_loop *main_loop; extern bool only_check_config; - -#endif diff --git a/include/i3/ipc.h b/include/i3/ipc.h index 6a50ccc8..94a39904 100644 --- a/include/i3/ipc.h +++ b/include/i3/ipc.h @@ -8,8 +8,7 @@ * for the IPC interface to i3 (see docs/ipc for more information). * */ -#ifndef I3_I3_IPC_H -#define I3_I3_IPC_H +#pragma once #include @@ -101,5 +100,3 @@ typedef struct i3_ipc_header { /** Bar config update will be triggered to update the bar config */ #define I3_IPC_EVENT_BARCONFIG_UPDATE (I3_IPC_EVENT_MASK | 4) - -#endif diff --git a/include/ipc.h b/include/ipc.h index dfb12b9b..418b040f 100644 --- a/include/ipc.h +++ b/include/ipc.h @@ -7,8 +7,7 @@ * ipc.c: UNIX domain socket IPC (initialization, client handling, protocol). * */ -#ifndef I3_IPC_H -#define I3_IPC_H +#pragma once #include #include @@ -17,6 +16,7 @@ #include "data.h" #include "tree.h" +#include "config.h" #include "i3/ipc.h" @@ -89,4 +89,13 @@ void dump_node(yajl_gen gen, Con *con, bool inplace_restart); */ void ipc_send_workspace_focus_event(Con *current, Con *old); -#endif +/** + * For the window events we send, along the usual "change" field, + * also the window container, in "container". + */ +void ipc_send_window_event(const char *property, Con *con); + +/** + * For the barconfig update events, we send the serialized barconfig. + */ +void ipc_send_barconfig_update_event(Barconfig *barconfig); diff --git a/include/key_press.h b/include/key_press.h index b231b8f5..9712e8b9 100644 --- a/include/key_press.h +++ b/include/key_press.h @@ -7,10 +7,7 @@ * key_press.c: key press handler * */ -#ifndef I3_KEY_PRESS_H -#define I3_KEY_PRESS_H - -extern pid_t command_error_nagbar_pid; +#pragma once /** * There was a key press. We compare this key code with our bindings table and pass @@ -30,5 +27,3 @@ void handle_key_press(xcb_key_press_event_t *event); * */ void kill_commanderror_nagbar(bool wait_for_it); - -#endif diff --git a/include/libi3.h b/include/libi3.h index 8c580da8..dc5d537f 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -8,8 +8,7 @@ * as i3-msg, i3-config-wizard, … * */ -#ifndef I3_LIBI3_H -#define I3_LIBI3_H +#pragma once #include #include @@ -383,4 +382,10 @@ char *get_process_filename(const char *prefix); */ char *get_exe_path(const char *argv0); -#endif +/** + * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI + * screen) to a corresponding amount of physical pixels on a standard or retina + * screen, e.g. 5 pixels on a 227 DPI MacBook Pro 13" Retina screen. + * + */ +int logical_px(const int logical); diff --git a/include/load_layout.h b/include/load_layout.h index 282512b2..a598c8c6 100644 --- a/include/load_layout.h +++ b/include/load_layout.h @@ -8,9 +8,6 @@ * restart. * */ -#ifndef I3_LOAD_LAYOUT_H -#define I3_LOAD_LAYOUT_H +#pragma once -void tree_append_json(const char *filename); - -#endif +void tree_append_json(Con *con, const char *filename, char **errormsg); diff --git a/include/log.h b/include/log.h index ef4dbd3c..2400092b 100644 --- a/include/log.h +++ b/include/log.h @@ -7,8 +7,7 @@ * log.c: Logging functions. * */ -#ifndef I3_LOG_H -#define I3_LOG_H +#pragma once #include #include @@ -102,5 +101,3 @@ void verboselog(char *fmt, ...) * failures. This function is invoked automatically when exiting. */ void purge_zerobyte_logfile(void); - -#endif diff --git a/include/main.h b/include/main.h new file mode 100644 index 00000000..18c6e374 --- /dev/null +++ b/include/main.h @@ -0,0 +1,18 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * i3 - an improved dynamic tiling window manager + * © 2009-2013 Michael Stapelberg and contributors (see also: LICENSE) + * + * main.c: Initialization, main loop + * + */ +#pragma once + +/** + * Enable or disable the main X11 event handling function. + * This is used by drag_pointer() which has its own, modal event handler, which + * takes precedence over the normal event handler. + * + */ +void main_set_x11_cb(bool enable); diff --git a/include/manage.h b/include/manage.h index d50f64d4..bd1a14f7 100644 --- a/include/manage.h +++ b/include/manage.h @@ -7,8 +7,7 @@ * manage.c: Initially managing new windows (or existing ones on restart). * */ -#ifndef I3_MANAGE_H -#define I3_MANAGE_H +#pragma once #include "data.h" @@ -52,4 +51,3 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, uint32_t border_width); #endif -#endif diff --git a/include/match.h b/include/match.h index e1d25904..09975cac 100644 --- a/include/match.h +++ b/include/match.h @@ -11,8 +11,7 @@ * match_matches_window() to find the windows affected by this command. * */ -#ifndef I3_MATCH_H -#define I3_MATCH_H +#pragma once /* * Initializes the Match data structure. This function is necessary because the @@ -46,5 +45,3 @@ bool match_matches_window(Match *match, i3Window *window); * */ void match_free(Match *match); - -#endif diff --git a/include/move.h b/include/move.h index d45e676e..5c8a7d20 100644 --- a/include/move.h +++ b/include/move.h @@ -7,8 +7,7 @@ * move.c: Moving containers into some direction. * */ -#ifndef I3_MOVE_H -#define I3_MOVE_H +#pragma once /** * Moves the current container in the given direction (TOK_LEFT, TOK_RIGHT, @@ -16,5 +15,3 @@ * */ void tree_move(int direction); - -#endif diff --git a/include/output.h b/include/output.h index e87da22e..10ee7d17 100644 --- a/include/output.h +++ b/include/output.h @@ -7,13 +7,10 @@ * output.c: Output (monitor) related functions. * */ -#ifndef I3_OUTPUT_H -#define I3_OUTPUT_H +#pragma once /** * Returns the output container below the given output container. * */ Con *output_get_content(Con *output); - -#endif diff --git a/include/queue.h b/include/queue.h index 0c685215..2307149b 100644 --- a/include/queue.h +++ b/include/queue.h @@ -32,8 +32,7 @@ * @(#)queue.h 8.5 (Berkeley) 8/20/94 */ -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ +#pragma once /* * This file defines five types of data structures: singly-linked lists, @@ -536,5 +535,3 @@ struct { \ _Q_INVALIDATE((elm)->field.cqe_prev); \ _Q_INVALIDATE((elm)->field.cqe_next); \ } while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/include/randr.h b/include/randr.h index dadcfd64..43f7efe8 100644 --- a/include/randr.h +++ b/include/randr.h @@ -9,8 +9,7 @@ * (take your time to read it completely, it answers all questions). * */ -#ifndef I3_RANDR_H -#define I3_RANDR_H +#pragma once #include "data.h" #include @@ -85,7 +84,7 @@ Output *get_output_by_name(const char *name); * if there is no output which contains these coordinates. * */ -Output *get_output_containing(int x, int y); +Output *get_output_containing(unsigned int x, unsigned int y); /* * In contained_by_output, we check if any active output contains part of the container. @@ -121,5 +120,3 @@ Output *get_output_next(direction_t direction, Output *current, output_close_far * */ Output *get_output_next_wrap(direction_t direction, Output *current); - -#endif diff --git a/include/regex.h b/include/regex.h index 7403abef..e11d377e 100644 --- a/include/regex.h +++ b/include/regex.h @@ -7,8 +7,7 @@ * regex.c: Interface to libPCRE (perl compatible regular expressions). * */ -#ifndef I3_REGEX_H -#define I3_REGEX_H +#pragma once /** * Creates a new 'regex' struct containing the given pattern and a PCRE @@ -35,5 +34,3 @@ void regex_free(struct regex *regex); * */ bool regex_matches(struct regex *regex, const char *input); - -#endif diff --git a/include/render.h b/include/render.h index a0eca01a..1794b513 100644 --- a/include/render.h +++ b/include/render.h @@ -8,8 +8,7 @@ * various rects. Needs to be pushed to X11 (see x.c) to be visible. * */ -#ifndef I3_RENDER_H -#define I3_RENDER_H +#pragma once /** * "Renders" the given container (and its children), meaning that all rects are @@ -25,5 +24,3 @@ void render_con(Con *con, bool render_fullscreen); * Returns the height for the decorations */ int render_deco_height(void); - -#endif diff --git a/include/resize.h b/include/resize.h index ae26ee99..5c795046 100644 --- a/include/resize.h +++ b/include/resize.h @@ -7,11 +7,8 @@ * resize.c: Interactive resizing. * */ -#ifndef I3_RESIZE_H -#define I3_RESIZE_H +#pragma once bool resize_find_tiling_participants(Con **current, Con **other, direction_t direction); int resize_graphical_handler(Con *first, Con *second, orientation_t orientation, const xcb_button_press_event_t *event); - -#endif diff --git a/include/restore_layout.h b/include/restore_layout.h new file mode 100644 index 00000000..3f0229d3 --- /dev/null +++ b/include/restore_layout.h @@ -0,0 +1,38 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * i3 - an improved dynamic tiling window manager + * © 2009-2013 Michael Stapelberg and contributors (see also: LICENSE) + * + * restore_layout.c: Everything for restored containers that is not pure state + * parsing (which can be found in load_layout.c). + * + */ +#pragma once + +/** + * Opens a separate connection to X11 for placeholder windows when restoring + * layouts. This is done as a safety measure (users can xkill a placeholder + * window without killing their window manager) and for better isolation, both + * on the wire to X11 and thus also in the code. + * + */ +void restore_connect(void); + +/** + * Open placeholder windows for all children of parent. The placeholder window + * will vanish as soon as a real window is swallowed by the container. Until + * then, it exposes the criteria that must be fulfilled for a window to be + * swallowed by this container. + * + */ +void restore_open_placeholder_windows(Con *con); + +/** + * Kill the placeholder window, if placeholder refers to a placeholder window. + * This function is called when manage.c puts a window into an existing + * container. In order not to leak resources, we need to destroy the window and + * all associated X11 objects (pixmap/gc). + * + */ +bool restore_kill_placeholder(xcb_window_t placeholder); diff --git a/include/scratchpad.h b/include/scratchpad.h index c6157052..1aca73bd 100644 --- a/include/scratchpad.h +++ b/include/scratchpad.h @@ -7,8 +7,7 @@ * scratchpad.c: Scratchpad functions (TODO: more description) * */ -#ifndef I3_SCRATCHPAD_H -#define I3_SCRATCHPAD_H +#pragma once /** * Moves the specified window to the __i3_scratch workspace, making it floating @@ -39,5 +38,3 @@ void scratchpad_show(Con *con); * */ void scratchpad_fix_resolution(void); - -#endif diff --git a/include/sd-daemon.h b/include/sd-daemon.h index 4b853a15..8746a3ad 100644 --- a/include/sd-daemon.h +++ b/include/sd-daemon.h @@ -1,7 +1,6 @@ /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ -#ifndef foosddaemonhfoo -#define foosddaemonhfoo +#pragma once /*** Copyright 2010 Lennart Poettering @@ -261,5 +260,3 @@ int sd_booted(void) _sd_hidden_; #ifdef __cplusplus } #endif - -#endif diff --git a/include/shmlog.h b/include/shmlog.h index 94da2bdb..5af697e7 100644 --- a/include/shmlog.h +++ b/include/shmlog.h @@ -8,8 +8,7 @@ * default (ringbuffer for storing the debug log). * */ -#ifndef I3_I3_SHMLOG_H -#define I3_I3_SHMLOG_H +#pragma once #include #include @@ -43,5 +42,3 @@ typedef struct i3_shmlog_header { * tail -f) in an efficient way. */ pthread_cond_t condvar; } i3_shmlog_header; - -#endif diff --git a/include/sighandler.h b/include/sighandler.h index 25d3385b..184db73b 100644 --- a/include/sighandler.h +++ b/include/sighandler.h @@ -9,13 +9,10 @@ * to restart inplace). * */ -#ifndef I3_SIGHANDLER_H -#define I3_SIGHANDLER_H +#pragma once /** * Setup signal handlers to safely handle SIGSEGV and SIGFPE * */ void setup_signal_handler(void); - -#endif diff --git a/include/startup.h b/include/startup.h index e39fe63b..fb017103 100644 --- a/include/startup.h +++ b/include/startup.h @@ -10,8 +10,7 @@ * the appropriate workspace. * */ -#ifndef I3_STARTUP_H -#define I3_STARTUP_H +#pragma once #define SN_API_NOT_YET_FROZEN 1 #include @@ -62,5 +61,3 @@ struct Startup_Sequence *startup_sequence_get(i3Window *cwindow, * */ char *startup_workspace_for_window(i3Window *cwindow, xcb_get_property_reply_t *startup_id_reply); - -#endif diff --git a/include/tree.h b/include/tree.h index 2799afee..b3c2a515 100644 --- a/include/tree.h +++ b/include/tree.h @@ -7,8 +7,7 @@ * tree.c: Everything that primarily modifies the layout tree data structure. * */ -#ifndef I3_TREE_H -#define I3_TREE_H +#pragma once extern Con *croot; /* TODO: i am not sure yet how much access to the focused container should @@ -105,5 +104,3 @@ bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry); * */ void tree_flatten(Con *child); - -#endif diff --git a/include/util.h b/include/util.h index 61a38f3e..514a47c2 100644 --- a/include/util.h +++ b/include/util.h @@ -8,8 +8,7 @@ * also libi3). * */ -#ifndef I3_UTIL_H -#define I3_UTIL_H +#pragma once #include @@ -58,6 +57,20 @@ int min(int a, int b); int max(int a, int b); bool rect_contains(Rect rect, uint32_t x, uint32_t y); Rect rect_add(Rect a, Rect b); +Rect rect_sub(Rect a, Rect b); + +/** + * Returns true if the name consists of only digits. + * + */ +__attribute__((pure)) bool name_is_digits(const char *name); + +/** + * Parses the workspace name as a number. Returns -1 if the workspace should be + * interpreted as a "named workspace". + * + */ +long ws_name_to_number(const char *name); /** * Updates *destination with new_value and returns true if it was changed or false @@ -141,5 +154,3 @@ void start_nagbar(pid_t *nagbar_pid, char *argv[]); * */ void kill_nagbar(pid_t *nagbar_pid, bool wait_for_it); - -#endif diff --git a/include/window.h b/include/window.h index abc27d6a..480cee18 100644 --- a/include/window.h +++ b/include/window.h @@ -7,8 +7,7 @@ * window.c: Updates window attributes (X11 hints/properties). * */ -#ifndef I3_WINDOW_H -#define I3_WINDOW_H +#pragma once /** * Updates the WM_CLASS (consisting of the class and instance) for the @@ -63,4 +62,16 @@ void window_update_role(i3Window *win, xcb_get_property_reply_t *prop, bool befo */ void window_update_hints(i3Window *win, xcb_get_property_reply_t *prop, bool *urgency_hint); -#endif +/** + * Updates the MOTIF_WM_HINTS. The container's border style should be set to + * `motif_border_style' if border style is not BS_NORMAL. + * + * i3 only uses this hint when it specifies a window should have no + * title bar, or no decorations at all, which is how most window managers + * handle it. + * + * The EWMH spec intended to replace Motif hints with _NET_WM_WINDOW_TYPE, but + * it is still in use by popular widget toolkits such as GTK+ and Java AWT. + * + */ +void window_update_motif_hints(i3Window *win, xcb_get_property_reply_t *prop, border_style_t *motif_border_style); diff --git a/include/workspace.h b/include/workspace.h index 907e959f..463ccf19 100644 --- a/include/workspace.h +++ b/include/workspace.h @@ -8,8 +8,7 @@ * workspaces. * */ -#ifndef I3_WORKSPACE_H -#define I3_WORKSPACE_H +#pragma once #include "data.h" #include "tree.h" @@ -181,4 +180,3 @@ Con *workspace_attach_to(Con *ws); * The container inherits the layout from the workspace. */ Con *workspace_encapsulate(Con *ws); -#endif diff --git a/include/x.h b/include/x.h index f1fa7e6a..07f8a725 100644 --- a/include/x.h +++ b/include/x.h @@ -8,8 +8,7 @@ * render.c). Basically a big state machine. * */ -#ifndef I3_X_H -#define I3_X_H +#pragma once /** Stores the X11 window ID of the currently focused window */ extern xcb_window_t focused_id; @@ -130,5 +129,3 @@ void x_set_warp_to(Rect *rect); * */ void x_mask_event_mask(uint32_t mask); - -#endif diff --git a/include/xcb.h b/include/xcb.h index 54013569..4df7f639 100644 --- a/include/xcb.h +++ b/include/xcb.h @@ -7,8 +7,7 @@ * xcb.c: Helper functions for easier usage of XCB * */ -#ifndef I3_XCB_H -#define I3_XCB_H +#pragma once #include "data.h" #include "xcursor.h" @@ -95,7 +94,7 @@ void fake_absolute_configure_notify(Con *con); * Sends the WM_TAKE_FOCUS ClientMessage to the given window * */ -void send_take_focus(xcb_window_t window); +void send_take_focus(xcb_window_t window, xcb_timestamp_t timestamp); /** * Raises the given window (typically client->frame) above all other windows @@ -137,5 +136,3 @@ uint16_t get_visual_depth(xcb_visualid_t visual_id); * */ xcb_visualid_t get_visualid_by_depth(uint16_t depth); - -#endif diff --git a/include/xcb_compat.h b/include/xcb_compat.h index fc09a254..89c2c457 100644 --- a/include/xcb_compat.h +++ b/include/xcb_compat.h @@ -9,8 +9,7 @@ * older versions. * */ -#ifndef I3_XCB_COMPAT_H -#define I3_XCB_COMPAT_H +#pragma once #define xcb_icccm_get_wm_protocols_reply_t xcb_get_wm_protocols_reply_t #define xcb_icccm_get_wm_protocols xcb_get_wm_protocols @@ -20,9 +19,12 @@ #define XCB_ICCCM_WM_STATE_NORMAL XCB_WM_STATE_NORMAL #define XCB_ICCCM_WM_STATE_WITHDRAWN XCB_WM_STATE_WITHDRAWN #define xcb_icccm_get_wm_size_hints_from_reply xcb_get_wm_size_hints_from_reply +#define xcb_icccm_get_wm_size_hints_reply xcb_get_wm_size_hints_reply +#define xcb_icccm_get_wm_normal_hints xcb_get_wm_normal_hints #define xcb_icccm_get_wm_normal_hints_reply xcb_get_wm_normal_hints_reply #define xcb_icccm_get_wm_normal_hints_unchecked xcb_get_wm_normal_hints_unchecked #define XCB_ICCCM_SIZE_HINT_P_MIN_SIZE XCB_SIZE_HINT_P_MIN_SIZE +#define XCB_ICCCM_SIZE_HINT_P_MAX_SIZE XCB_SIZE_HINT_P_MAX_SIZE #define XCB_ICCCM_SIZE_HINT_P_RESIZE_INC XCB_SIZE_HINT_P_RESIZE_INC #define XCB_ICCCM_SIZE_HINT_BASE_SIZE XCB_SIZE_HINT_BASE_SIZE #define XCB_ICCCM_SIZE_HINT_P_ASPECT XCB_SIZE_HINT_P_ASPECT @@ -43,5 +45,3 @@ #define XCB_ATOM_ATOM ATOM #define XCB_ATOM_WM_NORMAL_HINTS WM_NORMAL_HINTS #define XCB_ATOM_STRING STRING - -#endif diff --git a/include/xcursor.h b/include/xcursor.h index 868fee78..bb329e4c 100644 --- a/include/xcursor.h +++ b/include/xcursor.h @@ -7,8 +7,7 @@ * xcursor.c: libXcursor support for themed cursors. * */ -#ifndef I3_XCURSOR_CURSOR_H -#define I3_XCURSOR_CURSOR_H +#pragma once #include @@ -41,5 +40,3 @@ int xcursor_get_xcb_cursor(enum xcursor_cursor_t c); * */ void xcursor_set_root_cursor(int cursor_id); - -#endif diff --git a/include/xinerama.h b/include/xinerama.h index ca7c2ab5..46c2a635 100644 --- a/include/xinerama.h +++ b/include/xinerama.h @@ -9,8 +9,7 @@ * driver which does not support RandR in 2011 *sigh*. * */ -#ifndef I3_XINERAMA_H -#define I3_XINERAMA_H +#pragma once #include "data.h" @@ -20,5 +19,3 @@ * */ void xinerama_init(void); - -#endif diff --git a/include/yajl_utils.h b/include/yajl_utils.h index d8a53d3a..747e0ca0 100644 --- a/include/yajl_utils.h +++ b/include/yajl_utils.h @@ -7,8 +7,7 @@ * yajl_utils.h * */ -#ifndef I3_YAJL_UTILS_H -#define I3_YAJL_UTILS_H +#pragma once #include #include @@ -18,14 +17,6 @@ #define y(x, ...) yajl_gen_ ## x (gen, ##__VA_ARGS__) #define ystr(str) yajl_gen_string(gen, (unsigned char*)str, strlen(str)) -#if YAJL_MAJOR >= 2 #define ygenalloc() yajl_gen_alloc(NULL) #define yalloc(callbacks, client) yajl_alloc(callbacks, NULL, client) typedef size_t ylength; -#else -#define ygenalloc() yajl_gen_alloc(NULL, NULL); -#define yalloc(callbacks, client) yajl_alloc(callbacks, NULL, NULL, client) -typedef unsigned int ylength; -#endif - -#endif diff --git a/libi3/dpi.c b/libi3/dpi.c new file mode 100644 index 00000000..090a6560 --- /dev/null +++ b/libi3/dpi.c @@ -0,0 +1,16 @@ +#include "libi3.h" +#include + +extern xcb_screen_t *root_screen; + +/* + * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI + * screen) to a corresponding amount of physical pixels on a standard or retina + * screen, e.g. 5 pixels on a 227 DPI MacBook Pro 13" Retina screen. + * + */ +int logical_px(const int logical) { + const int dpi = (double)root_screen->height_in_pixels * 25.4 / + (double)root_screen->height_in_millimeters; + return ceil((dpi / 96.0) * logical); +} diff --git a/libi3/fake_configure_notify.c b/libi3/fake_configure_notify.c index 472d2351..2c0f5771 100644 --- a/libi3/fake_configure_notify.c +++ b/libi3/fake_configure_notify.c @@ -39,7 +39,7 @@ void fake_configure_notify(xcb_connection_t *conn, xcb_rectangle_t r, xcb_window generated_event->above_sibling = XCB_NONE; generated_event->override_redirect = false; - xcb_send_event(conn, false, window, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char*)generated_event); + xcb_send_event(conn, false, window, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *)generated_event); xcb_flush(conn); free(event); diff --git a/libi3/font.c b/libi3/font.c index e1e5b826..fc868e60 100644 --- a/libi3/font.c +++ b/libi3/font.c @@ -69,8 +69,7 @@ static bool load_pango_font(i3Font *font, const char *desc) { LOG("Using Pango font %s, size %d\n", pango_font_description_get_family(font->specific.pango_desc), - pango_font_description_get_size(font->specific.pango_desc) / PANGO_SCALE - ); + pango_font_description_get_size(font->specific.pango_desc) / PANGO_SCALE); /* We cache root_visual_type here, since you must call * load_pango_font before any other pango function @@ -103,11 +102,11 @@ static bool load_pango_font(i3Font *font, const char *desc) { * */ static void draw_text_pango(const char *text, size_t text_len, - xcb_drawable_t drawable, int x, int y, int max_width) { + xcb_drawable_t drawable, int x, int y, int max_width) { /* Create the Pango layout */ /* root_visual_type is cached in load_pango_font */ cairo_surface_t *surface = cairo_xcb_surface_create(conn, drawable, - root_visual_type, x + max_width, y + savedFont->height); + root_visual_type, x + max_width, y + savedFont->height); cairo_t *cr = cairo_create(surface); PangoLayout *layout = create_layout_with_dpi(cr); gint height; @@ -188,7 +187,7 @@ i3Font load_font(const char *pattern, const bool fallback) { /* Send all our requests first */ font.specific.xcb.id = xcb_generate_id(conn); xcb_void_cookie_t font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id, - strlen(pattern), pattern); + strlen(pattern), pattern); xcb_query_font_cookie_t info_cookie = xcb_query_font(conn, font.specific.xcb.id); /* Check for errors. If errors, fall back to default font. */ @@ -201,7 +200,7 @@ i3Font load_font(const char *pattern, const bool fallback) { pattern, error->error_code); pattern = "fixed"; font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id, - strlen(pattern), pattern); + strlen(pattern), pattern); info_cookie = xcb_query_font(conn, font.specific.xcb.id); /* Check if we managed to open 'fixed' */ @@ -212,12 +211,13 @@ i3Font load_font(const char *pattern, const bool fallback) { ELOG("Could not open fallback font 'fixed', trying with '-misc-*'.\n"); pattern = "-misc-*"; font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id, - strlen(pattern), pattern); + strlen(pattern), pattern); info_cookie = xcb_query_font(conn, font.specific.xcb.id); if ((error = xcb_request_check(conn, font_cookie)) != NULL) errx(EXIT_FAILURE, "Could open neither requested font nor fallbacks " - "(fixed or -misc-*): X11 error %d", error->error_code); + "(fixed or -misc-*): X11 error %d", + error->error_code); } } @@ -293,7 +293,7 @@ void set_font_colors(xcb_gcontext_t gc, uint32_t foreground, uint32_t background case FONT_TYPE_XCB: { /* Change the font and colors in the GC */ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; - uint32_t values[] = { foreground, background, savedFont->specific.xcb.id }; + uint32_t values[] = {foreground, background, savedFont->specific.xcb.id}; xcb_change_gc(conn, gc, mask, values); break; } @@ -314,7 +314,7 @@ void set_font_colors(xcb_gcontext_t gc, uint32_t foreground, uint32_t background static int predict_text_width_xcb(const xcb_char2b_t *text, size_t text_len); static void draw_text_xcb(const xcb_char2b_t *text, size_t text_len, xcb_drawable_t drawable, - xcb_gcontext_t gc, int x, int y, int max_width) { + xcb_gcontext_t gc, int x, int y, int max_width) { /* X11 coordinates for fonts start at the baseline */ int pos_y = y + savedFont->specific.xcb.info->font_ascent; @@ -360,7 +360,7 @@ void draw_text(i3String *text, xcb_drawable_t drawable, return; case FONT_TYPE_XCB: draw_text_xcb(i3string_as_ucs2(text), i3string_get_num_glyphs(text), - drawable, gc, x, y, max_width); + drawable, gc, x, y, max_width); break; #if PANGO_SUPPORT case FONT_TYPE_PANGO: @@ -379,15 +379,14 @@ void draw_text(i3String *text, xcb_drawable_t drawable, * */ void draw_text_ascii(const char *text, xcb_drawable_t drawable, - xcb_gcontext_t gc, int x, int y, int max_width) { + xcb_gcontext_t gc, int x, int y, int max_width) { assert(savedFont != NULL); switch (savedFont->type) { case FONT_TYPE_NONE: /* Nothing to do */ return; - case FONT_TYPE_XCB: - { + case FONT_TYPE_XCB: { size_t text_len = strlen(text); if (text_len > 255) { /* The text is too long to draw it directly to X */ @@ -425,9 +424,9 @@ static int xcb_query_text_width(const xcb_char2b_t *text, size_t text_len) { /* Query the text width */ xcb_generic_error_t *error; xcb_query_text_extents_cookie_t cookie = xcb_query_text_extents(conn, - savedFont->specific.xcb.id, text_len, (xcb_char2b_t*)text); + savedFont->specific.xcb.id, text_len, (xcb_char2b_t *)text); xcb_query_text_extents_reply_t *reply = xcb_query_text_extents_reply(conn, - cookie, &error); + cookie, &error); if (reply == NULL) { /* We return a safe estimate because a rendering error is better than * a crash. Plus, the user will see the error in his log. */ @@ -469,14 +468,14 @@ static int predict_text_width_xcb(const xcb_char2b_t *input, size_t text_len) { /* Don't you ask me, how this one works… (Merovius) */ info = &font_table[((row - font_info->min_byte1) * - (font_info->max_char_or_byte2 - font_info->min_char_or_byte2 + 1)) + - (col - font_info->min_char_or_byte2)]; + (font_info->max_char_or_byte2 - font_info->min_char_or_byte2 + 1)) + + (col - font_info->min_char_or_byte2)]; if (info->character_width != 0 || - (info->right_side_bearing | - info->left_side_bearing | - info->ascent | - info->descent) != 0) { + (info->right_side_bearing | + info->left_side_bearing | + info->ascent | + info->descent) != 0) { width += info->character_width; } } diff --git a/libi3/get_exe_path.c b/libi3/get_exe_path.c index e0437e5e..fc9b3014 100644 --- a/libi3/get_exe_path.c +++ b/libi3/get_exe_path.c @@ -15,87 +15,86 @@ * Returned value must be freed by the caller. */ char *get_exe_path(const char *argv0) { - size_t destpath_size = 1024; - size_t tmp_size = 1024; - char *destpath = smalloc(destpath_size); - char *tmp = smalloc(tmp_size); - + size_t destpath_size = 1024; + size_t tmp_size = 1024; + char *destpath = smalloc(destpath_size); + char *tmp = smalloc(tmp_size); #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - /* Linux and Debian/kFreeBSD provide /proc/self/exe */ +/* Linux and Debian/kFreeBSD provide /proc/self/exe */ #if defined(__linux__) || defined(__FreeBSD_kernel__) - const char *exepath = "/proc/self/exe"; + const char *exepath = "/proc/self/exe"; #elif defined(__FreeBSD__) - const char *exepath = "/proc/curproc/file"; + const char *exepath = "/proc/curproc/file"; #endif - ssize_t linksize; + ssize_t linksize; - while ((linksize = readlink(exepath, destpath, destpath_size)) == destpath_size) { - destpath_size = destpath_size * 2; - destpath = srealloc(destpath, destpath_size); - } - if (linksize != -1) { - /* readlink() does not NULL-terminate strings, so we have to. */ - destpath[linksize] = '\0'; - free(tmp); - return destpath; - } + while ((linksize = readlink(exepath, destpath, destpath_size)) == (ssize_t)destpath_size) { + destpath_size = destpath_size * 2; + destpath = srealloc(destpath, destpath_size); + } + if (linksize != -1) { + /* readlink() does not NULL-terminate strings, so we have to. */ + destpath[linksize] = '\0'; + free(tmp); + return destpath; + } #endif - /* argv[0] is most likely a full path if it starts with a slash. */ - if (argv0[0] == '/') { - free(tmp); - free(destpath); - return sstrdup(argv0); - } + /* argv[0] is most likely a full path if it starts with a slash. */ + if (argv0[0] == '/') { + free(tmp); + free(destpath); + return sstrdup(argv0); + } - /* if argv[0] contains a /, prepend the working directory */ - if (strchr(argv0, '/') != NULL) { - char *retgcwd; - while ((retgcwd = getcwd(tmp, tmp_size)) == NULL && errno == ERANGE) { - tmp_size = tmp_size * 2; - tmp = srealloc(tmp, tmp_size); - } - if (retgcwd != NULL) { - free(destpath); - sasprintf(&destpath, "%s/%s", tmp, argv0); - free(tmp); - return destpath; - } - } + /* if argv[0] contains a /, prepend the working directory */ + if (strchr(argv0, '/') != NULL) { + char *retgcwd; + while ((retgcwd = getcwd(tmp, tmp_size)) == NULL && errno == ERANGE) { + tmp_size = tmp_size * 2; + tmp = srealloc(tmp, tmp_size); + } + if (retgcwd != NULL) { + free(destpath); + sasprintf(&destpath, "%s/%s", tmp, argv0); + free(tmp); + return destpath; + } + } - /* Fall back to searching $PATH (or _CS_PATH in absence of $PATH). */ - char *path = getenv("PATH"); - if (path == NULL) { - /* _CS_PATH is typically something like "/bin:/usr/bin" */ - while (confstr(_CS_PATH, tmp, tmp_size) > tmp_size) { - tmp_size = tmp_size * 2; - tmp = srealloc(tmp, tmp_size); - } - sasprintf(&path, ":%s", tmp); - } else { - path = strdup(path); - } - const char *component; - char *str = path; - while (1) { - if ((component = strtok(str, ":")) == NULL) - break; - str = NULL; - free(destpath); - sasprintf(&destpath, "%s/%s", component, argv0); - /* Of course this is not 100% equivalent to actually exec()ing the + /* Fall back to searching $PATH (or _CS_PATH in absence of $PATH). */ + char *path = getenv("PATH"); + if (path == NULL) { + /* _CS_PATH is typically something like "/bin:/usr/bin" */ + while (confstr(_CS_PATH, tmp, tmp_size) > tmp_size) { + tmp_size = tmp_size * 2; + tmp = srealloc(tmp, tmp_size); + } + sasprintf(&path, ":%s", tmp); + } else { + path = strdup(path); + } + const char *component; + char *str = path; + while (1) { + if ((component = strtok(str, ":")) == NULL) + break; + str = NULL; + free(destpath); + sasprintf(&destpath, "%s/%s", component, argv0); + /* Of course this is not 100% equivalent to actually exec()ing the * binary, but meh. */ - if (access(destpath, X_OK) == 0) { - free(path); - free(tmp); - return destpath; - } - } - free(destpath); - free(path); - free(tmp); + if (access(destpath, X_OK) == 0) { + free(path); + free(tmp); + return destpath; + } + } + free(destpath); + free(path); + free(tmp); - /* Last resort: maybe it’s in /usr/bin? */ - return sstrdup("/usr/bin/i3-nagbar"); + /* Last resort: maybe it’s in /usr/bin? */ + return sstrdup("/usr/bin/i3-nagbar"); } diff --git a/libi3/get_mod_mask.c b/libi3/get_mod_mask.c index 752cea57..cf8cbe38 100644 --- a/libi3/get_mod_mask.c +++ b/libi3/get_mod_mask.c @@ -46,8 +46,8 @@ uint32_t aio_get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols) { * */ uint32_t get_mod_mask_for(uint32_t keysym, - xcb_key_symbols_t *symbols, - xcb_get_modifier_mapping_reply_t *modmap_reply) { + xcb_key_symbols_t *symbols, + xcb_get_modifier_mapping_reply_t *modmap_reply) { xcb_keycode_t *codes, *modmap; xcb_keycode_t mod_code; diff --git a/libi3/ipc_connect.c b/libi3/ipc_connect.c index d27e0467..69629daa 100644 --- a/libi3/ipc_connect.c +++ b/libi3/ipc_connect.c @@ -32,7 +32,7 @@ int ipc_connect(const char *socket_path) { memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_LOCAL; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); - if (connect(sockfd, (const struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0) + if (connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) err(EXIT_FAILURE, "Could not connect to i3"); return sockfd; diff --git a/libi3/ipc_recv_message.c b/libi3/ipc_recv_message.c index 8d36700a..cb4edd67 100644 --- a/libi3/ipc_recv_message.c +++ b/libi3/ipc_recv_message.c @@ -41,7 +41,6 @@ int ipc_recv_message(int sockfd, uint32_t *message_type, if (n == -1) return -1; if (n == 0) { - ELOG("IPC: received EOF instead of reply\n"); return -2; } diff --git a/libi3/ipc_send_message.c b/libi3/ipc_send_message.c index c5560c0d..28cb8359 100644 --- a/libi3/ipc_send_message.c +++ b/libi3/ipc_send_message.c @@ -28,19 +28,18 @@ int ipc_send_message(int sockfd, const uint32_t message_size, const uint32_t message_type, const uint8_t *payload) { const i3_ipc_header_t header = { /* We don’t use I3_IPC_MAGIC because it’s a 0-terminated C string. */ - .magic = { 'i', '3', '-', 'i', 'p', 'c' }, + .magic = {'i', '3', '-', 'i', 'p', 'c'}, .size = message_size, - .type = message_type - }; + .type = message_type}; - int sent_bytes = 0; + size_t sent_bytes = 0; int n = 0; /* This first loop is basically unnecessary. No operating system has * buffers which cannot fit 14 bytes into them, so the write() will only be * called once. */ while (sent_bytes < sizeof(i3_ipc_header_t)) { - if ((n = write(sockfd, ((void*)&header) + sent_bytes, sizeof(i3_ipc_header_t) - sent_bytes)) == -1) { + if ((n = write(sockfd, ((void *)&header) + sent_bytes, sizeof(i3_ipc_header_t) - sent_bytes)) == -1) { if (errno == EAGAIN) continue; return -1; diff --git a/libi3/root_atom_contents.c b/libi3/root_atom_contents.c index 00b74005..f70c31a7 100644 --- a/libi3/root_atom_contents.c +++ b/libi3/root_atom_contents.c @@ -80,14 +80,14 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, if (prop_reply->type == XCB_ATOM_CARDINAL) { /* We treat a CARDINAL as a >= 32-bit unsigned int. The only CARDINAL * we query is I3_PID, which is 32-bit. */ - if (asprintf(&content, "%u", *((unsigned int*)xcb_get_property_value(prop_reply))) == -1) { + if (asprintf(&content, "%u", *((unsigned int *)xcb_get_property_value(prop_reply))) == -1) { free(atom_reply); free(prop_reply); return NULL; } } else { if (asprintf(&content, "%.*s", xcb_get_property_value_length(prop_reply), - (char*)xcb_get_property_value(prop_reply)) == -1) { + (char *)xcb_get_property_value(prop_reply)) == -1) { free(atom_reply); free(prop_reply); return NULL; @@ -99,4 +99,3 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, free(prop_reply); return content; } - diff --git a/libi3/ucs2_conversion.c b/libi3/ucs2_conversion.c index fe7c2d4c..9a8c478f 100644 --- a/libi3/ucs2_conversion.c +++ b/libi3/ucs2_conversion.c @@ -42,8 +42,8 @@ char *convert_ucs2_to_utf8(xcb_char2b_t *text, size_t num_glyphs) { /* Do the conversion */ size_t input_len = num_glyphs * sizeof(xcb_char2b_t); - size_t rc = iconv(utf8_conversion_descriptor, (char**)&text, - &input_len, &output, &output_size); + size_t rc = iconv(utf8_conversion_descriptor, (char **)&text, + &input_len, &output, &output_size); if (rc == (size_t)-1) { perror("Converting to UTF-8 failed"); free(buffer); @@ -83,8 +83,8 @@ xcb_char2b_t *convert_utf8_to_ucs2(char *input, size_t *real_strlen) { } /* Do the conversion */ - size_t rc = iconv(ucs2_conversion_descriptor, (char**)&input, - &input_size, (char**)&output, &output_size); + size_t rc = iconv(ucs2_conversion_descriptor, (char **)&input, + &input_size, (char **)&output, &output_size); if (rc == (size_t)-1) { perror("Converting to UCS-2 failed"); free(buffer); diff --git a/man/asciidoc.conf b/man/asciidoc.conf index 9eadebe0..84b6d52c 100644 --- a/man/asciidoc.conf +++ b/man/asciidoc.conf @@ -7,7 +7,7 @@ template::[header-declarations] {mantitle} {manvolnum} i3 -4.7.2 +4.8 i3 Manual diff --git a/man/i3-nagbar.man b/man/i3-nagbar.man index 3dd37bb7..9e6619fa 100644 --- a/man/i3-nagbar.man +++ b/man/i3-nagbar.man @@ -9,7 +9,29 @@ i3-nagbar - displays an error bar on top of your screen == SYNOPSIS -i3-nagbar -m 'message' -b 'label' 'action' +i3-nagbar [-m ] [-b