1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-07-10 04:36:36 +02:00

Compare commits

...

66 Commits

Author SHA1 Message Date
David Maciejak a383074c99 WPrefs: sort alphabetically the key shortcut actions and expert options
There are too many entries now in key shortcut actions and expert options,
better to sort them dynamically.
2023-03-03 14:15:19 +00:00
David Maciejak 52a623729d Coverity: fix WRaster convert uninitialized scalar variable 2023-03-03 14:15:19 +00:00
David Maciejak d4ee17f0b5 Coverity: fix WPrefs workspace negative array index read 2023-03-03 14:15:19 +00:00
David Maciejak 7475bc5d0a Coverity: fix util wmsetbg resource leak 2023-03-03 14:15:19 +00:00
David Maciejak 35f87b5592 WRaster: add new file references for translation
This patch is adding the references for the two newly added files
save_jpeg.c and save_png.c for translation (even if those new
files are not adding any new strings to be translated).
2023-03-03 09:51:24 +00:00
David Maciejak 5e37d13eb6 Coverity: fix wmgenmenu resource leak 2023-03-02 17:04:48 +00:00
David Maciejak 4b1aee3e79 Coverity: fix wmmenugen resource leak 2023-03-02 17:04:48 +00:00
David Maciejak 0ccc5bbde7 Coverity: fix wmspec dereference after null check 2023-03-02 17:04:48 +00:00
David Maciejak 59a686d22e Coverity: fix WPrefs appearance negative array index read 2023-03-02 17:04:48 +00:00
David Maciejak 26d46f6e16 Coverity: fix WPrefs menu negative array index read 2023-03-02 17:04:48 +00:00
David Maciejak ceafbf0629 Coverity: fix WPrefs mousesettings menu negative array index read 2023-03-02 17:04:48 +00:00
David Maciejak cf178d011b Coverity: fix WPrefs preference negative array index read 2023-03-02 17:04:48 +00:00
David Maciejak 682c2767c2 Coverity: fix WPrefs texturepanel negative array index read 2023-03-02 17:04:48 +00:00
David Maciejak 0e00c6b605 Coverity: fix dialog dereference null return value
This patch is making sure defaultPath returns from FindImage() is not null
and freeing the variables.
2023-03-02 17:04:48 +00:00
David Maciejak e9717ed719 Coverity: fix WPrefs appearance time of check time of use 2023-03-02 17:04:48 +00:00
David Maciejak 9e59d19507 Coverity: fix WPrefs editmenu uninitialized scalar variables 2023-03-02 17:04:48 +00:00
David Maciejak 94f98dcd25 Coverity: fix WRaster convert uninitialized scalar variable 2023-03-02 17:04:48 +00:00
David Maciejak 6c7266c338 Coverity: fix session resource leak 2023-03-02 17:04:48 +00:00
David Maciejak b4bd6d0cad Coverity: fix xmodifier uninitialized scalar variable 2023-03-02 17:04:48 +00:00
David Maciejak c7f7c10d7c Coverity: fix wmsetbg string not null terminated 2023-03-02 17:04:48 +00:00
David Maciejak d831766572 Coverity: fix rootmenu structurally dead code 2023-03-02 17:04:48 +00:00
David Maciejak e2ecfbfd54 Coverity: fix wcolorpanel uninitialized scalar value 2023-03-02 17:04:48 +00:00
David Maciejak a8ec32d41a Coverity: fix setstyle resource leak 2023-03-02 17:04:48 +00:00
David Maciejak 1215680b6d Coverity: fix misc resource leak 2023-03-02 17:04:48 +00:00
David Maciejak 77df89396c Coverity: fix menuparser_macro uninitialized pointer read 2023-03-02 17:04:48 +00:00
David Maciejak c8883fdbb0 WRaster: add functions to save image on disk
This patch adds the RSaveTitledImage() function to the WRaster lib
to be able to save file on disk either as a PNG or a JPEG file.
Those two formats depends on optional external libs.
The function can take an optional title/comment which will
be save inside the file.

The WRaster lib and header versions are bumped.
2023-03-02 10:23:47 +00:00
David Maciejak 3cc5808dcd Coverity: fix wmspec uninitialized layer variable 2023-02-28 13:40:48 +00:00
David Maciejak 8ca89f0141 Coverity: fix RContextAttributes uninitialized variable 2023-02-28 13:33:11 +00:00
David Maciejak 76fa91d21e Coverity: fix wmiv resource leak 2023-02-28 13:33:11 +00:00
David Maciejak d2d5297a1e Coverity: fix potential buffer overflow 2023-02-28 13:33:11 +00:00
David 7b317a5fba wmiv: use W_KeycodeToKeysym instead of XkbKeycodeToKeysym
This patch replaces XkbKeycodeToKeysym in wmiv by our
own function W_KeycodeToKeysym.
2023-02-28 03:33:21 +00:00
David Maciejak 9f8dc6f5dc Use W_KeycodeToKeysym instead of XkbKeycodeToKeysym
This patch replaces XkbKeycodeToKeysym by our
own function W_KeycodeToKeysym.
2023-02-27 23:05:27 +00:00
David Maciejak bc56db0776 WPrefs: use W_KeycodeToKeysym instead of XkbKeycodeToKeysym
This patch replaces XKeycodeToKeysym and XkbKeycodeToKeysym
in WPrefs by our own function W_KeycodeToKeysym.
2023-02-27 23:05:27 +00:00
David Maciejak 15d06ff064 WINGs: Add W_KeycodeToKeysym to replace XKeycodeToKeysym/XkbKeycodeToKeysym calls
XKeycodeToKeysym was deprecated some time ago and we replaced
those function calls to XkbKeycodeToKeysym.
Usage of XkbKeycodeToKeysym is not the best as it appears
the XKEYBOARD can be disabled via xorg.conf (at least on Linux).
So just replacing XKeycodeToKeysym() with XkbKeycodeToKeysym()
could cause run-time errors on top of the compilation warning
we may have.
Better fix is to address the problem without introducing a
dependency on XKEYBOARD. W_KeycodeToKeysym is the equivalent
code for XKeycodeToKeysym/XkbKeycodeToKeysym using
XGetKeyboardMapping instead.

As a new function is added to the library WINGs library version
is bumped.
2023-02-27 22:37:44 +00:00
David Maciejak 2dd98666f1 Store window maximize state as hex value
As the maximize state is defined as a bit-field internally.
Better to store the flag in the WMSTATE file as hex value.
2023-02-27 22:37:44 +00:00
David Maciejak d1a7db8aea Compile by default with POSIX 7 revision
Compile by default with POSIX-2008 standard for Linux and FreeBSD.
2023-02-27 22:37:44 +00:00
David Maciejak 64a8ecb390 Code cleaning: removing trailing space
The patch is removing trailing space(s) before
the semicolon ending line. .c and .h files were checked.
2023-02-27 22:37:44 +00:00
David Maciejak a9e336256b Doc: add disable-res description 2023-02-26 11:02:46 +00:00
David Maciejak e9b20b51e9 WPrefs: check if captured keyboard shortcut is not in use
Make sure the captured keyboard shortcut is not already in use
by another action, if it's the case an error popup is shown and
the key is not kept.
2023-02-25 13:31:42 +00:00
David Maciejak 1d8b38b6e0 Fix compiler warnings from texture.c v2
The patch fixes those 2 warnings below from texture.c.
It reverts the previous v1 patch and fixes the compiler warning
by updating the texture.h wTextureMakeIGradient header instead.

texture.c:205:81: warning: argument 3 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  205 | WTexIGradient *wTextureMakeIGradient(WScreen *scr, int thickness1, const RColor colors1[2],
      |                                                                    ~~~~~~~~~~~~~^~~~~~~~~~
In file included from texture.c:33:
texture.h:165:53: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |                                                     ^~~~~~~~~~~~~~
texture.c:206:67: warning: argument 5 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  206 |                                      int thickness2, const RColor colors2[2])
      |                                                      ~~~~~~~~~~~~~^~~~~~~~~~
texture.h:165:74: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |
2023-02-25 13:31:42 +00:00
David Maciejak 82ad19d420 Fix compiler warnings from texture.c
The patch fixes those 2 warnings below from texture.c

texture.c:205:81: warning: argument 3 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  205 | WTexIGradient *wTextureMakeIGradient(WScreen *scr, int thickness1, const RColor colors1[2],
      |                                                                    ~~~~~~~~~~~~~^~~~~~~~~~
In file included from texture.c:33:
texture.h:165:53: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |                                                     ^~~~~~~~~~~~~~
texture.c:206:67: warning: argument 5 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  206 |                                      int thickness2, const RColor colors2[2])
      |                                                      ~~~~~~~~~~~~~^~~~~~~~~~
texture.h:165:74: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |
2023-02-24 12:19:38 +00:00
David Maciejak 492b22d975 Fix compiler warning from menu.c
The patch fixes the compiler warning below

menu.c: In function 'restoreMenuRecurs':
menu.c:2450:47: warning: '%s' directive output may be truncated writing up to 510 bytes into a region of size between 509 and 1019 [-Wformat-truncation=]
 2450 |         snprintf(buffer, sizeof(buffer), "%s\\%s", path, menu->frame->title);
      |                                               ^~

The code is taking care of checking properly the string passed to the buffer,
so there is no issue, the change is just to make the compiler happy.
2023-02-24 12:19:38 +00:00
David Maciejak 62405fbb75 Detect and override illegal window size hints v2
The patch is trying to mitigate and properly address the issue described at
https://github.com/window-maker/wmaker/issues/26
A buggy application (in that example virtualbox) is requesting a window size creation
that is way too big and basically at the limit of X11 protocol
(width and height are defined as CARD16).
See details at https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html
During the tests, virtualbox has been seen requesting for window creation of size 843x65508.
Even xprop is reporting incorrect values.

There had been an attempt before with the commit
https://repo.or.cz/wmaker-crm.git?a=commit;h=6668715402a5d8e2ecda6702076a06bf8988721e

But the patch is broken and not implemented at the right place.
As described in the wWindowConfigure function header, the size passed by the client app
should not be trusted and should be vetted with a prior call to wWindowConstrainSize.
wWindowConstrainSize call was missing only once in the wClientConfigure function from client.c
What wWindowConstrainSize doing now is basically setting a failsafe window size fo 640x480
if both width and height are above the size of CARD16.
If only one dimension is oversized, it's setting a default 4/3 window ratio.
Oversized here has not been changed and it's defined in windowmaker as double the screen size.
2023-02-22 20:10:31 +00:00
David Maciejak f1fef40f0d Make window maximize state persistent
Window maximize state is not persistent between windowmaker sessions.
This patch is updating the save and restore workspace state functions
to update the state in the WMSTATE file.
2023-02-21 18:16:35 +00:00
David Maciejak 2fb9308a67 Info Panel: Add libXRes info if supported
If windowmaker was compiled with libXRes,
add XRes info in the "Additional support" section.

Take also the chance to remove the mode +x on the source code file.
2023-02-20 23:07:02 +00:00
David Maciejak d902477efd Set missing WM_COMMAND using pid given from libXRes
For apps which are not setting the window WM_COMMAND property like those old
apps using Motif toolkit (I am thinking of NEdit for example)
it's bringing some issues in windowmaker which is relying on it for a few interactions.
Especially,
*an app without WM_COMMAND will not be saved during the workspace state
(so session restore is not working for them)
*when added to the dock, the settings parameters are empty and need to be filled
*cannot autostart from the dock (even if the settings are manually filled and saved)
*right click on the app titlebar, and choosing Launch has no effect

Most of the time, those apps are also not setting the X11_NET_WM_PID property.
With the pid we could have a chance to find the running program.
To link a window to a pid, there is the X11 Resource extension library (libXRes).
After checking, gnome and xfce are also using the same method to handle such issues.

The patch is checking if the libXRes is present on the system (but it's not mandatory to compile).
Then, it adds a layer on top of wNETWMGetPidForWindow to not only check the window property
but if necessary to get the underlying pid from libXRes if available.
That's solving the points mentioned above.
2023-02-20 15:00:55 +00:00
David Maciejak 5ee19c2308 Allow WM_COMMAND-less app to autostart
For apps which are not setting the window WM_COMMAND property like those old
apps using Motif toolkit (I am thinking of NEdit for example)
it's bringing some issues in windowmaker which is relying on it for a few interactions.
Especially,
*an app without WM_COMMAND will not be saved during the workspace state
(so session restore is not working for them)
*when added to the dock, the settings parameters are empty and need to be filled
*cannot autostart from the dock (even if the settings are manually filled and saved)
*right click on the app titlebar, and choosing Launch has no effect

The patch below allows the workspace state to be saved for those apps without WM_COMMAND
that have been launched from the dock. We are just reusing what have been set in the
Application Path Settings of the dock app (and it does not require extra libs like libXRes).
2023-02-20 15:00:55 +00:00
David Maciejak fabd4252ab Allow exit panel to be bound to a key shortcut
While debugging the save/restore workspace state, I found quite
useful to be able to exit windowmaker using a key shortcut.
2023-02-20 15:00:55 +00:00
David Maciejak 630e9292c2 Factorize duplicate run command code
Run command from the menu and run command from the key shortcut are from two different codes.
Merge them into one function instead.
2023-02-19 10:10:49 +00:00
David Maciejak 14d1b8197a WRaster: Avoid undefined setjmp() behavior with libjpeg
Fix compiler warning:
load_jpeg.c: In function 'RLoadJPEG':
load_jpeg.c:100:17: warning: variable 'image' might be clobbered by 'longjmp' or 'vfork' [-Wclobbered]

As it was not working to only set the RImage *image as volatile,
I had to refactor the code by following the example from
https://github.com/libjpeg-turbo/libjpeg-turbo/commit/410c028f3396d1fa9bcc72608079ff4d3d76b03e#diff-e7cb632359a2be17c1008b50f9ec85691cd5d66834d5fe8f63ef65ceb06682ee
2023-02-19 10:10:41 +00:00
David Maciejak 4d658341d2 Add support for _NET_WM_FULLSCREEN_MONITORS
This patch adds the _NET_WM_FULLSCREEN_MONITORS hint as defined in EWMH which is based on Xinerama.
It's allowing a window to be displayed fullscreen on multiple monitors.

Issue mentioned at https://github.com/window-maker/wmaker/issues/8
Specs at https://specifications.freedesktop.org/wm-spec/1.5/ar01s06.html#idm45763309187776
GTK test program used https://bugzilla.gnome.org/show_bug.cgi?id=414476
2023-02-18 08:41:08 +00:00
David Maciejak ac75047aef Fix mini workspace compiler warnings
The patch is to fix warnings like:
wsmap.c: In function "update_mini_workspace":
wsmap.c:451:55: warning: "%d" directive output may be truncated writing between 1 and 11 bytes into a region of size 10 [-Wformat-truncation=]
  451 |                         snprintf(name, sizeof(name), "%d", general_index);
2023-02-17 21:51:06 +00:00
David Maciejak 6d6f9f6ff5 Info Panel: Fix uninitialized posn variable 2023-02-16 11:34:54 +00:00
David Maciejak 370adc94e7 Ignore WM_NORMAL_HINTS resize increment for maximized windows
If you are trying to maximize old apps that are setting a resize increment
in term of WM_NORMAL_HINTS notion the window will not be maximized fully (by a few pixels).
It's easy to reproduce with xterm, ctrl double click on the title bar.
xprop extract sample is giving:
program specified resize increment: 6 by 13

For those maximized windows the patch is just ignoring the resize increment.
Seems the same issue happened on that project
https://github.com/paperwm/PaperWM/issues/106
2023-02-16 01:21:25 +00:00
David Maciejak 532acdc443 WRaster: Avoid types deprecated with libtiff 4.3
This patch is fixing compiler warnings like:

load_tiff.c:42:9: warning: 'uint16' is deprecated [-Wdeprecated-declarations]
load_tiff.c:43:9: warning: 'uint32' is deprecated [-Wdeprecated-declarations]

As starting from libtiff 4.3, released in April 2021, types were moved
from uint16 to uint16_t and uint32 to uint32_t respectively.

See https://libtiff.gitlab.io/libtiff/releases/v4.3.0.html
2023-02-15 11:24:09 +00:00
David Maciejak d7d38aa443 Info Panel: display more OS details
Rely on old utsname and os-release (http://0pointer.de/blog/projects/os-release) when available
to display more underlying OS details in the Info panel.
The idea is when someone creates a bug entry we can request them to copy/paste that screen
to give more info about the context that could help us debug the issue.
For example, on my current system it's displaying:
"Running on: Ubuntu 22.10 (x86_64)"
2023-02-15 09:37:06 +00:00
David Maciejak a6209cc89b Set a better exit panel message
Replace the exit window manager generic message with Window Maker term instead.
2023-02-15 09:37:06 +00:00
David Maciejak 01bd523cee WINGs: allow keypad enter key to validate button
This patch allows the keypad enter key to validate the button click action.
2023-02-15 09:37:06 +00:00
David Maciejak 45ab72a78a InfoPanel: fix out of display text
When debug is enabled, the memory allocated details is supposed to display the free chunks
but as the text length is too long it's getting out of the display area.
This patch is increasing the window width to handle such case.
2023-02-13 13:10:14 +00:00
David Maciejak 437b76812d Info Panel: mallinfo is deprecated use mallinfo2 instead
Replacing mallinfo with mallinfo2.

The fields of the mallinfo structure that is returned by the
older mallinfo() function are typed as int.  However, because
some internal bookkeeping values may be of type long, the
reported values may wrap around zero and thus be inaccurate.
2023-02-11 10:35:23 +00:00
David Maciejak e3ee459a78 Info Panel: use system time to get the current year
Use the system date to get the current year to insert inside the copyright line.
So no need to update that string anymore.
2023-02-11 10:33:22 +00:00
David Maciejak d70b546f2e Fix wrong XKeycodeToKeysym index value
XKeycodeToKeysym was deprecated some time ago and wmaker code was patched to use the definition from XKBlib instead.
(https://repo.or.cz/wmaker-crm.git?a=commit;h=0382dd5dd7ecae2112a0c6366eaf9e6ab68ad354)

Before being deprecated,  XKeycodeToKeysym was prototyped at X11/Xlib.h as
KeySym XKeycodeToKeysym(display, keycode, index)

Now it's available in X11/XKBlib.h as
KeySym XkbKeycodeToKeysym(display, keycode, group, level)

Basically level now which is the 4th parameter is our old index variable (3rd parameter).

On systems which don't have xkb supported the value set for index is wrong.
As seen in old patch at https://repo.or.cz/wmaker-crm.git/blobdiff/139f912e618870cc7fd908099f203450547eb658..43c3526d2120712f72579398b73ef92283d9078b:/WPrefs.app/MouseSettings.c
we should pass the l value to old XKeycodeToKeysym function and not the 0 value which is used for the group in the new XkbKeycodeToKeysym definition.
2023-02-11 10:30:52 +00:00
David Maciejak 812930b7cd Fix icon.c unused variable compiler warning
Just to please the compiler as it's reporting:
icon.c: In function 'get_icon_cache_path':
icon.c:425:13: warning: unused variable 'len' [-Wunused-variable]
2023-02-11 10:30:02 +00:00
David Maciejak 2a14004fc3 SwitchPanel: make sure WMRetainColor and WMReleaseColor calls are even
The number of calls to WMRetainColor for a color in use should the same as the number of calls to WMReleaseColor
to free that color. In case of discrepancy, random crashes can happen and memory is not freed properly.
To debug that issue I checked the retained colors when the switchpanel is opened and then checked if those colors are properly released once the panel is closed.

This patch fixes the issue mentioned at https://github.com/window-maker/wmaker/issues/22
2023-02-10 11:24:55 +00:00
David Maciejak 04e9f33437 WINGs: Fix incorrect findCloseColor exact flag value
In case the color cannot be allocated exactly by createRGBAColor function,
the findCloseColor function is used as a failover function to find a color close to the requested color.
By definition that color is then not exact.
createRGBAColor exact flag should be 1 while findCloseColor exact flag should be 0
2023-02-10 11:24:44 +00:00
David Maciejak 150816c687 Fix missing linefeed on the error message
Just to display the error message properly in case there is no display.
2023-02-08 00:14:48 +00:00
72 changed files with 1151 additions and 326 deletions
+6
View File
@@ -1,3 +1,9 @@
Changes since wmaker 0.95.10:
............................
- added W_KeycodeToKeysym to replace XKeycodeToKeysym/XkbKeycodeToKeysym calls
Changes since wmaker 0.92.0:
............................
+3 -1
View File
@@ -1,7 +1,9 @@
** API and ABI modifications since wmaker 0.92.0
** API and ABI modifications since wmaker 0.95.10
----------------------------------------------------
** libWINGs **
<WINGsP.h>
W_KeycodeToKeysym ADDED
struct W_DragDestinationInfo: new members added SIZE CHANGE
<WINGs.h>
+1 -1
View File
@@ -26,7 +26,7 @@
#include <WINGs/WUtil.h>
#include <X11/Xlib.h>
#define WINGS_H_VERSION 20210726
#define WINGS_H_VERSION 20230226
#ifdef __cplusplus
+2
View File
@@ -494,6 +494,8 @@ void W_SetPreeditPositon(W_View *view, int x, int y);
int W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer,
int buflen, KeySym *keysym, Status *status);
KeySym W_KeycodeToKeysym(Display *display, KeyCode keycode, int index);
/* ---[ wmisc.c ]--------------------------------------------------------- */
+2 -2
View File
@@ -612,10 +612,10 @@ static void menu_parser_condition_ifmacro(WMenuParser parser, Bool check_exists)
macro = menu_parser_find_macro(parser, macro_name);
parser->cond.stack[0].skip =
((check_exists) && (macro == NULL)) ||
((!check_exists) && (macro != NULL)) ;
((!check_exists) && (macro != NULL));
}
strcpy(parser->cond.stack[0].name, cmd_name);
strncpy(parser->cond.stack[0].name, cmd_name, sizeof(parser->cond.stack[0].name) - 1);
parser->cond.stack[0].line = parser->line_number;
}
+6 -2
View File
@@ -167,6 +167,7 @@ void menu_parser_define_macro(WMenuParser parser)
return;
}
macro = wmalloc(sizeof(*macro));
memset(arg_name, 0, MAX_MACRO_ARG_COUNT * sizeof(char *));
/* Isolate name of macro */
idx = 0;
@@ -279,7 +280,8 @@ WParserMacro *menu_parser_find_macro(WMenuParser parser, const char *name)
continue;
return macro;
check_next_macro: ;
check_next_macro:
;
}
return NULL;
}
@@ -391,6 +393,8 @@ void menu_parser_expand_macro(WMenuParser parser, WParserMacro *macro)
unsigned int size;
int i, space_left;
memset(arg_value, 0, MAX_MACRO_ARG_COUNT * sizeof(char *));
/* Skip the name of the macro, this was not done by caller */
for (i = 0; macro->name[i] != '\0'; i++)
parser->rd++;
@@ -692,7 +696,7 @@ static void w_create_macro(WMenuParser parser, const char *name, WParserMacroFun
WParserMacro *macro;
macro = wmalloc(sizeof(*macro));
strcpy(macro->name, name);
strncpy(macro->name, name, sizeof(macro->name) - 1);
macro->function = handler;
macro->arg_count = -1;
macro->next = parser->macros;
+3 -3
View File
@@ -51,7 +51,7 @@ static WMColor *findCloseColor(WMScreen * scr, unsigned short red, unsigned shor
color->refCount = 1;
color->color = xcolor;
color->alpha = alpha;
color->flags.exact = 1;
color->flags.exact = 0;
color->gc = NULL;
return color;
@@ -91,7 +91,7 @@ WMColor *WMCreateRGBColor(WMScreen * scr, unsigned short red, unsigned short gre
color = findCloseColor(scr, red, green, blue, 0xffff);
}
if (!color)
color = WMBlackColor(scr);
color = scr->black;
return color;
}
@@ -117,7 +117,7 @@ WMColor *WMCreateRGBAColor(WMScreen * scr, unsigned short red, unsigned short gr
color = findCloseColor(scr, red, green, blue, alpha);
}
if (!color)
color = WMBlackColor(scr);
color = scr->black;
return color;
}
+3 -3
View File
@@ -2259,7 +2259,7 @@ static void wheelPositionSelectionOutBounds(W_ColorPanel * panel, int x, int y)
static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel * panel)
{
CPColor from;
CPColor from = {};
unsigned long ofs;
ofs = panel->coly * panel->wheelMtrx->width + panel->colx;
@@ -2604,7 +2604,7 @@ static void cmykTextFieldCallback(void *observerData, WMNotification * notificat
static void hsbSliderCallback(WMWidget * w, void *data)
{
CPColor cpColor;
CPColor cpColor = {};
int value[3];
char tmp[4];
W_ColorPanel *panel = (W_ColorPanel *) data;
@@ -2640,7 +2640,7 @@ static void hsbSliderCallback(WMWidget * w, void *data)
static void hsbTextFieldCallback(void *observerData, WMNotification * notification)
{
CPColor cpColor;
CPColor cpColor = {};
int value[3];
char tmp[12]; /* We only 4 bytes needed, but compilers cannot know that */
int n;
+3
View File
@@ -253,6 +253,9 @@ WMFrame *WMCreateFrame(WMWidget * parent)
static void destroyFrame(Frame * fPtr)
{
if (fPtr->textColor)
WMReleaseColor(fPtr->textColor);
if (fPtr->caption)
wfree(fPtr->caption);
+32
View File
@@ -213,3 +213,35 @@ int W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer, int bufl
#endif
return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);
}
/*
* Map a keycode to the corresponding keysym
* To replace the deprecated X11 function XKeycodeToKeysym
*/
KeySym W_KeycodeToKeysym(Display *display, KeyCode keycode, int index)
{
static int min_kc = -1;
static int max_kc;
int num_syms;
KeySym *key_syms;
KeySym ks;
if (min_kc == -1) {
(void) XDisplayKeycodes(display, &min_kc, &max_kc);
}
if (keycode < min_kc || keycode > max_kc || index < 0) {
return NoSymbol;
}
key_syms = XGetKeyboardMapping(display, keycode, 1, &num_syms);
if (index >= num_syms) {
XFree(key_syms);
return NoSymbol;
}
ks = key_syms[index];
XFree(key_syms);
return ks;
}
+3 -3
View File
@@ -25,7 +25,7 @@ static void handleKeyPress(XEvent * event, void *clientData)
XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
if (ksym == XK_Return && panel->defBtn) {
if ((ksym == XK_Return || ksym == XK_KP_Enter) && panel->defBtn) {
WMPerformButtonClick(panel->defBtn);
} else if (ksym == XK_Escape) {
if (panel->altBtn || panel->othBtn) {
@@ -421,7 +421,7 @@ static void handleKeyPress2(XEvent * event, void *clientData)
XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
if (ksym == XK_Return && panel->defBtn) {
if ((ksym == XK_Return || ksym == XK_KP_Enter) && panel->defBtn) {
WMPerformButtonClick(panel->defBtn);
} else if (ksym == XK_Escape) {
if (panel->altBtn) {
@@ -709,7 +709,7 @@ static void handleKeyPress3(XEvent * event, void *clientData)
XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
if (ksym == XK_Return && panel->defBtn) {
if ((ksym == XK_Return || ksym == XK_KP_Enter) && panel->defBtn) {
WMPerformButtonClick(panel->defBtn);
} else if (ksym == XK_Escape) {
if (panel->altBtn) {
+1 -1
View File
@@ -622,7 +622,7 @@ static void paintText(Text * tPtr)
TextBlock *tb;
WMFont *font;
const char *text;
int len, y, c, s, done = False, dir /* 1 = down */ ;
int len, y, c, s, done = False, dir; /* dir 1 = down */
WMScreen *scr = tPtr->view->screen;
Display *dpy = tPtr->view->screen->display;
Window win = tPtr->view->window;
+1 -1
View File
@@ -661,7 +661,7 @@ static void didResizeTextField(W_ViewDelegate * self, WMView * view)
tPtr->offsetWidth = WMAX((tPtr->view->size.height - WMFontHeight(tPtr->font)) / 2, 1);
tPtr->usableWidth = tPtr->view->size.width - 2 * tPtr->offsetWidth /*+ 2 */ ;
tPtr->usableWidth = tPtr->view->size.width - 2 * tPtr->offsetWidth;
}
static char *makeHiddenString(int length)
+17 -5
View File
@@ -1076,6 +1076,8 @@ static void deleteTexture(WMWidget * w, void *data)
(void) w;
section = WMGetPopUpButtonSelectedItem(panel->secP);
if (section < 0)
return;
row = WMGetListSelectedItemRow(panel->texLs);
item = WMGetListItem(panel->texLs, row);
titem = (TextureListItem *) item->clientData;
@@ -1134,6 +1136,8 @@ static void changePage(WMWidget * w, void *data)
if (w) {
section = WMGetPopUpButtonSelectedItem(panel->secP);
if (section < 0)
return;
WMSelectListItem(panel->texLs, panel->textureIndex[section]);
@@ -1233,6 +1237,8 @@ static void textureDoubleClick(WMWidget * w, void *data)
/* unselect old texture */
section = WMGetPopUpButtonSelectedItem(panel->secP);
if (section < 0)
return;
item = WMGetListItem(panel->texLs, panel->textureIndex[section]);
titem = (TextureListItem *) item->clientData;
@@ -1261,7 +1267,7 @@ static void paintListItem(WMList * lPtr, int index, Drawable d, char *text, int
{
_Panel *panel = (_Panel *) WMGetHangedData(lPtr);
WMScreen *scr = WMWidgetScreen(lPtr);
int width, height, x, y;
int width, height, x, y, tmp;
Display *dpy = WMScreenDisplay(scr);
WMColor *back = (state & WLDSSelected) ? WMWhiteColor(scr) : WMGrayColor(scr);
WMListItem *item;
@@ -1290,7 +1296,8 @@ static void paintListItem(WMList * lPtr, int index, Drawable d, char *text, int
XCopyArea(dpy, titem->preview, d, WMColorGC(black), 0, 0,
TEXPREV_WIDTH, TEXPREV_HEIGHT, x + 5, y + 5);
if ((1 << WMGetPopUpButtonSelectedItem(panel->secP)) & titem->selectedFor)
tmp = WMGetPopUpButtonSelectedItem(panel->secP);
if ((tmp >= 0) && ((1 << tmp) & titem->selectedFor))
WMDrawPixmap(panel->onLed, d, x + TEXPREV_WIDTH + 10, y + 6);
else if (titem->selectedFor)
WMDrawPixmap(panel->offLed, d, x + TEXPREV_WIDTH + 10, y + 6);
@@ -1425,6 +1432,10 @@ static void changeColorPage(WMWidget * w, void *data)
WMScreen *scr = WMWidgetScreen(panel->box);
RContext *rc = WMScreenRContext(scr);
section = WMGetPopUpButtonSelectedItem(panel->colP);
if (section < 0)
return;
if (panel->preview) {
GC gc;
@@ -1436,7 +1447,6 @@ static void changeColorPage(WMWidget * w, void *data)
colorOptions[panel->oldcsection].hand.y);
}
if (w) {
section = WMGetPopUpButtonSelectedItem(panel->colP);
panel->oldcsection = section;
if (panel->preview)
@@ -1737,6 +1747,8 @@ static void colorWellObserver(void *self, WMNotification * n)
(void) n;
p = WMGetPopUpButtonSelectedItem(panel->colP);
if (p < 0)
return;
WMReleaseColor(panel->colors[p]);
@@ -1831,7 +1843,7 @@ static void createPanel(Panel * p)
panel->fprefix = wstrconcat(wuserdatapath(), "/" PACKAGE_TARNAME);
if (access(panel->fprefix, F_OK) != 0) {
if (mkdir(panel->fprefix, 0755) < 0) {
if (-1 == mkdir(panel->fprefix, 0755) && errno != EEXIST) {
werror("%s", panel->fprefix);
ok = False;
}
@@ -1841,7 +1853,7 @@ static void createPanel(Panel * p)
wfree(panel->fprefix);
panel->fprefix = tmp;
if (access(panel->fprefix, F_OK) != 0) {
if (mkdir(panel->fprefix, 0755) < 0) {
if (-1 == mkdir(panel->fprefix, 0755) && errno != EEXIST) {
werror("%s", panel->fprefix);
}
}
+15 -1
View File
@@ -25,7 +25,7 @@
/* This structure containts the list of all the check-buttons to display in the
* expert tab of the window with the corresponding information for effect
*/
static const struct {
static struct expert_option {
const char *label; /* Text displayed to user */
int def_state; /* True/False: the default value, if not defined in current config */
@@ -172,6 +172,19 @@ static void upButtonCallback(WMWidget *self, void *data)
changeIntTextfield(data, 1);
}
static int cmpExpertOptions(const void *v1, const void *v2)
{
int rc;
const struct expert_option *opt1 = (struct expert_option *)v1;
const struct expert_option *opt2 = (struct expert_option *)v2;
if ((rc = strcmp(opt1->label, opt2->label)) < 0)
return -1;
else if (rc > 0)
return 1;
return 0;
}
static void createPanel(Panel *p)
{
_Panel *panel = (_Panel *) p;
@@ -195,6 +208,7 @@ static void createPanel(Panel *p)
WMSetFrameRelief(f, WRFlat);
udb = WMGetStandardUserDefaults();
qsort(expert_options, wlengthof(expert_options), sizeof(expert_options[0]), cmpExpertOptions);
for (i = 0; i < wlengthof(expert_options); i++) {
if (expert_options[i].class != OPTION_WMAKER_INT) {
panel->swi[i] = WMCreateSwitchButton(f);
+62 -5
View File
@@ -65,7 +65,7 @@ typedef struct _Panel {
* First parameter is the internal keyword known by WMaker
* Second is the text displayed to the user
*/
static const struct {
static struct keyOption {
const char *key;
const char *title;
} keyOptions[] = {
@@ -156,6 +156,7 @@ static const struct {
{ "WindowRelaunchKey", N_("Launch new instance of application") },
{ "ScreenSwitchKey", N_("Switch to Next Screen/Monitor") },
{ "RunKey", N_("Run application") },
{ "ExitKey", N_("Exit Window Maker") },
{ "DockRaiseLowerKey", N_("Raise/Lower Dock") },
{ "ClipRaiseLowerKey", N_("Raise/Lower Clip") }
#ifdef XKB_MODELOCK
@@ -316,11 +317,8 @@ char *capture_shortcut(Display *dpy, Bool *capturing, Bool convert_case)
if (ev.type == KeyPress && ev.xkey.keycode != 0) {
numlock_mask = NumLockMask(dpy);
if (xext_xkb_supported)
/* conditional mask check to get numeric keypad keys */
ksym = XkbKeycodeToKeysym(dpy, ev.xkey.keycode, 0, ev.xkey.state & numlock_mask?1:0);
else
ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
ksym = W_KeycodeToKeysym(dpy, ev.xkey.keycode, ev.xkey.state & numlock_mask?1:0);
if (!IsModifierKey(ksym)) {
if (convert_case) {
@@ -368,6 +366,36 @@ char *capture_shortcut(Display *dpy, Bool *capturing, Bool convert_case)
return wstrdup(buffer);
}
/*
* check if the keystr entered is already set to another action
* if found it returns the position in the keyOptions
*/
static int isKeySet(_Panel *panel, char *keystr)
{
int i;
char *str;
for (i = 0; i < panel->actionCount; i++) {
str = NULL;
if (panel->shortcuts[i]) {
str = wtrimspace(panel->shortcuts[i]);
if (strlen(str) == 0) {
wfree(str);
str = NULL;
}
}
if (str) {
if (strcmp(keystr, str) == 0) {
wfree(str);
return i;
}
wfree(str);
}
}
return -1;
}
static void captureClick(WMWidget * w, void *data)
{
_Panel *panel = (_Panel *) data;
@@ -382,8 +410,21 @@ static void captureClick(WMWidget * w, void *data)
XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, GrabModeAsync, GrabModeAsync, CurrentTime);
shortcut = capture_shortcut(dpy, &panel->capturing, 1);
if (shortcut) {
int key_idx = -1;
int row = WMGetListSelectedItemRow(panel->actLs);
key_idx = isKeySet(panel, shortcut);
if (key_idx >= 0 && (key_idx != row)) {
char *msg;
msg = wstrconcat(_("Key shortcut already in use by the "), _(keyOptions[key_idx].title));
WMRunAlertPanel(WMWidgetScreen(w), GetWindow(),
_("Error"),
msg,
_("OK"), NULL, NULL);
wfree(msg);
wfree(shortcut);
} else {
WMSetTextFieldText(panel->shoT, shortcut);
if (row >= 0) {
if (panel->shortcuts[row])
@@ -396,6 +437,7 @@ static void captureClick(WMWidget * w, void *data)
}
}
}
}
panel->capturing = 0;
WMSetButtonText(w, _("Capture"));
WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
@@ -499,6 +541,20 @@ static void paintItem(WMList * lPtr, int index, Drawable d, char *text, int stat
WMDrawString(scr, d, panel->black, panel->font, x + 20, y, text, strlen(text));
}
static int cmpKeyOptions(const void *v1, const void *v2)
{
int rc;
const struct keyOption *opt1 = (struct keyOption *)v1;
const struct keyOption *opt2 = (struct keyOption *)v2;
if ((rc = strcmp(opt1->title, opt2->title)) < 0)
return -1;
else if (rc > 0)
return 1;
return 0;
}
static void createPanel(Panel * p)
{
_Panel *panel = (_Panel *) p;
@@ -538,6 +594,7 @@ static void createPanel(Panel * p)
WMSetListUserDrawProc(panel->actLs, paintItem);
WMHangData(panel->actLs, panel);
qsort(keyOptions, wlengthof(keyOptions), sizeof(keyOptions[0]), cmpKeyOptions);
for (i = 0; i < wlengthof(keyOptions); i++) {
WMAddListItem(panel->actLs, _(keyOptions[i].title));
}
+2
View File
@@ -291,6 +291,8 @@ static void changedItemPad(WMWidget * w, void *data)
_Panel *panel = (_Panel *) data;
int padn = WMGetPopUpButtonSelectedItem(w);
if (padn < 0)
return;
WMUnmapWidget(panel->itemPad[panel->currentPad]);
WMMapWidget(panel->itemPad[padn]);
+3 -4
View File
@@ -381,10 +381,7 @@ static void fillModifierPopUp(WMPopUpButton * pop)
if (mapping->modifiermap[idx] != 0) {
int l;
for (l = 0; l < 4; l++) {
if (xext_xkb_supported)
ksym = XkbKeycodeToKeysym(dpy, mapping->modifiermap[idx], 0, l);
else
ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], 0);
ksym = W_KeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
if (ksym != NoSymbol)
break;
}
@@ -751,6 +748,8 @@ static void storeData(_Panel * panel)
int action;
action = WMGetPopUpButtonSelectedItem(panel->mouse_action[i].popup);
if (action < 0)
continue;
if (button_list[i].type == T_BUTTON)
db_value = button_actions[action].db_value;
else
+4
View File
@@ -196,9 +196,13 @@ static void storeData(_Panel * panel)
int i;
i = WMGetPopUpButtonSelectedItem(panel->sizeP);
if (i < 0)
return;
SetStringForKey(resize_display[i].db_value, "ResizeDisplay");
i = WMGetPopUpButtonSelectedItem(panel->posiP);
if (i < 0)
return;
SetStringForKey(move_display[i].db_value, "MoveDisplay");
lr = WMGetButtonSelected(panel->lrB);
+1 -1
View File
@@ -689,7 +689,7 @@ static void changeTypeCallback(WMWidget *w, void *data)
int i;
newType = WMGetPopUpButtonSelectedItem(w);
if (newType == panel->currentType)
if (newType < 0 || newType == panel->currentType)
return;
if (panel->currentType >= 0) {
+1 -1
View File
@@ -33,6 +33,7 @@
#include <wraster.h>
#include <WINGs/WINGs.h>
#include <WINGs/WINGsP.h>
/* Needed for HAVE_LIBINTL_H and EXTENDED_WINDOWSHORTCUT */
#include "../src/wconfig.h"
@@ -54,7 +55,6 @@
/****/
extern char *NOptionValueChanged;
extern Bool xext_xkb_supported;
typedef struct _Panel Panel;
+5 -2
View File
@@ -207,12 +207,15 @@ static void createPanel(Panel * p)
static void storeData(_Panel * panel)
{
int tmp = WMGetPopUpButtonSelectedItem(panel->posP);
if (tmp < 0)
return;
SetBoolForKey(!WMGetButtonSelected(panel->linkB), "DontLinkWorkspaces");
SetBoolForKey(WMGetButtonSelected(panel->cyclB), "CycleWorkspaces");
SetBoolForKey(WMGetButtonSelected(panel->newB), "AdvanceToNewWorkspace");
SetStringForKey(WSNamePositions[WMGetPopUpButtonSelectedItem(panel->posP)],
"WorkspaceNameDisplayPosition");
SetStringForKey(WSNamePositions[tmp], "WorkspaceNameDisplayPosition");
}
Panel *InitWorkspace(WMWidget *parent)
+1 -1
View File
@@ -1150,7 +1150,7 @@ static void dragItem(WEditMenu * menu, WEditMenuItem * item, Bool copy)
static XColor back = { 0, 0xffff, 0xffff, 0xffff, DoRed | DoGreen | DoBlue, 0 };
Display *dpy = W_VIEW_DISPLAY(menu->view);
WMScreen *scr = W_VIEW_SCREEN(menu->view);
int x, y;
int x = 0, y = 0;
int dx, dy;
Bool done = False;
Window blaw;
-4
View File
@@ -35,8 +35,6 @@
#endif
char *NOptionValueChanged = "NOptionValueChanged";
Bool xext_xkb_supported = False;
#define MAX_DEATHS 64
@@ -157,8 +155,6 @@ int main(int argc, char **argv)
exit(0);
}
xext_xkb_supported = XkbQueryExtension(dpy, NULL, NULL, NULL, NULL, NULL);
WMPLSetCaseSensitive(False);
Initialize(scr);
+1 -4
View File
@@ -171,10 +171,7 @@ static void x_reset_modifier_mapping(Display * display)
KeySym sym;
if (code) {
if (xext_xkb_supported)
sym = XkbKeycodeToKeysym(display, code, 0, column);
else
sym = XKeycodeToKeysym(display, code, column);
sym = W_KeycodeToKeysym(display, code, column);
} else {
sym = NoSymbol;
}
+1
View File
@@ -232,6 +232,7 @@
WindowRelaunchKey = None;
ScreenSwitchKey = None;
RunKey = None;
ExitKey = None;
NormalCursor = (builtin, left_ptr);
ArrowCursor = (builtin, top_left_arrow);
MoveCursor = (builtin, fleur);
+19 -7
View File
@@ -71,16 +71,16 @@ dnl 6. If any interfaces have been removed or changed since the last
dnl public release, then set age to 0.
dnl
dnl libwraster
WRASTER_CURRENT=6
WRASTER_CURRENT=7
WRASTER_REVISION=0
WRASTER_AGE=0
WRASTER_AGE=1
WRASTER_VERSION=$WRASTER_CURRENT:$WRASTER_REVISION:$WRASTER_AGE
AC_SUBST(WRASTER_VERSION)
dnl
dnl libWINGs
WINGS_CURRENT=4
WINGS_CURRENT=5
WINGS_REVISION=0
WINGS_AGE=1
WINGS_AGE=2
WINGS_VERSION=$WINGS_CURRENT:$WINGS_REVISION:$WINGS_AGE
AC_SUBST(WINGS_VERSION)
dnl
@@ -270,8 +270,8 @@ supported_gfx=""
dnl Platform-specific Makefile setup
dnl ================================
AS_CASE(["$host"],
[*-*-linux*|*-*-cygwin*|*-gnu*], [WM_OSDEP="linux" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600"],
[*-*-freebsd*|*-k*bsd-gnu*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -DFREEBSD"],
[*-*-linux*|*-*-cygwin*|*-gnu*], [WM_OSDEP="linux" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=700"],
[*-*-freebsd*|*-k*bsd-gnu*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=700 -DFREEBSD"],
[*-*-netbsd*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -DNETBSD"],
[*-*-openbsd*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -DOPENBSD"],
[*-*-dragonfly*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -DDRAGONFLYBSD"],
@@ -387,7 +387,7 @@ AC_FUNC_MEMCMP
AC_FUNC_VPRINTF
WM_FUNC_SECURE_GETENV
AC_CHECK_FUNCS(gethostname select poll strcasecmp strncasecmp \
setsid mallinfo mkstemp sysconf)
setsid mallinfo2 mkstemp sysconf)
AC_SEARCH_LIBS([strerror], [cposix])
dnl nanosleep is generally available in standard libc, although not always the
@@ -580,6 +580,18 @@ AS_IF([test "x$enable_wmreplace" = "xyes"],
[define to support ICCCM protocol for window manager replacement])
supported_xext="$supported_xext WMReplace"])
dnl XRes support
dnl ==============
m4_divert_push([INIT_PREPARE])dnl
AC_ARG_ENABLE([res],
[AS_HELP_STRING([--disable-res], [disable resource window extension support])],
[AS_CASE(["$enableval"],
[yes|no], [],
[AC_MSG_ERROR([bad value $enableval for --enable-res]) ]) ],
[enable_res=auto])
m4_divert_pop([INIT_PREPARE])dnl
WM_XEXT_CHECK_XRES
dnl XShape support
dnl ==============
+4
View File
@@ -551,6 +551,10 @@ Disable use of the @emph{MIT shared memory} extension.
This will slow down texture generation a little bit, but in some cases it seems to be necessary due
to a bug that manifests as messed icons and textures.
@item --disable-res
Disables support for @emph{XRes} resource window extension support.
Which is used to find the underlying processes (and PIDs) displaying the windows.
@item --disable-shape
Disables support for @emph{shaped} windows (for @command{oclock}, @command{xeyes}, etc.).
+27
View File
@@ -16,6 +16,33 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# WM_XEXT_CHECK_XRES
# --------------------
#
# Check for the X Resource Window extension
# The check depends on variable 'enable_xshape' being either:
# yes - detect, fail if not found
# no - do not detect, disable support
# auto - detect, disable if not found
#
# When found, append appropriate stuff in XLIBS, and append info to
# the variable 'supported_xext'
# When not found, append info to variable 'unsupported'
AC_DEFUN_ONCE([WM_XEXT_CHECK_XRES],
[WM_LIB_CHECK([XRes], [-lXRes], [XResQueryClientIds], [$XLIBS],
[wm_save_CFLAGS="$CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([dnl
@%:@include <X11/extensions/XRes.h>
], [dnl
XResQueryClientIds(NULL, 0, NULL, NULL, NULL);])]
[],
[AC_MSG_ERROR([found $CACHEVAR but cannot compile using XRes header])])
CFLAGS="$wm_save_CFLAGS"],
[supported_xext], [XLIBS], [enable_res], [-])dnl
]) dnl AC_DEFUN
# WM_XEXT_CHECK_XSHAPE
# --------------------
#
+48
View File
@@ -912,6 +912,54 @@ void wUnmaximizeWindow(WWindow *wwin)
WMPostNotificationName(WMNChangedState, wwin, "maximize");
}
#ifdef USE_XINERAMA
void wFullscreenMonitorsWindow(WWindow *wwin, unsigned long top, unsigned long bottom,
unsigned long left, unsigned long right)
{
int i;
long monitor;
WMRect rect1, rect2;
if ((int)top < wwin->screen_ptr->xine_info.count &&
(int)bottom < wwin->screen_ptr->xine_info.count &&
(int)left < wwin->screen_ptr->xine_info.count &&
(int)right < wwin->screen_ptr->xine_info.count) {
wwin->flags.fullscreen_monitors[0] = top;
wwin->flags.fullscreen_monitors[1] = bottom;
wwin->flags.fullscreen_monitors[2] = left;
wwin->flags.fullscreen_monitors[3] = right;
} else {
wwin->flags.fullscreen_monitors[0] = -1;
return;
}
wwin->flags.fullscreen = True;
wWindowConfigureBorders(wwin);
ChangeStackingLevel(wwin->frame->core, WMFullscreenLevel);
wwin->bfs_geometry.x = wwin->frame_x;
wwin->bfs_geometry.y = wwin->frame_y;
wwin->bfs_geometry.width = wwin->frame->core->width;
wwin->bfs_geometry.height = wwin->frame->core->height;
i = 0;
monitor = wwin->flags.fullscreen_monitors[i];
rect1 = wwin->screen_ptr->xine_info.screens[monitor];
for (i = 1; i <= 3; i++) {
monitor = wwin->flags.fullscreen_monitors[i];
rect2 = wwin->screen_ptr->xine_info.screens[monitor];
wGetRectUnion(&rect1, &rect2, &rect1);
}
wWindowConfigure(wwin, rect1.pos.x, rect1.pos.y, rect1.size.width, rect1.size.height);
wwin->screen_ptr->bfs_focused_window = wwin->screen_ptr->focused_window;
wSetFocusTo(wwin->screen_ptr, wwin);
WMPostNotificationName(WMNChangedState, wwin, "fullscreen");
}
#endif
void wFullscreenWindow(WWindow *wwin)
{
int head;
+3
View File
@@ -75,6 +75,9 @@ void wArrangeIcons(WScreen *scr, Bool arrangeAll);
void wMakeWindowVisible(WWindow *wwin);
void wFullscreenMonitorsWindow(WWindow *wwin, unsigned long top, unsigned long bottom,
unsigned long left, unsigned long right);
void wFullscreenWindow(WWindow *wwin);
void wUnfullscreenWindow(WWindow *wwin);
+1
View File
@@ -244,6 +244,7 @@ void wClientConfigure(WWindow * wwin, XConfigureRequestEvent * xcre)
if (nheight != wwin->old_geometry.height)
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS);
wWindowConstrainSize(wwin, (unsigned int *)&nwidth, (unsigned int *)&nheight);
wWindowConfigure(wwin, nx, ny, nwidth, nheight);
wwin->old_geometry.x = nx;
wwin->old_geometry.y = ny;
+3 -1
View File
@@ -154,7 +154,7 @@ static WDECallbackUpdate setModifierKeyLabels;
static WDECallbackConvert getCursor;
static WDECallbackUpdate setCursor;
static WDECallbackUpdate updateDock ;
static WDECallbackUpdate updateDock;
/*
* Tables to convert strings to enumeration values.
@@ -788,6 +788,8 @@ WDefaultEntry optionList[] = {
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"RunKey", "None", (void *)WKBD_RUN,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"ExitKey", "None", (void *)WKBD_EXIT,
NULL, getKeybind, setKeyGrab, NULL, NULL},
#ifdef KEEP_XKB_LOCK_STATUS
{"ToggleKbdModeKey", "None", (void *)WKBD_TOGGLE,
+103 -14
View File
@@ -36,6 +36,8 @@
#include <dirent.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <sys/utsname.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
@@ -1101,15 +1103,17 @@ Bool wIconChooserDialog(WScreen *scr, char **file, const char *instance, const c
} else {
defaultPath = FindImage(wPreferences.icon_path, *file);
wantedPath = WMGetTextFieldText(panel->fileField);
if (defaultPath) {
/* if the file is not the default, use full path */
if (strcmp(wantedPath, defaultPath) != 0) {
*file = wantedPath;
*file = wstrdup(wantedPath);
} else {
*file = wstrdup(*file);
wfree(wantedPath);
}
wfree(defaultPath);
}
wfree(wantedPath);
}
} else {
*file = NULL;
}
@@ -1153,7 +1157,7 @@ typedef struct {
#define COPYRIGHT_TEXT \
"Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
"Copyright \xc2\xa9 1998-2006 Dan Pascu\n"\
"Copyright \xc2\xa9 2013-2020 Window Maker Developers Team"
"Copyright \xc2\xa9 2013-%hu Window Maker Developers Team"
static InfoPanel *infoPanel = NULL;
@@ -1171,6 +1175,57 @@ static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
infoPanel = NULL;
}
char *getPrettyOSName(void)
{
char line[200];
char *token;
char *posn = NULL;
const char s[2] = "=";
FILE *fp;
fp = fopen("/etc/os-release", "r");
if (!fp) {
fp = fopen("/usr/lib/os-release", "r");
if (!fp) {
wwarning(_("no os-release file on the system"));
return NULL;
}
}
while (fgets(line, sizeof(line), fp) != NULL) {
if (strncmp(line, "PRETTY_NAME", strlen("PRETTY_NAME")) == 0) {
line[strcspn(line, "\r\n")] = 0;
token = strtok(line, s);
if (token) {
//get straight to the second part of the line
token = strtok(NULL, s);
if (token) {
//removing potential quotes
char *dst = token;
char *src = token;
char c;
while ((c = *src++) != '\0') {
if (c == '\\') {
*dst++ = c;
if ((c = *src++) == '\0')
break;
*dst++ = c;
} else if (c != '"' && c != '\'')
*dst++ = c;
}
*dst = '\0';
posn = wmalloc(strlen(token) + 1);
strcpy(posn, token);
}
}
break;
}
}
fclose(fp);
return posn;
}
void wShowInfoPanel(WScreen *scr)
{
InfoPanel *panel;
@@ -1194,6 +1249,17 @@ void wShowInfoPanel(WScreen *scr)
};
int wmScaleWidth, wmScaleHeight;
int pwidth, pheight;
int current_year = 2020;
time_t s;
struct tm *current_time;
struct utsname uts;
s = time(NULL);
if (s) {
current_time = localtime(&s);
if (current_time->tm_year > (current_year - 1900))
current_year = current_time->tm_year + 1900;
}
if (infoPanel) {
if (infoPanel->scr == scr) {
@@ -1209,8 +1275,12 @@ void wShowInfoPanel(WScreen *scr)
panel->win = WMCreateWindow(scr->wmscreen, "info");
WMGetScaleBaseFromSystemFont(scr->wmscreen, &wmScaleWidth, &wmScaleHeight);
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO2) && defined(DEBUG)
pwidth = WMScaleX(412);
#else
pwidth = WMScaleX(382);
pheight = WMScaleY(250);
#endif
pheight = WMScaleY(270);
WMResizeWidget(panel->win, pwidth, pheight);
logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
@@ -1274,9 +1344,11 @@ void wShowInfoPanel(WScreen *scr)
panel->copyrL = WMCreateLabel(panel->win);
WMResizeWidget(panel->copyrL, WMScaleX(360), WMScaleY(60));
WMMoveWidget(panel->copyrL, WMScaleX(15), WMScaleY(190));
WMMoveWidget(panel->copyrL, WMScaleX(15), WMScaleY(210));
WMSetLabelTextAlignment(panel->copyrL, WALeft);
WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
snprintf(buffer, sizeof(buffer), COPYRIGHT_TEXT, current_year);
WMSetLabelText(panel->copyrL, buffer);
font = WMSystemFontOfSize(scr->wmscreen, WMScaleY(11));
if (font) {
WMSetLabelFont(panel->copyrL, font);
@@ -1285,9 +1357,19 @@ void wShowInfoPanel(WScreen *scr)
}
strbuf = NULL;
if (uname(&uts) != -1) {
char *posn = getPrettyOSName();
if (posn) {
snprintf(buffer, sizeof(buffer), _("Running on: %s (%s)\n"), posn, uts.machine);
free(posn);
}
else
snprintf(buffer, sizeof(buffer), _("Running on: %s (%s)\n"), uts.sysname, uts.machine);
strbuf = wstrappend(strbuf, buffer);
}
snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
(unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
strbuf = wstrappend(strbuf, buffer);
switch (scr->w_depth) {
@@ -1307,14 +1389,14 @@ void wShowInfoPanel(WScreen *scr)
break;
}
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO2)
{
struct mallinfo ma = mallinfo();
struct mallinfo2 ma = mallinfo2();
snprintf(buffer, sizeof(buffer),
#ifdef DEBUG
_("Total memory allocated: %i kB (in use: %i kB, %d free chunks).\n"),
_("Total memory allocated: %lu kB (in use: %lu kB, %lu free chunks)\n"),
#else
_("Total memory allocated: %i kB (in use: %i kB).\n"),
_("Total memory allocated: %lu kB (in use: %lu kB)\n"),
#endif
(ma.arena + ma.hblkhd) / 1024,
(ma.uordblks + ma.hblkhd) / 1024
@@ -1353,6 +1435,10 @@ void wShowInfoPanel(WScreen *scr)
strbuf = wstrappend(strbuf, ", XDnD");
#endif
#ifdef USE_XRES
strbuf = wstrappend(strbuf, ", XRes");
#endif
#ifdef USE_MAGICK
strbuf = wstrappend(strbuf, ", ImageMagick");
#endif
@@ -1365,7 +1451,7 @@ void wShowInfoPanel(WScreen *scr)
strbuf = wstrappend(strbuf, _("Xinerama: "));
{
char tmp[128];
snprintf(tmp, sizeof(tmp) - 1, _("%d head(s) found."), scr->xine_info.count);
snprintf(tmp, sizeof(tmp) - 1, _("%d head(s) found"), scr->xine_info.count);
strbuf = wstrappend(strbuf, tmp);
}
#endif
@@ -1377,11 +1463,14 @@ void wShowInfoPanel(WScreen *scr)
strbuf = wstrappend(strbuf, _("supported"));
else
strbuf = wstrappend(strbuf, _("unsupported"));
strbuf = wstrappend(strbuf, ".");
#endif
panel->infoL = WMCreateLabel(panel->win);
WMResizeWidget(panel->infoL, WMScaleX(350), WMScaleY(80));
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO2) && defined(DEBUG)
WMResizeWidget(panel->infoL, WMScaleX(380), WMScaleY(100));
#else
WMResizeWidget(panel->infoL, WMScaleX(350), WMScaleY(100));
#endif
WMMoveWidget(panel->infoL, WMScaleX(15), WMScaleY(115));
WMSetLabelText(panel->infoL, strbuf);
font = WMSystemFontOfSize(scr->wmscreen, WMScaleY(11));
+7 -14
View File
@@ -1852,21 +1852,14 @@ static void handleKeyPress(XEvent * event)
case WKBD_RUN:
{
char *cmdline;
cmdline = ExpandOptions(scr, _("exec %A(Run,Type command to run:)"));
if (cmdline) {
XGrabPointer(dpy, scr->root_win, True, 0,
GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_WAIT], CurrentTime);
XSync(dpy, False);
ExecuteShellCommand(scr, cmdline);
wfree(cmdline);
XUngrabPointer(dpy, CurrentTime);
XSync(dpy, False);
ExecuteInputCommand(scr, _("exec %A(Run, Type command:)"));
break;
}
case WKBD_EXIT:
{
/* quick mode is not allowed to prevent inadvertently call */
ExecuteExitCommand(scr, 0);
break;
}
+1 -1
View File
@@ -422,7 +422,7 @@ static char *get_icon_cache_path(void)
{
const char *prefix;
char *path;
int len, ret;
int ret;
prefix = wuserdatapath();
path = wstrconcat(prefix, CACHE_ICON_PATH "/");
+3
View File
@@ -145,6 +145,9 @@ enum {
/* open "run" dialog */
WKBD_RUN,
/* open "exit" dialog */
WKBD_EXIT,
#ifdef KEEP_XKB_LOCK_STATUS
WKBD_TOGGLE,
#endif
+15 -5
View File
@@ -56,6 +56,7 @@
#include "dialog.h"
#include "main.h"
#include "monitor.h"
#include "misc.h"
#include <WINGs/WUtil.h>
@@ -354,11 +355,19 @@ Bool RelaunchWindow(WWindow *wwin)
char **argv;
int argc;
char *command = NULL;
if (! XGetCommand(dpy, wwin->client_win, &argv, &argc) || argc == 0 || argv == NULL) {
command = GetCommandForWindow(wwin->client_win);
if (!command) {
#ifdef USE_XRES
werror("cannot relaunch the application because no associated process found");
#else
werror("cannot relaunch the application because no WM_COMMAND property is set");
#endif
return False;
}
} else
wtokensplit(command, &argv, &argc);
pid_t pid = fork();
@@ -384,18 +393,19 @@ Bool RelaunchWindow(WWindow *wwin)
} else if (pid < 0) {
werror("cannot fork a new process");
XFreeStringList(argv);
wfree(argv);
wfree(command);
return False;
} else {
_tuple *data = wmalloc(sizeof(_tuple));
data->scr = wwin->screen_ptr;
data->command = wtokenjoin(argv, argc);
data->command = command;
/* not actually a shell command */
wAddDeathHandler(pid, shellCommandHandler, data);
XFreeStringList(argv);
wfree(argv);
}
return True;
+1 -1
View File
@@ -2440,7 +2440,7 @@ static int restoreMenu(WScreen *scr, WMPropList *menu)
static int restoreMenuRecurs(WScreen *scr, WMPropList *menus, WMenu *menu, const char *path)
{
WMPropList *key, *entry;
char buffer[512];
char buffer[1024];
int i, x, y, res;
Bool lowered;
+62 -1
View File
@@ -38,6 +38,7 @@
#include <X11/XKBlib.h>
#include <WINGs/WUtil.h>
#include <WINGs/WINGsP.h>
#include <wraster.h>
#include "window.h"
@@ -53,6 +54,7 @@
#include "xmodifier.h"
#include "main.h"
#include "event.h"
#include "shutdown.h"
#define ICON_SIZE wPreferences.icon_size
@@ -679,6 +681,64 @@ char *ExpandOptions(WScreen *scr, const char *cmdline)
return NULL;
}
void ExecuteExitCommand(WScreen *scr, long quickmode)
{
static int inside = 0;
int result;
/* prevent reentrant calls */
if (inside)
return;
inside = 1;
#define R_CANCEL 0
#define R_EXIT 1
result = R_CANCEL;
if (quickmode == M_QUICK) {
result = R_EXIT;
} else {
int r, oldSaveSessionFlag;
oldSaveSessionFlag = wPreferences.save_session_on_exit;
r = wExitDialog(scr, _("Exit"),
_("Are you sure you want to quit Window Maker?"), _("Exit"), _("Cancel"), NULL);
if (r == WAPRDefault) {
result = R_EXIT;
} else if (r == WAPRAlternate) {
/* Don't modify the "save session on exit" flag if the
* user canceled the operation. */
wPreferences.save_session_on_exit = oldSaveSessionFlag;
}
}
if (result == R_EXIT)
Shutdown(WSExitMode);
#undef R_EXIT
#undef R_CANCEL
inside = 0;
}
void ExecuteInputCommand(WScreen *scr, const char *cmdline)
{
char *cmd;
cmd = ExpandOptions(scr, cmdline);
if (cmd) {
XGrabPointer(dpy, scr->root_win, True, 0,
GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_WAIT], CurrentTime);
XSync(dpy, False);
ExecuteShellCommand(scr, cmd);
wfree(cmd);
XUngrabPointer(dpy, CurrentTime);
XSync(dpy, False);
}
}
void ParseWindowName(WMPropList *value, char **winstance, char **wclass, const char *where)
{
char *name;
@@ -739,6 +799,7 @@ char *GetShortcutString(const char *shortcut)
*k = 0;
mod = wXModifierFromKey(text);
if (mod < 0) {
wfree(buffer);
return wstrdup("bug");
}
lbl = wXModifierToShortcutLabel(mod);
@@ -781,7 +842,7 @@ char *GetShortcutKey(WShortKey key)
}
}
key_name = XKeysymToString(XkbKeycodeToKeysym(dpy, key.keycode, 0, 0));
key_name = XKeysymToString(W_KeycodeToKeysym(dpy, key.keycode, 0));
if (!key_name)
return NULL;
+4
View File
@@ -25,6 +25,8 @@
#include "keybind.h"
#include "appicon.h"
#define M_QUICK 1
Bool wFetchName(Display *dpy, Window win, char **winname);
Bool wGetIconName(Display *dpy, Window win, char **iconname);
Bool UpdateDomainFile(WDDomain * domain);
@@ -45,6 +47,8 @@ void SendHelperMessage(WScreen *scr, char type, int workspace, const char *msg);
char *ShrinkString(WMFont *font, const char *string, int width);
char *FindImage(const char *paths, const char *file);
char *ExpandOptions(WScreen * scr, const char *cmdline);
void ExecuteInputCommand(WScreen *scr, const char *cmdline);
void ExecuteExitCommand(WScreen *scr, long quickmode);
char *GetShortcutString(const char *text);
char *GetShortcutKey(WShortKey key);
char *EscapeWM_CLASS(const char *name, const char *class);
+2 -53
View File
@@ -142,66 +142,17 @@ static Shortcut *shortcutList = NULL;
*
*/
#define M_QUICK 1
/* menu commands */
static void execCommand(WMenu * menu, WMenuEntry * entry)
{
char *cmdline;
cmdline = ExpandOptions(menu->frame->screen_ptr, (char *)entry->clientdata);
XGrabPointer(dpy, menu->frame->screen_ptr->root_win, True, 0,
GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_WAIT], CurrentTime);
XSync(dpy, 0);
if (cmdline) {
ExecuteShellCommand(menu->frame->screen_ptr, cmdline);
wfree(cmdline);
}
XUngrabPointer(dpy, CurrentTime);
XSync(dpy, 0);
ExecuteInputCommand(menu->frame->screen_ptr, (char *)entry->clientdata);
}
static void exitCommand(WMenu * menu, WMenuEntry * entry)
{
static int inside = 0;
int result;
ExecuteExitCommand(menu->frame->screen_ptr, (long)entry->clientdata);
/* prevent reentrant calls */
if (inside)
return;
inside = 1;
#define R_CANCEL 0
#define R_EXIT 1
result = R_CANCEL;
if ((long)entry->clientdata == M_QUICK) {
result = R_EXIT;
} else {
int r, oldSaveSessionFlag;
oldSaveSessionFlag = wPreferences.save_session_on_exit;
r = wExitDialog(menu->frame->screen_ptr, _("Exit"),
_("Exit window manager?"), _("Exit"), _("Cancel"), NULL);
if (r == WAPRDefault) {
result = R_EXIT;
} else if (r == WAPRAlternate) {
/* Don't modify the "save session on exit" flag if the
* user canceled the operation. */
wPreferences.save_session_on_exit = oldSaveSessionFlag;
}
}
if (result == R_EXIT)
Shutdown(WSExitMode);
#undef R_EXIT
#undef R_CANCEL
inside = 0;
}
static void shutdownCommand(WMenu * menu, WMenuEntry * entry)
@@ -1087,8 +1038,6 @@ static WMenu *readMenu(WScreen *scr, const char *flat_file, FILE *file)
freeline(title, command, params, shortcut);
break;
}
freeline(title, command, params, shortcut);
}
WMenuParserDelete(parser);
+1 -1
View File
@@ -617,7 +617,7 @@ WScreen *wScreenInit(int screen_number)
{
WScreen *scr;
XIconSize icon_size[1];
RContextAttributes rattr;
RContextAttributes rattr = {};
long event_mask;
XErrorHandler oldHandler;
int i;
+35 -2
View File
@@ -93,6 +93,7 @@ static WMPropList *sHost;
static WMPropList *sWorkspace;
static WMPropList *sShaded;
static WMPropList *sMiniaturized;
static WMPropList *sMaximized;
static WMPropList *sHidden;
static WMPropList *sGeometry;
static WMPropList *sShortcutMask;
@@ -112,6 +113,7 @@ static void make_keys(void)
sWorkspace = WMCreatePLString("Workspace");
sShaded = WMCreatePLString("Shaded");
sMiniaturized = WMCreatePLString("Miniaturized");
sMaximized = WMCreatePLString("Maximized");
sHidden = WMCreatePLString("Hidden");
sGeometry = WMCreatePLString("Geometry");
sDock = WMCreatePLString("Dock");
@@ -166,6 +168,22 @@ static unsigned getInt(WMPropList * value)
return n;
}
static unsigned getHex(WMPropList * value)
{
char *val;
unsigned n;
if (!WMIsPLString(value))
return 0;
val = WMGetFromPLString(value);
if (!val)
return 0;
if (sscanf(val, "0x%04X", &n) != 1)
return 0;
return n;
}
static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
{
WScreen *scr = wwin->screen_ptr;
@@ -174,7 +192,7 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
unsigned mask;
char *class, *instance, *command = NULL, buffer[512];
WMPropList *win_state, *cmd, *name, *workspace;
WMPropList *shaded, *miniaturized, *hidden, *geometry;
WMPropList *shaded, *miniaturized, *maximized, *hidden, *geometry;
WMPropList *dock, *shortcut;
if (wwin->orig_main_window != None && wwin->orig_main_window != wwin->client_win)
@@ -183,8 +201,13 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
win = wwin->client_win;
command = GetCommandForWindow(win);
if (!command)
if (!command) {
if (wapp->app_icon && wapp->app_icon->command) {
command = wmalloc(strlen(wapp->app_icon->command) + 1);
strcpy(command, wapp->app_icon->command);
} else
return NULL;
}
if (PropGetWMClass(win, &class, &instance)) {
if (class && instance)
@@ -202,6 +225,8 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
shaded = wwin->flags.shaded ? sYes : sNo;
miniaturized = wwin->flags.miniaturized ? sYes : sNo;
snprintf(buffer, sizeof(buffer), "0x%04X", wwin->flags.maximized);
maximized = WMCreatePLString(buffer);
hidden = wwin->flags.hidden ? sYes : sNo;
snprintf(buffer, sizeof(buffer), "%ix%i+%i+%i",
wwin->client.width, wwin->client.height, wwin->frame_x, wwin->frame_y);
@@ -221,12 +246,14 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
sWorkspace, workspace,
sShaded, shaded,
sMiniaturized, miniaturized,
sMaximized, maximized,
sHidden, hidden,
sShortcutMask, shortcut, sGeometry, geometry, NULL);
WMReleasePropList(name);
WMReleasePropList(cmd);
WMReleasePropList(workspace);
WMReleasePropList(maximized);
WMReleasePropList(geometry);
WMReleasePropList(shortcut);
if (wapp && wapp->app_icon && wapp->app_icon->dock) {
@@ -344,6 +371,7 @@ static pid_t execCommand(WScreen *scr, char *command)
wtokensplit(command, &argv, &argc);
if (!argc) {
wfree(argv);
return 0;
}
@@ -403,6 +431,11 @@ static WSavedState *getWindowState(WScreen * scr, WMPropList * win_state)
if (value != NULL)
state->miniaturized = getBool(value);
value = WMGetFromPLDictionary(win_state, sMaximized);
if (value != NULL) {
state->maximized = getHex(value);
}
value = WMGetFromPLDictionary(win_state, sHidden);
if (value != NULL)
state->hidden = getBool(value);
+8 -5
View File
@@ -61,6 +61,7 @@ struct SwitchPanel {
WMFont *font;
WMColor *white;
WMColor *gray;
};
/* these values will be updated whenever the switch panel
@@ -154,11 +155,9 @@ static void changeImage(WSwitchPanel *panel, int idecks, int selected, Bool dim,
border_space + pos.y, back->width, back->height, 0, 0);
} else {
RColor color;
WMScreen *wscr = WMWidgetScreen(icon);
color.red = 255;
color.red = WMRedComponentOfColor(WMGrayColor(wscr)) >> 8;
color.green = WMGreenComponentOfColor(WMGrayColor(wscr)) >> 8;
color.blue = WMBlueComponentOfColor(WMGrayColor(wscr)) >> 8;
color.red = WMRedComponentOfColor(panel->gray) >> 8;
color.green = WMGreenComponentOfColor(panel->gray) >> 8;
color.blue = WMBlueComponentOfColor(panel->gray) >> 8;
RFillImage(back, &color);
}
@@ -454,6 +453,7 @@ WSwitchPanel *wInitSwitchPanel(WScreen *scr, WWindow *curwin, Bool class_only)
}
panel->white = WMWhiteColor(scr->wmscreen);
panel->gray = WMGrayColor(scr->wmscreen);
panel->font = WMBoldSystemFontOfSize(scr->wmscreen, WMScaleY(12));
panel->icons = WMCreateArray(count);
panel->images = WMCreateArray(count);
@@ -589,6 +589,9 @@ void wSwitchPanelDestroy(WSwitchPanel *panel)
if (panel->white)
WMReleaseColor(panel->white);
if (panel->gray)
WMReleaseColor(panel->gray);
wfree(panel);
}
+1 -1
View File
@@ -162,7 +162,7 @@ WTexSolid *wTextureMakeSolid(WScreen*, XColor*);
WTexGradient *wTextureMakeGradient(WScreen*, int, const RColor*, const RColor*);
WTexMGradient *wTextureMakeMGradient(WScreen*, int, RColor**);
WTexTGradient *wTextureMakeTGradient(WScreen*, int, const RColor*, const RColor*, const char *, int);
WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[2], int, const RColor[2]);
WTexPixmap *wTextureMakePixmap(WScreen *scr, int style, const char *pixmap_file,
XColor *color);
void wTextureDestroy(WScreen*, WTexture*);
+69 -17
View File
@@ -29,6 +29,9 @@
#ifdef KEEP_XKB_LOCK_STATUS
#include <X11/XKBlib.h>
#endif /* KEEP_XKB_LOCK_STATUS */
#ifdef USE_XRES
#include <X11/extensions/XRes.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -475,6 +478,41 @@ Bool wWindowObscuresWindow(WWindow *wwin, WWindow *obscured)
return True;
}
/* Get the corresponding Process Identification Number of the active window */
static pid_t getWindowPid(Window win)
{
pid_t pid = -1;
pid = wNETWMGetPidForWindow(win);
#ifdef USE_XRES
if (pid > 0)
return pid;
else {
XResClientIdSpec spec;
int status;
long i, num_ids = 0;
XResClientIdValue *client_ids = NULL;
spec.client = win;
spec.mask = XRES_CLIENT_ID_PID_MASK;
status = XResQueryClientIds(dpy, 1, &spec, &num_ids, &client_ids);
if (status != Success)
return -1;
for (i = 0; i < num_ids; i++) {
if (client_ids[i].spec.mask == XRES_CLIENT_ID_PID_MASK) {
pid = XResGetClientPid(&client_ids[i]);
break;
}
}
XResClientIdsDestroy(num_ids, client_ids);
}
#endif
return pid;
}
static void fixLeaderProperties(WWindow *wwin)
{
XClassHint *classHint;
@@ -487,7 +525,7 @@ static void fixLeaderProperties(WWindow *wwin)
classHint = XAllocClassHint();
clientHints = XGetWMHints(dpy, wwin->client_win);
pid = wNETWMGetPidForWindow(wwin->client_win);
pid = getWindowPid(wwin->client_win);
if (pid > 0)
haveCommand = GetCommandForPid(pid, &argv, &argc);
else
@@ -688,6 +726,9 @@ WWindow *wManageWindow(WScreen *scr, Window window)
XChangeWindowAttributes(dpy, window, CWEventMask | CWDontPropagate | CWSaveUnder, &attribs);
XSetWindowBorderWidth(dpy, window, 0);
if (wwin->wm_class != NULL && strcmp(wwin->wm_class, "DockApp") != 0)
wwin->flags.fullscreen_monitors[0] = -1;
/* get hints from GNUstep app */
if (wwin->wm_class != NULL && strcmp(wwin->wm_class, "GNUstep") == 0)
wwin->flags.is_gnustep = 1;
@@ -878,6 +919,9 @@ WWindow *wManageWindow(WScreen *scr, Window window)
if (win_state->state->miniaturized > 0 && !WFLAGP(wwin, no_miniaturizable))
wwin->flags.miniaturized = win_state->state->miniaturized;
if (win_state->state->maximized > 0)
wwin->flags.maximized = win_state->state->maximized;
if (!IS_OMNIPRESENT(wwin)) {
int w = wDefaultGetStartWorkspace(scr, wwin->wm_instance,
wwin->wm_class);
@@ -1691,9 +1735,8 @@ void wWindowSingleFocus(WWindow *wwin)
/* bring window back to visible area */
move = wScreenBringInside(scr, &x, &y, wwin->frame->core->width, wwin->frame->core->height);
if (move) {
if (move)
wWindowConfigure(wwin, x, y, wwin->client.width, wwin->client.height);
}
}
void wWindowFocusPrev(WWindow *wwin, Bool inSameWorkspace)
@@ -1857,9 +1900,21 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe
int baseW = 0;
int baseH = 0;
/*
* X11 proto defines width and height as a CARD16
* if window size is guaranteed to fail, failsafe to a reasonable size
*/
if (width > USHRT_MAX && height > USHRT_MAX) {
width = 640;
height = 480;
return;
}
if (wwin->normal_hints) {
if (!wwin->flags.maximized) {
winc = wwin->normal_hints->width_inc;
hinc = wwin->normal_hints->height_inc;
}
minW = wwin->normal_hints->min_width;
minH = wwin->normal_hints->min_height;
maxW = wwin->normal_hints->max_width;
@@ -1875,15 +1930,19 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe
baseH = wwin->normal_hints->base_height;
}
/* trust the mins provided by the client but not the maxs */
if (width < minW)
width = minW;
if (height < minH)
height = minH;
if (width > maxW)
width = maxW;
if (height > maxH)
height = maxH;
/* if only one dimension is over the top, set a default 4/3 ratio */
if (width > maxW && height < maxH) {
width = height * 4 / 3;
} else {
if(height > maxH && width < maxW)
height = width * 3 / 4;
}
/* aspect ratio code borrowed from olwm */
if (minAX > 0) {
@@ -1922,6 +1981,7 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe
}
}
if (!wwin->flags.maximized) {
if (baseW != 0)
width = (((width - baseW) / winc) * winc) + baseW;
else
@@ -1931,6 +1991,7 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe
height = (((height - baseH) / hinc) * hinc) + baseH;
else
height = (((height - minH) / hinc) * hinc) + minH;
}
/* broken stupid apps may cause preposterous values for these.. */
if (width > 0)
@@ -2087,14 +2148,6 @@ void wWindowConfigure(WWindow *wwin, int req_x, int req_y, int req_width, int re
int synth_notify = False;
int resize;
/* if window size is guaranteed to fail - fix it to some reasonable
* defaults */
if (req_height > SHRT_MAX)
req_height = 480;
if (req_width > SHRT_MAX)
req_height = 640;
resize = (req_width != wwin->client.width || req_height != wwin->client.height);
/*
* if the window is being moved but not resized then
@@ -2649,7 +2702,7 @@ void wWindowUpdateGNUstepAttr(WWindow * wwin, GNUstepWMAttributes * attr)
}
WMagicNumber wWindowAddSavedState(const char *instance, const char *class,
const char *command, pid_t pid, WSavedState * state)
const char *command, pid_t pid, WSavedState *state)
{
WWindowState *wstate;
@@ -2884,7 +2937,6 @@ static void titlebarDblClick(WCoreWindow *sender, void *data, XEvent *event)
}
/* maximize window */
if (dir != 0 && IS_RESIZABLE(wwin)) {
int ndir = dir ^ wwin->flags.maximized;
+2 -1
View File
@@ -254,6 +254,7 @@ typedef struct WWindow {
unsigned int maximized:7;
unsigned int old_maximized:7;
unsigned int fullscreen:1;
long fullscreen_monitors[4];
unsigned int omnipresent:1;
unsigned int semi_focused:1;
/* window type flags */
@@ -308,9 +309,9 @@ typedef struct WWindow {
typedef struct WSavedState {
int workspace;
int miniaturized;
int maximized;
int shaded;
int hidden;
int maximized;
int x; /* original geometry of the */
int y; /* window if it's maximized */
unsigned int w;
+57 -5
View File
@@ -77,6 +77,9 @@ static Atom net_wm_visible_name; /* TODO (unnecessary?) */
static Atom net_wm_icon_name;
static Atom net_wm_visible_icon_name; /* TODO (unnecessary?) */
static Atom net_wm_desktop;
#ifdef USE_XINERAMA
static Atom net_wm_fullscreen_monitors;
#endif
static Atom net_wm_window_type;
static Atom net_wm_window_type_desktop;
static Atom net_wm_window_type_dock;
@@ -161,6 +164,9 @@ static atomitem_t atomNames[] = {
{"_NET_WM_ICON_NAME", &net_wm_icon_name},
{"_NET_WM_VISIBLE_ICON_NAME", &net_wm_visible_icon_name},
{"_NET_WM_DESKTOP", &net_wm_desktop},
#ifdef USE_XINERAMA
{"_NET_WM_FULLSCREEN_MONITORS", &net_wm_fullscreen_monitors},
#endif
{"_NET_WM_WINDOW_TYPE", &net_wm_window_type},
{"_NET_WM_WINDOW_TYPE_DESKTOP", &net_wm_window_type_desktop},
{"_NET_WM_WINDOW_TYPE_DOCK", &net_wm_window_type_dock},
@@ -287,6 +293,9 @@ static void setSupportedHints(WScreen *scr)
atom[i++] = net_wm_moveresize;
#endif
atom[i++] = net_wm_desktop;
#ifdef USE_XINERAMA
atom[i++] = net_wm_fullscreen_monitors;
#endif
atom[i++] = net_wm_window_type;
atom[i++] = net_wm_window_type_desktop;
atom[i++] = net_wm_window_type_dock;
@@ -988,7 +997,7 @@ static void updateWorkspaceNames(WScreen *scr)
len = 0;
for (i = 0; i < scr->workspace_count; i++) {
curr_size = strlen(scr->workspaces[i]->name);
strcpy(pos, scr->workspaces[i]->name);
strncpy(pos, scr->workspaces[i]->name, sizeof(pos) - 1);
pos += (curr_size + 1);
len += (curr_size + 1);
}
@@ -1027,6 +1036,9 @@ static void updateStateHint(WWindow *wwin, Bool changedWorkspace, Bool del)
{ /* changeable */
if (del) {
XDeleteProperty(dpy, wwin->client_win, net_wm_state);
#ifdef USE_XINERAMA
XDeleteProperty(dpy, wwin->client_win, net_wm_fullscreen_monitors);
#endif
} else {
Atom state[15]; /* nr of defined state atoms */
int i = 0;
@@ -1067,6 +1079,20 @@ static void updateStateHint(WWindow *wwin, Bool changedWorkspace, Bool del)
XChangeProperty(dpy, wwin->client_win, net_wm_state, XA_ATOM, 32,
PropModeReplace, (unsigned char *)state, i);
#ifdef USE_XINERAMA
if (wwin->flags.fullscreen && (wwin->flags.fullscreen_monitors[0] != -1)) {
unsigned long data[4];
data[0] = wwin->flags.fullscreen_monitors[0];
data[1] = wwin->flags.fullscreen_monitors[1];
data[2] = wwin->flags.fullscreen_monitors[2];
data[3] = wwin->flags.fullscreen_monitors[3];
XChangeProperty(dpy, wwin->client_win, net_wm_fullscreen_monitors, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)data, 4);
}
#endif
}
}
@@ -1260,8 +1286,10 @@ static void doStateAtom(WWindow *wwin, Atom state, int set, Bool init)
} else {
if (set)
wFullscreenWindow(wwin);
else
else {
wUnfullscreenWindow(wwin);
wwin->flags.fullscreen_monitors[0] = -1;
}
}
} else if (state == net_wm_state_above) {
if (set == _NET_WM_STATE_TOGGLE)
@@ -1455,7 +1483,8 @@ void wNETWMPositionSplash(WWindow *wwin, int *x, int *y, int width, int height)
static void updateWindowType(WWindow *wwin)
{
Atom type_ret;
int fmt_ret, layer;
int fmt_ret;
int layer = INT_MIN; //illegal level
unsigned long nitems_ret, bytes_after_ret;
long *data = NULL;
@@ -1473,6 +1502,7 @@ static void updateWindowType(WWindow *wwin)
}
if (wwin->frame != NULL) {
if (layer != INT_MIN)
ChangeStackingLevel(wwin->frame->core, layer);
wwin->frame->flags.need_texture_change = 1;
wWindowConfigureBorders(wwin);
@@ -1706,7 +1736,7 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent *event)
if (wwin->frame->workspace == wwin->screen_ptr->current_workspace /* No workspace change */
|| event->data.l[0] == 2 /* Requested by pager */
|| WFLAGP(wwin, focus_across_wksp) /* Explicitly allowed */) {
wNETWMShowingDesktop(scr, False);
wNETWMShowingDesktop(wwin->screen_ptr, False);
wMakeWindowVisible(wwin);
}
return True;
@@ -1759,8 +1789,30 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent *event)
wWindowChangeWorkspace(wwin, desktop);
}
return True;
}
#ifdef USE_XINERAMA
} else if (event->message_type == net_wm_fullscreen_monitors) {
unsigned long top, bottom, left, right, src_indication;
top = event->data.l[0];
bottom = event->data.l[1];
left = event->data.l[2];
right = event->data.l[3];
src_indication = event->data.l[4];
if (src_indication > 1)
wwarning("_NET_WM_FULLSCREEN_MONITORS source indication %ld not supported", src_indication);
wFullscreenMonitorsWindow(wwin, top, bottom, left, right);
return True;
}
#else
}
#endif
#ifdef DEBUG_WMSPEC
wmessage("processClientMessage unsupported type %s", XGetAtomName(dpy, event->message_type));
#endif
return False;
}
+6 -6
View File
@@ -337,9 +337,9 @@ static WMPixmap *get_mini_workspace(WWorkspaceMap *wsmap, int index)
static void create_mini_workspace(WScreen *scr, WWorkspaceMap *wsmap, W_WorkspaceMap *wsmap_array)
{
int workspace_index;
unsigned short workspace_index;
int mini_workspace_cnt;
char name[10];
char name[6];
WMButton *mini_workspace_btn;
WMPixmap *icon;
@@ -363,7 +363,7 @@ static void create_mini_workspace(WScreen *scr, WWorkspaceMap *wsmap, W_Workspac
WMReleasePixmap(icon);
}
snprintf(name, sizeof(name), "%d", workspace_index);
snprintf(name, sizeof(name), "%hu", workspace_index);
WMSetButtonText(mini_workspace_btn, name);
WMSetButtonAction(mini_workspace_btn, selected_workspace_callback, wsmap);
}
@@ -423,9 +423,9 @@ static WWorkspaceMap *create_workspace_map(WScreen *scr, W_WorkspaceMap *wsmap_a
static void update_mini_workspace(WWorkspaceMap *wsmap, W_WorkspaceMap *wsmap_array, int bulk_of_ten)
{
int local_index, general_index;
unsigned short local_index, general_index;
int mini_workspace_cnt;
char name[10];
char name[6];
WMPixmap *icon;
if (bulk_of_ten == wsmap_bulk_index)
@@ -448,7 +448,7 @@ static void update_mini_workspace(WWorkspaceMap *wsmap, W_WorkspaceMap *wsmap_ar
if (general_index < wsmap->scr->workspace_count) {
/* updating label */
WMSetLabelText(wsmap_array[local_index].workspace_label, wsmap->scr->workspaces[general_index]->name);
snprintf(name, sizeof(name), "%d", general_index);
snprintf(name, sizeof(name), "%hu", general_index);
WMSetButtonText(wsmap_array[local_index].workspace_img_button, name);
/* updating label background*/
+30
View File
@@ -410,3 +410,33 @@ WMPoint wGetPointToCenterRectInHead(WScreen * scr, int head, int width, int heig
return p;
}
/* Find the bounding rect of the union of two rectangles */
void wGetRectUnion(const WMRect *rect1, const WMRect *rect2, WMRect *dest)
{
int dest_x, dest_y;
int dest_w, dest_h;
dest_x = rect1->pos.x;
dest_y = rect1->pos.y;
dest_w = rect1->size.width;
dest_h = rect1->size.height;
if (rect2->pos.x < dest_x) {
dest_w += dest_x - rect2->pos.x;
dest_x = rect2->pos.x;
}
if (rect2->pos.y < dest_y) {
dest_h += dest_y - rect2->pos.y;
dest_y = rect2->pos.y;
}
if (rect2->pos.x + rect2->size.width > dest_x + dest_w)
dest_w = rect2->pos.x + rect2->size.width - dest_x;
if (rect2->pos.y + rect2->size.height > dest_y + dest_h)
dest_h = rect2->pos.y + rect2->size.height - dest_y;
dest->pos.x = dest_x;
dest->pos.y = dest_y;
dest->size.width = dest_w;
dest->size.height = dest_h;
}
+2
View File
@@ -60,6 +60,8 @@ WArea wGetUsableAreaForHead(WScreen *scr, int head, WArea *totalAreaPtr, Bool no
WMPoint wGetPointToCenterRectInHead(WScreen *scr, int head, int width, int height);
void wGetRectUnion(const WMRect *rect1, const WMRect *rect2, WMRect *dest);
Bool wWindowTouchesHead(WWindow *wwin, int head);
Bool wAppIconTouchesHead(WAppIcon *aicon, int head);
+2 -1
View File
@@ -36,6 +36,7 @@ Perpetrator: Sudish Joseph <sj@eng.mindspring.net>, Sept. 1997. */
#include <X11/XKBlib.h>
#include <WINGs/WUtil.h>
#include <WINGs/WINGsP.h>
#include "WindowMaker.h"
#include "xmodifier.h"
@@ -174,7 +175,7 @@ static void x_reset_modifier_mapping(Display * display)
}
code = x_modifier_keymap->modifiermap[modifier_index * mkpm + modifier_key];
sym = (code ? XkbKeycodeToKeysym(display, code, 0, column) : NoSymbol);
sym = W_KeycodeToKeysym(display, code, column);
if (sym == last_sym)
continue;
+5 -2
View File
@@ -70,10 +70,13 @@ wmmenugen_SOURCES = wmmenugen.c wmmenugen.h wmmenugen_misc.c \
wmmenugen_parse_wmconfig.c \
wmmenugen_parse_xdg.c
wmiv_CFLAGS = @PANGO_CFLAGS@ @PTHREAD_CFLAGS@
wmiv_LDADD = \
$(top_builddir)/wrlib/libwraster.la \
@XLFLAGS@ @XLIBS@ \
@GFXLIBS@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(LIBEXIF)
$(top_builddir)/WINGs/libWINGs.la \
@XLFLAGS@ @XLIBS@ @GFXLIBS@ \
@PANGO_LIBS@ @PTHREAD_LIBS@ @LIBEXIF@
wmiv_SOURCES = wmiv.c wmiv.h
+1
View File
@@ -349,6 +349,7 @@ static void hackStyle(WMPropList * style)
t = WMCreatePLArray(WMCreatePLString("solid"), value, NULL);
WMPutInPLDictionary(style, WMCreatePLString("ResizebarBack"), t);
WMReleasePropList(value);
}
}
}
+1
View File
@@ -451,6 +451,7 @@ static void find_and_write(const char *group, char *list[][2], int this_is_termi
WMAddToPLArray(L2Menu, L3Menu);
wfree(t);
}
wfree(argv);
i++;
}
if (L2Menu)
+7 -6
View File
@@ -22,11 +22,10 @@
#define _GNU_SOURCE
#endif
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include "wraster.h"
#include <WINGs/WINGsP.h>
#include <wraster.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -436,6 +435,7 @@ int zoom_in_out(int z)
tmp->height + (int)(tmp->height * zoom_factor));
if (!img) {
img = old_img;
RReleaseImage(tmp);
return EXIT_FAILURE;
}
} else {
@@ -450,6 +450,7 @@ int zoom_in_out(int z)
img = RScaleImage(tmp, new_width, new_height);
if (!img) {
img = old_img;
RReleaseImage(tmp);
return EXIT_FAILURE;
}
}
@@ -679,7 +680,7 @@ link_t *connect_dir(char *dirpath, linked_list_t *li)
int main(int argc, char **argv)
{
int option = -1;
RContextAttributes attr;
RContextAttributes attr = {};
XEvent e;
KeySym keysym;
char *reading_filename = "";
@@ -750,7 +751,7 @@ int main(int argc, char **argv)
dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "Error: can't open display");
fprintf(stderr, "Error: can't open display\n");
linked_list_free(&list);
return EXIT_FAILURE;
}
@@ -932,7 +933,7 @@ int main(int argc, char **argv)
continue;
}
if (e.type == KeyPress) {
keysym = XkbKeycodeToKeysym(dpy, e.xkey.keycode, 0, e.xkey.state & ShiftMask?1:0);
keysym = W_KeycodeToKeysym(dpy, e.xkey.keycode, e.xkey.state & ShiftMask?1:0);
#ifdef HAVE_PTHREAD
if (keysym != XK_Right)
diaporama_flag = False;
+24 -23
View File
@@ -275,45 +275,46 @@ static void assemblePLMenuFunc(WMTreeNode *aNode, void *data)
if (!wm->CmdLine) { /* new submenu */
WMAddToArray(plMenuNodes, WMCreatePLArray(WMCreatePLString(wm->Name), NULL));
} else { /* new menu item */
WMPropList *tmp1, *tmp2;
pl = WMPopFromArray(plMenuNodes);
if (wm->Flags & F_RESTART_OTHER) { /* RESTART, somewm */
char buf[1024];
WMPropList *tmp3;
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%s %s", _("Restart"), wm->Name);
WMAddToPLArray(pl, WMCreatePLArray(
WMCreatePLString(buf),
WMCreatePLString("RESTART"),
WMCreatePLString(wm->CmdLine),
NULL)
);
tmp1 = WMCreatePLString(buf);
tmp2 = WMCreatePLString("RESTART");
tmp3 = WMCreatePLString(wm->CmdLine);
WMAddToPLArray(pl, WMCreatePLArray(tmp1, tmp2, tmp3, NULL));
WMReleasePropList(tmp3);
} else if (wm->Flags & F_RESTART_SELF) {/* RESTART */
WMAddToPLArray(pl, WMCreatePLArray(
WMCreatePLString(_("Restart Window Maker")),
WMCreatePLString("RESTART"),
NULL)
);
tmp1 = WMCreatePLString(_("Restart Window Maker"));
tmp2 = WMCreatePLString("RESTART");
WMAddToPLArray(pl, WMCreatePLArray(tmp1, tmp2, NULL));
} else if (wm->Flags & F_QUIT) { /* EXIT */
WMAddToPLArray(pl, WMCreatePLArray(
WMCreatePLString(_("Exit Window Maker")),
WMCreatePLString("EXIT"),
NULL)
);
tmp1 = WMCreatePLString(_("Exit Window Maker"));
tmp2 = WMCreatePLString("EXIT");
WMAddToPLArray(pl, WMCreatePLArray(tmp1, tmp2, NULL));
} else { /* plain simple command */
char buf[1024];
WMPropList *tmp3;
memset(buf, 0, sizeof(buf));
if (wm->Flags & F_TERMINAL) /* XXX: quoting! */
snprintf(buf, sizeof(buf), "%s -e \"%s\"", terminal, wm->CmdLine);
else
snprintf(buf, sizeof(buf), "%s", wm->CmdLine);
WMAddToPLArray(pl, WMCreatePLArray(
WMCreatePLString(wm->Name),
WMCreatePLString("SHEXEC"),
WMCreatePLString(buf),
NULL)
);
tmp1 = WMCreatePLString(wm->Name);
tmp2 = WMCreatePLString("SHEXEC");
tmp3 = WMCreatePLString(buf);
WMAddToPLArray(pl, WMCreatePLArray(tmp1, tmp2, tmp3, NULL));
WMReleasePropList(tmp3);
}
WMReleasePropList(tmp1);
WMReleasePropList(tmp2);
WMAddToArray(plMenuNodes, pl);
}
+10 -1
View File
@@ -505,7 +505,15 @@ static BackgroundTexture *parseTexture(RContext * rc, char *text)
iheight = image->height;
}
GETSTRORGOTO(val, tmp, 2, error);
/* cannot use GETSTRORGOTO() here
* as we have to free image in case of error */
val = WMGetFromPLArray(texarray, 2);
if (!WMIsPLString(val)) {
wwarning("could not parse texture %s", text);
RReleaseImage(image);
goto error;
}
tmp = WMGetFromPLString(val);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s", tmp, text);
@@ -898,6 +906,7 @@ static noreturn void helperLoop(RContext * rc)
int errcount = 4;
memset(textures, 0, WORKSPACE_COUNT * sizeof(BackgroundTexture *));
memset(buffer, 0, sizeof(buffer));
while (1) {
int workspace = -1;
+2
View File
@@ -1,3 +1,5 @@
- added RSaveTitledImage()
- removed obsoleted RDestroyImage()
- removed Hermes code.
- Put back asm/mmx optimized code.
+2
View File
@@ -55,10 +55,12 @@ endif
if USE_JPEG
libwraster_la_SOURCES += load_jpeg.c
libwraster_la_SOURCES += save_jpeg.c
endif
if USE_PNG
libwraster_la_SOURCES += load_png.c
libwraster_la_SOURCES += save_png.c
endif
if USE_TIFF
+13 -2
View File
@@ -1,8 +1,19 @@
** API and ABI modifications since wmaker 0.92.0
** API and ABI modifications
----------------------------------------------------
Sat 25 Feb 2023
RSaveImage: Improved
Able to save image on disk as PNG or JPEG file
RSaveTitledImage: Added
Image title can be set on the image to be saved
----------------------------------------------------
Since wmaker 0.92.0
RLightImage: ADDED
----------------------------------------------------
Sat Apr 21 09:12:09 EEST 2001 -Dan
+8
View File
@@ -627,6 +627,10 @@ static RXImage *image2StandardPseudoColor(RContext * ctx, RImage * image)
RDestroyXImage(ctx, ximg);
return NULL;
}
memset(err, 0, 3 * (image->width + 2) * sizeof(short));
memset(nerr, 0, 3 * (image->width + 2) * sizeof(short));
for (x = 0, x1 = 0; x < image->width * 3; x1 += channels - 3) {
err[x++] = ptr[x1++];
err[x++] = ptr[x1++];
@@ -778,6 +782,10 @@ static RXImage *image2GrayScale(RContext * ctx, RImage * image)
RDestroyXImage(ctx, ximg);
return NULL;
}
memset(gerr, 0, (image->width + 2) * sizeof(short));
memset(ngerr, 0, (image->width + 2) * sizeof(short));
for (x = 0, y = 0; x < image->width; x++, y += channels) {
gerr[x] = (ptr[y] * 30 + ptr[y + 1] * 59 + ptr[y + 2] * 11) / 100;
}
+8 -2
View File
@@ -29,7 +29,6 @@
#ifndef IMGFORMAT_INTERNAL_H
#define IMGFORMAT_INTERNAL_H
typedef enum {
IM_ERROR = -1,
IM_UNKNOWN = 0,
@@ -82,8 +81,15 @@ void RReleaseMagick(void);
/*
* Function for Saving in a specific format
*/
Bool RSaveXPM(RImage *image, const char *file);
Bool RSaveXPM(RImage *image, const char *filename);
#ifdef USE_PNG
Bool RSavePNG(RImage *image, const char *filename, char *title);
#endif
#ifdef USE_JPEG
Bool RSaveJPEG(RImage *image, const char *filename, char *title);
#endif
/*
* Function to terminate properly
+74 -69
View File
@@ -95,19 +95,13 @@ static noreturn void my_error_exit(j_common_ptr cinfo)
longjmp(myerr->setjmp_buffer, 1);
}
RImage *RLoadJPEG(const char *file_name)
static RImage *do_read_jpeg_file(struct jpeg_decompress_struct *cinfo, const char *file_name)
{
RImage *image = NULL;
struct jpeg_decompress_struct cinfo;
int i;
unsigned char *ptr;
JSAMPROW buffer[1], bptr;
FILE *file;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
file = fopen(file_name, "rb");
if (!file) {
@@ -115,6 +109,78 @@ RImage *RLoadJPEG(const char *file_name)
return NULL;
}
jpeg_create_decompress(cinfo);
jpeg_stdio_src(cinfo, file);
jpeg_read_header(cinfo, TRUE);
if (cinfo->image_width < 1 || cinfo->image_height < 1) {
buffer[0] = NULL; /* Initialize pointer to avoid spurious free in cleanup code */
RErrorCode = RERR_BADIMAGEFILE;
goto abort_and_release_resources;
}
buffer[0] = (JSAMPROW) malloc(cinfo->image_width * cinfo->num_components);
if (!buffer[0]) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
if (cinfo->jpeg_color_space == JCS_GRAYSCALE)
cinfo->out_color_space = JCS_GRAYSCALE;
else
cinfo->out_color_space = JCS_RGB;
cinfo->quantize_colors = FALSE;
cinfo->do_fancy_upsampling = FALSE;
cinfo->do_block_smoothing = FALSE;
jpeg_calc_output_dimensions(cinfo);
image = RCreateImage(cinfo->image_width, cinfo->image_height, False);
if (!image) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
jpeg_start_decompress(cinfo);
ptr = image->data;
if (cinfo->out_color_space == JCS_RGB) {
while (cinfo->output_scanline < cinfo->output_height) {
jpeg_read_scanlines(cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
memcpy(ptr, bptr, cinfo->image_width * 3);
ptr += cinfo->image_width * 3;
}
} else {
while (cinfo->output_scanline < cinfo->output_height) {
jpeg_read_scanlines(cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
for (i = 0; i < cinfo->image_width; i++) {
*ptr++ = *bptr;
*ptr++ = *bptr;
*ptr++ = *bptr++;
}
}
}
jpeg_finish_decompress(cinfo);
abort_and_release_resources:
jpeg_destroy_decompress(cinfo);
fclose(file);
if (buffer[0])
free(buffer[0]);
return image;
}
RImage *RLoadJPEG(const char *file_name)
{
struct jpeg_decompress_struct cinfo;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main
* JPEG parameter struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
@@ -124,68 +190,7 @@ RImage *RLoadJPEG(const char *file_name)
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_destroy_decompress(&cinfo);
fclose(file);
return NULL;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, file);
jpeg_read_header(&cinfo, TRUE);
if (cinfo.image_width < 1 || cinfo.image_height < 1) {
buffer[0] = NULL; /* Initialize pointer to avoid spurious free in cleanup code */
RErrorCode = RERR_BADIMAGEFILE;
goto abort_and_release_resources;
}
buffer[0] = (JSAMPROW) malloc(cinfo.image_width * cinfo.num_components);
if (!buffer[0]) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
cinfo.out_color_space = JCS_GRAYSCALE;
else
cinfo.out_color_space = JCS_RGB;
cinfo.quantize_colors = FALSE;
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_calc_output_dimensions(&cinfo);
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
if (!image) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
jpeg_start_decompress(&cinfo);
ptr = image->data;
if (cinfo.out_color_space == JCS_RGB) {
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
memcpy(ptr, bptr, cinfo.image_width * 3);
ptr += cinfo.image_width * 3;
}
} else {
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
for (i = 0; i < cinfo.image_width; i++) {
*ptr++ = *bptr;
*ptr++ = *bptr;
*ptr++ = *bptr++;
}
}
}
jpeg_finish_decompress(&cinfo);
abort_and_release_resources:
jpeg_destroy_decompress(&cinfo);
fclose(file);
if (buffer[0])
free(buffer[0]);
return image;
return do_read_jpeg_file(&cinfo, file_name);
}
+15 -5
View File
@@ -28,6 +28,7 @@
#include <tiff.h>
#include <tiffio.h>
#include <tiffvers.h>
#include "wraster.h"
#include "imgformat.h"
@@ -38,14 +39,19 @@ RImage *RLoadTIFF(const char *file, int index)
{
RImage *image = NULL;
TIFF *tif;
int i;
int i, ch;
unsigned char *r, *g, *b, *a;
uint16 alpha, amode;
#if TIFFLIB_VERSION < 20210416
uint16 alpha, amode, extrasamples;
uint16 *sampleinfo;
uint32 width, height;
uint32 *data, *ptr;
uint16 extrasamples;
uint16 *sampleinfo;
int ch;
#else
uint16_t alpha, amode, extrasamples;;
uint16_t *sampleinfo;
uint32_t width, height;
uint32_t *data, *ptr;
#endif
tif = TIFFOpen(file, "r");
if (!tif)
@@ -79,7 +85,11 @@ RImage *RLoadTIFF(const char *file, int index)
}
/* read data */
#if TIFFLIB_VERSION < 20210416
ptr = data = (uint32 *) _TIFFmalloc(width * height * sizeof(uint32));
#else
ptr = data = (uint32_t *) _TIFFmalloc(width * height * sizeof(uint32_t));
#endif
if (!data) {
RErrorCode = RERR_NOMEMORY;
+2
View File
@@ -22,6 +22,8 @@ POTFILES = \
$(top_srcdir)/wrlib/rotate.c \
$(top_srcdir)/wrlib/flip.c \
$(top_srcdir)/wrlib/convolve.c \
$(top_srcdir)/wrlib/save_jpeg.c \
$(top_srcdir)/wrlib/save_png.c \
$(top_srcdir)/wrlib/save_xpm.c \
$(top_srcdir)/wrlib/xutil.c \
$(top_srcdir)/wrlib/load_ppm.c \
+21 -6
View File
@@ -3,6 +3,7 @@
* Raster graphics library
*
* Copyright (c) 1998-2003 Alfredo K. Kojima
* Copyright (c) 2013-2023 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,18 +30,32 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>
#include "wraster.h"
#include "imgformat.h"
#include "wr_i18n.h"
Bool RSaveImage(RImage * image, const char *filename, const char *format)
Bool RSaveImage(RImage *image, const char *filename, const char *format)
{
if (strcmp(format, "XPM") != 0) {
return RSaveTitledImage(image, filename, format, NULL);
}
Bool RSaveTitledImage(RImage *image, const char *filename, const char *format, char *title)
{
#ifdef USE_PNG
if (strcasecmp(format, "PNG") == 0)
return RSavePNG(image, filename, title);
#endif
#ifdef USE_JPEG
if (strcasecmp(format, "JPG") == 0)
return RSaveJPEG(image, filename, title);
if (strcasecmp(format, "JPEG") == 0)
return RSaveJPEG(image, filename, title);
#endif
if (strcasecmp(format, "XPM") == 0)
return RSaveXPM(image, filename);
RErrorCode = RERR_BADFORMAT;
return False;
}
return RSaveXPM(image, filename);
}
+104
View File
@@ -0,0 +1,104 @@
/* save_jpeg.c - save JPEG image
*
* Raster graphics library
*
* Copyright (c) 2023 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <jpeglib.h>
#include "wraster.h"
#include "imgformat.h"
#include "wr_i18n.h"
/*
* Save RImage to JPEG image
*/
Bool RSaveJPEG(RImage *img, const char *filename, char *title)
{
FILE *file;
int x, y, img_depth;
char *buffer;
RColor pixel;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer;
file = fopen(filename, "wb");
if (!file) {
RErrorCode = RERR_OPEN;
return False;
}
if (img->format == RRGBAFormat)
img_depth = 4;
else
img_depth = 3;
/* collect separate RGB values to a buffer */
buffer = malloc(sizeof(char) * 3 * img->width * img->height);
for (y = 0; y < img->height; y++) {
for (x = 0; x < img->width; x++) {
RGetPixel(img, x, y, &pixel);
buffer[y*img->width*3+x*3+0] = (char)(pixel.red);
buffer[y*img->width*3+x*3+1] = (char)(pixel.green);
buffer[y*img->width*3+x*3+2] = (char)(pixel.blue);
}
}
/* Setup Exception handling */
cinfo.err = jpeg_std_error(&jerr);
/* Initialize cinfo structure */
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, file);
cinfo.image_width = img->width;
cinfo.image_height = img->height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 85, TRUE);
jpeg_start_compress(&cinfo, TRUE);
/* Set title if any */
if (title)
jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET*)title, strlen(title));
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer = (JSAMPROW) &buffer[cinfo.next_scanline * img_depth * img->width];
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
/* Clean */
free(buffer);
fclose(file);
return True;
}
+127
View File
@@ -0,0 +1,127 @@
/* save_png.c - save PNG image
*
* Raster graphics library
*
* Copyright (c) 2023 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <png.h>
#include "wraster.h"
#include "imgformat.h"
#include "wr_i18n.h"
/*
* Save RImage to PNG image
*/
Bool RSavePNG(RImage *img, const char *filename, char *title)
{
FILE *file;
png_structp png_ptr;
png_infop png_info_ptr;
png_bytep png_row;
RColor pixel;
int x, y;
int width = img->width;
int height = img->height;
file = fopen(filename, "wb");
if (file == NULL) {
RErrorCode = RERR_OPEN;
return False;
}
/* Initialize write structure */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fclose(file);
RErrorCode = RERR_NOMEMORY;
return False;
}
/* Initialize info structure */
png_info_ptr = png_create_info_struct(png_ptr);
if (png_info_ptr == NULL) {
fclose(file);
RErrorCode = RERR_NOMEMORY;
return False;
}
/* Setup Exception handling */
if (setjmp(png_jmpbuf (png_ptr))) {
fclose(file);
RErrorCode = RERR_INTERNAL;
return False;
}
png_init_io(png_ptr, file);
/* Write header (8 bit colour depth) */
png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
/* Set title if any */
if (title) {
png_text title_text;
title_text.compression = PNG_TEXT_COMPRESSION_NONE;
title_text.key = "Title";
title_text.text = title;
png_set_text(png_ptr, png_info_ptr, &title_text, 1);
}
png_write_info(png_ptr, png_info_ptr);
/* Allocate memory for one row (3 bytes per pixel - RGB) */
png_row = (png_bytep) malloc(3 * width * sizeof(png_byte));
/* Write image data */
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
png_byte *ptr;
RGetPixel(img, x, y, &pixel);
ptr = &(png_row[x * 3]);
ptr[0] = pixel.red;
ptr[1] = pixel.green;
ptr[2] = pixel.blue;
}
png_write_row(png_ptr, png_row);
}
/* End write */
png_write_end(png_ptr, NULL);
/* Clean */
fclose(file);
if (png_info_ptr != NULL)
png_free_data(png_ptr, png_info_ptr, PNG_FREE_ALL, -1);
if (png_ptr != NULL)
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
if (png_row != NULL)
free(png_row);
return True;
}
+1 -1
View File
@@ -1,4 +1,4 @@
/* nxpm.c - load "normalized" XPM image
/* save_xpm.c - save "normalized" XPM image
*
* Raster graphics library
*
+4 -1
View File
@@ -41,7 +41,7 @@
/* version of the header for the library */
#define WRASTER_HEADER_VERSION 24
#define WRASTER_HEADER_VERSION 25
#include <X11/Xlib.h>
@@ -391,6 +391,9 @@ RImage *RGetImageFromXPMData(RContext *context, char **xpmData)
Bool RSaveImage(RImage *image, const char *filename, const char *format)
__wrlib_nonnull(1, 2, 3);
Bool RSaveTitledImage(RImage *image, const char *filename, const char *format, char *title)
__wrlib_nonnull(1, 2, 3);
/*
* Area manipulation
*/