Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
b7320893
Commit
b7320893
authored
Jan 25, 2009
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added x11 global hotkeys support (linux).
parent
e939adf8
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
370 additions
and
3 deletions
+370
-3
configure.ac
configure.ac
+3
-0
include/vlc_plugin.h
include/vlc_plugin.h
+1
-1
modules/control/Modules.am
modules/control/Modules.am
+0
-1
modules/control/globalhotkeys/Modules.am
modules/control/globalhotkeys/Modules.am
+2
-0
modules/control/globalhotkeys/win32.c
modules/control/globalhotkeys/win32.c
+1
-1
modules/control/globalhotkeys/x11.c
modules/control/globalhotkeys/x11.c
+363
-0
No files found.
configure.ac
View file @
b7320893
...
...
@@ -3886,6 +3886,9 @@ if test "${enable_x11}" != "no" &&
VLC_ADD_PLUGIN([panoramix])
VLC_ADD_LIBS([panoramix],[${X_LIBS} ${X_PRE_LIBS} -lX11])
VLC_ADD_CPPFLAGS([panoramix],[${X_CFLAGS}])
VLC_ADD_PLUGIN([globalhotkeys])
VLC_ADD_LIBS([globalhotkeys],[${X_LIBS} ${X_PRE_LIBS} -lX11])
VLC_ADD_CPPFLAGS([globalhotkeys],[${X_CFLAGS}])
AC_CHECK_LIB(Xext, XShmAttach, [
VLC_ADD_PLUGIN([x11])
VLC_ADD_LIBS([x11],[${X_LIBS} ${X_PRE_LIBS} -lX11 -lXext])
...
...
include/vlc_plugin.h
View file @
b7320893
...
...
@@ -353,7 +353,7 @@ enum vlc_config_properties
add_int_inner( CONFIG_ITEM_INTEGER, name, text, longtext, advc, \
p_callback, value )
#if
ndef WIN32
#if
!defined(WIN32) && !defined(SYS_LINUX)
#define add_key( name, value, p_callback, text, longtext, advc ) \
add_int_inner( CONFIG_ITEM_KEY, name, text, longtext, advc, p_callback, \
value )
...
...
modules/control/Modules.am
View file @
b7320893
...
...
@@ -5,7 +5,6 @@ SOURCES_telnet = telnet.c
SOURCES_netsync = netsync.c
SOURCES_ntservice = ntservice.c
SOURCES_hotkeys = hotkeys.c
SOURCES_globalhotkeys = globalhotkeys.c
SOURCES_lirc = lirc.c
SOURCES_rc = rc.c
SOURCES_dbus = dbus.c dbus.h
...
...
modules/control/globalhotkeys/Modules.am
View file @
b7320893
if HAVE_WIN32
globalhotkeys_extra = win32.c
else
globalhotkeys_extra = x11.c
endif
SOURCES_globalhotkeys = \
...
...
modules/control/globalhotkeys/win32.c
View file @
b7320893
/*****************************************************************************
*
globalhotkeys.c: Global-Hotkey
handling for vlc
*
win32.c: Global-Hotkey WIN32
handling for vlc
*****************************************************************************
* Copyright (C) 2008-2009 the VideoLAN team
*
...
...
modules/control/globalhotkeys/x11.c
0 → 100644
View file @
b7320893
/*****************************************************************************
* x11.c: Global-Hotkey X11 handling for vlc
*****************************************************************************
* Copyright (C) 2009 the VideoLAN team
*
* Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/XF86keysym.h>
#include <poll.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_interface.h>
#include <vlc_keys.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
);
static
void
Close
(
vlc_object_t
*
p_this
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin
();
set_shortname
(
_
(
"Global Hotkeys"
)
);
set_category
(
CAT_INTERFACE
);
set_subcategory
(
SUBCAT_INTERFACE_HOTKEYS
);
set_description
(
_
(
"Global Hotkeys interface"
)
);
set_capability
(
"interface"
,
0
);
set_callbacks
(
Open
,
Close
);
vlc_module_end
();
typedef
struct
{
KeyCode
i_x11
;
unsigned
i_modifier
;
int
i_action
;
}
hotkey_mapping_t
;
struct
intf_sys_t
{
vlc_thread_t
thread
;
Display
*
p_display
;
int
i_map
;
hotkey_mapping_t
*
p_map
;
};
static
void
Mapping
(
intf_thread_t
*
p_intf
);
static
void
Register
(
intf_thread_t
*
p_intf
);
static
void
Unregister
(
intf_thread_t
*
p_intf
);
static
void
*
Thread
(
void
*
p_data
);
/*****************************************************************************
* Open:
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
intf_thread_t
*
p_intf
=
(
intf_thread_t
*
)
p_this
;
intf_sys_t
*
p_sys
;
Display
*
p_display
=
XOpenDisplay
(
NULL
);
if
(
!
p_display
)
return
VLC_EGENERIC
;
p_intf
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
*
p_sys
)
);
if
(
!
p_sys
)
{
XCloseDisplay
(
p_display
);
return
VLC_ENOMEM
;
}
p_sys
->
p_display
=
p_display
;
Mapping
(
p_intf
);
Register
(
p_intf
);
if
(
vlc_clone
(
&
p_sys
->
thread
,
Thread
,
p_intf
,
VLC_THREAD_PRIORITY_LOW
)
)
{
Unregister
(
p_intf
);
XCloseDisplay
(
p_display
);
free
(
p_sys
->
p_map
);
free
(
p_sys
);
return
VLC_ENOMEM
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
intf_thread_t
*
p_intf
=
(
intf_thread_t
*
)
p_this
;
intf_sys_t
*
p_sys
=
p_intf
->
p_sys
;
vlc_cancel
(
p_sys
->
thread
);
vlc_join
(
p_sys
->
thread
,
NULL
);
Unregister
(
p_intf
);
XCloseDisplay
(
p_sys
->
p_display
);
free
(
p_sys
->
p_map
);
free
(
p_sys
);
}
/*****************************************************************************
* Thread:
*****************************************************************************/
static
unsigned
GetModifier
(
Display
*
p_display
,
KeySym
sym
)
{
static
const
unsigned
pi_mask
[
8
]
=
{
ShiftMask
,
LockMask
,
ControlMask
,
Mod1Mask
,
Mod2Mask
,
Mod3Mask
,
Mod4Mask
,
Mod5Mask
};
const
KeyCode
key
=
XKeysymToKeycode
(
p_display
,
sym
);
if
(
key
==
0
)
return
0
;
XModifierKeymap
*
p_map
=
XGetModifierMapping
(
p_display
);
if
(
!
p_map
)
return
0
;
unsigned
i_mask
=
0
;
for
(
int
i
=
0
;
i
<
8
*
p_map
->
max_keypermod
;
i
++
)
{
if
(
p_map
->
modifiermap
[
i
]
==
key
)
{
i_mask
=
pi_mask
[
i
/
p_map
->
max_keypermod
];
break
;
}
}
XFreeModifiermap
(
p_map
);
return
i_mask
;
}
static
unsigned
GetX11Modifier
(
Display
*
p_display
,
unsigned
i_vlc
)
{
unsigned
i_mask
=
0
;
if
(
i_vlc
&
KEY_MODIFIER_ALT
)
i_mask
|=
GetModifier
(
p_display
,
XK_Alt_L
)
|
GetModifier
(
p_display
,
XK_Alt_R
);
if
(
i_vlc
&
KEY_MODIFIER_CTRL
)
i_mask
|=
GetModifier
(
p_display
,
XK_Control_L
)
|
GetModifier
(
p_display
,
XK_Control_R
);
if
(
i_vlc
&
KEY_MODIFIER_SHIFT
)
i_mask
|=
GetModifier
(
p_display
,
XK_Shift_L
)
|
GetModifier
(
p_display
,
XK_Shift_R
);
return
i_mask
;
}
/* FIXME this table is also used by the vout */
static
const
struct
{
KeySym
i_x11
;
unsigned
i_vlc
;
}
x11keys_to_vlckeys
[]
=
{
{
XK_F1
,
KEY_F1
},
{
XK_F2
,
KEY_F2
},
{
XK_F3
,
KEY_F3
},
{
XK_F4
,
KEY_F4
},
{
XK_F5
,
KEY_F5
},
{
XK_F6
,
KEY_F6
},
{
XK_F7
,
KEY_F7
},
{
XK_F8
,
KEY_F8
},
{
XK_F9
,
KEY_F9
},
{
XK_F10
,
KEY_F10
},
{
XK_F11
,
KEY_F11
},
{
XK_F12
,
KEY_F12
},
{
XK_Return
,
KEY_ENTER
},
{
XK_KP_Enter
,
KEY_ENTER
},
{
XK_space
,
KEY_SPACE
},
{
XK_Escape
,
KEY_ESC
},
{
XK_Menu
,
KEY_MENU
},
{
XK_Left
,
KEY_LEFT
},
{
XK_Right
,
KEY_RIGHT
},
{
XK_Up
,
KEY_UP
},
{
XK_Down
,
KEY_DOWN
},
{
XK_Home
,
KEY_HOME
},
{
XK_End
,
KEY_END
},
{
XK_Page_Up
,
KEY_PAGEUP
},
{
XK_Page_Down
,
KEY_PAGEDOWN
},
{
XK_Insert
,
KEY_INSERT
},
{
XK_Delete
,
KEY_DELETE
},
{
XF86XK_AudioNext
,
KEY_MEDIA_NEXT_TRACK
},
{
XF86XK_AudioPrev
,
KEY_MEDIA_PREV_TRACK
},
{
XF86XK_AudioMute
,
KEY_VOLUME_MUTE
},
{
XF86XK_AudioLowerVolume
,
KEY_VOLUME_DOWN
},
{
XF86XK_AudioRaiseVolume
,
KEY_VOLUME_UP
},
{
XF86XK_AudioPlay
,
KEY_MEDIA_PLAY_PAUSE
},
{
XF86XK_AudioPause
,
KEY_MEDIA_PLAY_PAUSE
},
{
0
,
0
}
};
static
KeySym
GetX11Key
(
unsigned
i_vlc
)
{
for
(
int
i
=
0
;
x11keys_to_vlckeys
[
i
].
i_vlc
!=
0
;
i
++
)
{
if
(
x11keys_to_vlckeys
[
i
].
i_vlc
==
i_vlc
)
return
x11keys_to_vlckeys
[
i
].
i_x11
;
}
char
psz_key
[
2
];
psz_key
[
0
]
=
i_vlc
;
psz_key
[
1
]
=
'\0'
;
return
XStringToKeysym
(
psz_key
);
}
static
void
Mapping
(
intf_thread_t
*
p_intf
)
{
static
const
KeySym
p_x11_modifier_ignored
[]
=
{
0
,
XK_Num_Lock
,
XK_Scroll_Lock
,
XK_Caps_Lock
,
};
intf_sys_t
*
p_sys
=
p_intf
->
p_sys
;
p_sys
->
i_map
=
0
;
p_sys
->
p_map
=
NULL
;
/* Registering of Hotkeys */
for
(
struct
hotkey
*
p_hotkey
=
p_intf
->
p_libvlc
->
p_hotkeys
;
p_hotkey
->
psz_action
!=
NULL
;
p_hotkey
++
)
{
char
*
psz_hotkey
;
if
(
asprintf
(
&
psz_hotkey
,
"global-%s"
,
p_hotkey
->
psz_action
)
<
0
)
break
;
const
int
i_vlc_action
=
p_hotkey
->
i_action
;
const
int
i_vlc_key
=
config_GetInt
(
p_intf
,
psz_hotkey
);
free
(
psz_hotkey
);
if
(
!
i_vlc_key
)
continue
;
const
KeyCode
key
=
XKeysymToKeycode
(
p_sys
->
p_display
,
GetX11Key
(
i_vlc_key
&
~
KEY_MODIFIER
)
);
const
unsigned
i_modifier
=
GetX11Modifier
(
p_sys
->
p_display
,
i_vlc_key
&
KEY_MODIFIER
);
for
(
int
j
=
0
;
j
<
sizeof
(
p_x11_modifier_ignored
)
/
sizeof
(
*
p_x11_modifier_ignored
);
j
++
)
{
const
unsigned
i_ignored
=
GetModifier
(
p_sys
->
p_display
,
p_x11_modifier_ignored
[
j
]
);
if
(
j
!=
0
&&
i_ignored
==
0x00
)
continue
;
hotkey_mapping_t
*
p_map_old
=
p_sys
->
p_map
;
p_sys
->
p_map
=
realloc
(
p_sys
->
p_map
,
sizeof
(
*
p_sys
->
p_map
)
*
(
p_sys
->
i_map
+
1
)
);
if
(
!
p_sys
->
p_map
)
{
p_sys
->
p_map
=
p_map_old
;
break
;
}
hotkey_mapping_t
*
p_map
=
&
p_sys
->
p_map
[
p_sys
->
i_map
++
];
p_map
->
i_x11
=
key
;
p_map
->
i_modifier
=
i_modifier
|
i_ignored
;
p_map
->
i_action
=
i_vlc_action
;
}
}
}
static
void
Register
(
intf_thread_t
*
p_intf
)
{
intf_sys_t
*
p_sys
=
p_intf
->
p_sys
;
for
(
int
i
=
0
;
i
<
p_sys
->
i_map
;
i
++
)
{
hotkey_mapping_t
*
p_map
=
&
p_sys
->
p_map
[
i
];
XGrabKey
(
p_sys
->
p_display
,
p_map
->
i_x11
,
p_map
->
i_modifier
,
DefaultRootWindow
(
p_sys
->
p_display
),
True
,
GrabModeAsync
,
GrabModeAsync
);
}
}
static
void
Unregister
(
intf_thread_t
*
p_intf
)
{
intf_sys_t
*
p_sys
=
p_intf
->
p_sys
;
for
(
int
i
=
0
;
i
<
p_sys
->
i_map
;
i
++
)
{
hotkey_mapping_t
*
p_map
=
&
p_sys
->
p_map
[
i
];
XUngrabKey
(
p_sys
->
p_display
,
p_map
->
i_x11
,
p_map
->
i_modifier
,
DefaultRootWindow
(
p_sys
->
p_display
)
);
}
}
static
void
*
Thread
(
void
*
p_data
)
{
intf_thread_t
*
p_intf
=
p_data
;
intf_sys_t
*
p_sys
=
p_intf
->
p_sys
;
Display
*
p_display
=
p_sys
->
p_display
;
int
canc
=
vlc_savecancel
();
if
(
!
p_display
)
return
NULL
;
/* */
XFlush
(
p_display
);
/* */
int
fd
=
ConnectionNumber
(
p_display
);
for
(
;;
)
{
/* Wait for x11 event */
vlc_restorecancel
(
canc
);
struct
pollfd
fds
=
{
.
fd
=
fd
,
.
events
=
POLLIN
,
};
if
(
poll
(
&
fds
,
1
,
-
1
)
<
0
)
{
if
(
errno
!=
EINTR
)
break
;
continue
;
}
canc
=
vlc_savecancel
();
while
(
XPending
(
p_display
)
>
0
)
{
XEvent
e
;
XNextEvent
(
p_display
,
&
e
);
if
(
e
.
type
!=
KeyPress
)
continue
;
for
(
int
i
=
0
;
i
<
p_sys
->
i_map
;
i
++
)
{
hotkey_mapping_t
*
p_map
=
&
p_sys
->
p_map
[
i
];
if
(
p_map
->
i_x11
==
e
.
xkey
.
keycode
&&
p_map
->
i_modifier
==
e
.
xkey
.
state
)
{
var_SetInteger
(
p_intf
->
p_libvlc
,
"key-action"
,
p_map
->
i_action
);
break
;
}
}
}
}
vlc_restorecancel
(
canc
);
return
NULL
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment