diff options
Diffstat (limited to 'tmk_core')
25 files changed, 112 insertions, 2705 deletions
diff --git a/tmk_core/protocol/chibios.mk b/tmk_core/protocol/chibios.mk index a7f2d8e93d..8eaf5b10d2 100644 --- a/tmk_core/protocol/chibios.mk +++ b/tmk_core/protocol/chibios.mk @@ -15,7 +15,3 @@ VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)/lufa_utils OPT_DEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=64 OPT_DEFS += -DFIXED_NUM_CONFIGURATIONS=1 - -ifeq ($(strip $(MIDI_ENABLE)), yes) - include $(TMK_PATH)/protocol/midi.mk -endif diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index 2643906058..ddeeab433c 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -69,19 +69,27 @@ uint8_t keyboard_led_state = 0; volatile uint16_t keyboard_idle_count = 0; static virtual_timer_t keyboard_idle_timer; -#if CH_KERNEL_MAJOR >= 7 static void keyboard_idle_timer_cb(struct ch_virtual_timer *, void *arg); -#elif CH_KERNEL_MAJOR <= 6 -static void keyboard_idle_timer_cb(void *arg); -#endif report_keyboard_t keyboard_report_sent = {{0}}; -#ifdef MOUSE_ENABLE -report_mouse_t mouse_report_blank = {0}; -#endif /* MOUSE_ENABLE */ +report_mouse_t mouse_report_sent = {0}; + +union { + uint8_t report_id; + report_keyboard_t keyboard; #ifdef EXTRAKEY_ENABLE -uint8_t extra_report_blank[3] = {0}; -#endif /* EXTRAKEY_ENABLE */ + report_extra_t extra; +#endif +#ifdef MOUSE_ENABLE + report_mouse_t mouse; +#endif +#ifdef DIGITIZER_ENABLE + report_digitizer_t digitizer; +#endif +#ifdef JOYSTICK_ENABLE + report_joystick_t joystick; +#endif +} universal_report_blank = {0}; /* --------------------------------------------------------- * Descriptors and USB driver objects @@ -111,9 +119,10 @@ uint8_t extra_report_blank[3] = {0}; static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t wIndex) { (void)usbp; static USBDescriptor desc; - uint16_t wValue = ((uint16_t)dtype << 8) | dindex; - desc.ud_string = NULL; - desc.ud_size = get_usb_descriptor(wValue, wIndex, (const void **const) & desc.ud_string); + uint16_t wValue = ((uint16_t)dtype << 8) | dindex; + uint16_t wLength = ((uint16_t)usbp->setup[7] << 8) | usbp->setup[6]; + desc.ud_string = NULL; + desc.ud_size = get_usb_descriptor(wValue, wIndex, wLength, (const void **const) & desc.ud_string); if (desc.ud_string == NULL) return NULL; else @@ -585,7 +594,8 @@ static uint16_t get_hword(uint8_t *p) { */ static uint8_t set_report_buf[2] __attribute__((aligned(4))); -static void set_led_transfer_cb(USBDriver *usbp) { + +static void set_led_transfer_cb(USBDriver *usbp) { if (usbp->setup[6] == 2) { /* LSB(wLength) */ uint8_t report_id = set_report_buf[0]; if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) { @@ -614,20 +624,38 @@ static bool usb_request_hook_cb(USBDriver *usbp) { switch (usbp->setup[1]) { /* bRequest */ case HID_GET_REPORT: switch (usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */ +#ifndef KEYBOARD_SHARED_EP case KEYBOARD_INTERFACE: - usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent), NULL); + usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, KEYBOARD_REPORT_SIZE, NULL); return TRUE; break; - +#endif #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) case MOUSE_INTERFACE: - usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL); + usbSetupTransfer(usbp, (uint8_t *)&mouse_report_sent, sizeof(mouse_report_sent), NULL); return TRUE; break; #endif - +#ifdef SHARED_EP_ENABLE + case SHARED_INTERFACE: +# ifdef KEYBOARD_SHARED_EP + if (usbp->setup[2] == REPORT_ID_KEYBOARD) { + usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, KEYBOARD_REPORT_SIZE, NULL); + return TRUE; + break; + } +# endif +# ifdef MOUSE_SHARED_EP + if (usbp->setup[2] == REPORT_ID_MOUSE) { + usbSetupTransfer(usbp, (uint8_t *)&mouse_report_sent, sizeof(mouse_report_sent), NULL); + return TRUE; + break; + } +# endif +#endif /* SHARED_EP_ENABLE */ default: - usbSetupTransfer(usbp, NULL, 0, NULL); + universal_report_blank.report_id = usbp->setup[2]; + usbSetupTransfer(usbp, (uint8_t *)&universal_report_blank, usbp->setup[6], NULL); return TRUE; break; } @@ -798,12 +826,8 @@ __attribute__((weak)) void usb_start(USBDriver *usbp) { /* Idle requests timer code * callback (called from ISR, unlocked state) */ -#if CH_KERNEL_MAJOR >= 7 static void keyboard_idle_timer_cb(struct ch_virtual_timer *timer, void *arg) { (void)timer; -#elif CH_KERNEL_MAJOR <= 6 -static void keyboard_idle_timer_cb(void *arg) { -#endif USBDriver *usbp = (USBDriver *)arg; osalSysLockFromISR(); @@ -838,99 +862,61 @@ uint8_t keyboard_leds(void) { return keyboard_led_state; } -/* prepare and start sending a report IN - * not callable from ISR or locked state */ -void send_keyboard(report_keyboard_t *report) { - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - goto unlock; - } - -#ifdef NKRO_ENABLE - if (keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */ - /* need to wait until the previous packet has made it through */ - /* can rewrite this using the synchronous API, then would wait - * until *after* the packet has been transmitted. I think - * this is more efficient */ - /* busy wait, should be short and not very common */ - if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - osalThreadSuspendS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread); - - /* after osalThreadSuspendS returns USB status might have changed */ - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - goto unlock; - } - } - usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(struct nkro_report)); - } else -#endif /* NKRO_ENABLE */ - { /* regular protocol */ - /* need to wait until the previous packet has made it through */ - /* busy wait, should be short and not very common */ - if (usbGetTransmitStatusI(&USB_DRIVER, KEYBOARD_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread); - - /* after osalThreadSuspendS returns USB status might have changed */ - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - goto unlock; - } - } - uint8_t *data, size; - if (keyboard_protocol) { - data = (uint8_t *)report; - size = KEYBOARD_REPORT_SIZE; - } else { /* boot protocol */ - data = &report->mods; - size = 8; - } - usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size); - } - keyboard_report_sent = *report; - -unlock: - osalSysUnlock(); -} - -/* --------------------------------------------------------- - * Mouse functions - * --------------------------------------------------------- - */ - -#ifdef MOUSE_ENABLE -void send_mouse(report_mouse_t *report) { +void send_report(uint8_t endpoint, void *report, size_t size) { osalSysLock(); if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { osalSysUnlock(); return; } - if (usbGetTransmitStatusI(&USB_DRIVER, MOUSE_IN_EPNUM)) { + if (usbGetTransmitStatusI(&USB_DRIVER, endpoint)) { /* Need to either suspend, or loop and call unlock/lock during * every iteration - otherwise the system will remain locked, * no interrupts served, so USB not going through as well. * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[MOUSE_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { + if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[endpoint]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { osalSysUnlock(); return; } } - usbStartTransmitI(&USB_DRIVER, MOUSE_IN_EPNUM, (uint8_t *)report, sizeof(report_mouse_t)); + usbStartTransmitI(&USB_DRIVER, endpoint, report, size); osalSysUnlock(); } -#else /* MOUSE_ENABLE */ +/* prepare and start sending a report IN + * not callable from ISR or locked state */ +void send_keyboard(report_keyboard_t *report) { + uint8_t ep = KEYBOARD_IN_EPNUM; + size_t size = KEYBOARD_REPORT_SIZE; + + /* If we're in Boot Protocol, don't send any report ID or other funky fields */ + if (!keyboard_protocol) { + send_report(ep, &report->mods, 8); + } else { +#ifdef NKRO_ENABLE + if (keymap_config.nkro) { + ep = SHARED_IN_EPNUM; + size = sizeof(struct nkro_report); + } +#endif + + send_report(ep, report, size); + } + + keyboard_report_sent = *report; +} + +/* --------------------------------------------------------- + * Mouse functions + * --------------------------------------------------------- + */ + void send_mouse(report_mouse_t *report) { - (void)report; +#ifdef MOUSE_ENABLE + send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t)); + mouse_report_sent = *report; +#endif } -#endif /* MOUSE_ENABLE */ /* --------------------------------------------------------- * Extrakey functions @@ -939,97 +925,25 @@ void send_mouse(report_mouse_t *report) { void send_extra(report_extra_t *report) { #ifdef EXTRAKEY_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(report_extra_t)); - osalSysUnlock(); + send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t)); #endif } void send_programmable_button(report_programmable_button_t *report) { #ifdef PROGRAMMABLE_BUTTON_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(report_programmable_button_t)); - osalSysUnlock(); + send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t)); #endif } void send_joystick(report_joystick_t *report) { #ifdef JOYSTICK_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, JOYSTICK_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[JOYSTICK_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, JOYSTICK_IN_EPNUM, (uint8_t *)report, sizeof(report_joystick_t)); - osalSysUnlock(); + send_report(JOYSTICK_IN_EPNUM, report, sizeof(report_joystick_t)); #endif } void send_digitizer(report_digitizer_t *report) { #ifdef DIGITIZER_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, DIGITIZER_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[DIGITIZER_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, DIGITIZER_IN_EPNUM, (uint8_t *)report, sizeof(report_digitizer_t)); - osalSysUnlock(); + send_report(DIGITIZER_IN_EPNUM, report, sizeof(report_digitizer_t)); #endif } diff --git a/tmk_core/protocol/host.h b/tmk_core/protocol/host.h index 6e73bd17e0..4837456727 100644 --- a/tmk_core/protocol/host.h +++ b/tmk_core/protocol/host.h @@ -26,9 +26,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define IS_LED_ON(leds, led_name) ((leds) & (1 << (led_name))) #define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name))) -#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name) -#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name) - #ifdef __cplusplus extern "C" { #endif diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk index 00fec478ac..b048c1836c 100644 --- a/tmk_core/protocol/lufa.mk +++ b/tmk_core/protocol/lufa.mk @@ -18,7 +18,7 @@ LUFA_SRC = lufa.c \ $(LUFA_SRC_USB) ifeq ($(strip $(MIDI_ENABLE)), yes) - include $(TMK_PATH)/protocol/midi.mk + LUFA_SRC += $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MIDIClassDevice.c endif ifeq ($(strip $(VIRTSER_ENABLE)), yes) diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 8f36e02b9a..20bfc8fb3c 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -298,7 +298,7 @@ void EVENT_USB_Device_Reset(void) { * * FIXME: Needs doc */ -void EVENT_USB_Device_Suspend() { +void EVENT_USB_Device_Suspend(void) { print("[S]"); usb_device_state_set_suspend(USB_Device_ConfigurationNumber != 0, USB_Device_ConfigurationNumber); @@ -311,7 +311,7 @@ void EVENT_USB_Device_Suspend() { * * FIXME: Needs doc */ -void EVENT_USB_Device_WakeUp() { +void EVENT_USB_Device_WakeUp(void) { print("[W]"); #if defined(NO_USB_STARTUP_CHECK) suspend_wakeup_init(); @@ -901,5 +901,5 @@ void protocol_post_task(void) { } uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint16_t wIndex, const void **const DescriptorAddress) { - return get_usb_descriptor(wValue, wIndex, DescriptorAddress); + return get_usb_descriptor(wValue, wIndex, USB_ControlRequest.wLength, DescriptorAddress); } diff --git a/tmk_core/protocol/midi.mk b/tmk_core/protocol/midi.mk deleted file mode 100644 index a5f76b2d31..0000000000 --- a/tmk_core/protocol/midi.mk +++ /dev/null @@ -1,11 +0,0 @@ -MIDI_DIR = protocol/midi - -SRC += midi.c \ - midi_device.c \ - bytequeue/bytequeue.c \ - bytequeue/interrupt_setting.c \ - sysex_tools.c \ - qmk_midi.c \ - $(LUFA_SRC_USBCLASS) - -VPATH += $(TMK_PATH)/$(MIDI_DIR) diff --git a/tmk_core/protocol/midi/Config/LUFAConfig.h b/tmk_core/protocol/midi/Config/LUFAConfig.h deleted file mode 100644 index dead96de78..0000000000 --- a/tmk_core/protocol/midi/Config/LUFAConfig.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * \brief LUFA Library Configuration Header File - * - * This header file is used to configure LUFA's compile time options, - * as an alternative to the compile time constants supplied through - * a makefile. - * - * For information on what each token does, refer to the LUFA - * manual section "Summary of Compile Tokens". - */ - -#pragma once - -#if (ARCH == ARCH_AVR8) - -/* Non-USB Related Configuration Tokens: */ -// #define DISABLE_TERMINAL_CODES - -/* USB Class Driver Related Tokens: */ -// #define HID_HOST_BOOT_PROTOCOL_ONLY -// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} -// #define HID_USAGE_STACK_DEPTH {Insert Value Here} -// #define HID_MAX_COLLECTIONS {Insert Value Here} -// #define HID_MAX_REPORTITEMS {Insert Value Here} -// #define HID_MAX_REPORT_IDS {Insert Value Here} -// #define NO_CLASS_DRIVER_AUTOFLUSH - -/* General USB Driver Related Tokens: */ -// #define ORDERED_EP_CONFIG -# define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) -# define USB_DEVICE_ONLY -// #define USB_HOST_ONLY -// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} -// #define NO_LIMITED_CONTROLLER_CONNECT -// #define NO_SOF_EVENTS - -/* USB Device Mode Driver Related Tokens: */ -// #define USE_RAM_DESCRIPTORS -# define USE_FLASH_DESCRIPTORS -// #define USE_EEPROM_DESCRIPTORS -// #define NO_INTERNAL_SERIAL -# define FIXED_CONTROL_ENDPOINT_SIZE 8 -// #define DEVICE_STATE_AS_GPIOR {Insert Value Here} -# define FIXED_NUM_CONFIGURATIONS 1 -// #define CONTROL_ONLY_DEVICE -// #define INTERRUPT_CONTROL_ENDPOINT -// #define NO_DEVICE_REMOTE_WAKEUP -// #define NO_DEVICE_SELF_POWER - -/* USB Host Mode Driver Related Tokens: */ -// #define HOST_STATE_AS_GPIOR {Insert Value Here} -// #define USB_HOST_TIMEOUT_MS {Insert Value Here} -// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} -// #define NO_AUTO_VBUS_MANAGEMENT -// #define INVERTED_VBUS_ENABLE_LINE - -#else - -# error Unsupported architecture for this LUFA configuration file. - -#endif diff --git a/tmk_core/protocol/midi/bytequeue/COPYING b/tmk_core/protocol/midi/bytequeue/COPYING deleted file mode 100755 index 94a9ed024d..0000000000 --- a/tmk_core/protocol/midi/bytequeue/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be d |