Added slim-fork to the repo
- This introduces a minimalist display manager for the suckless-utils suite - Added crudely written scripts for reloaading slim's theme via pywal, meaning no on-the-fly reloading using keybinds as nost people wouldn't have their sudo passwordless - This is based on slim-fork 1.4.0 version.
This commit is contained in:
parent
9bee2d9c57
commit
e1207e1d0d
|
@ -17,6 +17,7 @@ This was designed to save me some sanity in maintaining it as well as easily int
|
|||
- dwmblocks-async
|
||||
- slock
|
||||
- nsxiv
|
||||
- slim
|
||||
|
||||
### Terminal
|
||||
- dvtm
|
||||
|
@ -25,6 +26,12 @@ This was designed to save me some sanity in maintaining it as well as easily int
|
|||
|
||||
## Notes
|
||||
|
||||
### slim notes
|
||||
|
||||
To reload the preset theme (located in `/usr/share/themes/slim/suckless`), then run `.cache/wal/slim-reload` **after** running pywal. The script must also be ran as sudo.
|
||||
|
||||
This is, if you wanted a display manager added. The scripts also works a workaround unless if slim could handle loading themes from other dirs.
|
||||
|
||||
### eww notes
|
||||
|
||||
The weather widget is pretty barebones as of now. Report bugs if found.
|
||||
|
|
5
config/wal/templates/slim-reload
Executable file
5
config/wal/templates/slim-reload
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
# Reloads slim (needs sudo to ask the passswoes)
|
||||
|
||||
sudo cp .cache/wal/slim.theme /usr/share/slim/themes/suckless
|
||||
sudo cp {wallpaper} /usr/share/slim/themes/suckless/background.png
|
52
config/wal/templates/slim.theme
Normal file
52
config/wal/templates/slim.theme
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Green glass theme for SLiM
|
||||
# by Rob Pearce <slim@flitspace.org.uk>
|
||||
|
||||
# Messages (e.g. shutdown)
|
||||
msg_color {color15}
|
||||
msg_font Hack Nerd Font:size=18:bold:dpi=75
|
||||
msg_x 50%
|
||||
msg_y 40%
|
||||
msg_shadow_color #702342
|
||||
msg_shadow_xoffset 1
|
||||
msg_shadow_yoffset 1
|
||||
|
||||
# valid values: stretch, tile
|
||||
background_style stretch
|
||||
background_color {color0}
|
||||
|
||||
# Input controls
|
||||
input_panel_x 50%
|
||||
input_panel_y 45%
|
||||
input_name_x 394
|
||||
input_name_y 142
|
||||
input_pass_x 394
|
||||
input_pass_y 178
|
||||
input_font Hack Nerd Font:size=12:dpi=75
|
||||
input_color {color0}
|
||||
|
||||
# Username / password request
|
||||
username_font Hack Nerd Font:size=18:dpi=75
|
||||
username_color {color15}
|
||||
username_x 270
|
||||
username_y 144
|
||||
password_x 270
|
||||
password_y 180
|
||||
username_shadow_color {color0}
|
||||
username_shadow_xoffset 1
|
||||
username_shadow_yoffset 1
|
||||
|
||||
username_msg Username:
|
||||
password_msg Password:
|
||||
|
||||
# Welcome message
|
||||
welcome_font Hack Nerd Font:size=28:bold:dpi=75
|
||||
welcome_color {color1}
|
||||
welcome_x 50%
|
||||
welcome_y 40
|
||||
welcome_msg Login to %host
|
||||
welcome_shadow_xoffset 2
|
||||
welcome_shadow_yoffset 2
|
||||
welcome_shadow_color {color0}
|
||||
|
||||
passwd_feedback_x 50%
|
||||
passwd_feedback_y 80%
|
252
slim/CMakeLists.txt
Normal file
252
slim/CMakeLists.txt
Normal file
|
@ -0,0 +1,252 @@
|
|||
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
|
||||
set(PROJECT_NAME slim)
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
#Pretty colors
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
#Dont force verbose
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
#Include current dir
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
||||
|
||||
INCLUDE(CheckIncludeFile)
|
||||
INCLUDE(CheckCCompilerFlag)
|
||||
INCLUDE(CheckCXXCompilerFlag)
|
||||
INCLUDE(CheckTypeSize)
|
||||
INCLUDE(GNUInstallDirs)
|
||||
|
||||
# Version
|
||||
set(SLIM_VERSION_MAJOR "1")
|
||||
set(SLIM_VERSION_MINOR "4")
|
||||
set(SLIM_VERSION_PATCH "0")
|
||||
set(SLIM_VERSION "${SLIM_VERSION_MAJOR}.${SLIM_VERSION_MINOR}.${SLIM_VERSION_PATCH}")
|
||||
|
||||
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/slim")
|
||||
set(SYSCONFDIR "/etc")
|
||||
|
||||
set(SLIM_DEFINITIONS)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR
|
||||
${CMAKE_SYSTEM_NAME} MATCHES "NetBSD" OR
|
||||
${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD"
|
||||
)
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DNEEDS_BASENAME")
|
||||
else()
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DHAVE_SHADOW")
|
||||
endif()
|
||||
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DAPPNAME=\"${PROJECT_NAME}\"")
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DVERSION=\"${SLIM_VERSION}\"")
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DPKGDATADIR=\"${PKGDATADIR}\"")
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DSYSCONFDIR=\"${SYSCONFDIR}\"")
|
||||
|
||||
# source
|
||||
set(slim_srcs
|
||||
main.cpp
|
||||
app.cpp
|
||||
numlock.cpp
|
||||
switchuser.cpp
|
||||
png.c
|
||||
jpeg.c
|
||||
)
|
||||
|
||||
set(slimlock_srcs
|
||||
slimlock.cpp
|
||||
)
|
||||
|
||||
set(common_srcs
|
||||
cfg.cpp
|
||||
image.cpp
|
||||
log.cpp
|
||||
panel.cpp
|
||||
util.cpp
|
||||
)
|
||||
if(USE_PAM)
|
||||
set(common_srcs ${common_srcs} PAM.cpp)
|
||||
# used to always build slimlock if we are using PAM. Removed as per Devuan
|
||||
# set(BUILD_SLIMLOCK 1)
|
||||
endif(USE_PAM)
|
||||
|
||||
# Build common library
|
||||
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
message(STATUS "Enable shared library building")
|
||||
add_library(libslim ${common_srcs})
|
||||
else(BUILD_SHARED_LIBS)
|
||||
message(STATUS "Disable shared library building")
|
||||
add_library(libslim STATIC ${common_srcs})
|
||||
endif(BUILD_SHARED_LIBS)
|
||||
|
||||
if(USE_CONSOLEKIT)
|
||||
set(slim_srcs ${slim_srcs} Ck.cpp)
|
||||
endif(USE_CONSOLEKIT)
|
||||
|
||||
add_executable(slim ${slim_srcs})
|
||||
if(BUILD_SLIMLOCK)
|
||||
add_executable(slimlock ${slimlock_srcs})
|
||||
endif(BUILD_SLIMLOCK)
|
||||
|
||||
#Set the custom CMake module directory where our include/lib finders are
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
|
||||
|
||||
find_package(X11 REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
find_package(JPEG REQUIRED)
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
# Fontconfig
|
||||
set(FONTCONFIG_DIR ${CMAKE_MODULE_PATH})
|
||||
find_package(FONTCONFIG REQUIRED)
|
||||
if(FONTCONFIG_FOUND)
|
||||
message("\tFontConfig Found")
|
||||
target_link_libraries(slim ${FONTCONFIG_LIBRARY})
|
||||
include_directories(${FONTCONFIG_INCLUDE_DIR})
|
||||
endif(FONTCONFIG_FOUND)
|
||||
|
||||
# PAM
|
||||
if(USE_PAM)
|
||||
message("\tPAM Enabled")
|
||||
find_package(PAM)
|
||||
if(PAM_FOUND)
|
||||
message("\tPAM Found")
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DUSE_PAM")
|
||||
target_link_libraries(slim ${PAM_LIBRARY})
|
||||
target_link_libraries(libslim ${PAM_LIBRARY})
|
||||
if(BUILD_SLIMLOCK)
|
||||
target_link_libraries(slimlock ${PAM_LIBRARY})
|
||||
endif(BUILD_SLIMLOCK)
|
||||
include_directories(${PAM_INCLUDE_DIR})
|
||||
else(PAM_FOUND)
|
||||
message("\tPAM Not Found")
|
||||
endif(PAM_FOUND)
|
||||
else(USE_PAM)
|
||||
message("\tPAM disabled")
|
||||
endif(USE_PAM)
|
||||
|
||||
# ConsoleKit
|
||||
if(USE_CONSOLEKIT)
|
||||
find_package(CkConnector)
|
||||
message("\tConsoleKit Enabled")
|
||||
if(CKCONNECTOR_FOUND)
|
||||
message("\tConsoleKit Found")
|
||||
# DBus check
|
||||
find_package(DBus REQUIRED)
|
||||
if(DBUS_FOUND)
|
||||
message("\tDBus Found")
|
||||
target_link_libraries(slim ${DBUS_LIBRARIES})
|
||||
include_directories(${DBUS_ARCH_INCLUDE_DIR})
|
||||
include_directories(${DBUS_INCLUDE_DIR})
|
||||
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DUSE_CONSOLEKIT")
|
||||
target_link_libraries(slim ${CKCONNECTOR_LIBRARIES})
|
||||
include_directories(${CKCONNECTOR_INCLUDE_DIR})
|
||||
else(DBUS_FOUND)
|
||||
message("\tDBus Not Found")
|
||||
endif(DBUS_FOUND)
|
||||
else(CKCONNECTOR_FOUND)
|
||||
message("\tConsoleKit Not Found")
|
||||
message("\tConsoleKit disabled")
|
||||
endif(CKCONNECTOR_FOUND)
|
||||
else(USE_CONSOLEKIT)
|
||||
message("\tConsoleKit disabled")
|
||||
endif(USE_CONSOLEKIT)
|
||||
|
||||
# system librarys
|
||||
find_library(M_LIB m)
|
||||
find_library(RT_LIB rt)
|
||||
find_library(CRYPTO_LIB crypt)
|
||||
find_package(Threads)
|
||||
|
||||
add_definitions(${SLIM_DEFINITIONS})
|
||||
|
||||
#Set up include dirs with all found packages
|
||||
include_directories(
|
||||
${X11_INCLUDE_DIR}
|
||||
${X11_Xft_INCLUDE_PATH}
|
||||
${X11_Xrender_INCLUDE_PATH}
|
||||
${X11_Xrandr_INCLUDE_PATH}
|
||||
${FREETYPE_INCLUDE_DIRS}
|
||||
${X11_Xmu_INCLUDE_PATH}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${JPEG_INCLUDE_DIR}
|
||||
${PNG_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(libslim
|
||||
${RT_LIB}
|
||||
${X11_Xft_LIB}
|
||||
${X11_Xrandr_LIB}
|
||||
${JPEG_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
)
|
||||
|
||||
#Set up library with all found packages for slim
|
||||
target_link_libraries(slim
|
||||
${M_LIB}
|
||||
${RT_LIB}
|
||||
${CRYPTO_LIB}
|
||||
${X11_X11_LIB}
|
||||
${X11_Xft_LIB}
|
||||
${X11_Xrender_LIB}
|
||||
${X11_Xrandr_LIB}
|
||||
${X11_Xmu_LIB}
|
||||
${FREETYPE_LIBRARY}
|
||||
${JPEG_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
libslim
|
||||
)
|
||||
|
||||
if(BUILD_SLIMLOCK)
|
||||
#Set up library with all found packages for slimlock
|
||||
target_link_libraries(slimlock
|
||||
${M_LIB}
|
||||
${RT_LIB}
|
||||
${CRYPTO_LIB}
|
||||
${X11_X11_LIB}
|
||||
${X11_Xft_LIB}
|
||||
${X11_Xrender_LIB}
|
||||
${X11_Xrandr_LIB}
|
||||
${X11_Xmu_LIB}
|
||||
${X11_Xext_LIB}
|
||||
${FREETYPE_LIBRARY}
|
||||
${JPEG_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
libslim
|
||||
)
|
||||
endif(BUILD_SLIMLOCK)
|
||||
|
||||
####### install
|
||||
# slim
|
||||
install(TARGETS slim RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set_target_properties(libslim PROPERTIES
|
||||
OUTPUT_NAME slim
|
||||
SOVERSION ${SLIM_VERSION})
|
||||
|
||||
install(TARGETS libslim
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
endif (BUILD_SHARED_LIBS)
|
||||
|
||||
# man file
|
||||
install(FILES slim.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
|
||||
# configure - in theory we should use CMAKE_INSTALL_SYSCONFDIR but that doesn't work
|
||||
install(FILES slim.conf DESTINATION ${SYSCONFDIR})
|
||||
|
||||
# systemd service file - commented out as broken - not all Linux uses systemd!
|
||||
#if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
# install(FILES slim.service DESTINATION ${LIBDIR}/systemd/system)
|
||||
#endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
#slimlock
|
||||
if(BUILD_SLIMLOCK)
|
||||
install(TARGETS slimlock RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE SETUID)
|
||||
install(FILES slimlock.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
endif(BUILD_SLIMLOCK)
|
||||
|
||||
# themes directory
|
||||
subdirs(themes)
|
339
slim/COPYING
Normal file
339
slim/COPYING
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
196
slim/ChangeLog
Normal file
196
slim/ChangeLog
Normal file
|
@ -0,0 +1,196 @@
|
|||
1.4.0 - 2023.01.21
|
||||
* - BREAKING CONFIG CHANGE - the position of the passwd_feedback in slim
|
||||
is now relative to the screen, not the panel. This is now consistent
|
||||
with slimlock and with the session and other messages.
|
||||
* The selected session is now preserved over failed logins
|
||||
* When testing themes with the -p option, the size of the window can now
|
||||
be specified, and the theme is previewed correctly for that size.
|
||||
* On exit from theme test, the "test message" now reports user and session
|
||||
* Failed login feedback is now disabled by default or if position negative
|
||||
* Applied some Devuan patches
|
||||
- Set the XDG_SESSION_CLASS. This fixes Gentoo bug #727544 - failure to
|
||||
register sessions with elogind in some instances. The (incorrect) bug
|
||||
note in the man page has therefore been removed again.
|
||||
- Use $DISPLAY instead of hardcoding :0.0 in sessionstart/stop commands
|
||||
- No longer always builds slimlock if using PAM - it must be explicitly
|
||||
enabled
|
||||
- Fixed formatting in slimlock man page
|
||||
- A couple of typos fixed in strings
|
||||
* Updated the README and encoded in UTF-8
|
||||
* Corrected the handling of the -n / -nodaemon option so that it doesn't
|
||||
swallow the next option if given as -n
|
||||
* Bug fixes in slimlock
|
||||
- The active entry is for password, so show the password prompt, not the
|
||||
username one
|
||||
- Don't react to F1, as it isn't appropriate and used to blank the
|
||||
screen
|
||||
- Keep it all on one screen even when the WM hasn't set a "primary" for
|
||||
RandR purposes
|
||||
* Fix ticket #4 - the config parser now works properly. Previously it got
|
||||
confused by option names that were substrings of other option names
|
||||
* Themes with "background_style color" no longer need a redundant image
|
||||
file to make them work.
|
||||
- This needed a bit of a re-write of the image handling, which also
|
||||
improves efficiency
|
||||
* New default theme - the old one is retained as "original"
|
||||
* Some general documentation improvements (man pages, comments in example
|
||||
files)
|
||||
|
||||
1.3.9 - 2022.11.18
|
||||
* Changed the handling of the "auth failed" message in DM mode so that it
|
||||
remains on display until a key is pressed.
|
||||
* Added a command line option to specify the configuration file
|
||||
* Allow the logfile to be specified as "stderr" to write to stderr
|
||||
Also now writes all log messages to stderr if they are printed before
|
||||
the log file is open, including when using the -p option.
|
||||
* Added a configuration option to retain the user name if authentication
|
||||
fails (which is probably more helpful if you just mistype your password)
|
||||
* Applied a modified version of the "wait for the X server" patch from guix
|
||||
* No longer unnecessarily re-opens an already open X display interface.
|
||||
Similarly removed a redundant "get root window" call
|
||||
* Deleted some unused member variables and methods. Various other internal
|
||||
clean-up
|
||||
* Reverted the install location definition for the configuration file, as
|
||||
the CMAKE_INSTALL_SYSCONFDIR wasn't right
|
||||
* Added a "bug" note to the man page, for the reliance on sessreg, which
|
||||
causes occasional misbehaviour for some people.
|
||||
|
||||
1.3.8 - 2022.03.01
|
||||
* Fixed some bugs listed on bugs.gentoo.org:
|
||||
832303 - failed to build with clang, Invalid suffix on string literal
|
||||
580458 - open fd on /var/log/slim.log passed to session
|
||||
* Fixed handling of log stream so that all the code uses the same instance
|
||||
* Handle return values from calls, to clean up warn-unused-result warnings
|
||||
* Fixed "sessions" config option (the earlier patch was incomplete)
|
||||
* Several QA improvements
|
||||
* Updated cmake config - use standard install paths, don't force options
|
||||
|
||||
1.3.7 - 2022.01.30
|
||||
* Imported several bug fixes from the Gentoo package:
|
||||
libslim-cmake-fixes
|
||||
disable-ck-for-systemd
|
||||
reinstate sessions config option as an alternative to sessiondir
|
||||
systemd session compatibility
|
||||
remove zlib dependency
|
||||
envcpy-bad-pointer-arithmetic patch
|
||||
add-missing-libgen_h
|
||||
wrong comparison for XCreateGC error return (GCC11 needs it fixed!)
|
||||
* Fixed a bug in handling expired user accounts with PAM
|
||||
* Show a message on login failure (using the same method as slimlock)
|
||||
|
||||
|
||||
--- The releases below were the original SLiM project ---
|
||||
|
||||
1.3.6 - 2013.10.01
|
||||
* Merge slimlock.
|
||||
* Add support ^H (like backspace).
|
||||
* And fix some bugs.
|
||||
|
||||
1.3.5 - 2012.12.31
|
||||
* Support UTF8 string.
|
||||
* Add systemd service.
|
||||
* And fix some bugs.
|
||||
|
||||
1.3.4 - 2012.06.26
|
||||
* Replaced stderr writes function.
|
||||
* Fix numlock control.
|
||||
* Fix build with GLUT.
|
||||
* Fix PAM authentication.
|
||||
|
||||
1.3.3 - 2012.02.22
|
||||
* Change build system to CMake.
|
||||
* Add support ConsoleKit.
|
||||
* Fix some bugs....
|
||||
|
||||
1.3.2 - 2010.07.08
|
||||
* Add support xauth secret.
|
||||
* Add xnest_debug mode.
|
||||
|
||||
1.3.1 - 2008.09.26
|
||||
* Added focus_password config option for focusing password
|
||||
automatically when default_user is enabled
|
||||
* Added auto_login option
|
||||
* Fixed uninitialized daemonmode, see
|
||||
http://www.freebsd.org/cgi/query-pr.cgi?pr=114366
|
||||
* Fixed maximum length for password
|
||||
* Introduced customization options for session text:
|
||||
font, colors, position, shadows.
|
||||
|
||||
1.3.0 - 2006.07.14
|
||||
* Added PAM support by Martin Parm
|
||||
* Fixed segfault on exit when testing themes. Thanks
|
||||
to Darren Salt & Mike Massonnet
|
||||
* Fixed vt argument detection, thanks to Henrik Brix Andersen
|
||||
* Corrected reference to input_color in the default theme
|
||||
* Fixed default shell setting
|
||||
* Fix segfault when calling XCloseDisplay(NULL); thanks Uli Schlachter
|
||||
|
||||
1.2.6 - 2006.09.15
|
||||
* Bug #008167: Update pid when in daemon mode
|
||||
* Fixed warnings when compiling with -Wall. Thanks to
|
||||
KIMURA Masaru
|
||||
* Fixed major memory leaks with repeated login (bug #007535)
|
||||
|
||||
1.2.5 - 2006.07.24
|
||||
* hiding of the cursor is now an option (disabled
|
||||
by default) since some WMs does not re-initialize
|
||||
the root window cursor.
|
||||
* The X server is restarted when the user logs out.
|
||||
This fixes potential security issues with user-launched
|
||||
apps staying attached to the root window after logout.
|
||||
* Bug #7432 : Added proper Xauth authentication: the X server
|
||||
is started with the -auth option and the user who logs
|
||||
in has his .Xauthority file initializated.
|
||||
|
||||
1.2.4 - 2006.01.18
|
||||
* Added commands for session start and stop
|
||||
(i.e. for session registering)
|
||||
* Added automatic numlock on/off option
|
||||
* Support for numpad Enter key
|
||||
* Restored support for daemon option in the config
|
||||
file.
|
||||
* Lock file now uses process id, no more false
|
||||
locking (thanks to Tobias Roth)
|
||||
|
||||
1.2.3 - 2005.09.11
|
||||
* Added FreeBSD, NetBSD, OpenBSD support
|
||||
* Replaced autotools with plain makefile(s)
|
||||
* Added 'suspend' command (untested, we don't use it)
|
||||
* Added support for %theme variable in login command
|
||||
|
||||
1.2.2 - 2005.05.21
|
||||
* fix panel drawing on screens <= 1024x768
|
||||
* Don't start X server unless valid theme found
|
||||
* revert to 'default' of invalid theme specified
|
||||
* try all themes from a set if one doesn't work
|
||||
|
||||
1.2.1 - 2005.05.17
|
||||
* draw input directly on panel
|
||||
|
||||
1.2.0 - 2005.05.16
|
||||
* added theme preview (slim -p /path/to/theme)
|
||||
* added JPEG support for panel image
|
||||
* added 'center' background type and 'background_color' option
|
||||
* added text shadow
|
||||
* added warning when execution of login command fails
|
||||
* Fix login failure when no shell specified in /etc/passwd
|
||||
* Print error when login command execution fails
|
||||
* add XNEST_DEBUG ifdef's to allow for easy debugging
|
||||
* Add support for Ctrl-u and Ctrl-w
|
||||
* Add 'vt07' to server arguments if not already specified
|
||||
* Removes daemon option from the config file. Use slim -d
|
||||
* Allow 'current_theme' to be a set of themes, choose randomly
|
||||
* Change default theme
|
||||
|
||||
1.1.0 - 2004.12.09
|
||||
* error messages for X11 apps are no longer redirected
|
||||
to the log file
|
||||
* fixed text position for default theme
|
||||
* added configurable shutdown and reboot messages
|
||||
* separated 'Enter username' and 'Enter password' messages
|
||||
position.
|
||||
* due to the previous two points, the theme format has
|
||||
slightly changed
|
||||
|
||||
1.0.0 - 2004.12.07
|
||||
* First public SLiM release
|
152
slim/Ck.cpp
Normal file
152
slim/Ck.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 2011 David Hauweele
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
#include <ck-connector.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "Ck.h"
|
||||
|
||||
namespace Ck
|
||||
{
|
||||
Exception::Exception(const std::string &func, const std::string &errstr)
|
||||
: func(func), errstr(errstr)
|
||||
{
|
||||
}
|
||||
|
||||
dbus_bool_t Session::ck_connector_open_graphic_session(
|
||||
const std::string &display,
|
||||
uid_t uid)
|
||||
{
|
||||
dbus_bool_t local = true;
|
||||
const char *session_type = "x11";
|
||||
const char *x11_display = display.c_str();
|
||||
const char *x11_device = get_x11_device(display);
|
||||
const char *remote_host = "";
|
||||
const char *display_dev = "";
|
||||
|
||||
return ck_connector_open_session_with_parameters(ckc, &error,
|
||||
"unix-user", &uid,
|
||||
"session-type", &session_type,
|
||||
"x11-display", &x11_display,
|
||||
"x11-display-device", &x11_device,
|
||||
"display-device", &display_dev,
|
||||
"remote-host-name", &remote_host,
|
||||
"is-local", &local,
|
||||
NULL);
|
||||
}
|
||||
|
||||
const char * Session::get_x11_device(const std::string &display)
|
||||
{
|
||||
static char device[32];
|
||||
|
||||
Display *xdisplay = XOpenDisplay(display.c_str());
|
||||
|
||||
if(!xdisplay)
|
||||
throw Exception(__func__, "cannot open display");
|
||||
|
||||
Window root;
|
||||
Atom xfree86_vt_atom;
|
||||
Atom return_type_atom;
|
||||
int return_format;
|
||||
unsigned long return_count;
|
||||
unsigned long bytes_left;
|
||||
unsigned char *return_value;
|
||||
long vt;
|
||||
|
||||
xfree86_vt_atom = XInternAtom(xdisplay, "XFree86_VT", true);
|
||||
|
||||
if(xfree86_vt_atom == None)
|
||||
throw Exception(__func__, "cannot get XFree86_VT");
|
||||
|
||||
root = DefaultRootWindow(xdisplay);
|
||||
|
||||
if(XGetWindowProperty(xdisplay, root, xfree86_vt_atom,
|
||||
0L, 1L, false, XA_INTEGER,
|
||||
&return_type_atom, &return_format,
|
||||
&return_count, &bytes_left,
|
||||
&return_value) != Success)
|
||||
throw Exception(__func__, "cannot get root window property");
|
||||
|
||||
if(return_type_atom != XA_INTEGER)
|
||||
throw Exception(__func__, "bad atom type");
|
||||
|
||||
if(return_format != 32)
|
||||
throw Exception(__func__, "invalid return format");
|
||||
|
||||
if(return_count != 1)
|
||||
throw Exception(__func__, "invalid count");
|
||||
|
||||
if(bytes_left != 0)
|
||||
throw Exception(__func__, "invalid bytes left");
|
||||
|
||||
vt = *((long *)return_value);
|
||||
|
||||
std::sprintf(device, "/dev/tty%ld", vt);
|
||||
|
||||
if(return_value)
|
||||
XFree(return_value);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
void Session::open_session(const std::string &display, uid_t uid)
|
||||
{
|
||||
ckc = ck_connector_new();
|
||||
|
||||
if(!ckc)
|
||||
throw Exception(__func__, "error setting up connection to ConsoleKit");
|
||||
|
||||
if (!ck_connector_open_graphic_session(display, uid)) {
|
||||
if(dbus_error_is_set(&error))
|
||||
throw Exception(__func__, error.message);
|
||||
else
|
||||
throw Exception(__func__, "cannot open ConsoleKit session: OOM,"
|
||||
" DBus system bus not available or insufficient"
|
||||
" privileges");
|
||||
}
|
||||
}
|
||||
|
||||
const char * Session::get_xdg_session_cookie()
|
||||
{
|
||||
return ck_connector_get_cookie(ckc);
|
||||
}
|
||||
|
||||
void Session::close_session()
|
||||
{
|
||||
if(!ck_connector_close_session(ckc, &error)) {
|
||||
if(dbus_error_is_set(&error))
|
||||
throw Exception(__func__, error.message);
|
||||
else
|
||||
throw Exception(__func__, "cannot close ConsoleKit session: OOM,"
|
||||
" DBus system bus not available or insufficient"
|
||||
" privileges");
|
||||
}
|
||||
}
|
||||
|
||||
Session::Session()
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
}
|
||||
|
||||
Session::~Session()
|
||||
{
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<( std::ostream& os, const Ck::Exception& e)
|
||||
{
|
||||
os << e.func << ": " << e.errstr;
|
||||
return os;
|
||||
}
|
49
slim/Ck.h
Normal file
49
slim/Ck.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 2007 Martin Parm
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
*(at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _CK_H_
|
||||
#define _CK_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <ck-connector.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
namespace Ck
|
||||
{
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
std::string func;
|
||||
std::string errstr;
|
||||
Exception(const std::string &func, const std::string &errstr);
|
||||
};
|
||||
|
||||
class Session
|
||||
{
|
||||
private:
|
||||
CkConnector *ckc;
|
||||
DBusError error;
|
||||
|
||||
const char *get_x11_device(const std::string &display);
|
||||
dbus_bool_t ck_connector_open_graphic_session(const std::string &display,
|
||||
uid_t uid);
|
||||
public:
|
||||
const char *get_xdg_session_cookie();
|
||||
void open_session(const std::string &display, uid_t uid);
|
||||
void close_session();
|
||||
|
||||
Session();
|
||||
~Session();
|
||||
};
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Ck::Exception &e);
|
||||
|
||||
#endif /* _CK_H_ */
|
39
slim/INSTALL
Normal file
39
slim/INSTALL
Normal file
|
@ -0,0 +1,39 @@
|
|||
INSTALL file for SLiM
|
||||
|
||||
0. Prerequisites:
|
||||
- cmake
|
||||
- X.org or XFree86
|
||||
- libxmu
|
||||
- libpng
|
||||
- libjpeg
|
||||
|
||||
1. to build and install the program:
|
||||
o Using the ccmake interactive tool:
|
||||
- cd into a clean directory, e.g. "mkdir slim; cd slim"
|
||||
- unpack the code, e.g. "tar zxf ../slim-1.4.0.tar.gz"
|
||||
- create a build directory and change to it, e.g. "mkdir build; cd build"
|
||||
- run ccmake to configure for your OS, e.g. "ccmake ../slim-1.4.0"
|
||||
. press 'c' to configure and 'e' to ignore warnings
|
||||
. set the CMAKE_INSTALL_PREFIX and other variables as needed
|
||||
. continue pressing 'c' until the 'g' option is available
|
||||
. press 'g' to generate the files needed
|
||||
- run "make"
|
||||
- run "make install"
|
||||
|
||||
o Using command line only:
|
||||
- cd into a clean directory
|
||||
- unpack the code
|
||||
- create a build directory and change to it
|
||||
- run cmake to configure for your OS and options
|
||||
- build and install as above
|
||||
e.g.
|
||||
mkdir slim; cd slim
|
||||
tar zxf ../slim-1.4.0.tar.gz
|
||||
mkdir build; cd build
|
||||
cmake ../slim-1.4.0 -DCMAKE_INSTALL_PREFIX=/opt -DUSE_PAM=yes -DUSE_CONSOLEKIT=yes
|
||||
make
|
||||
make install
|
||||
|
||||
2. automatic startup
|
||||
Edit the init scripts according to your OS/Distribution. An example for
|
||||
systemd is provided
|
309
slim/PAM.cpp
Normal file
309
slim/PAM.cpp
Normal file
|
@ -0,0 +1,309 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 2007 Martin Parm
|
||||
* Copyright (C) 2022 Rob Pearce <slim@flitspace.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "PAM.h"
|
||||
|
||||
namespace PAM
|
||||
{
|
||||
Exception::Exception(pam_handle_t* _pam_handle,
|
||||
const std::string& _func_name,
|
||||
int _errnum)
|
||||
: errnum(_errnum), errstr(pam_strerror(_pam_handle, _errnum)),
|
||||
func_name(_func_name)
|
||||
{}
|
||||
|
||||
Exception::~Exception(void) {}
|
||||
|
||||
Auth_Exception::Auth_Exception(pam_handle_t* _pam_handle,
|
||||
const std::string& _func_name,
|
||||
int _errnum)
|
||||
: Exception(_pam_handle, _func_name, _errnum)
|
||||
{}
|
||||
|
||||
Cred_Exception::Cred_Exception(pam_handle_t* _pam_handle,
|
||||
const std::string& _func_name,
|
||||
int _errnum)
|
||||
: Exception(_pam_handle, _func_name, _errnum)
|
||||
{}
|
||||
|
||||
int Authenticator::_end (void)
|
||||
{
|
||||
int result=pam_end(pam_handle, last_result);
|
||||
pam_handle=0;
|
||||
return result;
|
||||
}
|
||||
|
||||
Authenticator::Authenticator(conversation* conv, void* data)
|
||||
: pam_handle(0), last_result(PAM_SUCCESS)
|
||||
{
|
||||
pam_conversation.conv=conv;
|
||||
pam_conversation.appdata_ptr=data;
|
||||
}
|
||||
|
||||
Authenticator::~Authenticator(void)
|
||||
{
|
||||
if (pam_handle)
|
||||
_end();
|
||||
}
|
||||
|
||||
void Authenticator::start(const std::string& service)
|
||||
{
|
||||
switch ((last_result=pam_start(service.c_str(), NULL, &pam_conversation, &pam_handle))) {
|
||||
default:
|
||||
throw Exception(pam_handle, "pam_start()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Authenticator::end(void)
|
||||
{
|
||||
switch ((last_result=_end())) {
|
||||
default:
|
||||
throw Exception(pam_handle, "pam_end()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Authenticator::set_item(const Authenticator::ItemType item, const void* value)
|
||||
{
|
||||
switch ((last_result=pam_set_item(pam_handle, item, value))) {
|
||||
default:
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_set_item()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const void* Authenticator::get_item(const Authenticator::ItemType item)
|
||||
{
|
||||
const void* data;
|
||||
switch ((last_result=pam_get_item(pam_handle, item, &data))) {
|
||||
default:
|
||||
case PAM_SYSTEM_ERR:
|
||||
#ifdef __LIBPAM_VERSION
|
||||
case PAM_BAD_ITEM:
|
||||
#endif
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_get_item()", last_result);
|
||||
|
||||
case PAM_PERM_DENIED: /* The value of item was NULL */
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
#ifdef __LIBPAM_VERSION
|
||||
void Authenticator::fail_delay(const unsigned int micro_sec)
|
||||
{
|
||||
switch ((last_result=pam_fail_delay(pam_handle, micro_sec))) {
|
||||
default:
|
||||
_end();
|
||||
throw Exception(pam_handle, "fail_delay()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Authenticator::authenticate(void)
|
||||
{
|
||||
switch ((last_result=pam_authenticate(pam_handle, 0))) {
|
||||
default:
|
||||
case PAM_ABORT:
|
||||
case PAM_AUTHINFO_UNAVAIL:
|
||||
// _end();
|
||||
// throw Exception(pam_handle, "pam_authenticate()", last_result);
|
||||
|
||||
case PAM_USER_UNKNOWN:
|
||||
case PAM_MAXTRIES:
|
||||
case PAM_CRED_INSUFFICIENT:
|
||||
case PAM_ACCT_EXPIRED:
|
||||
case PAM_PERM_DENIED:
|
||||
case PAM_AUTH_ERR:
|
||||
throw Auth_Exception(pam_handle, "pam_authentication()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((last_result=pam_acct_mgmt(pam_handle, PAM_SILENT))) {
|
||||
/* The documentation and implementation of Linux PAM differs:
|
||||
PAM_NEW_AUTHTOKEN_REQD is described in the documentation but
|
||||
don't exists in the actual implementation. This issue needs
|
||||
to be fixes at some point. */
|
||||
|
||||
default:
|
||||
/* case PAM_NEW_AUTHTOKEN_REQD: */
|
||||
case PAM_ACCT_EXPIRED:
|
||||
case PAM_USER_UNKNOWN:
|
||||
case PAM_AUTH_ERR:
|
||||
case PAM_PERM_DENIED:
|
||||
throw Auth_Exception(pam_handle, "pam_acct_mgmt()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Authenticator::check_acct(void)
|
||||
{
|
||||
switch((last_result=pam_acct_mgmt(pam_handle, PAM_SILENT))){
|
||||
case PAM_ACCT_EXPIRED:
|
||||
case PAM_USER_UNKNOWN:
|
||||
case PAM_PERM_DENIED:
|
||||
throw Auth_Exception(pam_handle, "pam_acct_mgmt()", last_result);
|
||||
|
||||
default:
|
||||
//case PAM_NEW_AUTHTOKEN_REQD:
|
||||
case PAM_AUTH_ERR:
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void Authenticator::open_session(void)
|
||||
{
|
||||
switch ((last_result=pam_setcred(pam_handle, PAM_ESTABLISH_CRED))) {
|
||||
default:
|
||||
case PAM_CRED_ERR:
|
||||
case PAM_CRED_UNAVAIL:
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_setcred()", last_result);
|
||||
|
||||
case PAM_ACCT_EXPIRED:
|
||||
case PAM_PERM_DENIED:
|
||||
case PAM_CRED_EXPIRED:
|
||||
case PAM_USER_UNKNOWN:
|
||||
throw Cred_Exception(pam_handle, "pam_setcred()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((last_result=pam_open_session(pam_handle, 0))) {
|
||||
/* The documentation and implementation of Linux PAM differs:
|
||||
PAM_SESSION_ERROR is described in the documentation but
|
||||
don't exists in the actual implementation. This issue needs
|
||||
to be fixes at some point. */
|
||||
|
||||
default:
|
||||
/* case PAM_SESSION_ERROR: */
|
||||
pam_setcred(pam_handle, PAM_DELETE_CRED);
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_open_session()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Authenticator::close_session(void)
|
||||
{
|
||||
switch ((last_result=pam_close_session(pam_handle, 0))) {
|
||||
/* The documentation and implementation of Linux PAM differs:
|
||||
PAM_SESSION_ERROR is described in the documentation but
|
||||
don't exists in the actual implementation. This issue needs
|
||||
to be fixes at some point. */
|
||||
|
||||
default:
|
||||
/* case PAM_SESSION_ERROR: */
|
||||
pam_setcred(pam_handle, PAM_DELETE_CRED);
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_close_session", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
switch ((last_result=pam_setcred(pam_handle, PAM_DELETE_CRED))) {
|
||||
default:
|
||||
case PAM_CRED_ERR:
|
||||
case PAM_CRED_UNAVAIL:
|
||||
case PAM_CRED_EXPIRED:
|
||||
case PAM_USER_UNKNOWN:
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_setcred()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Authenticator::setenv(const std::string& key, const std::string& value)
|
||||
{
|
||||
std::string name_value = key+"="+value;
|
||||
switch ((last_result = pam_putenv(pam_handle, name_value.c_str()))) {
|
||||
default:
|
||||
case PAM_PERM_DENIED:
|
||||
case PAM_ABORT:
|
||||
case PAM_BUF_ERR:
|
||||
#ifdef __LIBPAM_VERSION
|
||||
case PAM_BAD_ITEM:
|
||||
#endif
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_putenv()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Authenticator::delenv(const std::string& key)
|
||||
{
|
||||
switch ((last_result = pam_putenv(pam_handle, key.c_str()))) {
|
||||
default:
|
||||
case PAM_PERM_DENIED:
|
||||
case PAM_ABORT:
|
||||
case PAM_BUF_ERR:
|
||||
#ifdef __LIBPAM_VERSION
|
||||
case PAM_BAD_ITEM:
|
||||
#endif
|
||||
_end();
|
||||
throw Exception(pam_handle, "pam_putenv()", last_result);
|
||||
|
||||
case PAM_SUCCESS:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const char* Authenticator::getenv(const std::string& key)
|
||||
{
|
||||
return pam_getenv(pam_handle, key.c_str());
|
||||
}
|
||||
|
||||
char** Authenticator::getenvlist(void)
|
||||
{
|
||||
return pam_getenvlist(pam_handle);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<( std::ostream& os, const PAM::Exception& e)
|
||||
{
|
||||
os << e.func_name << ": " << e.errstr;
|
||||
return os;
|
||||
}
|
106
slim/PAM.h
Normal file
106
slim/PAM.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
Copyright (C) 2007 Martin Parm
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PAM_H_
|
||||
#define _PAM_H_
|
||||
#include <string>
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#ifdef __LIBPAM_VERSION
|
||||
#include <security/pam_misc.h>
|
||||
#endif
|
||||
|
||||
namespace PAM
|
||||
{
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
int errnum;
|
||||
std::string errstr;
|
||||
std::string func_name;
|
||||
Exception(pam_handle_t* _pam_handle,
|
||||
const std::string& _func_name,
|
||||
int _errnum);
|
||||
virtual ~Exception(void);
|
||||
};
|
||||
|
||||
class Auth_Exception: public Exception
|
||||
{
|
||||
public:
|
||||
Auth_Exception(pam_handle_t* _pam_handle,
|
||||
const std::string& _func_name,
|
||||
int _errnum);
|
||||
};
|
||||
|
||||
class Cred_Exception: public Exception
|
||||
{
|
||||
public:
|
||||
Cred_Exception(pam_handle_t* _pam_handle,
|
||||
const std::string& _func_name,
|
||||
int _errnum);
|
||||
};
|
||||
|
||||
|
||||
class Authenticator
|
||||
{
|
||||
private:
|
||||
struct pam_conv pam_conversation;
|
||||
pam_handle_t* pam_handle;
|
||||
int last_result;
|
||||
|
||||
int _end(void);
|
||||
|
||||
public:
|
||||
typedef int (conversation)(int num_msg,
|
||||
const struct pam_message **msg,
|
||||
struct pam_response **resp,
|
||||
void *appdata_ptr);
|
||||
|
||||
enum ItemType {
|
||||
Service = PAM_SERVICE,
|
||||
User = PAM_USER,
|
||||
User_Prompt = PAM_USER_PROMPT,
|
||||
TTY = PAM_TTY,
|
||||
Requestor = PAM_RUSER,
|
||||
Host = PAM_RHOST,
|
||||
Conv = PAM_CONV,
|
||||
#ifdef __LIBPAM_VERSION
|
||||
/* Fail_Delay = PAM_FAIL_DELAY */
|
||||
#endif
|
||||
};
|
||||
|
||||
public:
|
||||
Authenticator(conversation* conv, void* data=0);
|
||||
~Authenticator(void);
|
||||
|
||||
void start(const std::string& service);
|
||||
void end(void);
|
||||
void set_item(const ItemType item, const void* value);
|
||||
const void* get_item(const ItemType item);
|
||||
#ifdef __LIBPAM_VERSION
|
||||
void fail_delay(const unsigned int micro_sec);
|
||||
#endif
|
||||
void authenticate(void);
|
||||
void check_acct(void);
|
||||
void open_session(void);
|
||||
void close_session(void);
|
||||
void setenv(const std::string& key, const std::string& value);
|
||||
void delenv(const std::string& key);
|
||||
const char* getenv(const std::string& key);
|
||||
char** getenvlist(void);
|
||||
|
||||
private:
|
||||
/* Explicitly disable copy constructor and copy assignment */
|
||||
Authenticator(const PAM::Authenticator&);
|
||||
Authenticator& operator=(const PAM::Authenticator&);
|
||||
};
|
||||
}
|
||||
|
||||
std::ostream& operator<<( std::ostream& os, const PAM::Exception& e);
|
||||
#endif /* _PAM_H_ */
|
69
slim/README
Normal file
69
slim/README
Normal file
|
@ -0,0 +1,69 @@
|
|||
README file for SLiM
|
||||
|
||||
Rob Pearce <slim@flitspace.org.uk>
|
||||
|
||||
INTRODUCTION
|
||||
SLiM (Simple Login Manager) is a graphical login manager for X11.
|
||||
It aims to be simple, fast and independent from the various
|
||||
desktop environments.
|
||||
SLiM was originally based on the last stable release of Login.app
|
||||
by Per Lidén.
|
||||
|
||||
Features:
|
||||
- External themes and configuration
|
||||
- PNG support with alpha transparency for panel
|
||||
- PNG / JPEG support for backgrounds
|
||||
- XFT / freetype support
|
||||
- Double or single (GDM-style) inputbox support
|
||||
- PAM support for authentication
|
||||
- Compatible with ConsoleKit or logind, OpenRC or systemd, etc.
|
||||
- CMake build procedure
|
||||
|
||||
INSTALLATION
|
||||
see the INSTALL file
|
||||
|
||||
USAGE
|
||||
SLiM is intended to be run automatically as part of the system
|
||||
startup. Get your SysVInint, OpenRC or systemd to run the slim
|
||||
executable, with the -d option if you want it to run as a daemon
|
||||
in the background (recommended for OpenRC, systemd may work
|
||||
better without)
|
||||
|
||||
As you would expect of a login manager, you enter your username
|
||||
and password to login. By default, the ~/.xinitrc file is run,
|
||||
so be sure to have a working .xinitrc file in your home. This
|
||||
behaviour is configurable, and may be set up differently by the
|
||||
distro package.
|
||||
|
||||
Special usernames can be entered to run commands that are
|
||||
configurable in the config file:
|
||||
- console: start a console login
|
||||
- exit: exit SLiM (this may not have desirable results)
|
||||
- halt: shut down the system
|
||||
- reboot: reboot the system
|
||||
|
||||
Pressing the F11 key executes a user-specified command (see the
|
||||
configuration file). The default is to take a screenshot, if the
|
||||
'import' program is available.
|
||||
|
||||
CONFIGURATION
|
||||
/etc/slim.conf is the main configuration file. Alternative files
|
||||
can be specified on the command line.
|
||||
Options are explained in the file itself
|
||||
|
||||
THEMES
|
||||
The appearance (and some parts of the behaviour) of SLiM depends
|
||||
on the "theme" specified by the configuration file. See the file
|
||||
THEMES for details.
|
||||
|
||||
COPYRIGHT
|
||||
SLiM is copyright (c) 2004-13 by Simone Rota, Johannes Winkelmann,
|
||||
Nobuhiro Iwamatsu and 2022-23 by Rob Pearce. It is available under the
|
||||
GNU General Public License.
|
||||
See the COPYING file for the complete license.
|
||||
|
||||
Image handling code adapted and extended from xplanet 1.0.1,
|
||||
copyright (c) 2002-04 by Hari Nair
|
||||
|
||||
Login.app is copyright (c) 1997, 1998 by Per Liden and is
|
||||
licensed through the GNU General Public License.
|
136
slim/THEMES
Normal file
136
slim/THEMES
Normal file
|
@ -0,0 +1,136 @@
|
|||
Quick THEME howto for SLiM
|
||||
|
||||
Some basic information regarding the slim theme format.
|
||||
Read this file if you plan to make some theme for
|
||||
the program, and of course have a look at the included themes
|
||||
|
||||
GENERAL CONCEPT
|
||||
A SLiM theme essentially consists of:
|
||||
- a background image (background.png or background.jpg)
|
||||
- a panel image (panel.png or panel.jpg)
|
||||
- input box(es) and messages and their placement
|
||||
and properties (slim.theme)
|
||||
|
||||
The panel and background images can be a PNG or JPEG file.
|
||||
The panel is blended into the background image,
|
||||
taking care of alpha transparency.
|
||||
|
||||
SUPPORTED FORMATS
|
||||
- fonts: use the xft font specs, ie: Verdana:size=16:bold
|
||||
- colors: use html hex format, ie #0066CC
|
||||
- positions: can be either absolute in pixels, ie 350
|
||||
or relative to the container, ie 50% is in the middle
|
||||
of the screen.
|
||||
|
||||
OPTIONS
|
||||
The following is an example slim.theme file
|
||||
----------------------------------------------------------------------
|
||||
# Color, font, position for the messages (ie: shutting down)
|
||||
msg_color #FFFFFF
|
||||
msg_font Verdana:size=16:bold
|
||||
msg_x 50%
|
||||
msg_y 30
|
||||
|
||||
# Color, font, position for the session list
|
||||
session_color #FFFFFF
|
||||
session_font Verdana:size=16:bold
|
||||
session_x 50%
|
||||
session_y 90%
|
||||
|
||||
# style of background ('stretch', 'tile', 'center') and color
|
||||
background_style stretch
|
||||
background_color #FF0033
|
||||
|
||||
# Horizonatal and vertical position for the panel.
|
||||
input_panel_x 50%
|
||||
input_panel_y 40%
|
||||
|
||||
# Input controls horizontal and vertical positions relative to
|
||||
# the panel.
|
||||
# Set input_pass_x and input_pass_y to -1 to use a single input
|
||||
# box for username/password (GDM Style).
|
||||
# Note that these fields only accept absolute values.
|
||||
input_name_x 40
|
||||
input_name_y 100
|
||||
input_pass_x 40
|
||||
input_pass_y 120
|
||||
|
||||
# Input controls font and color
|
||||
input_font Verdana:size=12
|
||||
input_color #000000
|
||||
|
||||
# Welcome message position. (relative to the panel)
|
||||
# use -1 for both values or comment the options to disable
|
||||
# the welcome message
|
||||
welcome_x 50%
|
||||
welcome_y 38
|
||||
|
||||
# Font and color for the welcome message
|
||||
welcome_font Verdana:size=16:bold:slant=italic
|
||||
welcome_color #d7dde8
|
||||
|
||||
# 'Enter username' font and foreground/background color
|
||||
username_font Verdana:size=12
|
||||
username_color #d7dde8
|
||||
|
||||
# 'Enter username' and 'Enter password' position (relative to the panel)
|
||||
# use -1 for both values to disable the message
|
||||
# note that in case of single inputbox the password values are ignored.
|
||||
username_x 50%
|
||||
username_y 146
|
||||
password_x 50%
|
||||
password_y 146
|
||||
|
||||
# The message to be displayed. Leave blank if no message
|
||||
# is needed (ie, when already present in the panel image)
|
||||
username_msg Please enter your username
|
||||
password_msg Please enter your password
|
||||
|
||||
# Optional message to show on a failed login. Similar set of values
|
||||
# to the above. Use -1 for the x & y to disable (default).
|
||||
password_feedback_x 50%
|
||||
password_feedback_y 165
|
||||
password_feedback_msg Authentication failed
|
||||
# The font and color are inherited from msg_xxx
|
||||
----------------------------------------------------------------------
|
||||
|
||||
SHADOWS
|
||||
|
||||
The 'msg', 'input', 'welcome', 'session' and 'username' sections
|
||||
support shadows; three values can be configured:
|
||||
- color: the shadow color
|
||||
- x offset: the offset in x direction, relative to the normal text
|
||||
- y offset: the offset in y direction, relative to the normal text
|
||||
|
||||
So to add a text shadow to the welcome message, add the following
|
||||
to slim.conf:
|
||||
----------------------------------------------------------------------
|
||||
welcome_shadow_xoffset -2
|
||||
welcome_shadow_yoffset 2
|
||||
welcome_shadow_color #ff0000
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The other keys are analogous:
|
||||
----------------------------------------------------------------------
|
||||
# for username and password label
|
||||
username_shadow_xoffset 2
|
||||
username_shadow_yoffset -2
|
||||
username_shadow_color #ff0000
|
||||
|
||||
# for the input fields
|
||||
input_shadow_xoffset 1
|
||||
input_shadow_yoffset 1
|
||||
input_shadow_color #0000ff
|
||||
|
||||
# for the messages:
|
||||
msg_shadow_xoffset 1
|
||||
msg_shadow_yoffset 1
|
||||
msg_shadow_color #ff00ff
|
||||
|
||||
# For the session:
|
||||
session_shadow_xoffset 1
|
||||
session_shadow_yoffset 1
|
||||
session_shadow_color #ff00ff
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
17
slim/TODO
Normal file
17
slim/TODO
Normal file
|
@ -0,0 +1,17 @@
|
|||
Important things
|
||||
----------------
|
||||
- Make it work better with multi-screen setups
|
||||
|
||||
Improvements suggested long ago
|
||||
-------------------------------
|
||||
- Don't start X server if theme's not found
|
||||
- i18n
|
||||
- FreeBSD fixes
|
||||
- restart X server on ctrl-alt-backspace
|
||||
|
||||
Other thoughts for improvement
|
||||
------------------------------
|
||||
- position text to fit screen, e.g. when at 90% position
|
||||
- allow nested config
|
||||
- make slimlock handle themes the same as slim
|
||||
- option to run X server as non-root
|
1455
slim/app.cpp
Normal file
1455
slim/app.cpp
Normal file
File diff suppressed because it is too large
Load diff
115
slim/app.h
Normal file
115
slim/app.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 1997, 1998 Per Liden
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _APP_H_
|
||||
#define _APP_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include "panel.h"
|
||||
#include "cfg.h"
|
||||
#include "image.h"
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include "PAM.h"
|
||||
#endif
|
||||
#ifdef USE_CONSOLEKIT
|
||||
#include "Ck.h"
|
||||
#endif
|
||||
|
||||
class App
|
||||
{
|
||||
public:
|
||||
App(int argc, char **argv);
|
||||
~App();
|
||||
void Run();
|
||||
int GetServerPID();
|
||||
void RestartServer();
|
||||
void StopServer();
|
||||
|
||||
/* Lock functions */
|
||||
void GetLock();
|
||||
void RemoveLock();
|
||||
|
||||
bool isServerStarted();
|
||||
|
||||
private:
|
||||
void Login();
|
||||
void Reboot();
|
||||
void Halt();
|
||||
void Suspend();
|
||||
void Console();
|
||||
void Exit();
|
||||
void KillAllClients(Bool top);
|
||||
void ReadConfig();
|
||||
void OpenLog();
|
||||
void CloseLog();
|
||||
void CreateServerAuth();
|
||||
char *StrConcat(const char *str1, const char *str2);
|
||||
void UpdatePid();
|
||||
|
||||
bool AuthenticateUser(bool focuspass);
|
||||
|
||||
static void replaceVariables(std::string &input,
|
||||
const std::string &var,
|
||||
const std::string &value);
|
||||
|
||||
/* Server functions */
|
||||
int StartServer();
|
||||
int ServerTimeout(int timeout, char *string);
|
||||
int WaitForServer();
|
||||
|
||||
/* Private data */
|
||||
Window Root; ///< The root window of the default screen, on which to draw
|
||||
Display *Dpy; ///< Connection to the X-server
|
||||
int Scr; ///< Which "screen" to use (which will be the default one)
|
||||
Panel *LoginPanel; ///< The panel we display and interact through
|
||||
int ServerPID; ///< Process ID of the X-server we launched
|
||||
const char *DisplayName; ///< The display to request, usually ":0.0"
|
||||
bool serverStarted; ///< Whether we (think we) have started an X server
|
||||
|
||||
#ifdef USE_PAM
|
||||
PAM::Authenticator pam; ///< Interface to the PAM authentication library
|
||||
#endif
|
||||
#ifdef USE_CONSOLEKIT
|
||||
Ck::Session ck; ///< Interface to ConsoleKit, if used
|
||||
#endif
|
||||
|
||||
/* Options */
|
||||
Cfg *cfg; ///< Collection of options from the configuration file
|
||||
|
||||
void blankScreen();
|
||||
|
||||
bool firstlogin; ///< Whether to exhibit first login behaviour, or repeat
|
||||
bool daemonmode; ///< Are we running as a daemon?
|
||||
bool force_nodaemon; ///< Are we forced NOT to be a daemon?
|
||||
/* For testing themes */
|
||||
char *testtheme; ///< Name of the theme to test, from command line
|
||||
bool testing; ///< Whether we're running in theme testing mode
|
||||
short tww, twh; ///< The user's requested test window size
|
||||
|
||||
#ifdef USE_CONSOLEKIT
|
||||
bool consolekit_support_enabled; ///< Whether to use ConsoleKit (not compatible with systemd)
|
||||
#endif
|
||||
|
||||
std::string themeName; ///< Name of the theme in use
|
||||
std::string mcookie; ///< Randomly generated X auth cookie
|
||||
|
||||
const int mcookiesize;
|
||||
};
|
||||
|
||||
#endif /* _APP_H_ */
|
478
slim/cfg.cpp
Normal file
478
slim/cfg.cpp
Normal file
|
@ -0,0 +1,478 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
* Copyright (C) 2012-13 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
* Copyright (C) 2022-23 Rob Pearce <slim@flitspace.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "util.h" // for Util::random
|
||||
#include "log.h" // for logStream
|
||||
|
||||
#include "cfg.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef pair<string,string> option;
|
||||
|
||||
/**
|
||||
* Constructor: creates the Cfg object and populates the available options
|
||||
* with default values.
|
||||
*/
|
||||
Cfg::Cfg()
|
||||
: currentSession(-1)
|
||||
{
|
||||
/* Configuration options */
|
||||
options.insert(option("default_path","/bin:/usr/bin:/usr/local/bin"));
|
||||
options.insert(option("default_xserver","/usr/bin/X"));
|
||||
options.insert(option("xserver_arguments",""));
|
||||
options.insert(option("numlock",""));
|
||||
options.insert(option("daemon",""));
|
||||
options.insert(option("xauth_path","/usr/bin/xauth"));
|
||||
options.insert(option("login_cmd","exec /bin/bash -login ~/.xinitrc %session"));
|
||||
options.insert(option("halt_cmd","/sbin/shutdown -h now"));
|
||||
options.insert(option("reboot_cmd","/sbin/shutdown -r now"));
|
||||
options.insert(option("suspend_cmd",""));
|
||||
options.insert(option("sessionstart_cmd",""));
|
||||
options.insert(option("sessionstop_cmd",""));
|
||||
options.insert(option("console_cmd","/usr/bin/xterm -C -fg white -bg black +sb -g %dx%d+%d+%d -fn %dx%d -T ""Console login"" -e /bin/sh -c ""/bin/cat /etc/issue; exec /bin/login"""));
|
||||
options.insert(option("screenshot_cmd","import -window root /slim.png"));
|
||||
options.insert(option("default_user",""));
|
||||
options.insert(option("focus_password","no"));
|
||||
options.insert(option("auto_login","no"));
|
||||
options.insert(option("current_theme","default"));
|
||||
options.insert(option("lockfile","/var/run/slim.lock"));
|
||||
options.insert(option("logfile","/var/log/slim.log"));
|
||||
options.insert(option("authfile","/var/run/slim.auth"));
|
||||
options.insert(option("shutdown_msg","The system is halting..."));
|
||||
options.insert(option("reboot_msg","The system is rebooting..."));
|
||||
options.insert(option("sessions", ""));
|
||||
options.insert(option("sessiondir",""));
|
||||
options.insert(option("hidecursor","false"));
|
||||
|
||||
/* Theme stuff */
|
||||
options.insert(option("background_style","stretch"));
|
||||
options.insert(option("background_color","#CCCCCC"));
|
||||
|
||||
options.insert(option("input_panel_x","50%")); /* Panel position on screen */
|
||||
options.insert(option("input_panel_y","40%"));
|
||||
options.insert(option("input_font","Verdana:size=11"));
|
||||
options.insert(option("input_color", "#000000"));
|
||||
options.insert(option("input_shadow_xoffset", "0"));
|
||||
options.insert(option("input_shadow_yoffset", "0"));
|
||||
options.insert(option("input_shadow_color","#FFFFFF"));
|
||||
options.insert(option("input_name_x","200")); /* relative to panel */
|
||||
options.insert(option("input_name_y","154"));
|
||||
options.insert(option("input_pass_x","-1")); /* default is single inputbox */
|
||||
options.insert(option("input_pass_y","-1"));
|
||||
|
||||
options.insert(option("welcome_msg","Welcome to %host"));
|
||||
options.insert(option("welcome_font","Verdana:size=14"));
|
||||
options.insert(option("welcome_color","#FFFFFF"));
|
||||
options.insert(option("welcome_x","-1"));
|
||||
options.insert(option("welcome_y","-1"));
|
||||
options.insert(option("welcome_shadow_xoffset", "0"));
|
||||
options.insert(option("welcome_shadow_yoffset", "0"));
|
||||
options.insert(option("welcome_shadow_color","#FFFFFF"));
|
||||
|
||||
options.insert(option("username_msg","Please enter your username"));
|
||||
options.insert(option("username_font","Verdana:size=12"));
|
||||
options.insert(option("username_color","#FFFFFF"));
|
||||
options.insert(option("username_x","-1"));
|
||||
options.insert(option("username_y","-1"));
|
||||
options.insert(option("username_shadow_xoffset", "0"));
|
||||
options.insert(option("username_shadow_yoffset", "0"));
|
||||
options.insert(option("username_shadow_color","#FFFFFF"));
|
||||
|
||||
options.insert(option("password_msg","Please enter your password"));
|
||||
options.insert(option("password_x","-1"));
|
||||
options.insert(option("password_y","-1"));
|
||||
|
||||
options.insert(option("msg_font","Verdana:size=16:bold"));
|
||||
options.insert(option("msg_color","#FFFFFF"));
|
||||
options.insert(option("msg_x","40"));
|
||||
options.insert(option("msg_y","40"));
|
||||
options.insert(option("msg_shadow_xoffset", "0"));
|
||||
options.insert(option("msg_shadow_yoffset", "0"));
|
||||
options.insert(option("msg_shadow_color","#FFFFFF"));
|
||||
|
||||
options.insert(option("session_msg","Session:"));
|
||||
options.insert(option("session_font","Verdana:size=16:bold"));
|
||||
options.insert(option("session_color","#FFFFFF"));
|
||||
options.insert(option("session_x","50%"));
|
||||
options.insert(option("session_y","90%"));
|
||||
options.insert(option("session_shadow_xoffset", "0"));
|
||||
options.insert(option("session_shadow_yoffset", "0"));
|
||||
options.insert(option("session_shadow_color","#FFFFFF"));
|
||||
|
||||
// What to do if the authorisation fails
|
||||
options.insert(option("keep_user_on_fail", "0"));
|
||||
options.insert(option("wrong_passwd_timeout", "2"));
|
||||
options.insert(option("passwd_feedback_msg", "Authentication failed"));
|
||||
options.insert(option("passwd_feedback_capslock", "Authentication failed (CapsLock is on)"));
|
||||
options.insert(option("passwd_feedback_x", "-1")); /* no feedback by default */
|
||||
options.insert(option("passwd_feedback_y", "-1"));
|
||||
options.insert(option("bell", "0"));
|
||||
|
||||
// slimlock-specific options
|
||||
options.insert(option("dpms_standby_timeout", "60"));
|
||||
options.insert(option("dpms_off_timeout", "600"));
|
||||
options.insert(option("show_username", "1"));
|
||||
options.insert(option("show_welcome_msg", "0"));
|
||||
options.insert(option("tty_lock", "1"));
|
||||
|
||||
error = "";
|
||||
}
|
||||
|
||||
Cfg::~Cfg()
|
||||
{
|
||||
options.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses known options from the given configfile / themefile
|
||||
*
|
||||
* @param configfile Path to configuration or theme
|
||||
* @return true on sucess, false if file not found
|
||||
*/
|
||||
bool Cfg::readConf(string configfile)
|
||||
{
|
||||
int n = -1;
|
||||
size_t pos = 0;
|
||||
string line, next, op, fn(configfile);
|
||||
map<string,string>::iterator it;
|
||||
ifstream cfgfile(fn.c_str());
|
||||
|
||||
if (!cfgfile)
|
||||
{
|
||||
error = "Cannot read configuration file: " + configfile;
|
||||
return false;
|
||||
}
|
||||
while (getline(cfgfile, line))
|
||||
{
|
||||
// New parser to fix ticket #4
|
||||
pos = line.length();
|
||||
if ( ( pos > 0 ) && ( line[pos-1] == '\\' ) )
|
||||
{
|
||||
line.replace ( pos-1, 1, " " );
|
||||
next = next + line;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !next.empty() )
|
||||
{
|
||||
line = next + line;
|
||||
next = "";
|
||||
}
|
||||
|
||||
// Ignore blank lines and comment lines
|
||||
if ( line.empty() || line[0] == '#' )
|
||||
continue;
|
||||
|
||||
// Now parse and assign
|
||||
if ( !parseOption ( line ) )
|
||||
cerr << error << '\n'; // not a fatal error
|
||||
}
|
||||
cfgfile.close();
|
||||
|
||||
fillSessionList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an option value from a line. Returns true on success.
|
||||
*/
|
||||
bool Cfg::parseOption ( string line )
|
||||
{
|
||||
size_t pos = 0;
|
||||
const string delims = " \t";
|
||||
string name, value;
|
||||
|
||||
// First split the line into a name/value pair
|
||||
pos = line.find_first_of ( delims );
|
||||
if ( pos == string::npos )
|
||||
{
|
||||
error = "Badly formed line: " + line;
|
||||
return false;
|
||||
}
|
||||
name = line.substr ( 0, pos );
|
||||
value = Trim ( line.substr ( pos ) );
|
||||
if ( value.empty() )
|
||||
{
|
||||
error = "Badly formed line: " + line;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Look to see if it's a known option
|
||||
if ( options.find ( name ) == options.end() )
|
||||
{
|
||||
error = "Unknown option name: " + name;
|
||||
return false;
|
||||
}
|
||||
// finally assign it
|
||||
options[name] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const string& Cfg::getError() const
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
string& Cfg::getOption(string option)
|
||||
{
|
||||
return options[option];
|
||||
}
|
||||
|
||||
/* return a trimmed string */
|
||||
string Cfg::Trim( const string& s )
|
||||
{
|
||||
if ( s.empty() ) {
|
||||
return s;
|
||||
}
|
||||
int pos = 0;
|
||||
string line = s;
|
||||
int len = line.length();
|
||||
while ( pos < len && isspace( line[pos] ) ) {
|
||||
++pos;
|
||||
}
|
||||
line.erase( 0, pos );
|
||||
pos = line.length()-1;
|
||||
while ( pos > -1 && isspace( line[pos] ) ) {
|
||||
--pos;
|
||||
}
|
||||
if ( pos != -1 ) {
|
||||
line.erase( pos+1 );
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/* Return the welcome message with replaced vars */
|
||||
string Cfg::getWelcomeMessage()
|
||||
{
|
||||
string s = getOption("welcome_msg");
|
||||
int n = s.find("%host");
|
||||
if (n >= 0) {
|
||||
string tmp = s.substr(0, n);
|
||||
char host[40];
|
||||
gethostname(host,40);
|
||||
tmp = tmp + host;
|
||||
tmp = tmp + s.substr(n+5, s.size() - n);
|
||||
s = tmp;
|
||||
}
|
||||
n = s.find("%domain");
|
||||
if (n >= 0) {
|
||||
string tmp = s.substr(0, n);
|
||||
char domain[40];
|
||||
if ( getdomainname(domain,40) == 0 )
|
||||
tmp = tmp + domain;
|
||||
else
|
||||
tmp = tmp + "<unknown domain>";
|
||||
tmp = tmp + s.substr(n+7, s.size() - n);
|
||||
s = tmp;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int Cfg::string2int(const char* string, bool* ok)
|
||||
{
|
||||
char* err = 0;
|
||||
int l = (int)strtol(string, &err, 10);
|
||||
if (ok) {
|
||||
*ok = (*err == 0);
|
||||
}
|
||||
return (*err == 0) ? l : 0;
|
||||
}
|
||||
|
||||
int Cfg::getIntOption(std::string option)
|
||||
{
|
||||
return string2int(options[option].c_str());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get absolute position
|
||||
*
|
||||
* Converts a config position string into absolute coordinates. If the string
|
||||
* is a plain number, this is just an atoi but if there is a percentage sign
|
||||
* then the value is converted using the size of the canvas and the object.
|
||||
*
|
||||
* @param position Configured position as a string
|
||||
* @param max Size of canvas in the relevant axis
|
||||
* @param width Size of the object being placed
|
||||
* @return Absolute coordinate to achieve placement
|
||||
*/
|
||||
int Cfg::absolutepos(const string& position, int max, int width)
|
||||
{
|
||||
int n = position.find("%");
|
||||
if (n>0) { /* X Position expressed in percentage */
|
||||
int result = (max*string2int(position.substr(0, n).c_str())/100) - (width / 2);
|
||||
return result < 0 ? 0 : result ;
|
||||
} else { /* Absolute X position */
|
||||
return string2int(position.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/* split a comma separated string into a vector of strings */
|
||||
void Cfg::split(vector<string>& v, const string& str, char c, bool useEmpty)
|
||||
{
|
||||
v.clear();
|
||||
string::const_iterator s = str.begin();
|
||||
string tmp;
|
||||
while (true) {
|
||||
string::const_iterator begin = s;
|
||||
while (*s != c && s != str.end())
|
||||
{
|
||||
++s;
|
||||
}
|
||||
tmp = string(begin, s);
|
||||
if (useEmpty || tmp.size() > 0)
|
||||
v.push_back(tmp);
|
||||
if (s == str.end()) {
|
||||
break;
|
||||
}
|
||||
if (++s == str.end()) {
|
||||
if (useEmpty)
|
||||
v.push_back("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cfg::fillSessionList()
|
||||
{
|
||||
string strSessionList = getOption("sessions");
|
||||
string strSessionDir = getOption("sessiondir");
|
||||
|
||||
sessions.clear();
|
||||
|
||||
if ( !strSessionDir.empty() )
|
||||
{
|
||||
DIR *pDir = opendir(strSessionDir.c_str());
|
||||
|
||||
if (pDir != NULL) {
|
||||
struct dirent *pDirent = NULL;
|
||||
|
||||
while ((pDirent = readdir(pDir)) != NULL) {
|
||||
string strFile(strSessionDir);
|
||||
strFile += "/";
|
||||
strFile += pDirent->d_name;
|
||||
|
||||
struct stat oFileStat;
|
||||
|
||||
if (stat(strFile.c_str(), &oFileStat) == 0) {
|
||||
if (S_ISREG(oFileStat.st_mode) &&
|
||||
access(strFile.c_str(), R_OK) == 0){
|
||||
ifstream desktop_file(strFile.c_str());
|
||||
if (desktop_file){
|
||||
string line, session_name = "", session_exec = "";
|
||||
while (getline( desktop_file, line )) {
|
||||
if (line.substr(0, 5) == "Name=") {
|
||||
session_name = line.substr(5);
|
||||
if (!session_exec.empty())
|
||||
break;
|
||||
}
|
||||
else if (line.substr(0, 5) == "Exec=") {
|
||||
session_exec = line.substr(5);
|
||||
if (!session_name.empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
desktop_file.close();
|
||||
if (!session_name.empty() && !session_exec.empty()) {
|
||||
pair<string,string> session(session_name,session_exec);
|
||||
sessions.push_back(session);
|
||||
} else if (access(strFile.c_str(), X_OK) == 0) {
|
||||
pair<string,string> session(string(pDirent->d_name),strFile);
|
||||
sessions.push_back(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(pDir);
|
||||
}
|
||||
}
|
||||
|
||||
if (sessions.empty())
|
||||
{
|
||||
if (strSessionList.empty())
|
||||
{
|
||||
pair<string,string> session("","");
|
||||
sessions.push_back(session);
|
||||
}
|
||||
else
|
||||
{
|
||||
// iterate through the split of the session list
|
||||
vector<string> sessit;
|
||||
split(sessit,strSessionList,',',false);
|
||||
for (vector<string>::iterator it = sessit.begin(); it != sessit.end(); ++it)
|
||||
{
|
||||
pair<string,string> session(*it,*it);
|
||||
sessions.push_back(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pair<string,string> Cfg::nextSession()
|
||||
{
|
||||
currentSession = (currentSession + 1) % sessions.size();
|
||||
return sessions[currentSession];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Choose a theme at random from the list in the config file. IF the theme
|
||||
* file cannot be found then issue a warning and try again.
|
||||
*/
|
||||
string Cfg::findValidRandomTheme ( const string& set )
|
||||
{
|
||||
/* extract random theme from theme set; return empty string on error */
|
||||
string name = set;
|
||||
struct stat buf;
|
||||
|
||||
if (name[name.length()-1] == ',')
|
||||
{
|
||||
name.erase(name.length() - 1);
|
||||
}
|
||||
|
||||
Util::srandom(Util::makeseed());
|
||||
|
||||
vector<string> themes;
|
||||
string themefile;
|
||||
Cfg::split(themes, name, ',');
|
||||
do {
|
||||
int sel = Util::random() % themes.size();
|
||||
|
||||
name = Cfg::Trim(themes[sel]);
|
||||
themefile = string(THEMESDIR) +"/" + name + THEMESFILE;
|
||||
if (stat(themefile.c_str(), &buf) != 0)
|
||||
{
|
||||
themes.erase(find(themes.begin(), themes.end(), name));
|
||||
logStream << APPNAME << ": Invalid theme in config: "
|
||||
<< name << endl;
|
||||
name = "";
|
||||
}
|
||||
} while (name == "" && themes.size());
|
||||
return name;
|
||||
}
|
||||
|
58
slim/cfg.h
Normal file
58
slim/cfg.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _CFG_H_
|
||||
#define _CFG_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#define INPUT_MAXLENGTH_NAME 30
|
||||
#define INPUT_MAXLENGTH_PASSWD 50
|
||||
|
||||
#define CFGFILE SYSCONFDIR"/slim.conf"
|
||||
#define THEMESDIR PKGDATADIR"/themes"
|
||||
#define THEMESFILE "/slim.theme"
|
||||
|
||||
class Cfg
|
||||
{
|
||||
|
||||
public:
|
||||
Cfg();
|
||||
~Cfg();
|
||||
|
||||
bool readConf(std::string configfile);
|
||||
bool parseOption ( std::string line );
|
||||
const std::string& getError() const;
|
||||
std::string& getOption(std::string option);
|
||||
int getIntOption(std::string option);
|
||||
std::string getWelcomeMessage();
|
||||
|
||||
static int absolutepos(const std::string &position, int max, int width);
|
||||
static int string2int(const char *string, bool *ok = 0);
|
||||
static void split(std::vector<std::string> &v, const std::string &str,
|
||||
char c, bool useEmpty=true);
|
||||
static std::string Trim(const std::string &s);
|
||||
|
||||
std::pair<std::string,std::string> nextSession();
|
||||
static std::string findValidRandomTheme(const std::string &set);
|
||||
|
||||
private:
|
||||
void fillSessionList();
|
||||
|
||||
private:
|
||||
std::map<std::string,std::string> options;
|
||||
std::vector<std::pair<std::string,std::string> > sessions;
|
||||
int currentSession;
|
||||
std::string error;
|
||||
};
|
||||
|
||||
#endif /* _CFG_H_ */
|
71
slim/cmake/modules/FONTCONFIGConfig.cmake
Normal file
71
slim/cmake/modules/FONTCONFIGConfig.cmake
Normal file
|
@ -0,0 +1,71 @@
|
|||
#
|
||||
# Find the native FONTCONFIG includes and library
|
||||
#
|
||||
|
||||
# This module defines
|
||||
# FONTCONFIG_INCLUDE_DIR, where to find art*.h etc
|
||||
# FONTCONFIG_LIBRARY, the libraries to link against to use FONTCONFIG.
|
||||
# FONTCONFIG_FOUND, If false, do not try to use FONTCONFIG.
|
||||
# LIBFONTCONFIG_LIBS, link information
|
||||
# LIBFONTCONFIG_CFLAGS, cflags for include information
|
||||
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 2.5)
|
||||
INCLUDE(UsePkgConfig)
|
||||
PKGCONFIG(fontconfig _fontconfigIncDir _fontconfigLinkDir _fontconfigLinkFlags _fontconfigCflags)
|
||||
SET(FONTCONFIG_LIBS ${_fontconfigCflags})
|
||||
ELSE (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 2.5)
|
||||
INCLUDE(FindPkgConfig)
|
||||
pkg_search_module(FONTCONFIG REQUIRED fontconfig)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 2.5)
|
||||
|
||||
#INCLUDE(UsePkgConfig)
|
||||
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
#PKGCONFIG(fontconfig _fontconfigIncDir _fontconfigLinkDir _fontconfigLinkFlags _fontconfigCflags)
|
||||
|
||||
#SET(FONTCONFIG_LIBS ${_fontconfigCflags})
|
||||
|
||||
IF(BUILD_OSX_BUNDLE)
|
||||
FIND_PATH(FONTCONFIG_INCLUDE_DIR
|
||||
NAMES fontconfig/fontconfig.h
|
||||
PATHS ${FONTCONFIG_INCLUDE_DIRS} /opt/local/include
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
FIND_LIBRARY(FONTCONFIG_LIBRARY
|
||||
NAMES fontconfig
|
||||
PATHS ${FONTCONFIG_LIBRARY_DIRS} /opt/local/lib
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
ELSE(BUILD_OSX_BUNDLE)
|
||||
FIND_PATH(FONTCONFIG_INCLUDE_DIR
|
||||
NAMES fontconfig/fontconfig.h
|
||||
PATHS ${FONTCONFIG_INCLUDE_DIRS}
|
||||
${_fontconfigIncDir}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
PATH_SUFFIXES fontconfig
|
||||
)
|
||||
# quick hack as the above finds it nicely but our source includes the libart_lgpl text at the moment
|
||||
#STRING(REGEX REPLACE "/libart_lgpl" "" FONTCONFIG_INCLUDE_DIR ${FONTCONFIG_INCLUDE_DIR})
|
||||
FIND_LIBRARY(FONTCONFIG_LIBRARY NAMES fontconfig
|
||||
PATHS ${FONTCONFIG_LIBRARY_DIRS} /usr/lib /usr/local/lib
|
||||
)
|
||||
ENDIF(BUILD_OSX_BUNDLE)
|
||||
|
||||
|
||||
# MESSAGE(STATUS "fclib ${FONTCONFIG_LIBRARY}")
|
||||
# MESSAGE(STATUS "fcinclude ${FONTCONFIG_INCLUDE_DIR}")
|
||||
|
||||
|
||||
IF (FONTCONFIG_LIBRARY)
|
||||
IF (FONTCONFIG_INCLUDE_DIR)
|
||||
SET( FONTCONFIG_FOUND "YES" )
|
||||
SET( FONTCONFIG_LIBRARIES ${FONTCONFIG_LIBRARY} )
|
||||
FIND_PROGRAM(FONTCONFIG_CONFIG NAMES fontconfig-config PATHS ${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin /usr/bin /usr/nekoware/bin /usr/X11/bin)
|
||||
# EXEC_PROGRAM(${FONTCONFIG_CONFIG} ARGS --libs OUTPUT_VARIABLE FONTCONFIG_LIBS)
|
||||
# EXEC_PROGRAM(${FONTCONFIG_CONFIG} ARGS --cflags OUTPUT_VARIABLE FONTCONFIG_CFLAGS)
|
||||
# MESSAGE(STATUS ${FONTCONFIG_LIBS})
|
||||
# MESSAGE(STATUS ${FONTCONFIG_CFLAGS})
|
||||
ENDIF (FONTCONFIG_INCLUDE_DIR)
|
||||
ENDIF (FONTCONFIG_LIBRARY)
|
59
slim/cmake/modules/FindCkConnector.cmake
Normal file
59
slim/cmake/modules/FindCkConnector.cmake
Normal file
|
@ -0,0 +1,59 @@
|
|||
# - Try to find the ConsoleKit connector library (libck-connector)
|
||||
# Once done this will define
|
||||
#
|
||||
# CKCONNECTOR_FOUND - system has the CK Connector
|
||||
# CKCONNECTOR_INCLUDE_DIR - the CK Connector include directory
|
||||
# CKCONNECTOR_LIBRARIES - the libraries needed to use CK Connector
|
||||
|
||||
# Copyright (c) 2008, Kevin Kofler, <kevin.kofler@chello.at>
|
||||
# modeled after FindLibArt.cmake:
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
if (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES)
|
||||
|
||||
# in cache already
|
||||
SET(CKCONNECTOR_FOUND TRUE)
|
||||
|
||||
else (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES)
|
||||
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
IF (PKG_CONFIG_FOUND)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
pkg_check_modules(_CKCONNECTOR_PC QUIET ck-connector)
|
||||
ENDIF (PKG_CONFIG_FOUND)
|
||||
ENDIF (NOT WIN32)
|
||||
|
||||
FIND_PATH(CKCONNECTOR_INCLUDE_DIR ck-connector.h
|
||||
${_CKCONNECTOR_PC_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
FIND_LIBRARY(CKCONNECTOR_LIBRARIES NAMES ck-connector
|
||||
PATHS
|
||||
${_CKCONNECTOR_PC_LIBDIR}
|
||||
)
|
||||
|
||||
|
||||
if (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES)
|
||||
set(CKCONNECTOR_FOUND TRUE)
|
||||
endif (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES)
|
||||
|
||||
|
||||
if (CKCONNECTOR_FOUND)
|
||||
if (NOT CkConnector_FIND_QUIETLY)
|
||||
message(STATUS "Found ck-connector: ${CKCONNECTOR_LIBRARIES}")
|
||||
endif (NOT CkConnector_FIND_QUIETLY)
|
||||
else (CKCONNECTOR_FOUND)
|
||||
if (CkConnector_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could NOT find ck-connector")
|
||||
endif (CkConnector_FIND_REQUIRED)
|
||||
endif (CKCONNECTOR_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(CKCONNECTOR_INCLUDE_DIR CKCONNECTOR_LIBRARIES)
|
||||
|
||||
endif (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES)
|
72
slim/cmake/modules/FindDBus.cmake
Normal file
72
slim/cmake/modules/FindDBus.cmake
Normal file
|
@ -0,0 +1,72 @@
|
|||
# - Try to find the low-level D-Bus library
|
||||
# Once done this will define
|
||||
#
|
||||
# DBUS_FOUND - system has D-Bus
|
||||
# DBUS_INCLUDE_DIR - the D-Bus include directory
|
||||
# DBUS_ARCH_INCLUDE_DIR - the D-Bus architecture-specific include directory
|
||||
# DBUS_LIBRARIES - the libraries needed to use D-Bus
|
||||
|
||||
# Copyright (c) 2008, Kevin Kofler, <kevin.kofler@chello.at>
|
||||
# modeled after FindLibArt.cmake:
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
# in cache already
|
||||
SET(DBUS_FOUND TRUE)
|
||||
|
||||
else (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
IF (PKG_CONFIG_FOUND)
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
pkg_check_modules(_DBUS_PC QUIET dbus-1)
|
||||
ENDIF (PKG_CONFIG_FOUND)
|
||||
ENDIF (NOT WIN32)
|
||||
|
||||
FIND_PATH(DBUS_INCLUDE_DIR dbus/dbus.h
|
||||
${_DBUS_PC_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/include/dbus-1.0
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
FIND_PATH(DBUS_ARCH_INCLUDE_DIR dbus/dbus-arch-deps.h
|
||||
${_DBUS_PC_INCLUDE_DIRS}
|
||||
/usr/lib${LIB_SUFFIX}/include
|
||||
/usr/lib${LIB_SUFFIX}/dbus-1.0/include
|
||||
/usr/lib64/include
|
||||
/usr/lib64/dbus-1.0/include
|
||||
/usr/lib/include
|
||||
/usr/lib/dbus-1.0/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(DBUS_LIBRARIES NAMES dbus-1 dbus
|
||||
PATHS
|
||||
${_DBUS_PC_LIBDIR}
|
||||
)
|
||||
|
||||
|
||||
if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
set(DBUS_FOUND TRUE)
|
||||
endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
||||
|
||||
|
||||
if (DBUS_FOUND)
|
||||
if (NOT DBus_FIND_QUIETLY)
|
||||
message(STATUS "Found D-Bus: ${DBUS_LIBRARIES}")
|
||||
endif (NOT DBus_FIND_QUIETLY)
|
||||
else (DBUS_FOUND)
|
||||
if (DBus_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could NOT find D-Bus")
|
||||
endif (DBus_FIND_REQUIRED)
|
||||
endif (DBUS_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES)
|
||||
|
||||
endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES)
|
74
slim/cmake/modules/FindPAM.cmake
Normal file
74
slim/cmake/modules/FindPAM.cmake
Normal file
|
@ -0,0 +1,74 @@
|
|||
# - Try to find the PAM libraries
|
||||
# Once done this will define
|
||||
#
|
||||
# PAM_FOUND - system has pam
|
||||
# PAM_INCLUDE_DIR - the pam include directory
|
||||
# PAM_LIBRARIES - libpam library
|
||||
|
||||
if (PAM_INCLUDE_DIR AND PAM_LIBRARY)
|
||||
# Already in cache, be silent
|
||||
set(PAM_FIND_QUIETLY TRUE)
|
||||
endif (PAM_INCLUDE_DIR AND PAM_LIBRARY)
|
||||
|
||||
find_path(PAM_INCLUDE_DIR NAMES security/pam_appl.h pam/pam_appl.h)
|
||||
find_library(PAM_LIBRARY pam)
|
||||
find_library(DL_LIBRARY dl)
|
||||
|
||||
if (PAM_INCLUDE_DIR AND PAM_LIBRARY)
|
||||
set(PAM_FOUND TRUE)
|
||||
if (DL_LIBRARY)
|
||||
set(PAM_LIBRARIES ${PAM_LIBRARY} ${DL_LIBRARY})
|
||||
else (DL_LIBRARY)
|
||||
set(PAM_LIBRARIES ${PAM_LIBRARY})
|
||||
endif (DL_LIBRARY)
|
||||
|
||||
if (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h)
|
||||
# darwin claims to be something special
|
||||
set(HAVE_PAM_PAM_APPL_H 1)
|
||||
endif (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h)
|
||||
|
||||
if (NOT DEFINED PAM_MESSAGE_CONST)
|
||||
include(CheckCXXSourceCompiles)
|
||||
# XXX does this work with plain c?
|
||||
check_cxx_source_compiles("
|
||||
#if ${HAVE_PAM_PAM_APPL_H}+0
|
||||
# include <pam/pam_appl.h>
|
||||
#else
|
||||
# include <security/pam_appl.h>
|
||||
#endif
|
||||
|
||||
static int PAM_conv(
|
||||
int num_msg,
|
||||
const struct pam_message **msg, /* this is the culprit */
|
||||
struct pam_response **resp,
|
||||
void *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct pam_conv PAM_conversation = {
|
||||
&PAM_conv, /* this bombs out if the above does not match */
|
||||
0
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
" PAM_MESSAGE_CONST)
|
||||
endif (NOT DEFINED PAM_MESSAGE_CONST)
|
||||
set(PAM_MESSAGE_CONST ${PAM_MESSAGE_CONST} CACHE BOOL "PAM expects a conversation function with const pam_message")
|
||||
|
||||
endif (PAM_INCLUDE_DIR AND PAM_LIBRARY)
|
||||
|
||||
if (PAM_FOUND)
|
||||
if (NOT PAM_FIND_QUIETLY)
|
||||
message(STATUS "Found PAM: ${PAM_LIBRARIES}")
|
||||
endif (NOT PAM_FIND_QUIETLY)
|
||||
else (PAM_FOUND)
|
||||
if (PAM_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "PAM was not found")
|
||||
endif(PAM_FIND_REQUIRED)
|
||||
endif (PAM_FOUND)
|
||||
|
||||
mark_as_advanced(PAM_INCLUDE_DIR PAM_LIBRARY DL_LIBRARY PAM_MESSAGE_CONST)
|
40
slim/const.h
Normal file
40
slim/const.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 1997, 1998 Per Liden
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
* Copyright (C) 2022-23 Rob Pearce <slim@flitspace.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _CONST_H_
|
||||
#define _CONST_H_
|
||||
|
||||
#define DISPLAY ":0.0"
|
||||
|
||||
#define CONSOLE_STR "console"
|
||||
#define HALT_STR "halt"
|
||||
#define REBOOT_STR "reboot"
|
||||
#define EXIT_STR "exit"
|
||||
#define SUSPEND_STR "suspend"
|
||||
|
||||
#define HIDE 0
|
||||
#define SHOW 1
|
||||
|
||||
#define OK_EXIT 0
|
||||
#define ERR_EXIT 1
|
||||
|
||||
/* variables replaced in login_cmd */
|
||||
#define SESSION_VAR "%session"
|
||||
#define THEME_VAR "%theme"
|
||||
|
||||
/* variables replaced in pre-session_cmd and post-session_cmd */
|
||||
#define USER_VAR "%user"
|
||||
|
||||
/* max height/width for images */
|
||||
#define MAX_DIMENSION 10000
|
||||
|
||||
#endif /* _CONST_H_ */
|
958
slim/image.cpp
Normal file
958
slim/image.cpp
Normal file
|
@ -0,0 +1,958 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
* Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
* Copyright (C) 2022-23 Rob Pearce <slim@flitspace.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The following code has been adapted and extended from
|
||||
* xplanet 1.0.1, Copyright (C) 2002-04 Hari Nair <hari@alumni.caltech.edu>
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "log.h"
|
||||
#include "const.h"
|
||||
#include "image.h"
|
||||
|
||||
extern "C" {
|
||||
#include <jpeglib.h>
|
||||
#include <png.h>
|
||||
}
|
||||
|
||||
Image::Image()
|
||||
: width(0), height(0), area(0), rgb_data(NULL), png_alpha(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Image::Image ( const int w, const int h, const unsigned char *rgb,
|
||||
const unsigned char *alpha)
|
||||
: width(w), height(h), area(w*h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
area = w * h;
|
||||
|
||||
rgb_data = (unsigned char *) malloc(3 * area);
|
||||
memcpy(rgb_data, rgb, 3 * area);
|
||||
|
||||
if (alpha == NULL) {
|
||||
png_alpha = NULL;
|
||||
} else {
|
||||
png_alpha = (unsigned char *) malloc(area);
|
||||
memcpy(png_alpha, alpha, area);
|
||||
}
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
}
|
||||
|
||||
bool Image::Read(const char *filename)
|
||||
{
|
||||
char buf[4];
|
||||
unsigned char *ubuf = (unsigned char *) buf;
|
||||
int success;
|
||||
int nr;
|
||||
|
||||
FILE *file;
|
||||
file = fopen(filename, "rb");
|
||||
if (file == NULL)
|
||||
return(false);
|
||||
|
||||
/* see what kind of file we have */
|
||||
|
||||
nr = fread(buf, 1, 4, file);
|
||||
fclose(file);
|
||||
if ( nr < 4 )
|
||||
return false; // Failed to read 4 bytes; probably empty file
|
||||
|
||||
if ((ubuf[0] == 0x89) && !strncmp("PNG", buf+1, 3))
|
||||
success = readPng(filename, &width, &height, &rgb_data, &png_alpha);
|
||||
else if ((ubuf[0] == 0xff) && (ubuf[1] == 0xd8))
|
||||
success = readJpeg(filename, &width, &height, &rgb_data);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unknown image format\n");
|
||||
success = 0;
|
||||
}
|
||||
return(success == 1);
|
||||
}
|
||||
|
||||
void Image::Reduce(const int factor)
|
||||
{
|
||||
if (factor < 1)
|
||||
return;
|
||||
|
||||
int scale = 1;
|
||||
for (int i = 0; i < factor; i++)
|
||||
scale *= 2;
|
||||
|
||||
double scale2 = scale*scale;
|
||||
|
||||
int w = width / scale;
|
||||
int h = height / scale;
|
||||
int new_area = w * h;
|
||||
|
||||
unsigned char *new_rgb = (unsigned char *) malloc(3 * new_area);
|
||||
memset(new_rgb, 0, 3 * new_area);
|
||||
|
||||
unsigned char *new_alpha = NULL;
|
||||
if (png_alpha != NULL) {
|
||||
new_alpha = (unsigned char *) malloc(new_area);
|
||||
memset(new_alpha, 0, new_area);
|
||||
}
|
||||
|
||||
int ipos = 0;
|
||||
for (int j = 0; j < height; j++) {
|
||||
int js = j / scale;
|
||||
for (int i = 0; i < width; i++) {
|
||||
int is = i/scale;
|
||||
for (int k = 0; k < 3; k++)
|
||||
new_rgb[3*(js * w + is) + k] += static_cast<unsigned char> ((rgb_data[3*ipos + k] + 0.5) / scale2);
|
||||
|
||||
if (png_alpha != NULL)
|
||||
new_alpha[js * w + is] += static_cast<unsigned char> (png_alpha[ipos]/scale2);
|
||||
ipos++;
|
||||
}
|
||||
}
|
||||
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
|
||||
rgb_data = new_rgb;
|
||||
png_alpha = new_alpha;
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
area = w * h;
|
||||
}
|
||||
|
||||
void Image::Resize(const int w, const int h)
|
||||
{
|
||||
|
||||
if (width==w && height==h){
|
||||
return;
|
||||
}
|
||||
|
||||
int new_area = w * h;
|
||||
|
||||
unsigned char *new_rgb = (unsigned char *) malloc(3 * new_area);
|
||||
unsigned char *new_alpha = NULL;
|
||||
if (png_alpha != NULL)
|
||||
new_alpha = (unsigned char *) malloc(new_area);
|
||||
|
||||
const double scale_x = ((double) w) / width;
|
||||
const double scale_y = ((double) h) / height;
|
||||
|
||||
int ipos = 0;
|
||||
for (int j = 0; j < h; j++) {
|
||||
const double y = j / scale_y;
|
||||
for (int i = 0; i < w; i++) {
|
||||
const double x = i / scale_x;
|
||||
if (new_alpha == NULL)
|
||||
getPixel(x, y, new_rgb + 3*ipos);
|
||||
else
|
||||
getPixel(x, y, new_rgb + 3*ipos, new_alpha + ipos);
|
||||
ipos++;
|
||||
}
|
||||
}
|
||||
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
|
||||
rgb_data = new_rgb;
|
||||
png_alpha = new_alpha;
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
area = w * h;
|
||||
}
|
||||
|
||||
/* Find the color of the desired point using bilinear interpolation. */
|
||||
/* Assume the array indices refer to the center of the pixel, so each */
|
||||
/* pixel has corners at (i - 0.5, j - 0.5) and (i + 0.5, j + 0.5) */
|
||||
void Image::getPixel(double x, double y, unsigned char *pixel)
|
||||
{
|
||||
getPixel(x, y, pixel, NULL);
|
||||
}
|
||||
|
||||
void Image::getPixel(double x, double y, unsigned char *pixel, unsigned char *alpha)
|
||||
{
|
||||
if (x < -0.5)
|
||||
x = -0.5;
|
||||
if (x >= width - 0.5)
|
||||
x = width - 0.5;
|
||||
|
||||
if (y < -0.5)
|
||||
y = -0.5;
|
||||
if (y >= height - 0.5)
|
||||
y = height - 0.5;
|
||||
|
||||
int ix0 = (int) (floor(x));
|
||||
int ix1 = ix0 + 1;
|
||||
if (ix0 < 0)
|
||||
ix0 = width - 1;
|
||||
if (ix1 >= width)
|
||||
ix1 = 0;
|
||||
|
||||
int iy0 = (int) (floor(y));
|
||||
int iy1 = iy0 + 1;
|
||||
if (iy0 < 0)
|
||||
iy0 = 0;
|
||||
if (iy1 >= height)
|
||||
iy1 = height - 1;
|
||||
|
||||
const double t = x - floor(x);
|
||||
const double u = 1 - (y - floor(y));
|
||||
|
||||
double weight[4];
|
||||
weight[1] = t * u;
|
||||
weight[0] = u - weight[1];
|
||||
weight[2] = 1 - t - u + weight[1];
|
||||
weight[3] = t - weight[1];
|
||||
|
||||
unsigned char *pixels[4];
|
||||
pixels[0] = rgb_data + 3 * (iy0 * width + ix0);
|
||||
pixels[1] = rgb_data + 3 * (iy0 * width + ix1);
|
||||
pixels[2] = rgb_data + 3 * (iy1 * width + ix0);
|
||||
pixels[3] = rgb_data + 3 * (iy1 * width + ix1);
|
||||
|
||||
memset(pixel, 0, 3);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 3; j++)
|
||||
pixel[j] += (unsigned char) (weight[i] * pixels[i][j]);
|
||||
}
|
||||
|
||||
if (alpha != NULL) {
|
||||
unsigned char pixels[4];
|
||||
pixels[0] = png_alpha[iy0 * width + ix0];
|
||||
pixels[1] = png_alpha[iy0 * width + ix1];
|
||||
pixels[2] = png_alpha[iy0 * width + ix0];
|
||||
pixels[3] = png_alpha[iy1 * width + ix1];
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
*alpha = (unsigned char) (weight[i] * pixels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merge the image with a background, taking care of the image Alpha
|
||||
* transparency. (background alpha is ignored).
|
||||
*
|
||||
* The image is merged with the section of background at position (x, y).
|
||||
* The background must fully contain the image.
|
||||
* If the image does not have any transparency (no alpha data) then this
|
||||
* is a no-operation.
|
||||
* @note use of double to calculate the new value of a U8
|
||||
*/
|
||||
void Image::Merge ( const Image* background, const int x, const int y )
|
||||
{
|
||||
if ( ( x + width > background->Width() )
|
||||
|| ( y + height > background->Height() ) )
|
||||
return;
|
||||
|
||||
if (png_alpha != NULL)
|
||||
{
|
||||
unsigned char *new_rgb = (unsigned char *) malloc(3 * width * height);
|
||||
const unsigned char *bg_rgb = background->getRGBData();
|
||||
double tmp;
|
||||
int opos = 0;
|
||||
for (int j = 0; j < height; j++)
|
||||
{
|
||||
int ipos = (y+j) * background->Width() + x;
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
tmp = rgb_data[3*opos + k]*png_alpha[opos]/255.0
|
||||
+ bg_rgb[3*ipos + k]*(1-png_alpha[opos]/255.0);
|
||||
new_rgb[3*opos + k] = static_cast<unsigned char> (tmp);
|
||||
}
|
||||
opos++;
|
||||
ipos++;
|
||||
}
|
||||
}
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
rgb_data = new_rgb;
|
||||
png_alpha = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Merge the image with a background, taking care of the
|
||||
* image Alpha transparency. (background alpha is ignored).
|
||||
* The images is merged on position (x, y) on the
|
||||
* background, the background must contain the image.
|
||||
*/
|
||||
#define IMG_POS_RGB(p, x) (3 * p + x)
|
||||
void Image::Merge_non_crop(Image* background, const int x, const int y)
|
||||
{
|
||||
int bg_w = background->Width();
|
||||
int bg_h = background->Height();
|
||||
|
||||
if (x + width > bg_w || y + height > bg_h)
|
||||
return;
|
||||
|
||||
double tmp;
|
||||
unsigned char *new_rgb = (unsigned char *)malloc(3 * bg_w * bg_h);
|
||||
const unsigned char *bg_rgb = background->getRGBData();
|
||||
int pnl_pos = 0;
|
||||
int bg_pos = 0;
|
||||
int pnl_w_end = x + width;
|
||||
int pnl_h_end = y + height;
|
||||
|
||||
memcpy(new_rgb, bg_rgb, 3 * bg_w * bg_h);
|
||||
|
||||
for (int j = 0; j < bg_h; j++) {
|
||||
for (int i = 0; i < bg_w; i++) {
|
||||
if (j >= y && i >= x && j < pnl_h_end && i < pnl_w_end ) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
if (png_alpha != NULL)
|
||||
tmp = rgb_data[IMG_POS_RGB(pnl_pos, k)]
|
||||
* png_alpha[pnl_pos]/255.0
|
||||
+ bg_rgb[IMG_POS_RGB(bg_pos, k)]
|
||||
* (1 - png_alpha[pnl_pos]/255.0);
|
||||
else
|
||||
tmp = rgb_data[IMG_POS_RGB(pnl_pos, k)];
|
||||
|
||||
new_rgb[IMG_POS_RGB(bg_pos, k)] = static_cast<unsigned char>(tmp);
|
||||
}
|
||||
pnl_pos++;
|
||||
}
|
||||
bg_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
width = bg_w;
|
||||
height = bg_h;
|
||||
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
rgb_data = new_rgb;
|
||||
png_alpha = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Tile the image growing its size to the minimum entire
|
||||
* multiple of w * h.
|
||||
* The new dimensions should be > of the current ones.
|
||||
* Note that this flattens image (alpha removed)
|
||||
*/
|
||||
void Image::Tile(const int w, const int h)
|
||||
{
|
||||
if (w < width || h < height)
|
||||
return;
|
||||
|
||||
int nx = w / width;
|
||||
if (w % width > 0)
|
||||
nx++;
|
||||
int ny = h / height;
|
||||
if (h % height > 0)
|
||||
ny++;
|
||||
|
||||
int newwidth = nx*width;
|
||||
int newheight=ny*height;
|
||||
|
||||
unsigned char *new_rgb = (unsigned char *) malloc(3 * newwidth * newheight);
|
||||
memset(new_rgb, 0, 3 * width * height * nx * ny);
|
||||
|
||||
int ipos = 0;
|
||||
int opos = 0;
|
||||
|
||||
for (int r = 0; r < ny; r++) {
|
||||
for (int c = 0; c < nx; c++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
opos = j*width + i;
|
||||
ipos = r*width*height*nx + j*newwidth + c*width +i;
|
||||
for (int k = 0; k < 3; k++) {
|
||||
new_rgb[3*ipos + k] = static_cast<unsigned char> (rgb_data[3*opos + k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
rgb_data = new_rgb;
|
||||
png_alpha = NULL;
|
||||
width = newwidth;
|
||||
height = newheight;
|
||||
area = width * height;
|
||||
Crop(0,0,w,h);
|
||||
}
|
||||
|
||||
|
||||
/* Crop the image
|
||||
*/
|
||||
void Image::Crop(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
if (x+w > width || y+h > height) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x2 = x + w;
|
||||
int y2 = y + h;
|
||||
unsigned char *new_rgb = (unsigned char *) malloc(3 * w * h);
|
||||
memset(new_rgb, 0, 3 * w * h);
|
||||
unsigned char *new_alpha = NULL;
|
||||
if (png_alpha != NULL) {
|
||||
new_alpha = (unsigned char *) malloc(w * h);
|
||||
memset(new_alpha, 0, w * h);
|
||||
}
|
||||
|
||||
int ipos = 0;
|
||||
int opos = 0;
|
||||
|
||||
for (int j = 0; j < height; j++) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
if (j>=y && i>=x && j<y2 && i<x2) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
new_rgb[3*ipos + k] = static_cast<unsigned char> (rgb_data[3*opos + k]);
|
||||
}
|
||||
if (png_alpha != NULL)
|
||||
new_alpha[ipos] = static_cast<unsigned char> (png_alpha[opos]);
|
||||
ipos++;
|
||||
}
|
||||
opos++;
|
||||
}
|
||||
}
|
||||
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
rgb_data = new_rgb;
|
||||
if (png_alpha != NULL)
|
||||
png_alpha = new_alpha;
|
||||
width = w;
|
||||
height = h;
|
||||
area = w * h;
|
||||
}
|
||||
|
||||
|
||||
/* Center the image in a rectangle of given width and height.
|
||||
* Fills the remaining space (if any) with the hex color
|
||||
*/
|
||||
void Image::Center(const int w, const int h, const char *hex)
|
||||
{
|
||||
unsigned long packed_rgb;
|
||||
sscanf(hex, "%lx", &packed_rgb);
|
||||
|
||||
unsigned long r = packed_rgb>>16;
|
||||
unsigned long g = packed_rgb>>8 & 0xff;
|
||||
unsigned long b = packed_rgb & 0xff;
|
||||
|
||||
unsigned char *new_rgb = (unsigned char *) malloc(3 * w * h);
|
||||
memset(new_rgb, 0, 3 * w * h);
|
||||
|
||||
int x = (w - width) / 2;
|
||||
int y = (h - height) / 2;
|
||||
|
||||
if (x<0) {
|
||||
Crop((width - w)/2,0,w,height);
|
||||
x = 0;
|
||||
}
|
||||
if (y<0) {
|
||||
Crop(0,(height - h)/2,width,h);
|
||||
y = 0;
|
||||
}
|
||||
int x2 = x + width;
|
||||
int y2 = y + height;
|
||||
|
||||
int ipos = 0;
|
||||
int opos = 0;
|
||||
double tmp;
|
||||
|
||||
area = w * h;
|
||||
for (int i = 0; i < area; i++) {
|
||||
new_rgb[3*i] = r;
|
||||
new_rgb[3*i+1] = g;
|
||||
new_rgb[3*i+2] = b;
|
||||
}
|
||||
|
||||
if (png_alpha != NULL) {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
if (j>=y && i>=x && j<y2 && i<x2) {
|
||||
ipos = j*w + i;
|
||||
for (int k = 0; k < 3; k++) {
|
||||
tmp = rgb_data[3*opos + k]*png_alpha[opos]/255.0
|
||||
+ new_rgb[k]*(1-png_alpha[opos]/255.0);
|
||||
new_rgb[3*ipos + k] = static_cast<unsigned char> (tmp);
|
||||
}
|
||||
opos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
if (j>=y && i>=x && j<y2 && i<x2) {
|
||||
ipos = j*w + i;
|
||||
for (int k = 0; k < 3; k++) {
|
||||
tmp = rgb_data[3*opos + k];
|
||||
new_rgb[3*ipos + k] = static_cast<unsigned char> (tmp);
|
||||
}
|
||||
opos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
rgb_data = new_rgb;
|
||||
png_alpha = NULL;
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
/* Fill the image with the given color and adjust its dimensions
|
||||
* to passed values.
|
||||
*/
|
||||
void Image::Plain(const int w, const int h, const char *hex)
|
||||
{
|
||||
unsigned long packed_rgb;
|
||||
sscanf(hex, "%lx", &packed_rgb);
|
||||
|
||||
unsigned long r = packed_rgb>>16;
|
||||
unsigned long g = packed_rgb>>8 & 0xff;
|
||||
unsigned long b = packed_rgb & 0xff;
|
||||
|
||||
unsigned char *new_rgb = (unsigned char *) malloc(3 * w * h);
|
||||
memset(new_rgb, 0, 3 * w * h);
|
||||
|
||||
area = w * h;
|
||||
for (int i = 0; i < area; i++) {
|
||||
new_rgb[3*i] = r;
|
||||
new_rgb[3*i+1] = g;
|
||||
new_rgb[3*i+2] = b;
|
||||
}
|
||||
|
||||
free(rgb_data);
|
||||
free(png_alpha);
|
||||
rgb_data = new_rgb;
|
||||
png_alpha = NULL;
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
void Image::computeShift(unsigned long mask,
|
||||
unsigned char &left_shift,
|
||||
unsigned char &right_shift)
|
||||
{
|
||||
left_shift = 0;
|
||||
right_shift = 8;
|
||||
if (mask != 0) {
|
||||
while ((mask & 0x01) == 0) {
|
||||
left_shift++;
|
||||
mask >>= 1;
|
||||
}
|
||||
while ((mask & 0x01) == 1) {
|
||||
right_shift--;
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Pixmap Image::createPixmap(Display* dpy, int scr, Window win)
|
||||
{
|
||||
int i, j; /* loop variables */
|
||||
|
||||
const int depth = DefaultDepth(dpy, scr);
|
||||
Visual *visual = DefaultVisual(dpy, scr);
|
||||
Colormap colormap = DefaultColormap(dpy, scr);
|
||||
|
||||
Pixmap tmp = XCreatePixmap(dpy, win, width, height, depth);
|
||||
|
||||
char *pixmap_data = NULL;
|
||||
switch (depth) {
|
||||
case 32:
|
||||
case 24:
|
||||
pixmap_data = new char[4 * width * height];
|
||||
break;
|
||||
case 16:
|
||||
case 15:
|
||||
pixmap_data = new char[2 * width * height];
|
||||
break;
|
||||
case 8:
|
||||
pixmap_data = new char[width * height];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
XImage *ximage = XCreateImage(dpy, visual, depth, ZPixmap, 0,
|
||||
pixmap_data, width, height,
|
||||
8, 0);
|
||||
|
||||
int entries;
|
||||
XVisualInfo v_template;
|
||||
v_template.visualid = XVisualIDFromVisual(visual);
|
||||
XVisualInfo *visual_info = XGetVisualInfo(dpy, VisualIDMask,
|
||||
&v_template, &entries);
|
||||
|
||||
unsigned long ipos = 0;
|
||||
switch (visual_info->c_class) {
|
||||
case PseudoColor: {
|
||||
XColor xc;
|
||||
xc.flags = DoRed | DoGreen | DoBlue;
|
||||
|
||||
int num_colors = 256;
|
||||
XColor *colors = new XColor[num_colors];
|
||||
for (i = 0; i < num_colors; i++)
|
||||
colors[i].pixel = (unsigned long) i;
|
||||
XQueryColors(dpy, colormap, colors, num_colors);
|
||||
|
||||
int *closest_color = new int[num_colors];
|
||||
|
||||
for (i = 0; i < num_colors; i++) {
|
||||
xc.red = (i & 0xe0) << 8; /* highest 3 bits */
|
||||
xc.green = (i & 0x1c) << 11; /* middle 3 bits */
|
||||
xc.blue = (i & 0x03) << 14; /* lowest 2 bits */
|
||||
|
||||
/* find the closest color in the colormap */
|
||||
double distance, distance_squared, min_distance = 0;
|
||||
for (int ii = 0; ii < num_colors; ii++) {
|
||||
distance = colors[ii].red - xc.red;
|
||||
distance_squared = distance * distance;
|
||||
distance = colors[ii].green - xc.green;
|
||||
distance_squared += distance * distance;
|
||||
distance = colors[ii].blue - xc.blue;
|
||||
distance_squared += distance * distance;
|
||||
|
||||
if ((ii == 0) || (distance_squared <= min_distance)) {
|
||||
min_distance = distance_squared;
|
||||
closest_color[i] = ii;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < height; j++) {
|
||||
for (i = 0; i < width; i++) {
|
||||
xc.red = (unsigned short) (rgb_data[ipos++] & 0xe0);
|
||||
xc.green = (unsigned short) (rgb_data[ipos++] & 0xe0);
|
||||
xc.blue = (unsigned short) (rgb_data[ipos++] & 0xc0);
|
||||
|
||||
xc.pixel = xc.red | (xc.green >> 3) | (xc.blue >> 6);
|
||||
XPutPixel(ximage, i, j,
|
||||
colors[closest_color[xc.pixel]].pixel);
|
||||
}
|
||||
}
|
||||
delete [] colors;
|
||||
delete [] closest_color;
|
||||
}
|
||||
break;
|
||||
case TrueColor: {
|
||||
unsigned char red_left_shift;
|
||||
unsigned char red_right_shift;
|
||||
unsigned char green_left_shift;
|
||||
unsigned char green_right_shift;
|
||||
unsigned char blue_left_shift;
|
||||
unsigned char blue_right_shift;
|
||||
|
||||
computeShift(visual_info->red_mask, red_left_shift,
|
||||
red_right_shift);
|
||||
computeShift(visual_info->green_mask, green_left_shift,
|
||||
green_right_shift);
|
||||
computeShift(visual_info->blue_mask, blue_left_shift,
|
||||
blue_right_shift);
|
||||
|
||||
unsigned long pixel;
|
||||
unsigned long red, green, blue;
|
||||
for (j = 0; j < height; j++) {
|
||||
for (i = 0; i < width; i++) {
|
||||
red = (unsigned long)
|
||||
rgb_data[ipos++] >> red_right_shift;
|
||||
green = (unsigned long)
|
||||
rgb_data[ipos++] >> green_right_shift;
|
||||
blue = (unsigned long)
|
||||
rgb_data[ipos++] >> blue_right_shift;
|
||||
|
||||
pixel = (((red << red_left_shift) & visual_info->red_mask)
|
||||
| ((green << green_left_shift)
|
||||
& visual_info->green_mask)
|
||||
| ((blue << blue_left_shift)
|
||||
& visual_info->blue_mask));
|
||||
|
||||
XPutPixel(ximage, i, j, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
logStream << APPNAME << ": could not load image" << endl;
|
||||
return(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
GC gc = XCreateGC(dpy, win, 0, NULL);
|
||||
XPutImage(dpy, tmp, gc, ximage, 0, 0, 0, 0, width, height);
|
||||
|
||||
XFreeGC(dpy, gc);
|
||||
|
||||
XFree(visual_info);
|
||||
|
||||
delete [] pixmap_data;
|
||||
|
||||
/* Set ximage data to NULL since pixmap data was deallocated above */
|
||||
ximage->data = NULL;
|
||||
XDestroyImage(ximage);
|
||||
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
int Image::readJpeg(const char *filename, int *width, int *height,
|
||||
unsigned char **rgb)
|
||||
{
|
||||
int ret = 0;
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
unsigned char *ptr = NULL;
|
||||
|
||||
FILE *infile = fopen(filename, "rb");
|
||||
if (infile == NULL) {
|
||||
logStream << APPNAME << "Cannot fopen file: " << filename << endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_stdio_src(&cinfo, infile);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
/* Prevent against integer overflow */
|
||||
if ( cinfo.output_width >= MAX_DIMENSION
|
||||
|| cinfo.output_height >= MAX_DIMENSION)
|
||||
{
|
||||
logStream << APPNAME << "Unreasonable dimension found in file: "
|
||||
<< filename << endl;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
*width = cinfo.output_width;
|
||||
*height = cinfo.output_height;
|
||||
|
||||
rgb[0] = (unsigned char*)
|
||||
malloc(3 * cinfo.output_width * cinfo.output_height);
|
||||
if (rgb[0] == NULL) {
|
||||
logStream << APPNAME << ": Can't allocate memory for JPEG file."
|
||||
<< endl;
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
if (cinfo.output_components == 3) {
|
||||
ptr = rgb[0];
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||
ptr += 3 * cinfo.output_width;
|
||||
}
|
||||
} else if (cinfo.output_components == 1) {
|
||||
ptr = (unsigned char*) malloc(cinfo.output_width);
|
||||
if (ptr == NULL) {
|
||||
logStream << APPNAME << ": Can't allocate memory for JPEG file."
|
||||
<< endl;
|
||||
goto rgb_free;
|
||||
}
|
||||
|
||||
unsigned int ipos = 0;
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||
|
||||
for (unsigned int i = 0; i < cinfo.output_width; i++) {
|
||||
memset(rgb[0] + ipos, ptr[i], 3);
|
||||
ipos += 3;
|
||||
}
|
||||
}
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
ret = 1;
|
||||
goto close_file;
|
||||
|
||||
rgb_free:
|
||||
free(rgb[0]);
|
||||
|
||||
close_file:
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(infile);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int Image::readPng(const char *filename, int *width, int *height,
|
||||
unsigned char **rgb, unsigned char **alpha)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_bytepp row_pointers;
|
||||
|
||||
unsigned char *ptr = NULL;
|
||||
png_uint_32 w, h;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
int i;
|
||||
|
||||
FILE *infile = fopen(filename, "rb");
|
||||
if (infile == NULL) {
|
||||
logStream << APPNAME << "Can not fopen file: " << filename << endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
(png_voidp) NULL,
|
||||
(png_error_ptr) NULL,
|
||||
(png_error_ptr) NULL);
|
||||
if (!png_ptr) {
|
||||
goto file_close;
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, (png_infopp) NULL,
|
||||
(png_infopp) NULL);
|
||||
}
|
||||
|
||||
#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
|
||||
if (setjmp(png_jmpbuf((png_ptr))))
|
||||
goto png_destroy;
|
||||
#else
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
goto png_destroy;
|
||||
#endif
|
||||
|
||||
|
||||
png_init_io(png_ptr, infile);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type,
|
||||
&interlace_type, (int *) NULL, (int *) NULL);
|
||||
|
||||
/* Prevent against integer overflow */
|
||||
if(w >= MAX_DIMENSION || h >= MAX_DIMENSION) {
|
||||
logStream << APPNAME << "Unreasonable dimension found in file: "
|
||||
<< filename << endl;
|
||||
goto png_destroy;
|
||||
}
|
||||
|
||||
*width = (int) w;
|
||||
*height = (int) h;
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
alpha[0] = (unsigned char *) malloc(*width * *height);
|
||||
if (alpha[0] == NULL) {
|
||||
logStream << APPNAME
|
||||
<< ": Can't allocate memory for alpha channel in PNG file."
|
||||
<< endl;
|
||||
goto png_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change a paletted/grayscale image to RGB */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
|
||||
{
|
||||
png_set_expand(png_ptr);
|
||||
}
|
||||
|
||||
/* Change a grayscale image to RGB */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
}
|
||||
|
||||
/* If the PNG file has 16 bits per channel, strip them down to 8 */
|
||||
if (bit_depth == 16) {
|
||||
png_set_strip_16(png_ptr);
|
||||
}
|
||||
|
||||
/* use 1 byte per pixel */
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
row_pointers = (png_byte **) malloc(*height * sizeof(png_bytep));
|
||||
if (row_pointers == NULL) {
|
||||
logStream << APPNAME << ": Can't allocate memory for PNG file." << endl;
|
||||
goto png_destroy;
|
||||
}
|
||||
|
||||
for (i = 0; i < *height; i++) {
|
||||
row_pointers[i] = (png_byte*) malloc(4 * *width);
|
||||
if (row_pointers == NULL) {
|
||||
logStream << APPNAME << ": Can't allocate memory for PNG file."
|
||||
<< endl;
|
||||
goto rows_free;
|
||||
}
|
||||
}
|
||||
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
rgb[0] = (unsigned char *) malloc(3 * (*width) * (*height));
|
||||
if (rgb[0] == NULL) {
|
||||
logStream << APPNAME << ": Can't allocate memory for PNG file." << endl;
|
||||
goto rows_free;
|
||||
}
|
||||
|
||||
if (alpha[0] == NULL) {
|
||||
ptr = rgb[0];
|
||||
for (i = 0; i < *height; i++) {
|
||||
memcpy(ptr, row_pointers[i], 3 * (*width));
|
||||
ptr += 3 * (*width);
|
||||
}
|
||||
} else {
|
||||
ptr = rgb[0];
|
||||
for (i = 0; i < *height; i++) {
|
||||
unsigned int ipos = 0;
|
||||
for (int j = 0; j < *width; j++) {
|
||||
*ptr++ = row_pointers[i][ipos++];
|
||||
*ptr++ = row_pointers[i][ipos++];
|
||||
*ptr++ = row_pointers[i][ipos++];
|
||||
alpha[0][i * (*width) + j] = row_pointers[i][ipos++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1; /* data reading is OK */
|
||||
|
||||
rows_free:
|
||||
for (i = 0; i < *height; i++) {
|
||||
if (row_pointers[i] != NULL ) {
|
||||
free(row_pointers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(row_pointers);
|
||||
|
||||
png_destroy:
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
|
||||
file_close:
|
||||
fclose(infile);
|
||||
return(ret);
|
||||
}
|
||||
|
75
slim/image.h
Normal file
75
slim/image.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The following code has been adapted and extended from
|
||||
xplanet 1.0.1, Copyright (C) 2002-04 Hari Nair <hari@alumni.caltech.edu>
|
||||
*/
|
||||
|
||||
#ifndef _IMAGE_H_
|
||||
#define _IMAGE_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xmu/WinUtil.h>
|
||||
|
||||
class Image
|
||||
{
|
||||
public:
|
||||
Image();
|
||||
Image(const int w, const int h, const unsigned char *rgb,
|
||||
const unsigned char *alpha);
|
||||
|
||||
~Image();
|
||||
|
||||
const unsigned char *getPNGAlpha() const {
|
||||
return(png_alpha);
|
||||
}
|
||||
const unsigned char *getRGBData() const {
|
||||
return(rgb_data);
|
||||
}
|
||||
|
||||
void getPixel(double px, double py, unsigned char *pixel);
|
||||
void getPixel(double px, double py, unsigned char *pixel,
|
||||
unsigned char *alpha);
|
||||
|
||||
int Width() const {
|
||||
return(width);
|
||||
}
|
||||
int Height() const {
|
||||
return(height);
|
||||
}
|
||||
|
||||
bool Read(const char *filename);
|
||||
|
||||
void Reduce(const int factor);
|
||||
void Resize(const int w, const int h);
|
||||
void Merge ( const Image *background, const int x, const int y );
|
||||
void Merge_non_crop(Image* background, const int x, const int y);
|
||||
void Crop(const int x, const int y, const int w, const int h);
|
||||
void Tile(const int w, const int h);
|
||||
void Center(const int w, const int h, const char *hex);
|
||||
void Plain(const int w, const int h, const char *hex);
|
||||
|
||||
void computeShift(unsigned long mask, unsigned char &left_shift,
|
||||
unsigned char &right_shift);
|
||||
|
||||
Pixmap createPixmap(Display *dpy, int scr, Window win);
|
||||
|
||||
private:
|
||||
int width, height, area;
|
||||
unsigned char *rgb_data;
|
||||
unsigned char *png_alpha;
|
||||
|
||||
int readJpeg(const char *filename, int *width, int *height,
|
||||
unsigned char **rgb);
|
||||
int readPng(const char *filename, int *width, int *height,
|
||||
unsigned char **rgb, unsigned char **alpha);
|
||||
};
|
||||
|
||||
#endif /* _IMAGE_H_ */
|
101
slim/jpeg.c
Normal file
101
slim/jpeg.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/****************************************************************************
|
||||
jpeg.c - read and write jpeg images using libjpeg routines
|
||||
Copyright (C) 2002 Hari Nair <hari@alumni.caltech.edu>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <jpeglib.h>
|
||||
#include "const.h"
|
||||
|
||||
int read_jpeg(const char *filename, int *width, int *height, unsigned char **rgb)
|
||||
{
|
||||
int ret = 0;
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
unsigned char *ptr = NULL;
|
||||
unsigned int i, ipos;
|
||||
|
||||
FILE *infile = fopen(filename, "rb");
|
||||
if (infile == NULL) {
|
||||
fprintf(stderr, "Can not fopen file: %s\n",filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_stdio_src(&cinfo, infile);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
/* Prevent against integer overflow */
|
||||
if(cinfo.output_width >= MAX_DIMENSION || cinfo.output_height >= MAX_DIMENSION) {
|
||||
fprintf(stderr, "Unreasonable dimension found in file: %s\n",filename);
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
*width = cinfo.output_width;
|
||||
*height = cinfo.output_height;
|
||||
|
||||
rgb[0] = malloc(3 * cinfo.output_width * cinfo.output_height);
|
||||
if (rgb[0] == NULL) {
|
||||
fprintf(stderr, "Can't allocate memory for JPEG file.\n");
|
||||
goto close_file;
|
||||
}
|
||||
|
||||
if (cinfo.output_components == 3) {
|
||||
ptr = rgb[0];
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||
ptr += 3 * cinfo.output_width;
|
||||
}
|
||||
} else if (cinfo.output_components == 1) {
|
||||
ptr = malloc(cinfo.output_width);
|
||||
if (ptr == NULL) {
|
||||
fprintf(stderr, "Can't allocate memory for JPEG file.\n");
|
||||
goto rgb_free;
|
||||
}
|
||||
|
||||
ipos = 0;
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||
|
||||
for (i = 0; i < cinfo.output_width; i++) {
|
||||
memset(rgb[0] + ipos, ptr[i], 3);
|
||||
ipos += 3;
|
||||
}
|
||||
}
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
ret = 1;
|
||||
goto close_file;
|
||||
|
||||
rgb_free:
|
||||
free(rgb[0]);
|
||||
|
||||
close_file:
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(infile);
|
||||
|
||||
return(ret);
|
||||
}
|
57
slim/log.cpp
Normal file
57
slim/log.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
* Copyright (C) 1997, 1998 Per Liden
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
* Copyright (C) 2022 Rob Pearce <slim@flitspace.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "const.h"
|
||||
#include "log.h"
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
LogUnit::LogUnit()
|
||||
{
|
||||
logOut = &cerr;
|
||||
}
|
||||
|
||||
bool LogUnit::openLog(const char * filename)
|
||||
{
|
||||
if (logFile.is_open()) {
|
||||
cerr << APPNAME
|
||||
<< ": opening a new Log file, while another is already open"
|
||||
<< endl;
|
||||
logFile.close();
|
||||
}
|
||||
|
||||
// cerr is the default
|
||||
if ( ( strcmp(filename, "/dev/stderr") == 0 )
|
||||
|| ( strcmp(filename, "stderr") == 0 ) )
|
||||
{
|
||||
logOut = &cerr;
|
||||
return true;
|
||||
}
|
||||
|
||||
logFile.open(filename, ios_base::out|ios_base::app);
|
||||
if ( logFile )
|
||||
{
|
||||
logOut = &logFile;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LogUnit::closeLog()
|
||||
{
|
||||
if (logFile.is_open())
|
||||
logFile.close();
|
||||
}
|
||||
|
||||
|
||||
/* Now instantiate a singleton for all the rest of the code to use */
|
||||
LogUnit logStream;
|
47
slim/log.h
Normal file
47
slim/log.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef _LOG_H_
|
||||
#define _LOG_H_
|
||||
|
||||
#ifdef USE_CONSOLEKIT
|
||||
#include "Ck.h"
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
#include "PAM.h"
|
||||
#endif
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class LogUnit
|
||||
{
|
||||
ofstream logFile;
|
||||
ostream * logOut;
|
||||
public:
|
||||
bool openLog(const char * filename);
|
||||
void closeLog();
|
||||
|
||||
LogUnit();
|
||||
|
||||
~LogUnit() { closeLog(); }
|
||||
|
||||
template<typename Type> LogUnit & operator<<(const Type & text)
|
||||
{
|
||||
*logOut << text; logOut->flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogUnit & operator<<(ostream & (*fp)(ostream&))
|
||||
{
|
||||
*logOut << fp; logOut->flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogUnit & operator<<(ios_base & (*fp)(ios_base&))
|
||||
{
|
||||
*logOut << fp; logOut->flush();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
extern LogUnit logStream;
|
||||
|
||||
#endif /* _LOG_H_ */
|
24
slim/main.cpp
Normal file
24
slim/main.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* SLiM - Simple Login Manager
|
||||
* Copyright (C) 1997, 1998 Per Liden
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "app.h"
|
||||
#include "const.h"
|
||||
|
||||
App* LoginApp = 0;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
LoginApp = new App(argc, argv);
|
||||
LoginApp->Run();
|
||||
return 0;
|
||||
}
|
||||
|
112
slim/numlock.cpp
Normal file
112
slim/numlock.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* SLiM - Simple Login Manager
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
* Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Code adapted from NumLockX, look at the end of this file for
|
||||
* the original Copyright information.
|
||||
*/
|
||||
|
||||
#include "numlock.h"
|
||||
#include <string.h>
|
||||
|
||||
NumLock::NumLock()
|
||||
{
|
||||
}
|
||||
|
||||
int NumLock::xkb_init(Display* dpy)
|
||||
{
|
||||
int xkb_opcode, xkb_event, xkb_error;
|
||||
int xkb_lmaj = XkbMajorVersion;
|
||||
int xkb_lmin = XkbMinorVersion;
|
||||
|
||||
return XkbLibraryVersion( &xkb_lmaj, &xkb_lmin )
|
||||
&& XkbQueryExtension( dpy, &xkb_opcode, &xkb_event, &xkb_error,
|
||||
&xkb_lmaj, &xkb_lmin );
|
||||
}
|
||||
|
||||
unsigned int NumLock::xkb_mask_modifier( XkbDescPtr xkb, const char *name )
|
||||
{
|
||||
int i;
|
||||
if( !xkb || !xkb->names )
|
||||
return 0;
|
||||
|
||||
for( i = 0; i < XkbNumVirtualMods; i++ ) {
|
||||
char* modStr = XGetAtomName( xkb->dpy, xkb->names->vmods[i] );
|
||||
if( modStr != NULL && strcmp(name, modStr) == 0 ) {
|
||||
unsigned int mask;
|
||||
XkbVirtualModsToReal( xkb, 1 << i, &mask );
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int NumLock::xkb_numlock_mask(Display* dpy)
|
||||
{
|
||||
XkbDescPtr xkb;
|
||||
|
||||
xkb = XkbGetKeyboard( dpy, XkbAllComponentsMask, XkbUseCoreKbd );
|
||||
if( xkb != NULL ) {
|
||||
unsigned int mask = xkb_mask_modifier( xkb, "NumLock" );
|
||||
XkbFreeKeyboard( xkb, 0, True );
|
||||
return mask;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NumLock::control_numlock(Display *dpy, bool flag)
|
||||
{
|
||||
unsigned int mask;
|
||||
|
||||
if( !xkb_init(dpy) )
|
||||
return;
|
||||
|
||||
mask = xkb_numlock_mask(dpy);
|
||||
if( mask == 0 )
|
||||
return;
|
||||
|
||||
if( flag == true )
|
||||
XkbLockModifiers ( dpy, XkbUseCoreKbd, mask, mask);
|
||||
else
|
||||
XkbLockModifiers ( dpy, XkbUseCoreKbd, mask, 0);
|
||||
}
|
||||
|
||||
void NumLock::setOn(Display *dpy)
|
||||
{
|
||||
control_numlock(dpy, true);
|
||||
}
|
||||
|
||||
void NumLock::setOff(Display *dpy)
|
||||
{
|
||||
control_numlock(dpy, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000-2001 Lubos Lunak <l.lunak@kde.org>
|
||||
* Copyright (C) 2001 Oswald Buddenhagen <ossi@kde.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
33
slim/numlock.h
Normal file
33
slim/numlock.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _NUMLOCK_H_
|
||||
#define _NUMLOCK_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
class NumLock
|
||||
{
|
||||
public:
|
||||
NumLock();
|
||||
static void setOn(Display *dpy);
|
||||
static void setOff(Display *dpy);
|
||||
|
||||
private:
|
||||
static int xkb_init(Display *dpy);
|
||||
static unsigned int xkb_mask_modifier(XkbDescPtr xkb, const char *name);
|
||||
static unsigned int xkb_numlock_mask(Display *dpy);
|
||||
static void control_numlock(Display *dpy, bool flag);
|
||||
};
|
||||
|
||||
#endif /* _NUMLOCK_H_ */
|
10
slim/pam.sample
Executable file
10
slim/pam.sample
Executable file
|
@ -0,0 +1,10 @@
|
|||
#%PAM-1.0
|
||||
auth requisite pam_nologin.so
|
||||
auth required pam_env.so
|
||||
auth required pam_unix.so
|
||||
account required pam_unix.so
|
||||
password required pam_unix.so
|
||||
session required pam_limits.so
|
||||
session required pam_unix.so
|
||||
session optional pam_loginuid.so
|
||||
session optional pam_ck_connector.so
|
1035
slim/panel.cpp
Normal file
1035
slim/panel.cpp
Normal file
File diff suppressed because it is too large
Load diff
188
slim/panel.h
Normal file
188
slim/panel.h
Normal file
|
@ -0,0 +1,188 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
Copyright (C) 1997, 1998 Per Liden
|
||||
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
Copyright (C) 2013 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
Copyright (C) 2022-23 Rob Pearce <slim@flitspace.org.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PANEL_H_
|
||||
#define _PANEL_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/Xmu/WinUtil.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifdef NEEDS_BASENAME
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
|
||||
// Forward declarations
|
||||
class Image;
|
||||
class Cfg;
|
||||
|
||||
|
||||
struct Rectangle {
|
||||
int x;
|
||||
int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
Rectangle() : x(0), y(0), width(0), height(0) {};
|
||||
Rectangle(int x, int y, unsigned int width, unsigned int height)
|
||||
: x(x), y(y), width(width), height(height)
|
||||
{}
|
||||
|
||||
bool is_empty() const { return width == 0 || height == 0; }
|
||||
};
|
||||
|
||||
class Panel
|
||||
{
|
||||
public:
|
||||
enum ActionType {
|
||||
Login,
|
||||
UnLock = Login, // slimlock doesn't actually care about this
|
||||
Console,
|
||||
Reboot,
|
||||
Halt,
|
||||
Exit,
|
||||
Suspend
|
||||
};
|
||||
|
||||
enum FieldType {
|
||||
Get_Name,
|
||||
Get_Passwd
|
||||
};
|
||||
|
||||
enum PanelType {
|
||||
Mode_DM,
|
||||
Mode_Test,
|
||||
Mode_Lock
|
||||
};
|
||||
|
||||
Panel(Display *dpy, int scr, Window root, Cfg *config,
|
||||
const std::string& themed, PanelType panel_mode);
|
||||
~Panel();
|
||||
void OpenPanel();
|
||||
void ClosePanel();
|
||||
void WrongPassword(int timeout);
|
||||
void Message(const std::string &text);
|
||||
void EventHandler(const FieldType &curfield);
|
||||
std::string getSession();
|
||||
ActionType getAction(void) const;
|
||||
|
||||
void Reset(void);
|
||||
void ResetName(void);
|
||||
void ResetPasswd(void);
|
||||
void SetName(const std::string &name);
|
||||
const std::string& GetName(void) const;
|
||||
const std::string& GetPasswd(void) const;
|
||||
void SwitchSession();
|
||||
|
||||
Atom BackgroundPixmapId; // from XInternAtom -- does it need to be a member var?
|
||||
void setBackground(void);
|
||||
void HideCursor();
|
||||
|
||||
private:
|
||||
Panel();
|
||||
void TextCursor(int visible);
|
||||
unsigned long GetColor(const char *colorname);
|
||||
void OnExpose(void);
|
||||
void EraseLastChar(std::string &formerString);
|
||||
bool OnKeyPress(XEvent& event);
|
||||
void ShowText();
|
||||
void ShowSession();
|
||||
|
||||
void SlimDrawString8(XftDraw *d, XftColor *color, XftFont *font,
|
||||
int x, int y, const std::string &str,
|
||||
XftColor *shadowColor,
|
||||
int xOffset, int yOffset);
|
||||
|
||||
Rectangle GetPrimaryViewport();
|
||||
void ApplyBackground(Rectangle = Rectangle());
|
||||
|
||||
/* Private data */
|
||||
PanelType mode; /* work mode */
|
||||
Cfg *cfg;
|
||||
Display *Dpy;
|
||||
int Scr;
|
||||
Window Win;
|
||||
Window Root;
|
||||
int X, Y;
|
||||
GC TextGC;
|
||||
GC WinGC;
|
||||
XftFont *font;
|
||||
XftColor inputshadowcolor;
|
||||
XftColor inputcolor;
|
||||
XftColor msgcolor;
|
||||
XftColor msgshadowcolor;
|
||||
XftFont *msgfont;
|
||||
XftFont *welcomefont;
|
||||
XftColor welcomecolor;
|
||||
XftFont *sessionfont;
|
||||
XftColor sessioncolor;
|
||||
XftColor sessionshadowcolor;
|
||||
XftColor welcomeshadowcolor;
|
||||
XftFont *enterfont;
|
||||
XftColor entercolor;
|
||||
XftColor entershadowcolor;
|
||||
ActionType action;
|
||||
FieldType field;
|
||||
XGlyphInfo MsgExtents;
|
||||
|
||||
/* Username/Password */
|
||||
std::string NameBuffer;
|
||||
std::string PasswdBuffer;
|
||||
std::string HiddenPasswdBuffer;
|
||||
|
||||
/* screen stuff */
|
||||
Rectangle viewport;
|
||||
|
||||
/* Configuration */
|
||||
int input_name_x;
|
||||
int input_name_y;
|
||||
int input_pass_x;
|
||||
int input_pass_y;
|
||||
int inputShadowXOffset;
|
||||
int inputShadowYOffset;
|
||||
int welcome_x;
|
||||
int welcome_y;
|
||||
int welcome_shadow_xoffset;
|
||||
int welcome_shadow_yoffset;
|
||||
int session_shadow_xoffset;
|
||||
int session_shadow_yoffset;
|
||||
int username_x;
|
||||
int username_y;
|
||||
int username_shadow_xoffset;
|
||||
int username_shadow_yoffset;
|
||||
int password_x;
|
||||
int password_y;
|
||||
std::string welcome_message;
|
||||
|
||||
/* Pixmap data */
|
||||
Pixmap PanelPixmap;
|
||||
|
||||
Image *image;
|
||||
Image *bgImg;
|
||||
|
||||
std::string themedir;
|
||||
|
||||
/* Session handling */
|
||||
std::string session_name;
|
||||
std::string session_exec;
|
||||
};
|
||||
|
||||
#endif /* _PANEL_H_ */
|
173
slim/png.c
Normal file
173
slim/png.c
Normal file
|
@ -0,0 +1,173 @@
|
|||
/****************************************************************************
|
||||
png.c - read and write png images using libpng routines.
|
||||
Distributed with Xplanet.
|
||||
Copyright (C) 2002 Hari Nair <hari@alumni.caltech.edu>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <png.h>
|
||||
#include "const.h"
|
||||
|
||||
int read_png(const char *filename, int *width, int *height, unsigned char **rgb,
|
||||
unsigned char **alpha)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_bytepp row_pointers;
|
||||
|
||||
unsigned char *ptr = NULL;
|
||||
png_uint_32 w, h;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
int i;
|
||||
|
||||
FILE *infile = fopen(filename, "rb");
|
||||
if (infile == NULL) {
|
||||
fprintf(stderr, "Can not fopen file: %s\n", filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
(png_voidp)NULL,
|
||||
(png_error_ptr)NULL,
|
||||
(png_error_ptr)NULL);
|
||||
if (!png_ptr)
|
||||
goto file_close;
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr,
|
||||
(png_infopp)NULL,
|
||||
(png_infopp)NULL);
|
||||
}
|
||||
|
||||
#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
|
||||
if (setjmp(png_jmpbuf((png_ptr))))
|
||||
#else
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
#endif
|
||||
goto png_destroy;
|
||||
|
||||
png_init_io(png_ptr, infile);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type,
|
||||
&interlace_type, (int *) NULL, (int *) NULL);
|
||||
|
||||
/* Prevent against integer overflow */
|
||||
if (w >= MAX_DIMENSION || h >= MAX_DIMENSION) {
|
||||
fprintf(stderr,
|
||||
"Unreasonable dimension found in file: %s\n", filename);
|
||||
goto png_destroy;
|
||||
}
|
||||
|
||||
*width = (int) w;
|
||||
*height = (int) h;
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||
alpha[0] = malloc(*width * *height);
|
||||
if (alpha[0] == NULL) {
|
||||
fprintf(stderr,
|
||||
"Can't allocate memory for alpha channel in PNG file.\n");
|
||||
goto png_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change a paletted/grayscale image to RGB */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
/* Change a grayscale image to RGB */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
|
||||
/* If the PNG file has 16 bits per channel, strip them down to 8 */
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
/* use 1 byte per pixel */
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
row_pointers = malloc(*height * sizeof(png_bytep));
|
||||
if (row_pointers == NULL) {
|
||||
fprintf(stderr, "Can't allocate memory for PNG file.\n");
|
||||
goto png_destroy;
|
||||
}
|
||||
|
||||
for (i = 0; i < *height; i++) {
|
||||
row_pointers[i] = malloc(4 * *width);
|
||||
if (row_pointers == NULL) {
|
||||
fprintf(stderr,
|
||||
"Can't allocate memory for PNG line.\n");
|
||||
goto rows_free;
|
||||
}
|
||||
}
|
||||
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
rgb[0] = malloc(3 * *width * *height);
|
||||
if (rgb[0] == NULL) {
|
||||
fprintf(stderr, "Can't allocate memory for PNG file.\n");
|
||||
goto rows_free;
|
||||
}
|
||||
|
||||
if (alpha[0] == NULL) {
|
||||
ptr = rgb[0];
|
||||
for (i = 0; i < *height; i++) {
|
||||
memcpy(ptr, row_pointers[i], 3 * *width);
|
||||
ptr += 3 * *width;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
ptr = rgb[0];
|
||||
for (i = 0; i < *height; i++) {
|
||||
int ipos = 0;
|
||||
for (j = 0; j < *width; j++) {
|
||||
*ptr++ = row_pointers[i][ipos++];
|
||||
*ptr++ = row_pointers[i][ipos++];
|
||||
*ptr++ = row_pointers[i][ipos++];
|
||||
alpha[0][i * *width + j]
|
||||
= row_pointers[i][ipos++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1; /* data reading is OK */
|
||||
|
||||
rows_free:
|
||||
for (i = 0; i < *height; i++) {
|
||||
if (row_pointers[i] != NULL)
|
||||
free(row_pointers[i]);
|
||||
}
|
||||
|
||||
free(row_pointers);
|
||||
|
||||
png_destroy:
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
|
||||
file_close:
|
||||
fclose(infile);
|
||||
return ret;
|
||||
}
|
126
slim/slim.1
Normal file
126
slim/slim.1
Normal file
|
@ -0,0 +1,126 @@
|
|||
.TH slim 1 "January 14, 2023" "" ""
|
||||
.SH NAME
|
||||
\fBslim \fP- Simple LogIn Manager
|
||||
\fB
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.fam C
|
||||
\fBslim\fP [\fIoptions\fP] [<arguments>]
|
||||
.fam T
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
SLiM is a lightweight login manager for X11, allowing the initialization
|
||||
of a graphical session by entering username and password in a login screen.
|
||||
It is desktop-agnostic and should work (suitably configured) with any
|
||||
session style.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B
|
||||
\fB-c\fP /path/to/config
|
||||
select a non-standard configuration file instead of /etc/slim.conf
|
||||
.TP
|
||||
.B
|
||||
\fB-d\fP
|
||||
run as a daemon
|
||||
.TP
|
||||
.B
|
||||
\fB-n\fP
|
||||
do NOT run as a daemon
|
||||
.TP
|
||||
.B
|
||||
\fB-s\fP
|
||||
be systemd compatible by disabling consolekit support. This option does
|
||||
nothing if consolekit support has not been built in.
|
||||
.TP
|
||||
.B
|
||||
\fB-p\fP /path/to/theme
|
||||
display a preview of the theme. An already running X11 session
|
||||
is required for theme preview.
|
||||
.TP
|
||||
.B
|
||||
\fB-w\fP <www>x<hhh>
|
||||
set the size of the window used for theme preview. This option is only valid
|
||||
after a -p option
|
||||
.TP
|
||||
.B
|
||||
\fB-h\fP
|
||||
display a brief help message
|
||||
.TP
|
||||
.B
|
||||
\fB-v\fP
|
||||
display version information
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B
|
||||
\fBslim\fP \fB-d\fP
|
||||
run \fBslim\fP in daemon mode
|
||||
.TP
|
||||
.B
|
||||
\fBslim\fP \fB-p\fP /usr/share/slim/themes/default \fB-w\fP 800x600
|
||||
preview of the default theme at low resolution
|
||||
.SH STARTING SLIM AT BOOT
|
||||
Please refer to the documentation of your Operating System to make \fBslim\fP
|
||||
automatically startup after the system boots. In particular, the method is
|
||||
very different between SysV, OpenRC, runit and systemd init processes.
|
||||
.SH CONFIGURATION
|
||||
Global configuration is stored in the /etc/slim.conf file. See the comments
|
||||
inside the file for a detailed explanation of the \fIoptions\fP.
|
||||
.SH USAGE AND SPECIAL USERNAMES
|
||||
When started, \fBslim\fP will show a login panel; enter the username and
|
||||
password of the user you want to login as.
|
||||
.PP
|
||||
Special usernames:
|
||||
.TP
|
||||
.B
|
||||
console
|
||||
open an xterm login console. No password needed
|
||||
.TP
|
||||
.B
|
||||
exit
|
||||
quit \fBslim\fP. No password needed. See the note in \fBBUGS\fI.
|
||||
.TP
|
||||
.B
|
||||
halt
|
||||
shutdown the machine
|
||||
.TP
|
||||
.B
|
||||
reboot
|
||||
reboot the machine
|
||||
.TP
|
||||
.B
|
||||
suspend
|
||||
power-suspend the machine
|
||||
.PP
|
||||
See the configuration file for customizing the above commands.
|
||||
The 'halt' and 'reboot' commands need the root password, and hence may not
|
||||
work on systems where root login is disabled.
|
||||
.PP
|
||||
Shortcuts:
|
||||
.TP
|
||||
.B
|
||||
F11
|
||||
executes a custom command (by default takes a screenshot)
|
||||
.TP
|
||||
.B
|
||||
F1
|
||||
choose session type from session list.
|
||||
.SH BUGS
|
||||
When run as a daemon from OpenRC (and possibly other init systems), causing
|
||||
SLiM to quit can sometimes result in a blank screen and unresponsive computer.
|
||||
This includes when using the "exit" special username.
|
||||
.PP
|
||||
Probably still a few more but I'm working on them.
|
||||
.SH AUTHORS
|
||||
Simone Rota <sip@varlock.com>
|
||||
.PP
|
||||
Johannes Winkelmann <jw@tks6.net>
|
||||
.PP
|
||||
Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
.PP
|
||||
Rob Pearce <slim@flitspace.org.uk>
|
||||
.SH SEE ALSO
|
||||
.\" .BR slim.conf (5), ... once I've written one!
|
||||
.BR slimlock (1)
|
||||
.PP
|
||||
See the online documentation at the SLiM web site for further information
|
||||
on themes, FAQs, etc.
|
124
slim/slim.conf
Normal file
124
slim/slim.conf
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Path, X server and arguments (if needed)
|
||||
# Note: -xauth $authfile is automatically appended, vt07 appended if no
|
||||
# vtxx argument given.
|
||||
default_path /bin:/usr/bin:/usr/local/bin
|
||||
default_xserver /usr/bin/X
|
||||
#xserver_arguments -dpi 75
|
||||
xserver_arguments -nolisten tcp -deferglyphs 16
|
||||
|
||||
# Full path to the xauth binary
|
||||
xauth_path /usr/bin/xauth
|
||||
|
||||
# Xauth file for server
|
||||
authfile /var/run/slim.auth
|
||||
|
||||
|
||||
# Commands for halt, login, etc.
|
||||
halt_cmd /sbin/shutdown -h now
|
||||
reboot_cmd /sbin/shutdown -r now
|
||||
console_cmd /usr/bin/xterm -C -fg white -bg black +sb -T "Console login" -e /bin/sh -c "/bin/cat /etc/issue; exec /bin/login"
|
||||
#suspend_cmd /usr/sbin/suspend
|
||||
|
||||
# Activate numlock when slim starts. Valid values: on|off
|
||||
# Default is to not change it
|
||||
#numlock on
|
||||
|
||||
# Hide the mouse cursor (note: does not work with some WMs).
|
||||
# Valid values: true|false
|
||||
#hidecursor false
|
||||
|
||||
# This command is executed after a succesful login.
|
||||
# You can place the %session and %theme variables to handle launching of
|
||||
# specific commands in .xinitrc depending on chosen session and slim theme.
|
||||
# Ensure that the command handles an empty %session, as that is the default
|
||||
#
|
||||
# NOTE: if your system does not have bash you need to adjust the command
|
||||
# according to your preferred shell, e.g. for freebsd use:
|
||||
# login_cmd exec /bin/sh - ~/.xinitrc %session
|
||||
login_cmd exec /bin/bash -login ~/.xinitrc %session
|
||||
|
||||
# Commands executed when starting and exiting a session.
|
||||
# They can be used for registering a X11 session with
|
||||
# sessreg. You can use the %user variable
|
||||
#
|
||||
# sessionstart_cmd some command
|
||||
# sessionstop_cmd some command
|
||||
sessionstart_cmd /usr/bin/sessreg -a -l "$DISPLAY" %user
|
||||
sessionstop_cmd /usr/bin/sessreg -d -l "$DISPLAY" %user
|
||||
|
||||
# Start in daemon mode. Valid values: yes | no
|
||||
# Note that this can be overridden by the command line options "-d" and "-n"
|
||||
daemon yes
|
||||
|
||||
# Available sessions:
|
||||
# The current chosen session name replaces %session in the login_cmd
|
||||
# above, so your login command can handle different sessions.
|
||||
# If no session is chosen (via F1), %session will be an empty string. This
|
||||
# allows the script to handle default in a user-specific manner, if desired.
|
||||
# See the xinitrc.sample file shipped with slim sources.
|
||||
#sessions xfce4,icewm-session,wmaker,blackbox
|
||||
|
||||
# Alternatively, read available sessions from the contents of a
|
||||
# directory. The directory can contain either executable scripts,
|
||||
# or xsessions .desktop files. In the case of .desktop files, the name
|
||||
# displayed is the Name= value and the string substutited in place of
|
||||
# %session is the Exec= value -- note that this may provide a full
|
||||
# path to the session executable!
|
||||
#sessiondir /usr/share/xsessions
|
||||
|
||||
|
||||
# Executed when pressing F11 (requires imagemagick)
|
||||
screenshot_cmd import -window root /slim.png
|
||||
# Alternative using scrot.
|
||||
#screenshot_cmd scrot /root/slim.png
|
||||
|
||||
# Delay after failed authentication before allowing another attempt
|
||||
# NOTE: This delay is additional to the time PAM takes to fail, and
|
||||
# the feedback message remains after this delay. While the
|
||||
# default value is 2 seconds, it's quite reasonable to set it
|
||||
# to zero.
|
||||
wrong_passwd_timeout 0
|
||||
|
||||
# Whether to sound the bell on failed login
|
||||
#bell 0
|
||||
|
||||
# Whether to leave the username intact if authorisation fails. For
|
||||
# users who mistype their password, 1 is better.
|
||||
#keep_user_on_fail 0
|
||||
|
||||
# default user, leave blank to not pre-load the username.
|
||||
#default_user simone
|
||||
|
||||
# Focus the password field on start when default_user is set
|
||||
# Set to "yes" to enable this feature
|
||||
#focus_password no
|
||||
|
||||
# Automatically login the default user (without entering
|
||||
# the password. Set to "yes" to enable this feature
|
||||
#auto_login no
|
||||
|
||||
|
||||
# current theme, use comma separated list to specify a set to
|
||||
# randomly choose from
|
||||
current_theme default
|
||||
|
||||
# Lock file
|
||||
lockfile /run/slim.pid
|
||||
|
||||
# Log file - full path for a file, or just stderr (or /dev/stderr) to send
|
||||
# all log messages to stderr.
|
||||
logfile /var/log/slim.log
|
||||
|
||||
#----------------------------------------------------
|
||||
# The following options might be considered better placed in the theme.They
|
||||
# will work either way; the theme takes priority if duplicated
|
||||
|
||||
# welcome message. Available variables: %host, %domain
|
||||
welcome_msg Welcome to %host
|
||||
|
||||
# Session message. Prepended to the session name when pressing F1
|
||||
#session_msg Session:
|
||||
|
||||
# shutdown / reboot messages
|
||||
shutdown_msg The system is halting...
|
||||
reboot_msg The system is rebooting...
|
10
slim/slim.service
Normal file
10
slim/slim.service
Normal file
|
@ -0,0 +1,10 @@
|
|||
[Unit]
|
||||
Description=SLiM Simple Login Manager
|
||||
After=systemd-user-sessions.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/slim -n -s
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
Alias=display-manager.service
|
78
slim/slimlock.1
Normal file
78
slim/slimlock.1
Normal file
|
@ -0,0 +1,78 @@
|
|||
.TH slimlock 1 "January 12, 2023" "version 0.9"
|
||||
.SH NAME
|
||||
\fBslimlock\fP - Unholy Screen Locker
|
||||
\fB
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.fam C
|
||||
\fBslimlock\fP [\-v]
|
||||
.fam T
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The Frankenstein's monster of screen lockers. Grafting SLiM and slock together
|
||||
leads to blood, tears, and locked screens.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B
|
||||
\fB-v\fP
|
||||
display version information
|
||||
.SH CONFIGURATION
|
||||
Slimlock reads the same configuration files you use for SLiM. It looks in
|
||||
\fICFGDIR/slim.conf\fP and \fICFGDIR/slimlock.conf\fP, where \fICFGDIR\fP
|
||||
is defined when built - usually \fI/etc\fP.
|
||||
The options that are read from slim.conf are
|
||||
hidecursor, current_theme, background_color and background_style,
|
||||
screenshot_cmd, and welcome_msg. See the SLiM docs for more information.
|
||||
|
||||
slimlock.conf contains the following settings:
|
||||
|
||||
.TP
|
||||
.B dpms_standby_timeout
|
||||
number of seconds of inactivity before the screen blanks.
|
||||
.BI "Default: " 60
|
||||
.TP
|
||||
.B dpms_off_timeout
|
||||
number of seconds of inactivity before the screen is turned off.
|
||||
.BI "Default: " 600
|
||||
.TP
|
||||
.B wrong_passwd_timeout
|
||||
delay in seconds after an incorrect password is entered.
|
||||
.BI "Default: " 2
|
||||
.TP
|
||||
.B passwd_feedback_msg
|
||||
message to display after a failed authentication attempt.
|
||||
.BI "Default: " "Authentication failed"
|
||||
.TP
|
||||
.B passwd_feedback_capslock
|
||||
message to display after a failed authentication attempt if the CapsLock is on.
|
||||
.BI "Default: " "Authentication failed (CapsLock is on)"
|
||||
.TP
|
||||
.B show_username
|
||||
1 to show username on themes with single input field; 0 to disable.
|
||||
.BI "Default: " 1
|
||||
.TP
|
||||
.B show_welcome_msg
|
||||
1 to show SLiM's welcome message; 0 to disable.
|
||||
.BI "Default: " 0
|
||||
.TP
|
||||
.B tty_lock
|
||||
1 to disallow virtual terminals switching; 0 to allow.
|
||||
.BI "Default: " 1
|
||||
.TP
|
||||
.B bell
|
||||
1 to enable the bell on authentication failure; 0 to disable.
|
||||
.BI "Default: " 1
|
||||
.SH BUGS
|
||||
Where the theme defines a welcome message or password prompt, \fBslimlock\fP
|
||||
displays them in the wrong place.
|
||||
.PP
|
||||
Using the same theme as \fBslim\fP assumes the theme is appropriate. Most of
|
||||
the themes out there (including our defaults) put the word "Login" on the
|
||||
panel, which isn't quite right for a screen lock.
|
||||
.PP
|
||||
To alleviate both of these, you can specify a different theme in
|
||||
\fICFGDIR/slimlock.conf\fP, which will override the setting in
|
||||
\fICFGDIR/slim.conf\fP, but you still need to find (or create) a suitable
|
||||
lock theme.
|
||||
.SH "SEE ALSO"
|
||||
.BR slim (1)
|
11
slim/slimlock.conf
Normal file
11
slim/slimlock.conf
Normal file
|
@ -0,0 +1,11 @@
|
|||
dpms_standby_timeout 60
|
||||
dpms_off_timeout 600
|
||||
|
||||
wrong_passwd_timeout 2
|
||||
passwd_feedback_x 50%
|
||||
passwd_feedback_y 10%
|
||||
passwd_feedback_msg Authentication failed
|
||||
passwd_feedback_capslock Authentication failed (CapsLock is on)
|
||||
show_username 1
|
||||
show_welcome_msg 0
|
||||
tty_lock 0
|
342
slim/slimlock.cpp
Normal file
342
slim/slimlock.cpp
Normal file
|
@ -0,0 +1,342 @@
|
|||
/* slimlock
|
||||
* Copyright (c) 2010-2012 Joel Burget <joelburget@gmail.com>
|
||||
* Copyright (c) 2022-2023 Rob Pearce <slim@flitspace.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/vt.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/dpms.h>
|
||||
#include <security/pam_appl.h>
|
||||
#include <pthread.h>
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h> // for usleep
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <errno.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "cfg.h"
|
||||
#include "util.h"
|
||||
#include "panel.h"
|
||||
#include "const.h"
|
||||
|
||||
#undef APPNAME
|
||||
#define APPNAME "slimlock"
|
||||
#define SLIMLOCKCFG SYSCONFDIR"/slimlock.conf"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool AuthenticateUser();
|
||||
static int ConvCallback(int num_msgs, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr);
|
||||
void HandleSignal(int sig);
|
||||
void *RaiseWindow(void *data);
|
||||
|
||||
// In the absence of a class instance to contain these, just make them file
|
||||
// public, as they're needed by multiple functions
|
||||
static Display* Dpy;
|
||||
static int Scr;
|
||||
static Window Root;
|
||||
static Window win;
|
||||
static Cfg* cfg;
|
||||
static Panel* LoginPanel;
|
||||
|
||||
static pam_handle_t *pam_handle;
|
||||
|
||||
static const struct pam_conv conv = {ConvCallback, NULL};
|
||||
|
||||
static CARD16 dpms_standby, dpms_suspend, dpms_off, dpms_level;
|
||||
static BOOL dpms_state, using_dpms;
|
||||
|
||||
static int term; // Used by a C callback function
|
||||
|
||||
|
||||
static void die(const char *errstr, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, errstr);
|
||||
vfprintf(stderr, errstr, ap);
|
||||
va_end(ap);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if((argc == 2) && !strcmp("-v", argv[1]))
|
||||
die ( APPNAME "-" VERSION ", © 2010-2012 Joel Burget\nUpdates © 2022-2023 Rob Pearce\n" );
|
||||
else if(argc != 1)
|
||||
die ( "usage: " APPNAME " [-v]\n" );
|
||||
|
||||
void (*prev_fn)(int);
|
||||
|
||||
// restore DPMS settings should slimlock be killed in the line of duty
|
||||
prev_fn = signal(SIGTERM, HandleSignal);
|
||||
if (prev_fn == SIG_IGN)
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
||||
// create a lock file to solve mutliple instances problem
|
||||
// /var/lock used to be the place to put this, now it's /run/lock
|
||||
// ...i think
|
||||
struct stat statbuf;
|
||||
int lock_file;
|
||||
|
||||
// try /run/lock first, since i believe it's preferred
|
||||
if (!stat("/run/lock", &statbuf))
|
||||
lock_file = open ( "/run/lock/" APPNAME ".lock", O_CREAT | O_RDWR, 0666);
|
||||
else
|
||||
lock_file = open ( "/var/lock/" APPNAME ".lock", O_CREAT | O_RDWR, 0666);
|
||||
|
||||
int rc = flock(lock_file, LOCK_EX | LOCK_NB);
|
||||
|
||||
if(rc) {
|
||||
if(EWOULDBLOCK == errno)
|
||||
die(APPNAME" already running\n");
|
||||
}
|
||||
|
||||
unsigned int cfg_passwd_timeout;
|
||||
|
||||
/* Read configuration and theme */
|
||||
cfg = new Cfg;
|
||||
cfg->readConf(CFGFILE);
|
||||
cfg->readConf(SLIMLOCKCFG);
|
||||
string themeName = "";
|
||||
string themebase = "";
|
||||
string themefile = "";
|
||||
string themedir = "";
|
||||
|
||||
themebase = string(THEMESDIR) + "/";
|
||||
themeName = cfg->getOption("current_theme");
|
||||
string::size_type pos;
|
||||
if ((pos = themeName.find(",")) != string::npos)
|
||||
{
|
||||
/* input is a set */
|
||||
themeName = cfg->findValidRandomTheme(themeName);
|
||||
}
|
||||
|
||||
bool loaded = false;
|
||||
while (!loaded)
|
||||
{
|
||||
themedir = themebase + themeName;
|
||||
themefile = themedir + THEMESFILE;
|
||||
if (!cfg->readConf(themefile))
|
||||
{
|
||||
if (themeName == "default")
|
||||
{
|
||||
cerr << APPNAME << ": Failed to open default theme file "
|
||||
<< themefile << endl;
|
||||
exit(ERR_EXIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << APPNAME << ": Invalid theme in config: "
|
||||
<< themeName << endl;
|
||||
themeName = "default";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
const char *DisplayName = getenv("DISPLAY");
|
||||
if (!DisplayName)
|
||||
DisplayName = DISPLAY;
|
||||
|
||||
Dpy = XOpenDisplay(DisplayName);
|
||||
if ( Dpy == 0 )
|
||||
die(APPNAME": cannot open display\n");
|
||||
|
||||
/* Get screen and root window */
|
||||
Scr = DefaultScreen(Dpy);
|
||||
Root = RootWindow(Dpy, Scr);
|
||||
|
||||
XSetWindowAttributes wa;
|
||||
wa.override_redirect = 1;
|
||||
wa.background_pixel = BlackPixel(Dpy, Scr);
|
||||
|
||||
// Create a full screen window
|
||||
win = XCreateWindow(Dpy, Root,
|
||||
0, 0, DisplayWidth(Dpy, Scr), DisplayHeight(Dpy, Scr),
|
||||
0, DefaultDepth(Dpy, Scr), CopyFromParent,
|
||||
DefaultVisual(Dpy, Scr), CWOverrideRedirect | CWBackPixel,
|
||||
&wa);
|
||||
XMapWindow(Dpy, win);
|
||||
|
||||
XFlush(Dpy);
|
||||
for (int len = 1000; len; len--) {
|
||||
if(XGrabKeyboard(Dpy, Root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
|
||||
== GrabSuccess)
|
||||
break;
|
||||
usleep(1000);
|
||||
}
|
||||
XSelectInput(Dpy, win, ExposureMask | KeyPressMask);
|
||||
|
||||
/* Create panel */
|
||||
LoginPanel = new Panel(Dpy, Scr, win, cfg, themedir, Panel::Mode_Lock);
|
||||
LoginPanel->HideCursor();
|
||||
|
||||
int ret = pam_start(APPNAME, LoginPanel->GetName().c_str(), &conv, &pam_handle);
|
||||
// If we can't start PAM, just exit because slimlock won't work right
|
||||
if (ret != PAM_SUCCESS)
|
||||
die("PAM: %s\n", pam_strerror(pam_handle, ret));
|
||||
|
||||
// disable tty switching
|
||||
if(cfg->getOption("tty_lock") == "1") {
|
||||
if ((term = open("/dev/console", O_RDWR)) == -1)
|
||||
perror("error opening console");
|
||||
|
||||
if ((ioctl(term, VT_LOCKSWITCH)) == -1)
|
||||
perror("error locking console");
|
||||
}
|
||||
|
||||
// Set up DPMS
|
||||
unsigned int cfg_dpms_standby, cfg_dpms_off;
|
||||
cfg_dpms_standby = Cfg::string2int(cfg->getOption("dpms_standby_timeout").c_str());
|
||||
cfg_dpms_off = Cfg::string2int(cfg->getOption("dpms_off_timeout").c_str());
|
||||
using_dpms = DPMSCapable(Dpy) && (cfg_dpms_standby > 0);
|
||||
if (using_dpms) {
|
||||
DPMSGetTimeouts(Dpy, &dpms_standby, &dpms_suspend, &dpms_off);
|
||||
|
||||
DPMSSetTimeouts(Dpy, cfg_dpms_standby,
|
||||
cfg_dpms_standby, cfg_dpms_off);
|
||||
|
||||
DPMSInfo(Dpy, &dpms_level, &dpms_state);
|
||||
if (!dpms_state)
|
||||
DPMSEnable(Dpy);
|
||||
}
|
||||
|
||||
// Get password timeout
|
||||
cfg_passwd_timeout = Cfg::string2int(cfg->getOption("wrong_passwd_timeout").c_str());
|
||||
// Let's just make sure it has a sane value
|
||||
cfg_passwd_timeout = cfg_passwd_timeout > 60 ? 60 : cfg_passwd_timeout;
|
||||
|
||||
pthread_t raise_thread;
|
||||
pthread_create(&raise_thread, NULL, RaiseWindow, NULL);
|
||||
|
||||
#if 0 // The DM code does this:
|
||||
/* Init Root */
|
||||
LoginPanel->setBackground();
|
||||
|
||||
/* Show panel */
|
||||
LoginPanel->OpenPanel();
|
||||
#endif
|
||||
|
||||
// Main loop
|
||||
while (true)
|
||||
{
|
||||
LoginPanel->ResetPasswd();
|
||||
|
||||
// AuthenticateUser returns true if authenticated
|
||||
if (AuthenticateUser())
|
||||
break;
|
||||
|
||||
LoginPanel->WrongPassword(cfg_passwd_timeout);
|
||||
}
|
||||
|
||||
// kill thread before destroying the window that it's supposed to be raising
|
||||
pthread_cancel(raise_thread);
|
||||
|
||||
LoginPanel->ClosePanel();
|
||||
delete LoginPanel;
|
||||
|
||||
// Get DPMS stuff back to normal
|
||||
if (using_dpms) {
|
||||
DPMSSetTimeouts(Dpy, dpms_standby, dpms_suspend, dpms_off);
|
||||
// turn off DPMS if it was off when we entered
|
||||
if (!dpms_state)
|
||||
DPMSDisable(Dpy);
|
||||
}
|
||||
|
||||
XCloseDisplay(Dpy);
|
||||
|
||||
close(lock_file); // will inherently release the flock
|
||||
|
||||
if(cfg->getOption("tty_lock") == "1") {
|
||||
if ((ioctl(term, VT_UNLOCKSWITCH)) == -1) {
|
||||
perror("error unlocking console");
|
||||
}
|
||||
}
|
||||
close(term);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ConvCallback(int num_msgs, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr)
|
||||
{
|
||||
LoginPanel->EventHandler(Panel::Get_Passwd);
|
||||
|
||||
// PAM expects an array of responses, one for each message
|
||||
if (num_msgs == 0 ||
|
||||
(*resp = (pam_response*) calloc(num_msgs, sizeof(struct pam_message))) == NULL)
|
||||
return PAM_BUF_ERR;
|
||||
|
||||
for (int i = 0; i < num_msgs; i++) {
|
||||
if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF &&
|
||||
msg[i]->msg_style != PAM_PROMPT_ECHO_ON)
|
||||
continue;
|
||||
|
||||
// return code is currently not used but should be set to zero
|
||||
resp[i]->resp_retcode = 0;
|
||||
if ((resp[i]->resp = strdup(LoginPanel->GetPasswd().c_str())) == NULL) {
|
||||
free(*resp);
|
||||
return PAM_BUF_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
bool AuthenticateUser()
|
||||
{
|
||||
return(pam_authenticate(pam_handle, 0) == PAM_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
void HandleSignal(int sig)
|
||||
{
|
||||
// Get DPMS stuff back to normal
|
||||
if (using_dpms) {
|
||||
DPMSSetTimeouts(Dpy, dpms_standby, dpms_suspend, dpms_off);
|
||||
// turn off DPMS if it was off when we entered
|
||||
if (!dpms_state)
|
||||
DPMSDisable(Dpy);
|
||||
}
|
||||
|
||||
if ((ioctl(term, VT_UNLOCKSWITCH)) == -1) {
|
||||
perror("error unlocking console");
|
||||
}
|
||||
close(term);
|
||||
|
||||
LoginPanel->ClosePanel();
|
||||
delete LoginPanel;
|
||||
|
||||
die(APPNAME": Caught signal; dying\n");
|
||||
}
|
||||
|
||||
void* RaiseWindow(void *data)
|
||||
{
|
||||
while(1) {
|
||||
XRaiseWindow(Dpy, win);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return (void *)0;
|
||||
}
|
2
slim/slimlock.pam
Normal file
2
slim/slimlock.pam
Normal file
|
@ -0,0 +1,2 @@
|
|||
#%PAM-1.0
|
||||
auth required pam_unix.so nodelay nullok
|
74
slim/switchuser.cpp
Normal file
74
slim/switchuser.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* SLiM - Simple Login Manager
|
||||
* Copyright (C) 1997, 1998 Per Liden
|
||||
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
* Copyright (C) 2022 Rob Pearce <slim@flitspace.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include "const.h"
|
||||
#include "cfg.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "switchuser.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SwitchUser::SwitchUser(struct passwd *pw, Cfg *c, const string& display,
|
||||
char** _env)
|
||||
: cfg(c), Pw(pw), env(_env)
|
||||
{
|
||||
}
|
||||
|
||||
SwitchUser::~SwitchUser()
|
||||
{
|
||||
/* Never called */
|
||||
}
|
||||
|
||||
void SwitchUser::Login(const char* cmd, const char* mcookie)
|
||||
{
|
||||
SetUserId();
|
||||
SetClientAuth(mcookie);
|
||||
Execute(cmd);
|
||||
}
|
||||
|
||||
void SwitchUser::SetUserId()
|
||||
{
|
||||
if( (Pw == 0) ||
|
||||
(initgroups(Pw->pw_name, Pw->pw_gid) != 0) ||
|
||||
(setgid(Pw->pw_gid) != 0) ||
|
||||
(setuid(Pw->pw_uid) != 0) ) {
|
||||
logStream << APPNAME << ": could not switch user id" << endl;
|
||||
exit(ERR_EXIT);
|
||||
}
|
||||
}
|
||||
|
||||
void SwitchUser::Execute(const char* cmd)
|
||||
{
|
||||
if ( chdir(Pw->pw_dir) < 0 )
|
||||
logStream << APPNAME << ": unable to chdir() to user's home: " << strerror(errno) << endl;
|
||||
logStream.closeLog();
|
||||
execle(Pw->pw_shell, Pw->pw_shell, "-c", cmd, NULL, env);
|
||||
/// @todo this copy-paste of App:CloseLog() should be cleaned up
|
||||
if ( !logStream.openLog( cfg->getOption("logfile").c_str() ) ) {
|
||||
cerr << APPNAME << ": Could not access log file: " << cfg->getOption("logfile") << endl;
|
||||
exit(ERR_EXIT);
|
||||
}
|
||||
logStream << APPNAME << ": could not execute login command: " << strerror(errno) << endl;
|
||||
}
|
||||
|
||||
void SwitchUser::SetClientAuth(const char* mcookie)
|
||||
{
|
||||
string home = string(Pw->pw_dir);
|
||||
string authfile = home + "/.Xauthority";
|
||||
remove(authfile.c_str());
|
||||
Util::add_mcookie(mcookie, ":0", cfg->getOption("xauth_path"),
|
||||
authfile);
|
||||
}
|
45
slim/switchuser.h
Normal file
45
slim/switchuser.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
Copyright (C) 1997, 1998 Per Liden
|
||||
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
||||
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _SWITCHUSER_H_
|
||||
#define _SWITCHUSER_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <paths.h>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
class Cfg;
|
||||
|
||||
class SwitchUser
|
||||
{
|
||||
public:
|
||||
SwitchUser(struct passwd *pw, Cfg *c, const std::string& display,
|
||||
char** _env);
|
||||
~SwitchUser();
|
||||
void Login(const char* cmd, const char* mcookie);
|
||||
|
||||
private:
|
||||
SwitchUser();
|
||||
void SetEnvironment();
|
||||
void SetUserId();
|
||||
void Execute(const char* cmd);
|
||||
void SetClientAuth(const char* mcookie);
|
||||
Cfg* cfg;
|
||||
struct passwd *Pw;
|
||||
|
||||
char** env;
|
||||
};
|
||||
|
||||
#endif /* _SWITCHUSER_H_ */
|
1
slim/themes/CMakeLists.txt
Normal file
1
slim/themes/CMakeLists.txt
Normal file
|
@ -0,0 +1 @@
|
|||
subdirs (default original)
|
5
slim/themes/default/CMakeLists.txt
Normal file
5
slim/themes/default/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
set (THEMES "themes/default")
|
||||
|
||||
install(FILES slim.theme DESTINATION ${PKGDATADIR}/${THEMES})
|
||||
install(FILES panel.png DESTINATION ${PKGDATADIR}/${THEMES})
|
||||
install(FILES background.jpg DESTINATION ${PKGDATADIR}/${THEMES})
|
1
slim/themes/default/COPYRIGHT.background
Normal file
1
slim/themes/default/COPYRIGHT.background
Normal file
|
@ -0,0 +1 @@
|
|||
Green glass image copyright Rob Pearce (c)2022
|
1
slim/themes/default/COPYRIGHT.panel
Normal file
1
slim/themes/default/COPYRIGHT.panel
Normal file
|
@ -0,0 +1 @@
|
|||
The icon in the panel was downloaded from https://icons8.com
|
340
slim/themes/default/LICENSE.panel
Normal file
340
slim/themes/default/LICENSE.panel
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
BIN
slim/themes/default/background.jpg
Normal file
BIN
slim/themes/default/background.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 272 KiB |
BIN
slim/themes/default/panel.png
Normal file
BIN
slim/themes/default/panel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
52
slim/themes/default/slim.theme
Normal file
52
slim/themes/default/slim.theme
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Green glass theme for SLiM
|
||||
# by Rob Pearce <slim@flitspace.org.uk>
|
||||
|
||||
# Messages (e.g. shutdown)
|
||||
msg_color #FFFFFF
|
||||
msg_font Verdana:size=18:bold:dpi=75
|
||||
msg_x 50%
|
||||
msg_y 40%
|
||||
msg_shadow_color #702342
|
||||
msg_shadow_xoffset 1
|
||||
msg_shadow_yoffset 1
|
||||
|
||||
# valid values: stretch, tile
|
||||
background_style stretch
|
||||
background_color #11dd56
|
||||
|
||||
# Input controls
|
||||
input_panel_x 50%
|
||||
input_panel_y 45%
|
||||
input_name_x 394
|
||||
input_name_y 142
|
||||
input_pass_x 394
|
||||
input_pass_y 178
|
||||
input_font Verdana:size=12:dpi=75
|
||||
input_color #000000
|
||||
|
||||
# Username / password request
|
||||
username_font Verdana:size=18:dpi=75
|
||||
username_color #FFDFFF
|
||||
username_x 270
|
||||
username_y 144
|
||||
password_x 270
|
||||
password_y 180
|
||||
username_shadow_color #704f42
|
||||
username_shadow_xoffset 1
|
||||
username_shadow_yoffset 1
|
||||
|
||||
username_msg Username:
|
||||
password_msg Password:
|
||||
|
||||
# Welcome message
|
||||
welcome_font Verdana:size=28:bold:dpi=75
|
||||
welcome_color #F4D5C0
|
||||
welcome_x 50%
|
||||
welcome_y 40
|
||||
welcome_msg Login to %host
|
||||
welcome_shadow_xoffset 2
|
||||
welcome_shadow_yoffset 2
|
||||
welcome_shadow_color #338353
|
||||
|
||||
passwd_feedback_x 50%
|
||||
passwd_feedback_y 80%
|
5
slim/themes/original/CMakeLists.txt
Normal file
5
slim/themes/original/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
set (THEMES "themes/original")
|
||||
|
||||
install(FILES slim.theme DESTINATION ${PKGDATADIR}/${THEMES})
|
||||
install(FILES panel.png DESTINATION ${PKGDATADIR}/${THEMES})
|
||||
install(FILES background.jpg DESTINATION ${PKGDATADIR}/${THEMES})
|
2
slim/themes/original/COPYRIGHT.background
Normal file
2
slim/themes/original/COPYRIGHT.background
Normal file
|
@ -0,0 +1,2 @@
|
|||
Text. 04 is copyright (c) 2005 by rafael nascimento
|
||||
http://darkevil.deviantart.com
|
16
slim/themes/original/COPYRIGHT.panel
Normal file
16
slim/themes/original/COPYRIGHT.panel
Normal file
|
@ -0,0 +1,16 @@
|
|||
Lila SVG Icon and Theme Artwork
|
||||
Copyright (C) 2004 Lila Community
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
340
slim/themes/original/LICENSE.panel
Normal file
340
slim/themes/original/LICENSE.panel
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
BIN
slim/themes/original/background.jpg
Normal file
BIN
slim/themes/original/background.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 151 KiB |
BIN
slim/themes/original/panel.png
Normal file
BIN
slim/themes/original/panel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
37
slim/themes/original/slim.theme
Normal file
37
slim/themes/original/slim.theme
Normal file
|
@ -0,0 +1,37 @@
|
|||
# text04 theme for SLiM
|
||||
# by Johannes Winkelmann
|
||||
|
||||
# Messages (ie: shutdown)
|
||||
msg_color #FFFFFF
|
||||
msg_font Verdana:size=18:bold:dpi=75
|
||||
msg_x 50%
|
||||
msg_y 40%
|
||||
msg_shadow_color #702342
|
||||
msg_shadow_xoffset 1
|
||||
msg_shadow_yoffset 1
|
||||
|
||||
# valid values: stretch, tile
|
||||
background_style stretch
|
||||
background_color #eedddd
|
||||
|
||||
# Input controls
|
||||
input_panel_x 25%
|
||||
input_panel_y 65%
|
||||
input_name_x 394
|
||||
input_name_y 181
|
||||
input_font Verdana:size=12:dpi=75
|
||||
input_color #000000
|
||||
|
||||
# Username / password request
|
||||
username_font Verdana:size=14:bold:dpi=75
|
||||
username_color #f9f9f9
|
||||
username_x 280
|
||||
username_y 183
|
||||
password_x 50%
|
||||
password_y 183
|
||||
username_shadow_color #702342
|
||||
username_shadow_xoffset 1
|
||||
username_shadow_yoffset 1
|
||||
|
||||
username_msg Username:
|
||||
password_msg Password:
|
BIN
slim/themes/suckless/panel.png
Normal file
BIN
slim/themes/suckless/panel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
52
slim/themes/suckless/slim.theme
Normal file
52
slim/themes/suckless/slim.theme
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Green glass theme for SLiM
|
||||
# by Rob Pearce <slim@flitspace.org.uk>
|
||||
|
||||
# Messages (e.g. shutdown)
|
||||
msg_color #ced9dc
|
||||
msg_font Hack Nerd Font:size=18:bold:dpi=75
|
||||
msg_x 50%
|
||||
msg_y 40%
|
||||
msg_shadow_color #702342
|
||||
msg_shadow_xoffset 1
|
||||
msg_shadow_yoffset 1
|
||||
|
||||
# valid values: stretch, tile
|
||||
background_style stretch
|
||||
background_color #003E53
|
||||
|
||||
# Input controls
|
||||
input_panel_x 50%
|
||||
input_panel_y 45%
|
||||
input_name_x 394
|
||||
input_name_y 142
|
||||
input_pass_x 394
|
||||
input_pass_y 178
|
||||
input_font Hack Nerd Font:size=12:dpi=75
|
||||
input_color #003E53
|
||||
|
||||
# Username / password request
|
||||
username_font Hack Nerd Font:size=18:dpi=75
|
||||
username_color #ced9dc
|
||||
username_x 270
|
||||
username_y 144
|
||||
password_x 270
|
||||
password_y 180
|
||||
username_shadow_color #003E53
|
||||
username_shadow_xoffset 1
|
||||
username_shadow_yoffset 1
|
||||
|
||||
username_msg Username:
|
||||
password_msg Password:
|
||||
|
||||
# Welcome message
|
||||
welcome_font Hack Nerd Font:size=28:bold:dpi=75
|
||||
welcome_color #37817E
|
||||
welcome_x 50%
|
||||
welcome_y 40
|
||||
welcome_msg Login to %host
|
||||
welcome_shadow_xoffset 2
|
||||
welcome_shadow_yoffset 2
|
||||
welcome_shadow_color #003E53
|
||||
|
||||
passwd_feedback_x 50%
|
||||
passwd_feedback_y 80%
|
70
slim/util.cpp
Normal file
70
slim/util.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* SLiM - Simple Login Manager
|
||||
* Copyright (C) 2009 Eygene Ryabinkin <rea@codelabs.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
* Adds the given cookie to the specified Xauthority file.
|
||||
* Returns true on success, false on fault.
|
||||
*/
|
||||
bool Util::add_mcookie(const std::string &mcookie, const char *display,
|
||||
const std::string &xauth_cmd, const std::string &authfile)
|
||||
{
|
||||
FILE *fp;
|
||||
std::string cmd = xauth_cmd + " -f " + authfile + " -q";
|
||||
|
||||
fp = popen(cmd.c_str(), "w");
|
||||
if (!fp)
|
||||
return false;
|
||||
fprintf(fp, "remove %s\n", display);
|
||||
fprintf(fp, "add %s %s %s\n", display, ".", mcookie.c_str());
|
||||
fprintf(fp, "exit\n");
|
||||
|
||||
pclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface for random number generator. Just now it uses ordinary
|
||||
* random/srandom routines and serves as a wrapper for them.
|
||||
*/
|
||||
void Util::srandom(unsigned long seed)
|
||||
{
|
||||
::srandom(seed);
|
||||
}
|
||||
|
||||
long Util::random(void)
|
||||
{
|
||||
return ::random();
|
||||
}
|
||||
|
||||
/*
|
||||
* Makes seed for the srandom() using "random" values obtained from
|
||||
* getpid(), time(NULL) and others.
|
||||
*/
|
||||
long Util::makeseed(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
long pid = getpid();
|
||||
long tm = time(NULL);
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
|
||||
ts.tv_sec = ts.tv_nsec = 0;
|
||||
}
|
||||
|
||||
return pid + tm + (ts.tv_sec ^ ts.tv_nsec);
|
||||
}
|
25
slim/util.h
Normal file
25
slim/util.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* SLiM - Simple Login Manager
|
||||
Copyright (C) 2009 Eygene Ryabinkin <rea@codelabs.ru>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
#ifndef _UTIL_H__
|
||||
#define _UTIL_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Util
|
||||
{
|
||||
bool add_mcookie(const std::string &mcookie, const char *display,
|
||||
const std::string &xauth_cmd, const std::string &authfile);
|
||||
|
||||
void srandom(unsigned long seed);
|
||||
long random(void);
|
||||
|
||||
long makeseed(void);
|
||||
}
|
||||
|
||||
#endif /* _UTIL_H__ */
|
23
slim/xinitrc.sample
Normal file
23
slim/xinitrc.sample
Normal file
|
@ -0,0 +1,23 @@
|
|||
# the following variable defines the session which is started if the user
|
||||
# doesn't explicitly select a session
|
||||
DEFAULT_SESSION=twm
|
||||
|
||||
case $1 in
|
||||
xfce4)
|
||||
exec startxfce4
|
||||
;;
|
||||
icewm)
|
||||
icewmbg &
|
||||
icewmtray &
|
||||
exec icewm
|
||||
;;
|
||||
wmaker)
|
||||
exec wmaker
|
||||
;;
|
||||
blackbox)
|
||||
exec blackbox
|
||||
;;
|
||||
*)
|
||||
exec $DEFAULT_SESSION
|
||||
;;
|
||||
esac
|
Loading…
Reference in a new issue